mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-16 12:33:48 -07:00
Compare commits
287 Commits
v0.15.0bet
...
v0.18.0bet
Author | SHA1 | Date | |
---|---|---|---|
|
c02bfc3897 | ||
|
878a20741b | ||
|
d5eafe1926 | ||
|
e2da4ff257 | ||
|
dbb6732743 | ||
|
4034aa2c60 | ||
|
fcb5037a1d | ||
|
0634abf168 | ||
|
478fa7cafe | ||
|
549fdf63f6 | ||
|
1a14841a75 | ||
|
a7ed3a5e47 | ||
|
884fc4f89c | ||
|
1e5cab1ee7 | ||
|
5a00f0c657 | ||
|
2cbb10d850 | ||
|
23cd1b8c66 | ||
|
be6f5ce831 | ||
|
78a545112a | ||
|
2cdabf581e | ||
|
34a7f17956 | ||
|
dd11434e90 | ||
|
61995e3b4e | ||
|
13befbd266 | ||
|
a5ffd44caf | ||
|
0208dff574 | ||
|
3157bebed7 | ||
|
c0bb4db15c | ||
|
27cada2a02 | ||
|
153c99217d | ||
|
851df11eb5 | ||
|
5f2c741f49 | ||
|
9a9ecc25db | ||
|
34b145ee65 | ||
|
f41fe59cb6 | ||
|
7ff1fd9d69 | ||
|
d0b3cdc835 | ||
|
1cf829c889 | ||
|
17992b633d | ||
|
c545ab4993 | ||
|
1d2e4243dc | ||
|
aefc34b405 | ||
|
2a20cf5379 | ||
|
e3a3837164 | ||
|
c86ab4694c | ||
|
5d5066570c | ||
|
1a55fb4170 | ||
|
efbc3f8194 | ||
|
f755351511 | ||
|
57817f7252 | ||
|
b4c45aa2e3 | ||
|
5295244026 | ||
|
082f439db2 | ||
|
12697d2b72 | ||
|
976b44443a | ||
|
6553fb5a40 | ||
|
bee06f3507 | ||
|
5a750b485a | ||
|
a71f44baa5 | ||
|
65db3a7bd3 | ||
|
22384869a6 | ||
|
ff76fbe763 | ||
|
cfbab453e8 | ||
|
6a59b57ef8 | ||
|
f50c786640 | ||
|
70aece8522 | ||
|
c9eb0f3aab | ||
|
206360177f | ||
|
34ad837fd9 | ||
|
e796157672 | ||
|
b51222c004 | ||
|
9aad352789 | ||
|
ce8c20c1ed | ||
|
349afa0e7a | ||
|
748a6965ca | ||
|
97af7c416e | ||
|
47512dd6db | ||
|
653b9ed0e4 | ||
|
d0e47d9fe0 | ||
|
f978368a4e | ||
|
c47581fc5a | ||
|
31aa357c17 | ||
|
6ddfae0a07 | ||
|
0d7176792b | ||
|
c1542da18a | ||
|
5b548f5bc3 | ||
|
5ac2005318 | ||
|
a2b8e3b34e | ||
|
d78b53968f | ||
|
61b950d942 | ||
|
a16073a87b | ||
|
603a90886f | ||
|
95bbac8791 | ||
|
a69fd21a1a | ||
|
b6e33830af | ||
|
2c67c1c4f8 | ||
|
989deafd5e | ||
|
9f1d7f7fc7 | ||
|
6245c92bd0 | ||
|
2e32e202e9 | ||
|
d994ad75e8 | ||
|
2caebb3b10 | ||
|
05f3eebd96 | ||
|
74d05d0adc | ||
|
341a0616aa | ||
|
ea7f617df6 | ||
|
644c64d79d | ||
|
d193d70ecf | ||
|
9e227a52c0 | ||
|
1a767b021b | ||
|
83e4006b16 | ||
|
1759b0483c | ||
|
f7174acc48 | ||
|
c2cd718e89 | ||
|
c21808dd2d | ||
|
2c2e35eec1 | ||
|
c064711d2a | ||
|
7d6ccca695 | ||
|
28c81fc71e | ||
|
d5a0610ea2 | ||
|
4aebb73de0 | ||
|
46e51a81c4 | ||
|
83ad59fae7 | ||
|
f9a7b6bf26 | ||
|
cdb331076a | ||
|
ba9a8a9ded | ||
|
34bd2cf803 | ||
|
69f1d7b360 | ||
|
e0bc952c83 | ||
|
cf869d9636 | ||
|
077c1491a8 | ||
|
c04563734e | ||
|
1d0d350fc3 | ||
|
d55338a3f5 | ||
|
c6a3092b45 | ||
|
10303259f7 | ||
|
3dca2fd61e | ||
|
47eac4be1c | ||
|
2995867760 | ||
|
c132f5a91f | ||
|
24587492dd | ||
|
44cee0f5f8 | ||
|
2c714eace5 | ||
|
0d7d7a970d | ||
|
3a27ef5e12 | ||
|
6d273c8e44 | ||
|
c775153e01 | ||
|
b71d7c9007 | ||
|
ce5f025428 | ||
|
6df6aea1ba | ||
|
ca2d2db0ef | ||
|
1ccb0b5f96 | ||
|
c2545b3ae6 | ||
|
dada872981 | ||
|
1eec5161bd | ||
|
53c3644c29 | ||
|
6d66dde208 | ||
|
1b349f79ac | ||
|
da8be82c9a | ||
|
8ffd244ef6 | ||
|
bf9d31ce49 | ||
|
98a32f5e52 | ||
|
dc1737f128 | ||
|
48634d7e4a | ||
|
ecf0cdaba4 | ||
|
286cb90c48 | ||
|
3f77cde50e | ||
|
1145654987 | ||
|
da4cfb9c32 | ||
|
58375bc87a | ||
|
83d99ce5bd | ||
|
dca30815b0 | ||
|
edeb759bb1 | ||
|
610d4d9473 | ||
|
f30e572e00 | ||
|
34cd8b125a | ||
|
b0544dbfff | ||
|
a7bdfc06ca | ||
|
7e7cb40909 | ||
|
724fa4a7d4 | ||
|
cee0645fd1 | ||
|
df9409b8a2 | ||
|
f274a70edf | ||
|
ef24a27ade | ||
|
670d6ce8f4 | ||
|
f3917f2122 | ||
|
5d6e56b67c | ||
|
624303bfb9 | ||
|
eb3c132fc5 | ||
|
170def35d7 | ||
|
2ee9fb0675 | ||
|
1396d2a39b | ||
|
7ecc41db9c | ||
|
7ffe4eda12 | ||
|
25756afad5 | ||
|
8880298f50 | ||
|
d89355f0a6 | ||
|
ae91f6610f | ||
|
6e7143e0f5 | ||
|
f55f56f260 | ||
|
6287f2b71b | ||
|
7e781f24c5 | ||
|
3bf7c5aea1 | ||
|
092dbda88a | ||
|
cb687c208c | ||
|
945b4d7139 | ||
|
881f828250 | ||
|
0743dab3f0 | ||
|
496e37d044 | ||
|
1263bd5dcb | ||
|
9ee78b1a92 | ||
|
406b2fe6dc | ||
|
90f2259f5e | ||
|
948f4978e7 | ||
|
32ae0c51f0 | ||
|
fe4a97f245 | ||
|
2f3528c076 | ||
|
1964bcb13f | ||
|
4b779ac142 | ||
|
abc2d442dd | ||
|
b64f1fc5c4 | ||
|
33d264eaa7 | ||
|
5e3b8c3233 | ||
|
bbdfb7853d | ||
|
a19b152e4a | ||
|
1468001d3b | ||
|
7faa3c367d | ||
|
fd379db846 | ||
|
28a6e0ce31 | ||
|
af7d60b3f8 | ||
|
c4487534d2 | ||
|
e4820d1c71 | ||
|
b4a8efc1a7 | ||
|
9480c0fb90 | ||
|
f901c60da5 | ||
|
922e978f56 | ||
|
0508c7d384 | ||
|
ee3b770cfd | ||
|
a29af89545 | ||
|
552c4b7361 | ||
|
d7ef19e2e7 | ||
|
190ddb5697 | ||
|
095688712d | ||
|
d264fbd36a | ||
|
e4527c6b60 | ||
|
32e8eda40a | ||
|
477ad2dd82 | ||
|
e90c5c6347 | ||
|
11ce468996 | ||
|
9c5023ab1a | ||
|
0e4a894edb | ||
|
71e2562a41 | ||
|
9153a81090 | ||
|
0d7f6eac9e | ||
|
6d46ed4011 | ||
|
f825b87c2a | ||
|
44da575ea8 | ||
|
a587909fd5 | ||
|
fd81ba5a4f | ||
|
934f81c93d | ||
|
e8be1507ef | ||
|
60c414ccad | ||
|
0d702b556d | ||
|
9bbae5b8e2 | ||
|
719a5b4f0b | ||
|
7bdfdaa28a | ||
|
a80e0cecfe | ||
|
3e3f6aef5e | ||
|
996938b7e7 | ||
|
f9325b1655 | ||
|
63dfe305dd | ||
|
ec0c6fa22a | ||
|
c6333ba796 | ||
|
6fe103cf06 | ||
|
71733f68ef | ||
|
d867d42366 | ||
|
6eb7d00386 | ||
|
09268d756f | ||
|
e5dced8b3f | ||
|
b38e7b596f | ||
|
1424539e4d | ||
|
425b07d1e5 | ||
|
65fb526d5c | ||
|
0549aa193f | ||
|
168a326609 | ||
|
7edbaea23d | ||
|
5ff44467d7 |
34
.github/workflows/ci.yaml
vendored
34
.github/workflows/ci.yaml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
cp ./LICENSE hyprland/
|
||||
cp build/Hyprland hyprland/
|
||||
cp hyprctl/hyprctl hyprland/
|
||||
cp subprojects/wlroots/build/libwlroots.so.11032 hyprland/
|
||||
cp subprojects/wlroots/build/libwlroots.so.12032 hyprland/
|
||||
cp build/Hyprland hyprland/
|
||||
cp -r example/ hyprland/
|
||||
cp -r assets/ hyprland/
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
run: |
|
||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
||||
pacman --noconfirm --noprogressbar -Syyu
|
||||
pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers xcb-util-errors xcb-util-renderutil xcb-util-wm xorg-fonts-encodings xorg-server-common xorg-setxkbmap xorg-xkbcomp xorg-xwayland git go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd
|
||||
pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers git go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd cmake
|
||||
- name: Checkout Hyprland
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
@@ -73,13 +73,23 @@ jobs:
|
||||
-Ddefault_library=static
|
||||
- name: Compile
|
||||
run: ninja -C obj-x86_64-pc-linux-gnu
|
||||
# - name: Compress artifacts
|
||||
# run: |
|
||||
# mkdir x86_64-pc-linux-gnu
|
||||
# DESTDIR=$PWD/x86_64-pc-linux-gnu meson install -C obj-x86_64-pc-linux-gnu --tags runtime
|
||||
# tar -cvf x86_64-pc-linux-gnu.tar.xz x86_64-pc-linux-gnu
|
||||
# - name: Upload artifacts
|
||||
# uses: actions/upload-artifact@v3
|
||||
# with:
|
||||
# name: Build artifacts (x86_64-pc-linux-gnu)
|
||||
# path: x86_64-pc-linux-gnu.tar.xz
|
||||
|
||||
noxwayland:
|
||||
name: "Build Hyprland in pure Wayland (Arch)"
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: archlinux
|
||||
steps:
|
||||
- name: Download dependencies
|
||||
run: |
|
||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
||||
pacman --noconfirm --noprogressbar -Syyu
|
||||
pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers git cmake go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd
|
||||
- name: Checkout Hyprland
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Configure
|
||||
run: mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DNO_XWAYLAND:STRING=true -H./ -B./build -G Ninja
|
||||
- name: Compile
|
||||
run: make config && make release
|
||||
|
6
.github/workflows/nix-build.yaml
vendored
6
.github/workflows/nix-build.yaml
vendored
@@ -16,13 +16,13 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install nix
|
||||
uses: cachix/install-nix-action@v17
|
||||
uses: cachix/install-nix-action@v18
|
||||
with:
|
||||
install_url: https://releases.nixos.org/nix/nix-2.10.3/install
|
||||
install_url: https://nixos.org/nix/install
|
||||
extra_nix_config: |
|
||||
auto-optimise-store = true
|
||||
experimental-features = nix-command flakes
|
||||
- uses: cachix/cachix-action@v10
|
||||
- uses: cachix/cachix-action@v12
|
||||
with:
|
||||
name: hyprland
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
|
4
.github/workflows/nix-update.yaml
vendored
4
.github/workflows/nix-update.yaml
vendored
@@ -9,9 +9,9 @@ jobs:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Install nix
|
||||
uses: cachix/install-nix-action@v17
|
||||
uses: cachix/install-nix-action@v18
|
||||
with:
|
||||
install_url: https://releases.nixos.org/nix/nix-2.8.0/install
|
||||
install_url: https://nixos.org/nix/install
|
||||
extra_nix_config: |
|
||||
auto-optimise-store = true
|
||||
experimental-features = nix-command flakes
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -25,3 +25,5 @@ hyprctl/hyprctl
|
||||
gmon.out
|
||||
*.out
|
||||
*.tar.gz
|
||||
|
||||
PKGBUILD
|
||||
|
@@ -5,7 +5,7 @@ project(Hyprland
|
||||
|
||||
set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
|
||||
|
||||
message(STATUS "Configuring Hyprland!")
|
||||
message(STATUS "Gathering git info")
|
||||
|
||||
# Get git info
|
||||
# hash and branch
|
||||
@@ -22,27 +22,38 @@ execute_process(
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(
|
||||
COMMAND bash -c "git show ${GIT_COMMIT_HASH} | head -n 5 | tail -n 1"
|
||||
COMMAND sh -c "git show ${GIT_COMMIT_HASH} | head -n 5 | tail -n 1 | sed -s 's/#|\"//g'"
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT_MESSAGE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(
|
||||
COMMAND bash -c "git diff-index --quiet HEAD -- || echo \"dirty\""
|
||||
COMMAND sh -c "git diff-index --quiet HEAD -- || echo \"dirty\""
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_DIRTY
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
#
|
||||
#
|
||||
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||
message(STATUS "Configuring Hyprland in Debug with CMake")
|
||||
add_definitions( -DHYPRLAND_DEBUG )
|
||||
ELSE()
|
||||
add_compile_options( -O3 )
|
||||
message(STATUS "Configuring Hyprland in Release with CMake")
|
||||
ENDIF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||
|
||||
include_directories(. PRIVATE "subprojects/wlroots/include/")
|
||||
include_directories(. PRIVATE "subprojects/wlroots/build/include/")
|
||||
add_compile_options(-std=c++23 -DWLR_USE_UNSTABLE )
|
||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-narrowing)
|
||||
|
||||
message(STATUS "Checking deps...")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo pango pangocairo libdrm egl xkbcommon libinput xcb) # we do not check for wlroots, as we provide it ourselves
|
||||
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo pango pangocairo libdrm egl xkbcommon libinput) # we do not check for wlroots, as we provide it ourselves
|
||||
|
||||
file(GLOB_RECURSE SRCFILES "src/*.cpp")
|
||||
|
||||
@@ -56,15 +67,11 @@ ENDIF(LEGACY_RENDERER MATCHES true)
|
||||
IF(NO_XWAYLAND MATCHES true)
|
||||
message(STATUS "Using the NO_XWAYLAND flag, disabling XWayland!")
|
||||
add_definitions( -DNO_XWAYLAND )
|
||||
ENDIF(NO_XWAYLAND MATCHES true)
|
||||
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||
message(STATUS "Configuring Hyprland in Debug with CMake!")
|
||||
add_definitions( -DHYPRLAND_DEBUG )
|
||||
ELSE()
|
||||
add_compile_options( -O3 )
|
||||
message(STATUS "Configuring Hyprland in Release with CMake!")
|
||||
ENDIF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||
message(STATUS "XWAYLAND Enabled (NO_XWAYLAND not defined) checking deps...")
|
||||
pkg_check_modules(xcbdep REQUIRED xcb)
|
||||
target_link_libraries(Hyprland xcb)
|
||||
ENDIF(NO_XWAYLAND MATCHES true)
|
||||
|
||||
target_compile_definitions(Hyprland PRIVATE "-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"")
|
||||
target_compile_definitions(Hyprland PRIVATE "-DGIT_BRANCH=\"${GIT_BRANCH}\"")
|
||||
@@ -77,10 +84,12 @@ set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||
include(CPack)
|
||||
|
||||
message(STATUS "Setting link libraries")
|
||||
|
||||
target_link_libraries(Hyprland PkgConfig::deps)
|
||||
|
||||
target_link_libraries(Hyprland
|
||||
${CMAKE_SOURCE_DIR}/subprojects/wlroots/build/libwlroots.so.11032 # wlroots is provided by us
|
||||
${CMAKE_SOURCE_DIR}/subprojects/wlroots/build/libwlroots.so.12032 # wlroots is provided by us
|
||||
pixman-1
|
||||
OpenGL
|
||||
GLESv2
|
||||
@@ -90,6 +99,8 @@ target_link_libraries(Hyprland
|
||||
)
|
||||
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||
message(STATUS "Setting debug flags")
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg -no-pie -fno-builtin")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg -no-pie -fno-builtin")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg -no-pie -fno-builtin")
|
||||
|
30
Makefile
30
Makefile
@@ -91,21 +91,31 @@ wlr-output-power-management-unstable-v1-protocol.c:
|
||||
|
||||
wlr-output-power-management-unstable-v1-protocol.o: wlr-output-power-management-unstable-v1-protocol.h
|
||||
|
||||
linux-dmabuf-unstable-v1-protocol.h:
|
||||
$(WAYLAND_SCANNER) server-header \
|
||||
$(WAYLAND_PROTOCOLS)/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml $@
|
||||
|
||||
linux-dmabuf-unstable-v1-protocol.c:
|
||||
$(WAYLAND_SCANNER) private-code \
|
||||
$(WAYLAND_PROTOCOLS)/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml $@
|
||||
|
||||
linux-dmabuf-unstable-v1-protocol.o: linux-dmabuf-unstable-v1-protocol.h
|
||||
|
||||
legacyrenderer:
|
||||
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DLEGACY_RENDERER:STRING=true -H./ -B./build -G Ninja
|
||||
cmake --build ./build --config Release --target all -j $(nproc)
|
||||
cmake --build ./build --config Release --target all -j$(shell nproc)
|
||||
|
||||
legacyrendererdebug:
|
||||
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DLEGACY_RENDERER:STRING=true -H./ -B./build -G Ninja
|
||||
cmake --build ./build --config Release --target all -j $(nproc)
|
||||
cmake --build ./build --config Release --target all -j$(shell nproc)
|
||||
|
||||
release:
|
||||
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -H./ -B./build -G Ninja
|
||||
cmake --build ./build --config Release --target all -j $(nproc)
|
||||
cmake --build ./build --config Release --target all -j$(shell nproc)
|
||||
|
||||
debug:
|
||||
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -H./ -B./build -G Ninja
|
||||
cmake --build ./build --config Debug --target all -j $(nproc)
|
||||
cmake --build ./build --config Debug --target all -j$(shell nproc)
|
||||
|
||||
clear:
|
||||
rm -rf build
|
||||
@@ -121,7 +131,7 @@ all:
|
||||
install:
|
||||
make clear
|
||||
make fixwlr
|
||||
cd ./subprojects/wlroots && meson build/ --buildtype=release && ninja -C build/ && cp ./build/libwlroots.so.11032 /usr/lib/ && cd ../..
|
||||
cd ./subprojects/wlroots && meson build/ --buildtype=release && ninja -C build/ && cp ./build/libwlroots.so.12032 /usr/lib/ && cd ../..
|
||||
make protocols
|
||||
make release
|
||||
cd hyprctl && make all && cd ..
|
||||
@@ -141,7 +151,7 @@ install:
|
||||
cleaninstall:
|
||||
make clear
|
||||
make fixwlr
|
||||
cd ./subprojects/wlroots && meson build/ --buildtype=release && ninja -C build/ && cp ./build/libwlroots.so.11032 /usr/lib/ && cd ../..
|
||||
cd ./subprojects/wlroots && meson build/ --buildtype=release && ninja -C build/ && cp ./build/libwlroots.so.12032 /usr/lib/ && cd ../..
|
||||
make protocols
|
||||
make release
|
||||
cd hyprctl && make all && cd ..
|
||||
@@ -161,15 +171,15 @@ uninstall:
|
||||
rm -f ${PREFIX}/share/wayland-sessions/hyprland.desktop
|
||||
rm -f ${PREFIX}/bin/Hyprland
|
||||
rm -f ${PREFIX}/bin/hyprctl
|
||||
rm -f /usr/lib/libwlroots.so.11032
|
||||
rm -f /usr/lib/libwlroots.so.12032
|
||||
rm -rf ${PREFIX}/share/hyprland
|
||||
rm -f ${PREFIX}/share/man/man1/Hyprland.1
|
||||
rm -f ${PREFIX}/share/man/man1/hyprctl.1
|
||||
|
||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o wlr-output-power-management-unstable-v1-protocol.o
|
||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o wlr-output-power-management-unstable-v1-protocol.o linux-dmabuf-unstable-v1-protocol.o
|
||||
|
||||
fixwlr:
|
||||
sed -i -E 's/(soversion = 11)([^032]|$$)/soversion = 11032/g' subprojects/wlroots/meson.build
|
||||
sed -i -E 's/(soversion = 12)([^032]|$$)/soversion = 12032/g' subprojects/wlroots/meson.build
|
||||
|
||||
rm -rf ./subprojects/wlroots/build
|
||||
|
||||
@@ -178,7 +188,7 @@ config:
|
||||
|
||||
make fixwlr
|
||||
|
||||
cd subprojects/wlroots && meson ./build --prefix=/usr --buildtype=release
|
||||
cd subprojects/wlroots && meson ./build --prefix=/usr --buildtype=release -Dwerror=false -Dexamples=false
|
||||
cd subprojects/wlroots && ninja -C build/
|
||||
|
||||
cd subprojects/wlroots && ninja -C build/ install
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\"
|
||||
.TH "Hyprland" "1" "24 Aug 2022" "" "Hyprland User Manual"
|
||||
.TH "Hyprland" "1" "11 Oct 2022" "" "Hyprland User Manual"
|
||||
.hy
|
||||
.SH NAME
|
||||
.PP
|
||||
|
@@ -57,3 +57,15 @@ coredumpctl info [PID]
|
||||
```
|
||||
where `[PID]` is the PID you remembered.
|
||||
|
||||
## Obtaining the debug Hyprland coredump
|
||||
In very rare cases, the normal coredump would not be enough.
|
||||
If that's the case, you could try obtaining the debug coredump.
|
||||
1. [Compile Hyprland with debug mode](http://wiki.hyprland.org/Contributing-and-Debugging/#build-in-debug-mode)
|
||||
> Note: The config file used will be `hyprlandd.conf` instead of `hyprland.conf`
|
||||
|
||||
2. Reproduce the crash in debug mode.
|
||||
3. `env DEBUGINFOD_URLS="https://debuginfod.archlinux.org/" coredumpctl debug [PID]`(see section above)
|
||||
4. Wait until the `(gdb)` appears
|
||||
5. If gdb asks you `press y to continue without paging?` Type `y`
|
||||
6. `bt -full`
|
||||
7. copy the output of the command and provide that.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\"
|
||||
.TH "hyprctl" "1" "24 Aug 2022" "" "hyprctl User Manual"
|
||||
.TH "hyprctl" "1" "11 Oct 2022" "" "hyprctl User Manual"
|
||||
.hy
|
||||
.SH NAME
|
||||
.PP
|
||||
|
@@ -1,117 +1,158 @@
|
||||
# This is an example Hyprland config file.
|
||||
# Syntax is the same as in Hypr, but settings might differ.
|
||||
#
|
||||
# Refer to the wiki for more information.
|
||||
|
||||
#
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki (basic and advanced configuring)
|
||||
# For a full list, see the wiki
|
||||
#
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Monitors/
|
||||
monitor=,preferred,auto,1
|
||||
workspace=DP-1,1
|
||||
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
|
||||
|
||||
# Execute your favorite apps at launch
|
||||
# exec-once = waybar & hyprpaper & firefox
|
||||
|
||||
# Source a file (multi-file configs)
|
||||
# source = ~/.config/hypr/myColors.conf
|
||||
|
||||
# For all categories, see https://wiki.hyprland.org/Configuring/Variables/
|
||||
input {
|
||||
kb_file=
|
||||
kb_layout=
|
||||
kb_variant=
|
||||
kb_model=
|
||||
kb_options=
|
||||
kb_rules=
|
||||
kb_layout = us
|
||||
kb_variant =
|
||||
kb_model =
|
||||
kb_options =
|
||||
kb_rules =
|
||||
|
||||
follow_mouse=1
|
||||
follow_mouse = 1
|
||||
|
||||
touchpad {
|
||||
natural_scroll=no
|
||||
natural_scroll = no
|
||||
}
|
||||
|
||||
sensitivity=0 # -1.0 - 1.0, 0 means no modification.
|
||||
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
|
||||
}
|
||||
|
||||
general {
|
||||
gaps_in=5
|
||||
gaps_out=20
|
||||
border_size=2
|
||||
col.active_border=0x66ee1111
|
||||
col.inactive_border=0x66333333
|
||||
# See https://wiki.hyprland.org/Configuring/Variables/ for more
|
||||
|
||||
apply_sens_to_raw=0 # whether to apply the sensitivity to raw input (e.g. used by games where you aim using your mouse)
|
||||
gaps_in = 5
|
||||
gaps_out = 20
|
||||
border_size = 2
|
||||
col.active_border = rgba(1affffee)
|
||||
col.inactive_border = rgba(595959aa)
|
||||
|
||||
damage_tracking=full # leave it on full unless you hate your GPU and want to make it suffer
|
||||
layout = dwindle
|
||||
}
|
||||
|
||||
decoration {
|
||||
rounding=10
|
||||
blur=1
|
||||
blur_size=3 # minimum 1
|
||||
blur_passes=1 # minimum 1
|
||||
blur_new_optimizations=1
|
||||
# See https://wiki.hyprland.org/Configuring/Variables/ for more
|
||||
|
||||
rounding = 10
|
||||
blur = yes
|
||||
blur_size = 3
|
||||
blur_passes = 1
|
||||
blur_new_optimizations = on
|
||||
|
||||
drop_shadow = yes
|
||||
shadow_range = 4
|
||||
shadow_render_power = 3
|
||||
col.shadow = rgba(1a1a1aee)
|
||||
}
|
||||
|
||||
animations {
|
||||
enabled=1
|
||||
animation=windows,1,7,default
|
||||
animation=border,1,10,default
|
||||
animation=fade,1,10,default
|
||||
animation=workspaces,1,6,default
|
||||
enabled = yes
|
||||
|
||||
# Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||
|
||||
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
|
||||
|
||||
animation = windows, 1, 7, myBezier
|
||||
animation = windowsOut, 1, 7, default, popin 80%
|
||||
animation = border, 1, 10, default
|
||||
animation = fade, 1, 7, default
|
||||
animation = workspaces, 1, 6, default
|
||||
}
|
||||
|
||||
dwindle {
|
||||
pseudotile=0 # enable pseudotiling on dwindle
|
||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||
pseudotile = yes # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||
preserve_split = yes # you probably want this
|
||||
}
|
||||
|
||||
master {
|
||||
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
|
||||
new_is_master = true
|
||||
}
|
||||
|
||||
gestures {
|
||||
workspace_swipe=no
|
||||
# See https://wiki.hyprland.org/Configuring/Variables/ for more
|
||||
workspace_swipe = off
|
||||
}
|
||||
|
||||
# example window rules
|
||||
# for windows named/classed as abc and xyz
|
||||
#windowrule=move 69 420,abc
|
||||
#windowrule=size 420 69,abc
|
||||
#windowrule=tile,xyz
|
||||
#windowrule=float,abc
|
||||
#windowrule=pseudo,abc
|
||||
#windowrule=monitor 0,xyz
|
||||
# Example per-device config
|
||||
# See https://wiki.hyprland.org/Configuring/Keywords/#executing for more
|
||||
device:epic mouse V1 {
|
||||
sensitivity = -0.5
|
||||
}
|
||||
|
||||
# some nice mouse binds
|
||||
bindm=SUPER,mouse:272,movewindow
|
||||
bindm=SUPER,mouse:273,resizewindow
|
||||
# Example windowrule v1
|
||||
# windowrule = float, ^(kitty)$
|
||||
# Example windowrule v2
|
||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
|
||||
|
||||
# example binds
|
||||
bind=SUPER,Q,exec,kitty
|
||||
bind=SUPER,C,killactive,
|
||||
bind=SUPER,M,exit,
|
||||
bind=SUPER,E,exec,dolphin
|
||||
bind=SUPER,V,togglefloating,
|
||||
bind=SUPER,R,exec,wofi --show drun -o DP-3
|
||||
bind=SUPER,P,pseudo,
|
||||
|
||||
bind=SUPER,left,movefocus,l
|
||||
bind=SUPER,right,movefocus,r
|
||||
bind=SUPER,up,movefocus,u
|
||||
bind=SUPER,down,movefocus,d
|
||||
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
|
||||
$mainMod = SUPER
|
||||
|
||||
bind=SUPER,1,workspace,1
|
||||
bind=SUPER,2,workspace,2
|
||||
bind=SUPER,3,workspace,3
|
||||
bind=SUPER,4,workspace,4
|
||||
bind=SUPER,5,workspace,5
|
||||
bind=SUPER,6,workspace,6
|
||||
bind=SUPER,7,workspace,7
|
||||
bind=SUPER,8,workspace,8
|
||||
bind=SUPER,9,workspace,9
|
||||
bind=SUPER,0,workspace,10
|
||||
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
|
||||
bind = $mainMod, Q, exec, kitty
|
||||
bind = $mainMod, C, killactive,
|
||||
bind = $mainMod, M, exit,
|
||||
bind = $mainMod, E, exec, dolphin
|
||||
bind = $mainMod, V, togglefloating,
|
||||
bind = $mainMod, R, exec, wofi --show drun
|
||||
bind = $mainMod, P, pseudo, # dwindle
|
||||
bind = $mainMod, J, togglesplit, # dwindle
|
||||
|
||||
bind=ALT,1,movetoworkspace,1
|
||||
bind=ALT,2,movetoworkspace,2
|
||||
bind=ALT,3,movetoworkspace,3
|
||||
bind=ALT,4,movetoworkspace,4
|
||||
bind=ALT,5,movetoworkspace,5
|
||||
bind=ALT,6,movetoworkspace,6
|
||||
bind=ALT,7,movetoworkspace,7
|
||||
bind=ALT,8,movetoworkspace,8
|
||||
bind=ALT,9,movetoworkspace,9
|
||||
bind=ALT,0,movetoworkspace,10
|
||||
# Move focus with mainMod + arrow keys
|
||||
bind = $mainMod, left, movefocus, l
|
||||
bind = $mainMod, right, movefocus, r
|
||||
bind = $mainMod, up, movefocus, u
|
||||
bind = $mainMod, down, movefocus, d
|
||||
|
||||
bind=SUPER,mouse_down,workspace,e+1
|
||||
bind=SUPER,mouse_up,workspace,e-1
|
||||
# Switch workspaces with mainMod + [0-9]
|
||||
bind = $mainMod, 1, workspace, 1
|
||||
bind = $mainMod, 2, workspace, 2
|
||||
bind = $mainMod, 3, workspace, 3
|
||||
bind = $mainMod, 4, workspace, 4
|
||||
bind = $mainMod, 5, workspace, 5
|
||||
bind = $mainMod, 6, workspace, 6
|
||||
bind = $mainMod, 7, workspace, 7
|
||||
bind = $mainMod, 8, workspace, 8
|
||||
bind = $mainMod, 9, workspace, 9
|
||||
bind = $mainMod, 0, workspace, 10
|
||||
|
||||
# Move active window to a workspace with mainMod + SHIFT + [0-9]
|
||||
bind = $mainMod SHIFT, 1, movetoworkspace, 1
|
||||
bind = $mainMod SHIFT, 2, movetoworkspace, 2
|
||||
bind = $mainMod SHIFT, 3, movetoworkspace, 3
|
||||
bind = $mainMod SHIFT, 4, movetoworkspace, 4
|
||||
bind = $mainMod SHIFT, 5, movetoworkspace, 5
|
||||
bind = $mainMod SHIFT, 6, movetoworkspace, 6
|
||||
bind = $mainMod SHIFT, 7, movetoworkspace, 7
|
||||
bind = $mainMod SHIFT, 8, movetoworkspace, 8
|
||||
bind = $mainMod SHIFT, 9, movetoworkspace, 9
|
||||
bind = $mainMod SHIFT, 0, movetoworkspace, 10
|
||||
|
||||
# Scroll through existing workspaces with mainMod + scroll
|
||||
bind = $mainMod, mouse_down, workspace, e+1
|
||||
bind = $mainMod, mouse_up, workspace, e-1
|
||||
|
||||
# Move/resize windows with mainMod + LMB/RMB and dragging
|
||||
bindm = $mainMod, mouse:272, movewindow
|
||||
bindm = $mainMod, mouse:273, resizewindow
|
||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1664687381,
|
||||
"narHash": "sha256-9czSuDzS+OGGwq2kC4KXBLXWfYaup+oLB+AA1Md25U4=",
|
||||
"lastModified": 1668087632,
|
||||
"narHash": "sha256-T/cUx44aYDuLMFfaiVpMdTjL4kpG7bh0VkN6JEM78/E=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "59d2991d4256cdca1c0cda45d876c80a0fe45c31",
|
||||
"rev": "5f588eb4a958f1a526ed8da02d6ea1bea0047b9f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -26,11 +26,11 @@
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"host": "gitlab.freedesktop.org",
|
||||
"lastModified": 1664816798,
|
||||
"narHash": "sha256-oLJyFT1Fc4UNNaDSN+EYUAWL4CufCBpuS5AV4Z4XANo=",
|
||||
"lastModified": 1668292512,
|
||||
"narHash": "sha256-lCMnIguyZgAGq7W2IwIVPoQS8fAfZ/XFwz/1TQ53eI8=",
|
||||
"owner": "wlroots",
|
||||
"repo": "wlroots",
|
||||
"rev": "50cc1ef4d3791d86854dd83c15fff17e5ea1a5b6",
|
||||
"rev": "627a5c511278e67c3c308cdc6a639cbb490f48c3",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
37
flake.nix
37
flake.nix
@@ -20,35 +20,18 @@
|
||||
"aarch64-linux"
|
||||
"x86_64-linux"
|
||||
];
|
||||
pkgsFor = genSystems (system:
|
||||
import nixpkgs {
|
||||
|
||||
pkgsFor = genSystems (system: import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(_: prev: {
|
||||
libdrm = prev.libdrm.overrideAttrs (old: rec {
|
||||
version = "2.4.113";
|
||||
src = prev.fetchurl {
|
||||
url = "https://dri.freedesktop.org/${old.pname}/${old.pname}-${version}.tar.xz";
|
||||
sha256 = "sha256-f9frKWf2O+tGBvItUOJ32ZNIDQXvdd2Iqb2OZ3Mj5eE=";
|
||||
};
|
||||
mesonFlags =
|
||||
[
|
||||
"-Dinstall-test-programs=true"
|
||||
"-Domap=enabled"
|
||||
"-Dcairo-tests=disabled"
|
||||
]
|
||||
++ lib.optionals prev.stdenv.hostPlatform.isAarch [
|
||||
"-Dtegra=enabled"
|
||||
"-Detnaviv=enabled"
|
||||
];
|
||||
});
|
||||
})
|
||||
];
|
||||
overlays = [(_: prev: {
|
||||
hwdata = prev.callPackage ./nix/hwdata.nix {};
|
||||
})];
|
||||
});
|
||||
|
||||
mkDate = longDate: (lib.concatStringsSep "-" [
|
||||
(__substring 0 4 longDate)
|
||||
(__substring 4 2 longDate)
|
||||
(__substring 6 2 longDate)
|
||||
(builtins.substring 0 4 longDate)
|
||||
(builtins.substring 4 2 longDate)
|
||||
(builtins.substring 6 2 longDate)
|
||||
]);
|
||||
in {
|
||||
overlays.default = _: prev: rec {
|
||||
@@ -58,7 +41,7 @@
|
||||
};
|
||||
hyprland = prev.callPackage ./nix/default.nix {
|
||||
stdenv = prev.gcc12Stdenv;
|
||||
version = "0.14.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
version = "0.17.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
wlroots = wlroots-hyprland;
|
||||
};
|
||||
hyprland-debug = hyprland.override {debug = true;};
|
||||
|
@@ -36,6 +36,7 @@ commands:
|
||||
reload
|
||||
setcursor
|
||||
getoption
|
||||
cursorpos
|
||||
|
||||
flags:
|
||||
-j -> output in JSON
|
||||
@@ -80,6 +81,7 @@ void request(std::string arg) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string reply = "";
|
||||
char buffer[8192] = {0};
|
||||
|
||||
sizeWritten = read(SERVERSOCKET, buffer, 8192);
|
||||
@@ -89,9 +91,20 @@ void request(std::string arg) {
|
||||
return;
|
||||
}
|
||||
|
||||
reply += std::string(buffer, sizeWritten);
|
||||
|
||||
while (sizeWritten == 8192) {
|
||||
sizeWritten = read(SERVERSOCKET, buffer, 8192);
|
||||
if (sizeWritten < 0) {
|
||||
std::cout << "Couldn't read (5)";
|
||||
return;
|
||||
}
|
||||
reply += std::string(buffer, sizeWritten);
|
||||
}
|
||||
|
||||
close(SERVERSOCKET);
|
||||
|
||||
std::cout << std::string(buffer);
|
||||
std::cout << reply;
|
||||
}
|
||||
|
||||
void requestHyprpaper(std::string arg) {
|
||||
@@ -145,25 +158,31 @@ void requestHyprpaper(std::string arg) {
|
||||
std::cout << std::string(buffer);
|
||||
}
|
||||
|
||||
void dispatchRequest(int argc, char** argv) {
|
||||
int dispatchRequest(int argc, char** argv) {
|
||||
|
||||
if (argc < 4) {
|
||||
std::cout << "dispatch requires 2 params";
|
||||
return;
|
||||
std::cout << "Usage: hyprctl dispatch <dispatcher> <arg>\n\
|
||||
Execute a hyprland keybind dispatcher with the given argument";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string rq = "/dispatch";
|
||||
|
||||
for(int i = 2; i < argc; i++)
|
||||
for(int i = 2; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--"))
|
||||
continue;
|
||||
rq += " " + std::string(argv[i]);
|
||||
}
|
||||
|
||||
request(rq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void keywordRequest(int argc, char** argv) {
|
||||
int keywordRequest(int argc, char** argv) {
|
||||
if (argc < 4) {
|
||||
std::cout << "keyword requires 2 params";
|
||||
return;
|
||||
std::cout << "Usage: hyprctl keyword <keyword> <arg>\n\
|
||||
Execute a hyprland keyword with the given argument";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string rq = "/keyword";
|
||||
@@ -172,28 +191,48 @@ void keywordRequest(int argc, char** argv) {
|
||||
rq += " " + std::string(argv[i]);
|
||||
|
||||
request(rq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hyprpaperRequest(int argc, char** argv) {
|
||||
int hyprpaperRequest(int argc, char** argv) {
|
||||
if (argc < 4) {
|
||||
std::cout << "hyprpaper requires 2 params";
|
||||
return;
|
||||
std::cout << "Usage: hyprctl hyprpaper <command> <arg>\n\
|
||||
Execute a hyprpaper command with the given argument";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string rq = std::string(argv[2]) + " " + std::string(argv[3]);
|
||||
|
||||
requestHyprpaper(rq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setcursorRequest(int argc, char** argv) {
|
||||
int setcursorRequest(int argc, char** argv) {
|
||||
if (argc < 4) {
|
||||
std::cout << "setcursor requires 2 params";
|
||||
return;
|
||||
std::cout << "Usage: hyprctl setcursor <theme> <size>\n\
|
||||
Sets the cursor theme for everything except GTK and reloads the cursor";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string rq = "setcursor " + std::string(argv[2]) + " " + std::string(argv[3]);
|
||||
|
||||
request(rq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int outputRequest(int argc, char** argv) {
|
||||
if (argc < 4) {
|
||||
std::cout << "Usage: hyprctl output <mode> <name>\n\
|
||||
creates / destroys a fake output\n\
|
||||
with create, name is the backend name to use (available: auto, x11, wayland, headless)\n\
|
||||
with destroy, name is the output name to destroy";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string rq = "output " + std::string(argv[2]) + " " + std::string(argv[3]);
|
||||
|
||||
request(rq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void batchRequest(std::string arg) {
|
||||
@@ -212,11 +251,14 @@ std::deque<std::string> splitArgs(int argc, char** argv) {
|
||||
}
|
||||
|
||||
bool isNumber(const std::string& str, bool allowfloat) {
|
||||
if (str.empty())
|
||||
return false;
|
||||
return std::ranges::all_of(str.begin(), str.end(), [&](char c) { return isdigit(c) != 0 || c == '-' || (allowfloat && c == '.'); });
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int bflag = 0, sflag = 0, index, c;
|
||||
bool parseArgs = true;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("%s\n", USAGE.c_str());
|
||||
@@ -228,7 +270,12 @@ int main(int argc, char** argv) {
|
||||
const auto ARGS = splitArgs(argc, argv);
|
||||
|
||||
for (auto i = 0; i < ARGS.size(); ++i) {
|
||||
if (ARGS[i][0] == '-' && !isNumber(ARGS[i], true) /* For stuff like -2 */) {
|
||||
if (ARGS[i] == "--") {
|
||||
// Stop parsing arguments after --
|
||||
parseArgs = false;
|
||||
continue;
|
||||
}
|
||||
if (parseArgs && (ARGS[i][0] == '-') && !isNumber(ARGS[i], true) /* For stuff like -2 */) {
|
||||
// parse
|
||||
if (ARGS[i] == "-j" && !fullArgs.contains("j")) {
|
||||
fullArgs += "j";
|
||||
@@ -254,6 +301,8 @@ int main(int argc, char** argv) {
|
||||
|
||||
fullRequest = fullArgs + "/" + fullRequest;
|
||||
|
||||
int exitStatus = 0;
|
||||
|
||||
if (fullRequest.contains("/--batch")) batchRequest(fullRequest);
|
||||
else if (fullRequest.contains("/monitors")) request(fullRequest);
|
||||
else if (fullRequest.contains("/clients")) request(fullRequest);
|
||||
@@ -266,10 +315,12 @@ int main(int argc, char** argv) {
|
||||
else if (fullRequest.contains("/devices")) request(fullRequest);
|
||||
else if (fullRequest.contains("/reload")) request(fullRequest);
|
||||
else if (fullRequest.contains("/getoption")) request(fullRequest);
|
||||
else if (fullRequest.contains("/setcursor")) setcursorRequest(argc, argv);
|
||||
else if (fullRequest.contains("/dispatch")) dispatchRequest(argc, argv);
|
||||
else if (fullRequest.contains("/keyword")) keywordRequest(argc, argv);
|
||||
else if (fullRequest.contains("/hyprpaper")) hyprpaperRequest(argc, argv);
|
||||
else if (fullRequest.contains("/cursorpos")) request(fullRequest);
|
||||
else if (fullRequest.contains("/output")) exitStatus = outputRequest(argc, argv);
|
||||
else if (fullRequest.contains("/setcursor")) exitStatus = setcursorRequest(argc, argv);
|
||||
else if (fullRequest.contains("/dispatch")) exitStatus = dispatchRequest(argc, argv);
|
||||
else if (fullRequest.contains("/keyword")) exitStatus = keywordRequest(argc, argv);
|
||||
else if (fullRequest.contains("/hyprpaper")) exitStatus = hyprpaperRequest(argc, argv);
|
||||
else if (fullRequest.contains("/--help")) printf("%s", USAGE.c_str());
|
||||
else {
|
||||
printf("%s\n", USAGE.c_str());
|
||||
@@ -277,5 +328,5 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
return exitStatus;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
project('Hyprland', 'cpp', 'c',
|
||||
version : '0.14.0beta',
|
||||
version : '0.17.0beta',
|
||||
default_options : [
|
||||
'warning_level=2',
|
||||
'default_library=static',
|
||||
@@ -20,8 +20,8 @@ endif
|
||||
|
||||
GIT_BRANCH = run_command('git', 'rev-parse', '--abbrev-ref', 'HEAD', check: false).stdout().strip()
|
||||
GIT_COMMIT_HASH = run_command('git', 'rev-parse', 'HEAD', check: false).stdout().strip()
|
||||
GIT_COMMIT_MESSAGE = run_command('bash', '-c', 'git show | head -n 5 | tail -n 1', check: false).stdout().strip()
|
||||
GIT_DIRTY = run_command('bash', '-c', 'git diff-index --quiet HEAD -- || echo "dirty"', check: false).stdout().strip()
|
||||
GIT_COMMIT_MESSAGE = run_command('sh', '-c', 'git show | head -n 5 | tail -n 1', check: false).stdout().strip()
|
||||
GIT_DIRTY = run_command('sh', '-c', 'git diff-index --quiet HEAD -- || echo "dirty"', check: false).stdout().strip()
|
||||
|
||||
add_project_arguments(
|
||||
[
|
||||
|
@@ -14,6 +14,7 @@
|
||||
mesa,
|
||||
mount,
|
||||
pango,
|
||||
pciutils,
|
||||
wayland,
|
||||
wayland-protocols,
|
||||
wayland-scanner,
|
||||
@@ -62,17 +63,16 @@ in
|
||||
git
|
||||
libdrm
|
||||
libinput
|
||||
libxcb
|
||||
libxkbcommon
|
||||
mesa
|
||||
pango
|
||||
wayland
|
||||
wayland-protocols
|
||||
wayland-scanner
|
||||
pciutils
|
||||
(wlroots.override {inherit enableXWayland hidpiXWayland nvidiaPatches;})
|
||||
xcbutilwm
|
||||
]
|
||||
++ lib.optional enableXWayland xwayland;
|
||||
++ lib.optionals enableXWayland [libxcb xcbutilwm xwayland];
|
||||
|
||||
mesonBuildType =
|
||||
if debug
|
||||
|
@@ -92,7 +92,7 @@ in {
|
||||
++ lib.optional cfg.xwayland.enable pkgs.xwayland;
|
||||
|
||||
home.sessionVariables = lib.mkIf cfg.recommendedEnvironment {
|
||||
GDK_BACKEND = "wayland";
|
||||
GDK_BACKEND = "wayland,x11";
|
||||
_JAVA_AWT_WM_NONREPARENTING = "1";
|
||||
NIXOS_OZONE_WL = "1";
|
||||
XCURSOR_SIZE = toString config.home.pointerCursor.size or "24";
|
||||
@@ -102,8 +102,7 @@ in {
|
||||
xdg.configFile."hypr/hyprland.conf" = {
|
||||
text =
|
||||
(lib.optionalString cfg.systemdIntegration ''
|
||||
exec-once=${pkgs.dbus}/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP
|
||||
exec-once=systemctl --user start hyprland-session.target
|
||||
exec-once=${pkgs.dbus}/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP && systemctl --user start hyprland-session.target
|
||||
'')
|
||||
+ cfg.extraConfig;
|
||||
|
||||
|
28
nix/hwdata.nix
Normal file
28
nix/hwdata.nix
Normal file
@@ -0,0 +1,28 @@
|
||||
{ lib, stdenv, fetchFromGitHub }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "hwdata";
|
||||
version = "0.363";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "vcrhonek";
|
||||
repo = "hwdata";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-A6GNrHc/t2SVyAyJWmzQTa+pD9wGESsz7DNruW2kH4s=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
patchShebangs ./configure
|
||||
'';
|
||||
|
||||
configureFlags = [ "--datadir=${placeholder "out"}/share" ];
|
||||
|
||||
doCheck = false; # this does build machine-specific checks (e.g. enumerates PCI bus)
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/vcrhonek/hwdata";
|
||||
description = "Hardware Database, including Monitors, pci.ids, usb.ids, and video cards";
|
||||
license = lib.licenses.gpl2Plus;
|
||||
platforms = lib.platforms.all;
|
||||
};
|
||||
}
|
@@ -47,7 +47,7 @@ in {
|
||||
systemPackages = lib.optional (cfg.package != null) cfg.package;
|
||||
|
||||
sessionVariables = mkIf cfg.recommendedEnvironment {
|
||||
GDK_BACKEND = "wayland";
|
||||
GDK_BACKEND = "wayland,x11";
|
||||
_JAVA_AWT_WM_NONREPARENTING = "1";
|
||||
NIXOS_OZONE_WL = "1";
|
||||
XCURSOR_SIZE = "24";
|
||||
|
@@ -6,6 +6,7 @@
|
||||
xwayland,
|
||||
fetchpatch,
|
||||
lib,
|
||||
hwdata,
|
||||
hidpiXWayland ? true,
|
||||
enableXWayland ? true,
|
||||
nvidiaPatches ? false,
|
||||
@@ -51,6 +52,7 @@ assert (lib.assertMsg (hidpiXWayland -> enableXWayland) ''
|
||||
''
|
||||
else ""
|
||||
);
|
||||
buildInputs = old.buildInputs ++ [hwdata];
|
||||
}))
|
||||
.override {
|
||||
xwayland = xwayland.overrideAttrs (old: {
|
||||
|
@@ -13,6 +13,7 @@ wayland_scanner = find_program(
|
||||
|
||||
protocols = [
|
||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
||||
['wlr-layer-shell-unstable-v1.xml'],
|
||||
['wlr-output-power-management-unstable-v1.xml'],
|
||||
['ext-workspace-unstable-v1.xml'],
|
||||
|
@@ -73,7 +73,15 @@ CCompositor::CCompositor() {
|
||||
throw std::runtime_error("wlr_gles2_renderer_create_with_drm_fd() failed!");
|
||||
}
|
||||
|
||||
wlr_renderer_init_wl_display(m_sWLRRenderer, m_sWLDisplay);
|
||||
wlr_renderer_init_wl_shm(m_sWLRRenderer, m_sWLDisplay);
|
||||
|
||||
if (wlr_renderer_get_dmabuf_texture_formats(m_sWLRRenderer)) {
|
||||
if (wlr_renderer_get_drm_fd(m_sWLRRenderer) >= 0) {
|
||||
wlr_drm_create(m_sWLDisplay, m_sWLRRenderer);
|
||||
}
|
||||
|
||||
m_sWLRLinuxDMABuf = wlr_linux_dmabuf_v1_create(m_sWLDisplay, m_sWLRRenderer);
|
||||
}
|
||||
|
||||
m_sWLRAllocator = wlr_allocator_autocreate(m_sWLRBackend, m_sWLRRenderer);
|
||||
|
||||
@@ -107,7 +115,7 @@ CCompositor::CCompositor() {
|
||||
m_sWLRScene = wlr_scene_create();
|
||||
wlr_scene_attach_output_layout(m_sWLRScene, m_sWLROutputLayout);
|
||||
|
||||
m_sWLRXDGShell = wlr_xdg_shell_create(m_sWLDisplay, 4);
|
||||
m_sWLRXDGShell = wlr_xdg_shell_create(m_sWLDisplay, 5);
|
||||
|
||||
m_sWLRCursor = wlr_cursor_create();
|
||||
wlr_cursor_attach_output_layout(m_sWLRCursor, m_sWLROutputLayout);
|
||||
@@ -115,6 +123,9 @@ CCompositor::CCompositor() {
|
||||
m_sWLRXCursorMgr = wlr_xcursor_manager_create(nullptr, 24);
|
||||
wlr_xcursor_manager_load(m_sWLRXCursorMgr, 1);
|
||||
|
||||
if (const auto XCURSORENV = getenv("XCURSOR_SIZE"); !XCURSORENV || std::string(XCURSORENV).empty())
|
||||
setenv("XCURSOR_SIZE", "24", true);
|
||||
|
||||
m_sSeat.seat = wlr_seat_create(m_sWLDisplay, "seat0");
|
||||
|
||||
m_sWLRPresentation = wlr_presentation_create(m_sWLDisplay, m_sWLRBackend);
|
||||
@@ -167,6 +178,17 @@ CCompositor::CCompositor() {
|
||||
m_sWLRTextInputMgr = wlr_text_input_manager_v3_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRIMEMgr = wlr_input_method_manager_v2_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRActivation = wlr_xdg_activation_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRHeadlessBackend = wlr_headless_backend_create(m_sWLDisplay);
|
||||
|
||||
if (!m_sWLRHeadlessBackend) {
|
||||
Debug::log(CRIT, "Couldn't create the headless backend");
|
||||
throw std::runtime_error("wlr_headless_backend_create() failed!");
|
||||
}
|
||||
|
||||
wlr_multi_backend_add(m_sWLRBackend, m_sWLRHeadlessBackend);
|
||||
}
|
||||
|
||||
CCompositor::~CCompositor() {
|
||||
@@ -223,6 +245,7 @@ void CCompositor::initAllSignals() {
|
||||
addWLSignal(&m_sWLROutputPowerMgr->events.set_mode, &Events::listen_powerMgrSetMode, m_sWLROutputPowerMgr, "PowerMgr");
|
||||
addWLSignal(&m_sWLRIMEMgr->events.input_method, &Events::listen_newIME, m_sWLRIMEMgr, "IMEMgr");
|
||||
addWLSignal(&m_sWLRTextInputMgr->events.text_input, &Events::listen_newTextInput, m_sWLRTextInputMgr, "TextInputMgr");
|
||||
addWLSignal(&m_sWLRActivation->events.request_activate, &Events::listen_activateXDG, m_sWLRActivation, "ActivationV1");
|
||||
|
||||
if(m_sWRLDRMLeaseMgr)
|
||||
addWLSignal(&m_sWRLDRMLeaseMgr->events.request, &Events::listen_leaseRequest, &m_sWRLDRMLeaseMgr, "DRM");
|
||||
@@ -235,15 +258,15 @@ void CCompositor::cleanup() {
|
||||
if (!m_sWLDisplay || m_bIsShuttingDown)
|
||||
return;
|
||||
|
||||
m_bIsShuttingDown = true;
|
||||
|
||||
m_pLastFocus = nullptr;
|
||||
m_pLastWindow = nullptr;
|
||||
|
||||
// accumulate all PIDs for killing, also request closing.
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_bIsMapped || !w->m_bIsX11)
|
||||
if (w->m_bIsMapped && !w->isHidden())
|
||||
m_dProcessPIDsOnShutdown.push_back(w->getPID());
|
||||
|
||||
closeWindow(w.get());
|
||||
}
|
||||
|
||||
// end threads
|
||||
@@ -259,6 +282,8 @@ void CCompositor::cleanup() {
|
||||
wlr_output_commit(m->output);
|
||||
}
|
||||
|
||||
m_vMonitors.clear();
|
||||
|
||||
if (g_pXWaylandManager->m_sWLRXWayland) {
|
||||
wlr_xwayland_destroy(g_pXWaylandManager->m_sWLRXWayland);
|
||||
g_pXWaylandManager->m_sWLRXWayland = nullptr;
|
||||
@@ -266,8 +291,6 @@ void CCompositor::cleanup() {
|
||||
|
||||
wl_display_terminate(m_sWLDisplay);
|
||||
|
||||
m_bIsShuttingDown = true;
|
||||
|
||||
g_pKeybindManager->spawn("sleep 5 && kill -9 " + std::to_string(m_iHyprlandPID)); // this is to prevent that random "freezing"
|
||||
// the PID should not be reused.
|
||||
}
|
||||
@@ -334,6 +357,9 @@ void CCompositor::startCompositor() {
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
if (m_sWLRSession /* Session-less Hyprland usually means a nest, don't update the env in that case */ && fork() == 0)
|
||||
execl("/bin/sh", "/bin/sh", "-c", "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE", nullptr);
|
||||
|
||||
Debug::log(LOG, "Running on WAYLAND_DISPLAY: %s", m_szWLDisplaySocket);
|
||||
|
||||
if (!wlr_backend_start(m_sWLRBackend)) {
|
||||
@@ -445,13 +471,13 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->m_bHidden)
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->isHidden())
|
||||
return (*w).get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && !w->m_bHidden)
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && !w->isHidden())
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
@@ -459,20 +485,20 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
|
||||
// pinned
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && !(*w)->m_bHidden && (*w)->m_bPinned)
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && !(*w)->isHidden() && (*w)->m_bPinned)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
// first loop over floating cuz they're above, m_vWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bPinned)
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->isHidden() && !(*w)->m_bPinned)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && PMONITOR->activeWorkspace == w->m_iWorkspaceID && !w->m_bHidden)
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && PMONITOR->activeWorkspace == w->m_iWorkspaceID && !w->isHidden())
|
||||
return w.get();
|
||||
}
|
||||
|
||||
@@ -485,14 +511,14 @@ CWindow* CCompositor::vectorToWindowTiled(const Vector2D& pos) {
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bIsFloating && !w->m_bHidden)
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bIsFloating && !w->isHidden())
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bIsFloating && !w->m_bHidden)
|
||||
if (w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bIsFloating && !w->isHidden())
|
||||
return w.get();
|
||||
}
|
||||
|
||||
@@ -515,13 +541,13 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->m_bHidden && !(*w)->m_bX11ShouldntFocus)
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->isHidden() && !(*w)->m_bX11ShouldntFocus)
|
||||
return (*w).get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (!w->m_bIsFloating && w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bHidden && !w->m_bX11ShouldntFocus)
|
||||
if (!w->m_bIsFloating && w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->isHidden() && !w->m_bX11ShouldntFocus)
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
@@ -529,7 +555,7 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
// pinned windows on top of floating regardless
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && !(*w)->m_bHidden && !(*w)->m_bX11ShouldntFocus && (*w)->m_bPinned) {
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && !(*w)->isHidden() && !(*w)->m_bX11ShouldntFocus && (*w)->m_bPinned) {
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y))
|
||||
return w->get();
|
||||
|
||||
@@ -548,7 +574,7 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bPinned) {
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->isHidden() && !(*w)->m_bPinned) {
|
||||
// OR windows should add focus to parent
|
||||
if ((*w)->m_bX11ShouldntFocus && (*w)->m_iX11Type != 2)
|
||||
continue;
|
||||
@@ -578,7 +604,7 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
|
||||
// for windows, we need to check their extensions too, first.
|
||||
for (auto& w : m_vWindows) {
|
||||
if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden && !w->m_bX11ShouldntFocus) {
|
||||
if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->isHidden() && !w->m_bX11ShouldntFocus) {
|
||||
wlr_surface* resultSurf = nullptr;
|
||||
Vector2D origin = w->m_vRealPosition.vec();
|
||||
SExtensionFindingData data = {origin, pos, &resultSurf};
|
||||
@@ -590,7 +616,7 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
}
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (!w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden && !w->m_bX11ShouldntFocus)
|
||||
if (!w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->isHidden() && !w->m_bX11ShouldntFocus)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
@@ -603,7 +629,7 @@ CWindow* CCompositor::windowFromCursor() {
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && !(*w)->m_bHidden)
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && !(*w)->isHidden())
|
||||
return (*w).get();
|
||||
}
|
||||
|
||||
@@ -640,13 +666,13 @@ CWindow* CCompositor::windowFromCursor() {
|
||||
CWindow* CCompositor::windowFloatingFromCursor() {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && !(*w)->m_bHidden && (*w)->m_bPinned)
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && !(*w)->isHidden() && (*w)->m_bPinned)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bPinned)
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->isHidden() && !(*w)->m_bPinned)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
@@ -709,6 +735,8 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
if (windowValidMapped(PLASTWINDOW)) {
|
||||
updateWindowAnimatedDecorationValues(PLASTWINDOW);
|
||||
|
||||
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
|
||||
|
||||
if (PLASTWINDOW->m_phForeignToplevel)
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(PLASTWINDOW->m_phForeignToplevel, false);
|
||||
}
|
||||
@@ -717,7 +745,11 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr);
|
||||
|
||||
m_pLastFocus = nullptr;
|
||||
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -742,10 +774,8 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
if (windowValidMapped(PLASTWINDOW)) {
|
||||
updateWindowAnimatedDecorationValues(PLASTWINDOW);
|
||||
|
||||
if (PLASTWINDOW->m_bIsX11) {
|
||||
wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat);
|
||||
wlr_seat_pointer_clear_focus(m_sSeat.seat);
|
||||
}
|
||||
if (!pWindow->m_bIsX11 || pWindow->m_iX11Type == 1)
|
||||
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
|
||||
|
||||
if (PLASTWINDOW->m_phForeignToplevel)
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(PLASTWINDOW->m_phForeignToplevel, false);
|
||||
@@ -768,8 +798,19 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
// Send an event
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(pWindow) + "," + pWindow->m_szTitle});
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(pWindow);
|
||||
|
||||
if (pWindow->m_phForeignToplevel)
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(pWindow->m_phForeignToplevel, true);
|
||||
|
||||
if (!pWindow->m_bIsX11) {
|
||||
const auto PCONSTRAINT = wlr_pointer_constraints_v1_constraint_for_surface(m_sWLRPointerConstraints, pWindow->m_uSurface.xdg->surface, m_sSeat.seat);
|
||||
|
||||
if (PCONSTRAINT)
|
||||
g_pInputManager->constrainMouse(m_sSeat.mouse, PCONSTRAINT);
|
||||
}
|
||||
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
}
|
||||
|
||||
void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
|
||||
@@ -778,7 +819,7 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
|
||||
return; // Don't focus when already focused on this.
|
||||
|
||||
// Unfocus last surface if should
|
||||
if (m_pLastFocus && ((m_sSeat.seat->keyboard_state.focused_surface && wlr_surface_is_xdg_surface(m_pLastFocus)) || !pSurface))
|
||||
if (m_pLastFocus && !pWindowOwner)
|
||||
g_pXWaylandManager->activateSurface(m_pLastFocus, false);
|
||||
|
||||
if (!pSurface) {
|
||||
@@ -810,11 +851,14 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
|
||||
else
|
||||
Debug::log(LOG, "Set keyboard focus to surface %x", pSurface);
|
||||
|
||||
g_pXWaylandManager->activateSurface(pSurface, false);
|
||||
g_pXWaylandManager->activateSurface(pSurface, true);
|
||||
m_pLastFocus = pSurface;
|
||||
}
|
||||
|
||||
bool CCompositor::windowValidMapped(CWindow* pWindow) {
|
||||
if (!pWindow)
|
||||
return false;
|
||||
|
||||
if (!windowExists(pWindow))
|
||||
return false;
|
||||
|
||||
@@ -824,7 +868,7 @@ bool CCompositor::windowValidMapped(CWindow* pWindow) {
|
||||
if (!pWindow->m_bIsMapped)
|
||||
return false;
|
||||
|
||||
if (pWindow->m_bHidden)
|
||||
if (pWindow->isHidden())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -934,7 +978,7 @@ int CCompositor::getWindowsOnWorkspace(const int& id) {
|
||||
|
||||
CWindow* CCompositor::getFirstWindowOnWorkspace(const int& id) {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == id && w->m_bIsMapped && !w->m_bHidden)
|
||||
if (w->m_iWorkspaceID == id && w->m_bIsMapped && !w->isHidden())
|
||||
return w.get();
|
||||
}
|
||||
|
||||
@@ -980,7 +1024,7 @@ void CCompositor::moveWindowToTop(CWindow* pWindow) {
|
||||
std::deque<CWindow*> toMove;
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_bIsMapped && w->m_bMappedX11 && !w->m_bHidden && w->m_bIsX11 && w->X11TransientFor() == pWindow) {
|
||||
if (w->m_bIsMapped && w->m_bMappedX11 && !w->isHidden() && w->m_bIsX11 && w->X11TransientFor() == pWindow) {
|
||||
toMove.emplace_back(w.get());
|
||||
}
|
||||
}
|
||||
@@ -1103,7 +1147,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
||||
CWindow* longestIntersectWindow = nullptr;
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w.get() == pWindow || !w->m_bIsMapped || w->m_bHidden || w->m_bIsFloating || !isWorkspaceVisible(w->m_iWorkspaceID))
|
||||
if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || w->m_bIsFloating || !isWorkspaceVisible(w->m_iWorkspaceID))
|
||||
continue;
|
||||
|
||||
const auto BWINDOWIDEALBB = w->getWindowIdealBoundingBoxIgnoreReserved();
|
||||
@@ -1177,12 +1221,12 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow, bool focusableO
|
||||
continue;
|
||||
}
|
||||
|
||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden && (!focusableOnly || !w->m_bNoFocus))
|
||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_bNoFocus))
|
||||
return w.get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden && (!focusableOnly || !w->m_bNoFocus))
|
||||
if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_bNoFocus))
|
||||
return w.get();
|
||||
}
|
||||
|
||||
@@ -1200,12 +1244,12 @@ CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow, bool focusableO
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden && (!focusableOnly || !(*it)->m_bNoFocus))
|
||||
if ((*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->isHidden() && (!focusableOnly || !(*it)->m_bNoFocus))
|
||||
return it->get();
|
||||
}
|
||||
|
||||
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
||||
if (it->get() != pWindow && (*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden && (!focusableOnly || !(*it)->m_bNoFocus))
|
||||
if (it->get() != pWindow && (*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->isHidden() && (!focusableOnly || !(*it)->m_bNoFocus))
|
||||
return it->get();
|
||||
}
|
||||
|
||||
@@ -1255,6 +1299,11 @@ bool CCompositor::isPointOnAnyMonitor(const Vector2D& point) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkFocusSurfaceIter(wlr_surface* pSurface, int x, int y, void* data) {
|
||||
auto pair = (std::pair<wlr_surface*, bool>*)data;
|
||||
pair->second = pair->second || pSurface == pair->first;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getConstraintWindow(SMouse* pMouse) {
|
||||
if (!pMouse->currentConstraint)
|
||||
return nullptr;
|
||||
@@ -1262,10 +1311,17 @@ CWindow* CCompositor::getConstraintWindow(SMouse* pMouse) {
|
||||
const auto PSURFACE = pMouse->currentConstraint->surface;
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
if (PSURFACE == g_pXWaylandManager->getWindowSurface(w.get())) {
|
||||
if (!w->m_bIsX11 && w->m_bIsMapped && !w->m_bHidden)
|
||||
if (w->isHidden() || !w->m_bMappedX11 || !w->m_bIsMapped || !g_pXWaylandManager->getWindowSurface(w.get()))
|
||||
continue;
|
||||
|
||||
if (w->m_bIsX11) {
|
||||
if (PSURFACE == g_pXWaylandManager->getWindowSurface(w.get()))
|
||||
return w.get();
|
||||
} else {
|
||||
std::pair<wlr_surface*, bool> check = {PSURFACE, false};
|
||||
wlr_surface_for_each_surface(w->m_uSurface.xdg->surface, checkFocusSurfaceIter, &check);
|
||||
|
||||
if (check.second)
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
@@ -1359,7 +1415,9 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
|
||||
if (RENDERDATA.isBorderColor)
|
||||
pWindow->m_cRealBorderColor = RENDERDATA.borderColor;
|
||||
else
|
||||
pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ? *ACTIVECOL : *INACTIVECOL);
|
||||
pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ?
|
||||
(pWindow->m_sSpecialRenderData.activeBorderColor >= 0 ? pWindow->m_sSpecialRenderData.activeBorderColor : *ACTIVECOL) :
|
||||
(pWindow->m_sSpecialRenderData.inactiveBorderColor >= 0 ? pWindow->m_sSpecialRenderData.inactiveBorderColor : *INACTIVECOL));
|
||||
|
||||
|
||||
// opacity
|
||||
@@ -1480,7 +1538,40 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
|
||||
if (isNumber(name)) {
|
||||
if (name[0] == '+' || name[0] == '-') {
|
||||
// relative
|
||||
const auto OFFSET = name[0] == '-' ? name : name.substr(1);
|
||||
|
||||
if (!isNumber(OFFSET)) {
|
||||
Debug::log(ERR, "Error in getMonitorFromString: Not a number in relative.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int offsetLeft = std::stoi(OFFSET) % m_vMonitors.size(); // no need to cycle more
|
||||
|
||||
int currentPlace = 0;
|
||||
for (int i = 0; i < (int)m_vMonitors.size(); i++) {
|
||||
if (m_vMonitors[i].get() == m_pLastMonitor) {
|
||||
currentPlace = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentPlace += offsetLeft;
|
||||
|
||||
if (currentPlace < 0) {
|
||||
currentPlace = m_vMonitors.size() - currentPlace;
|
||||
} else {
|
||||
currentPlace = currentPlace % m_vMonitors.size();
|
||||
}
|
||||
|
||||
if (currentPlace != std::clamp(currentPlace, 0, (int)m_vMonitors.size())) {
|
||||
Debug::log(WARN, "Error in getMonitorFromString: Vaxry's code sucks.");
|
||||
currentPlace = std::clamp(currentPlace, 0, (int)m_vMonitors.size());
|
||||
}
|
||||
|
||||
return m_vMonitors[currentPlace].get();
|
||||
} else if (isNumber(name)) {
|
||||
// change by ID
|
||||
int monID = -1;
|
||||
try {
|
||||
@@ -1543,7 +1634,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
|
||||
if (nextWorkspaceOnMonitorID == -1) {
|
||||
nextWorkspaceOnMonitorID = 1;
|
||||
|
||||
while (getWorkspaceByID(nextWorkspaceOnMonitorID))
|
||||
while (getWorkspaceByID(nextWorkspaceOnMonitorID) || [&]() -> bool { const auto B = g_pConfigManager->getBoundMonitorForWS(std::to_string(nextWorkspaceOnMonitorID)); return B && B != POLDMON; }())
|
||||
nextWorkspaceOnMonitorID++;
|
||||
|
||||
Debug::log(LOG, "moveWorkspaceToMonitor: Plugging gap with new %d", nextWorkspaceOnMonitorID);
|
||||
@@ -1564,7 +1655,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
|
||||
w->m_iMonitorID = pMonitor->ID;
|
||||
|
||||
// additionally, move floating and fs windows manually
|
||||
if (w->m_bIsMapped && !w->m_bHidden) {
|
||||
if (w->m_bIsMapped && !w->isHidden()) {
|
||||
if (w->m_bIsFloating)
|
||||
w->m_vRealPosition = w->m_vRealPosition.vec() - POLDMON->vecPosition + pMonitor->vecPosition;
|
||||
|
||||
@@ -1641,12 +1732,15 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
|
||||
|
||||
g_pXWaylandManager->setWindowFullscreen(pWindow, pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL);
|
||||
|
||||
pWindow->updateDynamicRules();
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
|
||||
|
||||
// make all windows on the same workspace under the fullscreen window
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID) {
|
||||
w->m_bCreatedOverFullscreen = false;
|
||||
if (w.get() != pWindow && !w->m_bFadingOut && !w->m_bPinned)
|
||||
w->m_fAlpha = pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL ? 0.f : 255.f;
|
||||
w->m_fAlpha = pWindow->m_bIsFullscreen ? 0.f : 255.f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1658,6 +1752,11 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv(), true);
|
||||
|
||||
forceReportSizesToWindowsOnWorkspace(pWindow->m_iWorkspaceID);
|
||||
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
|
||||
// DMAbuf stuff for direct scanout
|
||||
g_pHyprRenderer->setWindowScanoutMode(pWindow);
|
||||
}
|
||||
|
||||
void CCompositor::moveUnmanagedX11ToWindows(CWindow* pWindow) {
|
||||
@@ -1718,7 +1817,7 @@ CWindow* CCompositor::getWindowByRegex(const std::string& regexp) {
|
||||
}
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (!w->m_bIsMapped || w->m_bHidden)
|
||||
if (!w->m_bIsMapped || w->isHidden())
|
||||
continue;
|
||||
|
||||
switch (mode) {
|
||||
@@ -1846,7 +1945,7 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con
|
||||
|
||||
void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == wid && w->m_bIsMapped && !w->m_bHidden) {
|
||||
if (w->m_iWorkspaceID == wid && w->m_bIsMapped && !w->isHidden()) {
|
||||
g_pXWaylandManager->setWindowSize(w.get(), w->m_vRealSize.vec(), true);
|
||||
}
|
||||
}
|
||||
@@ -1862,3 +1961,24 @@ bool CCompositor::cursorOnReservedArea() {
|
||||
|
||||
return !VECINRECT(CURSORPOS, XY1.x, XY1.y, XY2.x, XY2.y);
|
||||
}
|
||||
|
||||
CWorkspace* CCompositor::createNewWorkspace(const int& id, const int& monid, const std::string& name) {
|
||||
const auto NAME = name == "" ? std::to_string(id) : name;
|
||||
auto monID = monid;
|
||||
|
||||
// check if bound
|
||||
if (const auto PMONITOR = g_pConfigManager->getBoundMonitorForWS(NAME); PMONITOR) {
|
||||
monID = PMONITOR->ID;
|
||||
}
|
||||
|
||||
const auto PWORKSPACE = m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(monID, NAME, id == SPECIAL_WORKSPACE_ID)).get();
|
||||
|
||||
// We are required to set the name here immediately
|
||||
if (id != SPECIAL_WORKSPACE_ID)
|
||||
wlr_ext_workspace_handle_v1_set_name(PWORKSPACE->m_pWlrHandle, NAME.c_str());
|
||||
|
||||
PWORKSPACE->m_iID = id;
|
||||
PWORKSPACE->m_iMonitorID = monID;
|
||||
|
||||
return PWORKSPACE;
|
||||
}
|
||||
|
@@ -69,6 +69,9 @@ public:
|
||||
wlr_output_power_manager_v1* m_sWLROutputPowerMgr;
|
||||
wlr_input_method_manager_v2* m_sWLRIMEMgr;
|
||||
wlr_text_input_manager_v3* m_sWLRTextInputMgr;
|
||||
wlr_xdg_activation_v1* m_sWLRActivation;
|
||||
wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf;
|
||||
wlr_backend* m_sWLRHeadlessBackend;
|
||||
// ------------------------------------------------- //
|
||||
|
||||
|
||||
@@ -165,6 +168,7 @@ public:
|
||||
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
||||
void forceReportSizesToWindowsOnWorkspace(const int&);
|
||||
bool cursorOnReservedArea();
|
||||
CWorkspace* createNewWorkspace(const int&, const int&, const std::string& name = ""); // will be deleted next frame if left empty and unfocused!
|
||||
|
||||
std::string explicitConfigPath;
|
||||
|
||||
|
120
src/Window.cpp
120
src/Window.cpp
@@ -3,7 +3,7 @@
|
||||
#include "render/decorations/CHyprDropShadowDecoration.hpp"
|
||||
|
||||
CWindow::CWindow() {
|
||||
m_vRealPosition.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*) this, AVARDAMAGE_ENTIRE);
|
||||
m_vRealPosition.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_vRealSize.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_cRealBorderColor.create(AVARTYPE_COLOR, g_pConfigManager->getAnimationPropertyConfig("border"), (void*)this, AVARDAMAGE_BORDER);
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), (void*)this, AVARDAMAGE_ENTIRE);
|
||||
@@ -244,3 +244,121 @@ void CWindow::removeDecorationByType(eDecorationType type) {
|
||||
|
||||
updateWindowDecos();
|
||||
}
|
||||
|
||||
void unregisterVar(void* ptr) {
|
||||
((CAnimatedVariable*)ptr)->unregister();
|
||||
}
|
||||
|
||||
void CWindow::onUnmap() {
|
||||
if (g_pCompositor->m_pLastWindow == this)
|
||||
g_pCompositor->m_pLastWindow = nullptr;
|
||||
|
||||
m_vRealPosition.setCallbackOnEnd(unregisterVar);
|
||||
m_vRealSize.setCallbackOnEnd(unregisterVar);
|
||||
m_cRealBorderColor.setCallbackOnEnd(unregisterVar);
|
||||
m_fActiveInactiveAlpha.setCallbackOnEnd(unregisterVar);
|
||||
m_fAlpha.setCallbackOnEnd(unregisterVar);
|
||||
m_cRealShadowColor.setCallbackOnEnd(unregisterVar);
|
||||
m_fDimPercent.setCallbackOnEnd(unregisterVar);
|
||||
|
||||
m_vRealSize.setCallbackOnBegin(nullptr);
|
||||
}
|
||||
|
||||
void CWindow::onMap() {
|
||||
m_vRealPosition.registerVar();
|
||||
m_vRealSize.registerVar();
|
||||
m_cRealBorderColor.registerVar();
|
||||
m_fActiveInactiveAlpha.registerVar();
|
||||
m_fAlpha.registerVar();
|
||||
m_cRealShadowColor.registerVar();
|
||||
m_fDimPercent.registerVar();
|
||||
|
||||
m_vRealSize.setCallbackOnEnd([&] (void* ptr) {
|
||||
g_pHyprOpenGL->onWindowResizeEnd(this);
|
||||
}, false);
|
||||
m_vRealSize.setCallbackOnBegin([&] (void* ptr) {
|
||||
g_pHyprOpenGL->onWindowResizeStart(this);
|
||||
}, false);
|
||||
}
|
||||
|
||||
void CWindow::setHidden(bool hidden) {
|
||||
m_bHidden = hidden;
|
||||
|
||||
if (hidden && g_pCompositor->m_pLastWindow == this) {
|
||||
g_pCompositor->m_pLastWindow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool CWindow::isHidden() {
|
||||
return m_bHidden;
|
||||
}
|
||||
|
||||
void CWindow::applyDynamicRule(const SWindowRule& r) {
|
||||
if (r.szRule == "noblur") {
|
||||
m_sAdditionalConfigData.forceNoBlur = true;
|
||||
} else if (r.szRule == "noborder") {
|
||||
m_sAdditionalConfigData.forceNoBorder = true;
|
||||
} else if (r.szRule == "noshadow") {
|
||||
m_sAdditionalConfigData.forceNoShadow = true;
|
||||
} else if (r.szRule == "opaque") {
|
||||
m_sAdditionalConfigData.forceOpaque = true;
|
||||
} else if (r.szRule.find("rounding") == 0) {
|
||||
try {
|
||||
m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Rounding rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
|
||||
}
|
||||
} else if (r.szRule.find("opacity") == 0) {
|
||||
try {
|
||||
std::string alphaPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
||||
|
||||
if (alphaPart.contains(' ')) {
|
||||
// we have a space, 2 values
|
||||
m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' ')));
|
||||
m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1));
|
||||
} else {
|
||||
m_sSpecialRenderData.alpha = std::stof(alphaPart);
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
Debug::log(ERR, "Opacity rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
|
||||
}
|
||||
} else if (r.szRule == "noanim") {
|
||||
m_sAdditionalConfigData.forceNoAnims = true;
|
||||
} else if (r.szRule.find("animation") == 0) {
|
||||
auto STYLE = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
|
||||
m_sAdditionalConfigData.animationStyle = STYLE;
|
||||
} else if (r.szRule.find("bordercolor") == 0) {
|
||||
try {
|
||||
std::string colorPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
||||
|
||||
if (colorPart.contains(' ')) {
|
||||
// we have a space, 2 values
|
||||
m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart.substr(0, colorPart.find_first_of(' ')));
|
||||
m_sSpecialRenderData.inactiveBorderColor = configStringToInt(colorPart.substr(colorPart.find_first_of(' ') + 1));
|
||||
} else {
|
||||
m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart);
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
Debug::log(ERR, "BorderColor rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWindow::updateDynamicRules() {
|
||||
m_sSpecialRenderData.activeBorderColor = -1;
|
||||
m_sSpecialRenderData.inactiveBorderColor = -1;
|
||||
m_sSpecialRenderData.alpha = 1.f;
|
||||
m_sSpecialRenderData.alphaInactive = -1.f;
|
||||
m_sAdditionalConfigData.forceNoBlur = false;
|
||||
m_sAdditionalConfigData.forceNoBorder = false;
|
||||
m_sAdditionalConfigData.forceNoShadow = false;
|
||||
m_sAdditionalConfigData.forceOpaque = false;
|
||||
m_sAdditionalConfigData.forceNoAnims = false;
|
||||
m_sAdditionalConfigData.animationStyle = "";
|
||||
m_sAdditionalConfigData.rounding = -1;
|
||||
|
||||
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(this);
|
||||
for (auto& r : WINDOWRULES) {
|
||||
applyDynamicRule(r);
|
||||
}
|
||||
}
|
||||
|
@@ -7,10 +7,20 @@
|
||||
#include "render/decorations/IHyprWindowDecoration.hpp"
|
||||
#include <deque>
|
||||
|
||||
enum eIdleInhibitMode {
|
||||
IDLEINHIBIT_NONE = 0,
|
||||
IDLEINHIBIT_ALWAYS,
|
||||
IDLEINHIBIT_FULLSCREEN,
|
||||
IDLEINHIBIT_FOCUS
|
||||
};
|
||||
|
||||
struct SWindowSpecialRenderData {
|
||||
float alpha = 1.f;
|
||||
float alphaInactive = -1.f; // -1 means unset
|
||||
|
||||
int64_t activeBorderColor = -1; // -1 means unset
|
||||
int64_t inactiveBorderColor = -1; // -1 means unset
|
||||
|
||||
// set by the layout
|
||||
bool rounding = true;
|
||||
bool border = true;
|
||||
@@ -23,6 +33,23 @@ struct SWindowAdditionalConfigData {
|
||||
bool forceNoBlur = false;
|
||||
bool forceOpaque = false;
|
||||
bool forceAllowsInput = false;
|
||||
bool forceNoAnims = false;
|
||||
bool forceNoBorder = false;
|
||||
bool forceNoShadow = false;
|
||||
bool windowDanceCompat = false;
|
||||
};
|
||||
|
||||
struct SWindowRule {
|
||||
std::string szRule;
|
||||
std::string szValue;
|
||||
|
||||
bool v2 = false;
|
||||
std::string szTitle;
|
||||
std::string szClass;
|
||||
int bX11 = -1; // -1 means "ANY"
|
||||
int bFloating = -1;
|
||||
int bFullscreen = -1;
|
||||
int bPinned = -1;
|
||||
};
|
||||
|
||||
class CWindow {
|
||||
@@ -117,9 +144,6 @@ public:
|
||||
Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in
|
||||
Vector2D m_vOriginalClosedSize; // drawing the closing animations
|
||||
|
||||
// For hidden windows and stuff
|
||||
bool m_bHidden = false;
|
||||
|
||||
// For pinned (sticky) windows
|
||||
bool m_bPinned = false;
|
||||
|
||||
@@ -153,6 +177,9 @@ public:
|
||||
uint64_t m_iLastToplevelMonitorID = -1;
|
||||
uint64_t m_iLastSurfaceMonitorID = -1;
|
||||
|
||||
// for idle inhibiting windows
|
||||
eIdleInhibitMode m_eIdleInhibitMode = IDLEINHIBIT_NONE;
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CWindow& rhs) {
|
||||
return m_uSurface.xdg == rhs.m_uSurface.xdg && m_uSurface.xwayland == rhs.m_uSurface.xwayland && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize && m_bFadingOut == rhs.m_bFadingOut;
|
||||
@@ -171,4 +198,15 @@ public:
|
||||
void updateSurfaceOutputs();
|
||||
void moveToWorkspace(int);
|
||||
CWindow* X11TransientFor();
|
||||
void onUnmap();
|
||||
void onMap();
|
||||
void setHidden(bool hidden);
|
||||
bool isHidden();
|
||||
void applyDynamicRule(const SWindowRule& r);
|
||||
void updateDynamicRules();
|
||||
|
||||
private:
|
||||
// For hidden windows and stuff
|
||||
bool m_bHidden = false;
|
||||
|
||||
};
|
||||
|
@@ -35,9 +35,6 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["general:main_mod"].strValue = "SUPER"; // exposed to the user for easier configuring
|
||||
configValues["general:main_mod_internal"].intValue = g_pKeybindManager->stringToModMask("SUPER"); // actually used and automatically calculated
|
||||
|
||||
configValues["general:damage_tracking"].strValue = "full";
|
||||
configValues["general:damage_tracking_internal"].intValue = DAMAGE_TRACKING_FULL;
|
||||
|
||||
configValues["general:border_size"].intValue = 1;
|
||||
configValues["general:no_border_on_floating"].intValue = 0;
|
||||
configValues["general:gaps_in"].intValue = 5;
|
||||
@@ -60,6 +57,8 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["misc:disable_autoreload"].intValue = 0;
|
||||
configValues["misc:enable_swallow"].intValue = 0;
|
||||
configValues["misc:swallow_regex"].strValue = STRVAL_EMPTY;
|
||||
configValues["misc:focus_on_activate"].intValue = 0;
|
||||
configValues["misc:no_direct_scanout"].intValue = 0;
|
||||
|
||||
configValues["debug:int"].intValue = 0;
|
||||
configValues["debug:log_damage"].intValue = 0;
|
||||
@@ -67,6 +66,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["debug:damage_blink"].intValue = 0;
|
||||
configValues["debug:disable_logs"].intValue = 0;
|
||||
configValues["debug:disable_time"].intValue = 1;
|
||||
configValues["debug:damage_tracking"].intValue = DAMAGE_TRACKING_FULL;
|
||||
|
||||
configValues["decoration:rounding"].intValue = 0;
|
||||
configValues["decoration:blur"].intValue = 1;
|
||||
@@ -84,6 +84,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["decoration:shadow_render_power"].intValue = 3;
|
||||
configValues["decoration:shadow_ignore_window"].intValue = 1;
|
||||
configValues["decoration:shadow_offset"].vecValue = Vector2D();
|
||||
configValues["decoration:shadow_scale"].floatValue = 1.f;
|
||||
configValues["decoration:col.shadow"].intValue = 0xee1a1a1a;
|
||||
configValues["decoration:col.shadow_inactive"].intValue = INT_MAX;
|
||||
configValues["decoration:dim_inactive"].intValue = 0;
|
||||
@@ -105,6 +106,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["master:no_gaps_when_only"].intValue = 0;
|
||||
|
||||
configValues["animations:enabled"].intValue = 1;
|
||||
configValues["animations:use_resize_transitions"].intValue = 0;
|
||||
configValues["animations:speed"].floatValue = 7.f;
|
||||
configValues["animations:curve"].strValue = "default";
|
||||
configValues["animations:windows_style"].strValue = STRVAL_EMPTY;
|
||||
@@ -125,6 +127,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["animations:workspaces"].intValue = 1;
|
||||
|
||||
configValues["input:sensitivity"].floatValue = 0.f;
|
||||
configValues["input:accel_profile"].strValue = STRVAL_EMPTY;
|
||||
configValues["input:kb_file"].strValue = STRVAL_EMPTY;
|
||||
configValues["input:kb_layout"].strValue = "us";
|
||||
configValues["input:kb_variant"].strValue = STRVAL_EMPTY;
|
||||
@@ -137,12 +140,17 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["input:numlock_by_default"].intValue = 0;
|
||||
configValues["input:force_no_accel"].intValue = 0;
|
||||
configValues["input:float_switch_override_focus"].intValue = 1;
|
||||
configValues["input:left_handed"].intValue = 0;
|
||||
configValues["input:scroll_method"].strValue = STRVAL_EMPTY;
|
||||
configValues["input:touchpad:natural_scroll"].intValue = 0;
|
||||
configValues["input:touchpad:disable_while_typing"].intValue = 1;
|
||||
configValues["input:touchpad:clickfinger_behavior"].intValue = 0;
|
||||
configValues["input:touchpad:middle_button_emulation"].intValue = 0;
|
||||
configValues["input:touchpad:tap-to-click"].intValue = 1;
|
||||
configValues["input:touchpad:drag_lock"].intValue = 0;
|
||||
configValues["input:touchpad:scroll_factor"].floatValue = 1.f;
|
||||
configValues["input:touchdevice:transform"].intValue = 0;
|
||||
configValues["input:touchdevice:output"].strValue = STRVAL_EMPTY;
|
||||
|
||||
configValues["binds:pass_mouse_when_bound"].intValue = 0;
|
||||
configValues["binds:scroll_event_delay"].intValue = 300;
|
||||
@@ -155,6 +163,8 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["gestures:workspace_swipe_invert"].intValue = 1;
|
||||
configValues["gestures:workspace_swipe_min_speed_to_force"].intValue = 30;
|
||||
configValues["gestures:workspace_swipe_cancel_ratio"].floatValue = 0.5f;
|
||||
configValues["gestures:workspace_swipe_create_new"].intValue = 1;
|
||||
configValues["gestures:workspace_swipe_forever"].intValue = 0;
|
||||
|
||||
configValues["input:follow_mouse"].intValue = 1;
|
||||
|
||||
@@ -165,6 +175,7 @@ void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
|
||||
auto& cfgValues = deviceConfigs[dev];
|
||||
|
||||
cfgValues["sensitivity"].floatValue = 0.f;
|
||||
cfgValues["accel_profile"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["kb_file"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["kb_layout"].strValue = "us";
|
||||
cfgValues["kb_variant"].strValue = STRVAL_EMPTY;
|
||||
@@ -180,6 +191,11 @@ void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
|
||||
cfgValues["middle_button_emulation"].intValue = 0;
|
||||
cfgValues["tap-to-click"].intValue = 1;
|
||||
cfgValues["drag_lock"].intValue = 0;
|
||||
cfgValues["left_handed"].intValue = 0;
|
||||
cfgValues["scroll_method"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["touch_transform"].intValue = 0;
|
||||
cfgValues["touch_output"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["enabled"].intValue = 1; // only for mice / touchpads
|
||||
}
|
||||
|
||||
void CConfigManager::setDefaultAnimationVars() {
|
||||
@@ -296,20 +312,10 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
||||
|
||||
if (CONFIGENTRY->intValue != -INT64_MAX) {
|
||||
try {
|
||||
if (VALUE.find("0x") == 0) {
|
||||
// Values with 0x are hex
|
||||
const auto VALUEWITHOUTHEX = VALUE.substr(2);
|
||||
CONFIGENTRY->intValue = stol(VALUEWITHOUTHEX, nullptr, 16);
|
||||
} else if (VALUE.find("true") == 0 || VALUE.find("on") == 0 || VALUE.find("yes") == 0) {
|
||||
CONFIGENTRY->intValue = 1;
|
||||
} else if (VALUE.find("false") == 0 || VALUE.find("off") == 0 || VALUE.find("no") == 0) {
|
||||
CONFIGENTRY->intValue = 0;
|
||||
}
|
||||
else
|
||||
CONFIGENTRY->intValue = stol(VALUE);
|
||||
} catch (...) {
|
||||
CONFIGENTRY->intValue = configStringToInt(VALUE);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">. " + e.what();
|
||||
}
|
||||
} else if (CONFIGENTRY->floatValue != -__FLT_MAX__) {
|
||||
try {
|
||||
@@ -347,57 +353,7 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
||||
|
||||
void CConfigManager::handleRawExec(const std::string& command, const std::string& args) {
|
||||
// Exec in the background dont wait for it.
|
||||
|
||||
std::string toExec = args;
|
||||
|
||||
if (g_pXWaylandManager->m_sWLRXWayland)
|
||||
toExec = std::string("WAYLAND_DISPLAY=") + std::string(g_pCompositor->m_szWLDisplaySocket) + " DISPLAY=" + std::string(g_pXWaylandManager->m_sWLRXWayland->display_name) + " " + toExec;
|
||||
else
|
||||
toExec = std::string("WAYLAND_DISPLAY=") + std::string(g_pCompositor->m_szWLDisplaySocket) + " " + toExec;
|
||||
|
||||
Debug::log(LOG, "Config executing %s", toExec.c_str());
|
||||
|
||||
int socket[2];
|
||||
if (pipe(socket) != 0) {
|
||||
Debug::log(LOG, "Unable to create pipe for fork");
|
||||
}
|
||||
|
||||
pid_t child, grandchild;
|
||||
child = fork();
|
||||
if (child < 0) {
|
||||
close(socket[0]);
|
||||
close(socket[1]);
|
||||
Debug::log(LOG, "Fail to create the first fork");
|
||||
return;
|
||||
}
|
||||
if (child == 0) {
|
||||
// run in child
|
||||
grandchild = fork();
|
||||
if (grandchild == 0) {
|
||||
// run in grandchild
|
||||
close(socket[0]);
|
||||
close(socket[1]);
|
||||
execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
|
||||
// exit grandchild
|
||||
_exit(0);
|
||||
}
|
||||
close(socket[0]);
|
||||
write(socket[1], &grandchild, sizeof(grandchild));
|
||||
close(socket[1]);
|
||||
// exit child
|
||||
_exit(0);
|
||||
}
|
||||
// run in parent
|
||||
close(socket[1]);
|
||||
read(socket[0], &grandchild, sizeof(grandchild));
|
||||
close(socket[0]);
|
||||
// clear child and leave child to init
|
||||
waitpid(child, NULL, 0);
|
||||
if (child < 0) {
|
||||
Debug::log(LOG, "Fail to create the second fork");
|
||||
return;
|
||||
}
|
||||
Debug::log(LOG, "Process created with pid %d", grandchild);
|
||||
g_pKeybindManager->spawn(args);
|
||||
}
|
||||
|
||||
void CConfigManager::handleMonitor(const std::string& command, const std::string& args) {
|
||||
@@ -488,6 +444,9 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
if (ARGS[argno] == "mirror") {
|
||||
newrule.mirrorOf = ARGS[argno + 1];
|
||||
argno++;
|
||||
} else if (ARGS[argno] == "bitdepth") {
|
||||
newrule.enable10bit = ARGS[argno + 1] == "10";
|
||||
argno++;
|
||||
} else {
|
||||
Debug::log(ERR, "Config error: invalid monitor syntax");
|
||||
parseError = "invalid syntax at \"" + ARGS[argno] + "\"";
|
||||
@@ -705,18 +664,26 @@ bool windowRuleValid(const std::string& RULE) {
|
||||
&& RULE.find("opacity") != 0
|
||||
&& RULE.find("move") != 0
|
||||
&& RULE.find("size") != 0
|
||||
&& RULE.find("minsize") != 0
|
||||
&& RULE.find("maxsize") != 0
|
||||
&& RULE.find("pseudo") != 0
|
||||
&& RULE.find("monitor") != 0
|
||||
&& RULE.find("idleinhibit") != 0
|
||||
&& RULE != "nofocus"
|
||||
&& RULE != "noblur"
|
||||
&& RULE != "noshadow"
|
||||
&& RULE != "noborder"
|
||||
&& RULE != "center"
|
||||
&& RULE != "opaque"
|
||||
&& RULE != "forceinput"
|
||||
&& RULE != "fullscreen"
|
||||
&& RULE != "pin"
|
||||
&& RULE != "noanim"
|
||||
&& RULE != "windowdance"
|
||||
&& RULE.find("animation") != 0
|
||||
&& RULE.find("rounding") != 0
|
||||
&& RULE.find("workspace") != 0);
|
||||
&& RULE.find("workspace") != 0
|
||||
&& RULE.find("bordercolor") != 0);
|
||||
}
|
||||
|
||||
void CConfigManager::handleWindowRule(const std::string& command, const std::string& value) {
|
||||
@@ -728,6 +695,13 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str
|
||||
return;
|
||||
}
|
||||
|
||||
if (RULE == "unset") {
|
||||
std::erase_if(m_dWindowRules, [&] (const SWindowRule& other) {
|
||||
return other.szValue == VALUE;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// verify we support a rule
|
||||
if (!windowRuleValid(RULE)) {
|
||||
Debug::log(ERR, "Invalid rule found: %s", RULE.c_str());
|
||||
@@ -742,7 +716,7 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s
|
||||
const auto RULE = value.substr(0, value.find_first_of(","));
|
||||
const auto VALUE = value.substr(value.find_first_of(",") + 1);
|
||||
|
||||
if (!windowRuleValid(RULE)) {
|
||||
if (!windowRuleValid(RULE) && RULE != "unset") {
|
||||
Debug::log(ERR, "Invalid rulev2 found: %s", RULE.c_str());
|
||||
parseError = "Invalid rulev2 found: " + RULE;
|
||||
return;
|
||||
@@ -758,8 +732,12 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s
|
||||
const auto CLASSPOS = VALUE.find("class:");
|
||||
const auto X11POS = VALUE.find("xwayland:");
|
||||
const auto FLOATPOS = VALUE.find("floating:");
|
||||
const auto FULLSCREENPOS = VALUE.find("fullscreen:");
|
||||
const auto PINNEDPOS = VALUE.find("pinned:");
|
||||
|
||||
if (TITLEPOS == std::string::npos && CLASSPOS == std::string::npos && X11POS == std::string::npos && FLOATPOS == std::string::npos) {
|
||||
if (TITLEPOS == std::string::npos && CLASSPOS == std::string::npos &&
|
||||
X11POS == std::string::npos && FLOATPOS == std::string::npos &&
|
||||
FULLSCREENPOS == std::string::npos && PINNEDPOS == std::string::npos) {
|
||||
Debug::log(ERR, "Invalid rulev2 syntax: %s", VALUE.c_str());
|
||||
parseError = "Invalid rulev2 syntax: " + VALUE;
|
||||
return;
|
||||
@@ -774,6 +752,8 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s
|
||||
if (CLASSPOS > pos && CLASSPOS < min) min = CLASSPOS;
|
||||
if (X11POS > pos && X11POS < min) min = X11POS;
|
||||
if (FLOATPOS > pos && FLOATPOS < min) min = FLOATPOS;
|
||||
if (FULLSCREENPOS > pos && FULLSCREENPOS < min) min = FULLSCREENPOS;
|
||||
if (PINNEDPOS > pos && PINNEDPOS < min) min = PINNEDPOS;
|
||||
|
||||
result = result.substr(0, min - pos);
|
||||
|
||||
@@ -801,6 +781,49 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s
|
||||
rule.bFloating = extract(FLOATPOS + 9) == "1" ? 1 : 0;
|
||||
}
|
||||
|
||||
if (FULLSCREENPOS != std::string::npos) {
|
||||
rule.bFullscreen = extract(FULLSCREENPOS + 11) == "1" ? 1 : 0;
|
||||
}
|
||||
|
||||
if (PINNEDPOS != std::string::npos) {
|
||||
rule.bPinned = extract(PINNEDPOS + 7) == "1" ? 1 : 0;
|
||||
}
|
||||
|
||||
if (RULE == "unset") {
|
||||
std::erase_if(m_dWindowRules, [&](const SWindowRule& other) {
|
||||
if (!other.v2) {
|
||||
return other.szClass == rule.szClass && !rule.szClass.empty();
|
||||
} else {
|
||||
if (!rule.szClass.empty() && rule.szClass != other.szClass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rule.szTitle.empty() && rule.szTitle != other.szTitle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rule.bX11 != -1 && rule.bX11 != other.bX11) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rule.bFloating != -1 && rule.bFloating != other.bFloating) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rule.bFullscreen != -1 && rule.bFullscreen != other.bFullscreen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rule.bPinned != -1 && rule.bPinned != other.bPinned) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
m_dWindowRules.push_back(rule);
|
||||
}
|
||||
|
||||
@@ -967,13 +990,26 @@ void CConfigManager::applyUserDefinedVars(std::string& line, const size_t equals
|
||||
|
||||
void CConfigManager::parseLine(std::string& line) {
|
||||
// first check if its not a comment
|
||||
const auto COMMENTSTART = line.find_first_of('#');
|
||||
if (COMMENTSTART == 0)
|
||||
if (line[0] == '#')
|
||||
return;
|
||||
|
||||
// now, cut the comment off
|
||||
if (COMMENTSTART != std::string::npos)
|
||||
line = line.substr(0, COMMENTSTART);
|
||||
// now, cut the comment off. ## is an escape.
|
||||
for (long unsigned int i = 1; i < line.length(); ++i) {
|
||||
if (line[i] == '#') {
|
||||
if (i + 1 < line.length() && line[i + 1] != '#') {
|
||||
line = line.substr(0, i);
|
||||
break; // no need to parse more
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
size_t startPos = 0;
|
||||
while ((startPos = line.find("##", startPos)) != std::string::npos && startPos < line.length() - 1 && startPos > 0) {
|
||||
line.replace(startPos, 2, "#");
|
||||
startPos++;
|
||||
}
|
||||
|
||||
// remove shit at the beginning
|
||||
while (line[0] == ' ' || line[0] == '\t') {
|
||||
@@ -1124,18 +1160,12 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
// Update the keyboard layout to the cfg'd one if this is not the first launch
|
||||
if (!isFirstLaunch) {
|
||||
g_pInputManager->setKeyboardLayout();
|
||||
g_pInputManager->setMouseConfigs();
|
||||
g_pInputManager->setPointerConfigs();
|
||||
g_pInputManager->setTouchDeviceConfigs();
|
||||
}
|
||||
|
||||
// Calculate the internal vars
|
||||
configValues["general:main_mod_internal"].intValue = g_pKeybindManager->stringToModMask(configValues["general:main_mod"].strValue);
|
||||
const auto DAMAGETRACKINGMODE = g_pHyprRenderer->damageTrackingModeFromStr(configValues["general:damage_tracking"].strValue);
|
||||
if (DAMAGETRACKINGMODE != DAMAGE_TRACKING_INVALID)
|
||||
configValues["general:damage_tracking_internal"].intValue = DAMAGETRACKINGMODE;
|
||||
else {
|
||||
parseError = "invalid value for general:damage_tracking, supported: full, monitor, none";
|
||||
configValues["general:damage_tracking_internal"].intValue = DAMAGE_TRACKING_NONE;
|
||||
}
|
||||
|
||||
// parseError will be displayed next frame
|
||||
if (parseError != "")
|
||||
@@ -1154,6 +1184,7 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
|
||||
// check
|
||||
ensureDPMS();
|
||||
ensureVRR();
|
||||
}
|
||||
|
||||
// Update window border colors
|
||||
@@ -1294,11 +1325,11 @@ void CConfigManager::setString(std::string v, std::string val) {
|
||||
configValues[v].strValue = val;
|
||||
}
|
||||
|
||||
SMonitorRule CConfigManager::getMonitorRuleFor(std::string name) {
|
||||
SMonitorRule CConfigManager::getMonitorRuleFor(std::string name, std::string displayName) {
|
||||
SMonitorRule* found = nullptr;
|
||||
|
||||
for (auto& r : m_dMonitorRules) {
|
||||
if (r.name == name) {
|
||||
if (r.name == name || (r.name.find("desc:") == 0 && (r.name.substr(5) == displayName || r.name.substr(5) == removeBeginEndSpacesTabs(displayName.substr(0, displayName.find_first_of('(')))))) {
|
||||
found = &r;
|
||||
break;
|
||||
}
|
||||
@@ -1380,6 +1411,16 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow) {
|
||||
if (pWindow->m_bIsFloating != rule.bFloating)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rule.bFullscreen != -1) {
|
||||
if (pWindow->m_bIsFullscreen != rule.bFullscreen)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rule.bPinned != -1) {
|
||||
if (pWindow->m_bPinned != rule.bPinned)
|
||||
continue;
|
||||
}
|
||||
} catch (...) {
|
||||
Debug::log(ERR, "Regex error at %s", rule.szValue.c_str());
|
||||
continue;
|
||||
@@ -1392,6 +1433,19 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow) {
|
||||
returns.push_back(rule);
|
||||
}
|
||||
|
||||
const uint64_t PID = pWindow->getPID();
|
||||
bool anyExecFound = false;
|
||||
|
||||
for (auto& er : execRequestedRules) {
|
||||
if (er.iPid == PID) {
|
||||
returns.push_back({er.szRule, "execRule"});
|
||||
anyExecFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyExecFound) // remove exec rules to unclog searches in the future, why have the garbage here.
|
||||
execRequestedRules.erase(std::remove_if(execRequestedRules.begin(), execRequestedRules.end(), [&](const SExecRequestedRule& other) { return other.iPid == PID; }));
|
||||
|
||||
return returns;
|
||||
}
|
||||
|
||||
@@ -1409,7 +1463,8 @@ void CConfigManager::dispatchExecOnce() {
|
||||
|
||||
// set input, fixes some certain issues
|
||||
g_pInputManager->setKeyboardLayout();
|
||||
g_pInputManager->setMouseConfigs();
|
||||
g_pInputManager->setPointerConfigs();
|
||||
g_pInputManager->setTouchDeviceConfigs();
|
||||
|
||||
// set ws names again
|
||||
for (auto& ws : g_pCompositor->m_vWorkspaces) {
|
||||
@@ -1422,7 +1477,7 @@ void CConfigManager::performMonitorReload() {
|
||||
bool overAgain = false;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||
auto rule = getMonitorRuleFor(m->szName);
|
||||
auto rule = getMonitorRuleFor(m->szName, m->output->description ? m->output->description : "");
|
||||
|
||||
// ensure mirror
|
||||
m->setMirror(rule.mirrorOf);
|
||||
@@ -1475,7 +1530,7 @@ bool CConfigManager::shouldBlurLS(const std::string& ns) {
|
||||
|
||||
void CConfigManager::ensureDPMS() {
|
||||
for (auto& rm : g_pCompositor->m_vRealMonitors) {
|
||||
auto rule = getMonitorRuleFor(rm->szName);
|
||||
auto rule = getMonitorRuleFor(rm->szName, rm->output->description ? rm->output->description : "");
|
||||
|
||||
if (rule.disabled == rm->m_bEnabled) {
|
||||
rm->m_pThisWrap = &rm;
|
||||
@@ -1484,6 +1539,49 @@ void CConfigManager::ensureDPMS() {
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||
static auto *const PNOVRR = &getConfigValuePtr("misc:no_vfr")->intValue;
|
||||
|
||||
auto ensureVRRForDisplay = [&](CMonitor* m) -> void {
|
||||
if (!*PNOVRR && !m->vrrActive) {
|
||||
// Adaptive sync (VRR)
|
||||
wlr_output_enable_adaptive_sync(m->output, 1);
|
||||
|
||||
if (!wlr_output_test(m->output)) {
|
||||
Debug::log(LOG, "Pending output %s does not accept VRR.", m->output->name);
|
||||
wlr_output_enable_adaptive_sync(m->output, 0);
|
||||
}
|
||||
|
||||
if (!wlr_output_commit(m->output)) {
|
||||
Debug::log(ERR, "Couldn't commit output %s in ensureVRR -> true", m->output->name);
|
||||
}
|
||||
|
||||
m->vrrActive = true;
|
||||
|
||||
Debug::log(LOG, "VRR ensured on %s -> true", m->output->name);
|
||||
} else if (*PNOVRR && m->vrrActive) {
|
||||
wlr_output_enable_adaptive_sync(m->output, 0);
|
||||
|
||||
if (!wlr_output_commit(m->output)) {
|
||||
Debug::log(ERR, "Couldn't commit output %s in ensureVRR -> false", m->output->name);
|
||||
}
|
||||
|
||||
m->vrrActive = false;
|
||||
|
||||
Debug::log(LOG, "VRR ensured on %s -> false", m->output->name);
|
||||
}
|
||||
};
|
||||
|
||||
if (pMonitor) {
|
||||
ensureVRRForDisplay(pMonitor);
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
ensureVRRForDisplay(m.get());
|
||||
}
|
||||
}
|
||||
|
||||
SAnimationPropertyConfig* CConfigManager::getAnimationPropertyConfig(const std::string& name) {
|
||||
return &animationConfig[name];
|
||||
}
|
||||
@@ -1504,3 +1602,7 @@ CMonitor* CConfigManager::getBoundMonitorForWS(std::string wsname) {
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CConfigManager::addExecRule(SExecRequestedRule rule) {
|
||||
execRequestedRules.push_back(rule);
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ struct SMonitorRule {
|
||||
bool disabled = false;
|
||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
std::string mirrorOf = "";
|
||||
bool enable10bit = false;
|
||||
};
|
||||
|
||||
struct SMonitorAdditionalReservedArea {
|
||||
@@ -47,17 +48,6 @@ struct SMonitorAdditionalReservedArea {
|
||||
int right = 0;
|
||||
};
|
||||
|
||||
struct SWindowRule {
|
||||
std::string szRule;
|
||||
std::string szValue;
|
||||
|
||||
bool v2 = false;
|
||||
std::string szTitle;
|
||||
std::string szClass;
|
||||
int bX11 = -1; // -1 means "ANY"
|
||||
int bFloating = -1;
|
||||
};
|
||||
|
||||
struct SAnimationPropertyConfig {
|
||||
bool overriden = true;
|
||||
|
||||
@@ -70,14 +60,19 @@ struct SAnimationPropertyConfig {
|
||||
SAnimationPropertyConfig* pParentAnimation = nullptr;
|
||||
};
|
||||
|
||||
struct SExecRequestedRule {
|
||||
std::string szRule = "";
|
||||
uint64_t iPid = 0;
|
||||
};
|
||||
|
||||
class CVarList {
|
||||
public:
|
||||
CVarList(const std::string& in, long unsigned int lastArgNo = 0) {
|
||||
CVarList(const std::string& in, long unsigned int lastArgNo = 0, const char separator = ',') {
|
||||
std::string curitem = "";
|
||||
std::string argZ = in;
|
||||
|
||||
auto nextItem = [&]() {
|
||||
auto idx = lastArgNo != 0 && m_vArgs.size() >= lastArgNo - 1 ? std::string::npos : argZ.find_first_of(',');
|
||||
auto idx = lastArgNo != 0 && m_vArgs.size() >= lastArgNo - 1 ? std::string::npos : argZ.find_first_of(separator);
|
||||
|
||||
if (idx != std::string::npos) {
|
||||
curitem = argZ.substr(0, idx);
|
||||
@@ -108,7 +103,13 @@ public:
|
||||
return m_vArgs[idx];
|
||||
}
|
||||
|
||||
private:
|
||||
// for range-based loops
|
||||
std::vector<std::string>::iterator begin() { return m_vArgs.begin(); }
|
||||
std::vector<std::string>::const_iterator begin() const { return m_vArgs.begin(); }
|
||||
std::vector<std::string>::iterator end() { return m_vArgs.end(); }
|
||||
std::vector<std::string>::const_iterator end() const { return m_vArgs.end(); }
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_vArgs;
|
||||
};
|
||||
|
||||
@@ -135,7 +136,7 @@ public:
|
||||
SConfigValue* getConfigValuePtr(std::string);
|
||||
SConfigValue* getConfigValuePtrSafe(std::string);
|
||||
|
||||
SMonitorRule getMonitorRuleFor(std::string);
|
||||
SMonitorRule getMonitorRuleFor(std::string, std::string displayName = "");
|
||||
|
||||
CMonitor* getBoundMonitorForWS(std::string);
|
||||
|
||||
@@ -151,6 +152,7 @@ public:
|
||||
bool m_bForceReload = false;
|
||||
bool m_bNoMonitorReload = false;
|
||||
void ensureDPMS();
|
||||
void ensureVRR(CMonitor* pMonitor = nullptr);
|
||||
|
||||
std::string parseKeyword(const std::string&, const std::string&, bool dynamic = false);
|
||||
|
||||
@@ -158,6 +160,8 @@ public:
|
||||
|
||||
SAnimationPropertyConfig* getAnimationPropertyConfig(const std::string&);
|
||||
|
||||
void addExecRule(SExecRequestedRule);
|
||||
|
||||
std::string configCurrentPath;
|
||||
|
||||
private:
|
||||
@@ -177,6 +181,8 @@ private:
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> boundWorkspaces;
|
||||
|
||||
std::vector<SExecRequestedRule> execRequestedRules; // rules requested with exec, e.g. [workspace 2] kitty
|
||||
|
||||
bool isFirstLaunch = true; // For exec-once
|
||||
|
||||
std::deque<SMonitorRule> m_dMonitorRules;
|
||||
|
@@ -9,121 +9,160 @@ PLEASE USE THE CONFIG PROVIDED IN THE GIT REPO /examples/hypr.conf AND EDIT IT,
|
||||
OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
|
||||
########################################################################################
|
||||
|
||||
|
||||
#
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki (basic and advanced configuring)
|
||||
# For a full list, see the wiki
|
||||
#
|
||||
|
||||
autogenerated=1 # remove this line to get rid of the warning on top.
|
||||
autogenerated = 1 # remove this line to remove the warning
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Monitors/
|
||||
monitor=,preferred,auto,1
|
||||
|
||||
input {
|
||||
kb_file=
|
||||
kb_layout=
|
||||
kb_variant=
|
||||
kb_model=
|
||||
kb_options=
|
||||
kb_rules=
|
||||
|
||||
follow_mouse=1
|
||||
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
|
||||
|
||||
# Execute your favorite apps at launch
|
||||
# exec-once = waybar & hyprpaper & firefox
|
||||
|
||||
# Source a file (multi-file configs)
|
||||
# source = ~/.config/hypr/myColors.conf
|
||||
|
||||
# For all categories, see https://wiki.hyprland.org/Configuring/Variables/
|
||||
input {
|
||||
kb_layout = us
|
||||
kb_variant =
|
||||
kb_model =
|
||||
kb_options =
|
||||
kb_rules =
|
||||
|
||||
follow_mouse = 1
|
||||
|
||||
touchpad {
|
||||
natural_scroll=no
|
||||
natural_scroll = no
|
||||
}
|
||||
|
||||
sensitivity=0 # -1.0 - 1.0, 0 means no modification.
|
||||
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
|
||||
}
|
||||
|
||||
general {
|
||||
main_mod=SUPER
|
||||
# See https://wiki.hyprland.org/Configuring/Variables/ for more
|
||||
|
||||
gaps_in=5
|
||||
gaps_out=20
|
||||
border_size=2
|
||||
col.active_border=0x66ee1111
|
||||
col.inactive_border=0x66333333
|
||||
gaps_in = 5
|
||||
gaps_out = 20
|
||||
border_size = 2
|
||||
col.active_border = rgba(1affffee)
|
||||
col.inactive_border = rgba(595959aa)
|
||||
|
||||
apply_sens_to_raw=0 # whether to apply the sensitivity to raw input (e.g. used by games where you aim using your mouse)
|
||||
|
||||
damage_tracking=full # leave it on full unless you hate your GPU and want to make it suffer
|
||||
layout = dwindle
|
||||
}
|
||||
|
||||
decoration {
|
||||
rounding=10
|
||||
blur=1
|
||||
blur_size=3 # minimum 1
|
||||
blur_passes=1 # minimum 1
|
||||
blur_new_optimizations=1
|
||||
# See https://wiki.hyprland.org/Configuring/Variables/ for more
|
||||
|
||||
rounding = 10
|
||||
blur = yes
|
||||
blur_size = 3
|
||||
blur_passes = 1
|
||||
blur_new_optimizations = on
|
||||
|
||||
drop_shadow = yes
|
||||
shadow_range = 4
|
||||
shadow_render_power = 3
|
||||
col.shadow = rgba(1a1a1aee)
|
||||
}
|
||||
|
||||
animations {
|
||||
enabled=1
|
||||
animation=windows,1,7,default
|
||||
animation=border,1,10,default
|
||||
animation=fade,1,10,default
|
||||
animation=workspaces,1,6,default
|
||||
enabled = yes
|
||||
|
||||
# Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||
|
||||
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
|
||||
|
||||
animation = windows, 1, 7, myBezier
|
||||
animation = windowsOut, 1, 7, default, popin 80%
|
||||
animation = border, 1, 10, default
|
||||
animation = fade, 1, 7, default
|
||||
animation = workspaces, 1, 6, default
|
||||
}
|
||||
|
||||
dwindle {
|
||||
pseudotile=0 # enable pseudotiling on dwindle
|
||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||
pseudotile = yes # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||
preserve_split = yes # you probably want this
|
||||
}
|
||||
|
||||
master {
|
||||
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
|
||||
new_is_master = true
|
||||
}
|
||||
|
||||
gestures {
|
||||
workspace_swipe=no
|
||||
# See https://wiki.hyprland.org/Configuring/Variables/ for more
|
||||
workspace_swipe = off
|
||||
}
|
||||
|
||||
# example window rules
|
||||
# for windows named/classed as abc and xyz
|
||||
#windowrule=move 69 420,abc
|
||||
#windowrule=size 420 69,abc
|
||||
#windowrule=tile,xyz
|
||||
#windowrule=float,abc
|
||||
#windowrule=pseudo,abc
|
||||
#windowrule=monitor 0,xyz
|
||||
# Example per-device config
|
||||
# See https://wiki.hyprland.org/Configuring/Keywords/#executing for more
|
||||
device:epic mouse V1 {
|
||||
sensitivity = -0.5
|
||||
}
|
||||
|
||||
# some nice mouse binds
|
||||
bindm=SUPER,mouse:272,movewindow
|
||||
bindm=SUPER,mouse:273,resizewindow
|
||||
# Example windowrule v1
|
||||
# windowrule = float, ^(kitty)$
|
||||
# Example windowrule v2
|
||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
|
||||
|
||||
# example binds
|
||||
bind=SUPER,Q,exec,kitty
|
||||
bind=SUPER,RETURN,exec,alacritty
|
||||
bind=SUPER,C,killactive,
|
||||
bind=SUPER,M,exit,
|
||||
bind=SUPER,E,exec,dolphin
|
||||
bind=SUPER,V,togglefloating,
|
||||
bind=SUPER,R,exec,wofi --show drun -o DP-3
|
||||
bind=SUPER,P,pseudo,
|
||||
|
||||
bind=SUPER,left,movefocus,l
|
||||
bind=SUPER,right,movefocus,r
|
||||
bind=SUPER,up,movefocus,u
|
||||
bind=SUPER,down,movefocus,d
|
||||
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
|
||||
$mainMod = SUPER
|
||||
|
||||
bind=SUPER,1,workspace,1
|
||||
bind=SUPER,2,workspace,2
|
||||
bind=SUPER,3,workspace,3
|
||||
bind=SUPER,4,workspace,4
|
||||
bind=SUPER,5,workspace,5
|
||||
bind=SUPER,6,workspace,6
|
||||
bind=SUPER,7,workspace,7
|
||||
bind=SUPER,8,workspace,8
|
||||
bind=SUPER,9,workspace,9
|
||||
bind=SUPER,0,workspace,10
|
||||
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
|
||||
bind = $mainMod, Q, exec, kitty
|
||||
bind = $mainMod, C, killactive,
|
||||
bind = $mainMod, M, exit,
|
||||
bind = $mainMod, E, exec, dolphin
|
||||
bind = $mainMod, V, togglefloating,
|
||||
bind = $mainMod, R, exec, wofi --show drun
|
||||
bind = $mainMod, P, pseudo, # dwindle
|
||||
bind = $mainMod, J, togglesplit, # dwindle
|
||||
|
||||
bind=ALT,1,movetoworkspace,1
|
||||
bind=ALT,2,movetoworkspace,2
|
||||
bind=ALT,3,movetoworkspace,3
|
||||
bind=ALT,4,movetoworkspace,4
|
||||
bind=ALT,5,movetoworkspace,5
|
||||
bind=ALT,6,movetoworkspace,6
|
||||
bind=ALT,7,movetoworkspace,7
|
||||
bind=ALT,8,movetoworkspace,8
|
||||
bind=ALT,9,movetoworkspace,9
|
||||
bind=ALT,0,movetoworkspace,10
|
||||
# Move focus with mainMod + arrow keys
|
||||
bind = $mainMod, left, movefocus, l
|
||||
bind = $mainMod, right, movefocus, r
|
||||
bind = $mainMod, up, movefocus, u
|
||||
bind = $mainMod, down, movefocus, d
|
||||
|
||||
bind=SUPER,mouse_down,workspace,e+1
|
||||
bind=SUPER,mouse_up,workspace,e-1
|
||||
# Switch workspaces with mainMod + [0-9]
|
||||
bind = $mainMod, 1, workspace, 1
|
||||
bind = $mainMod, 2, workspace, 2
|
||||
bind = $mainMod, 3, workspace, 3
|
||||
bind = $mainMod, 4, workspace, 4
|
||||
bind = $mainMod, 5, workspace, 5
|
||||
bind = $mainMod, 6, workspace, 6
|
||||
bind = $mainMod, 7, workspace, 7
|
||||
bind = $mainMod, 8, workspace, 8
|
||||
bind = $mainMod, 9, workspace, 9
|
||||
bind = $mainMod, 0, workspace, 10
|
||||
|
||||
# Move active window to a workspace with mainMod + SHIFT + [0-9]
|
||||
bind = $mainMod SHIFT, 1, movetoworkspace, 1
|
||||
bind = $mainMod SHIFT, 2, movetoworkspace, 2
|
||||
bind = $mainMod SHIFT, 3, movetoworkspace, 3
|
||||
bind = $mainMod SHIFT, 4, movetoworkspace, 4
|
||||
bind = $mainMod SHIFT, 5, movetoworkspace, 5
|
||||
bind = $mainMod SHIFT, 6, movetoworkspace, 6
|
||||
bind = $mainMod SHIFT, 7, movetoworkspace, 7
|
||||
bind = $mainMod SHIFT, 8, movetoworkspace, 8
|
||||
bind = $mainMod SHIFT, 9, movetoworkspace, 9
|
||||
bind = $mainMod SHIFT, 0, movetoworkspace, 10
|
||||
|
||||
# Scroll through existing workspaces with mainMod + scroll
|
||||
bind = $mainMod, mouse_down, workspace, e+1
|
||||
bind = $mainMod, mouse_up, workspace, e-1
|
||||
|
||||
# Move/resize windows with mainMod + LMB/RMB and dragging
|
||||
bindm = $mainMod, mouse:272, movewindow
|
||||
bindm = $mainMod, mouse:273, resizewindow
|
||||
)#";
|
||||
|
@@ -23,6 +23,7 @@ std::string monitorsRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
R"#({
|
||||
"id": %i,
|
||||
"name": "%s",
|
||||
"description": "%s",
|
||||
"width": %i,
|
||||
"height": %i,
|
||||
"refreshRate": %f,
|
||||
@@ -35,10 +36,12 @@ R"#({
|
||||
"reserved": [%i, %i, %i, %i],
|
||||
"scale": %.2f,
|
||||
"transform": %i,
|
||||
"focused": %s
|
||||
"focused": %s,
|
||||
"dpmsStatus": %s
|
||||
},)#",
|
||||
m->ID,
|
||||
escapeJSONStrings(m->szName).c_str(),
|
||||
escapeJSONStrings(m->output->description ? m->output->description : "").c_str(),
|
||||
(int)m->vecPixelSize.x, (int)m->vecPixelSize.y,
|
||||
m->refreshRate,
|
||||
(int)m->vecPosition.x, (int)m->vecPosition.y,
|
||||
@@ -46,7 +49,8 @@ R"#({
|
||||
(int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y,
|
||||
m->scale,
|
||||
(int)m->transform,
|
||||
(m.get() == g_pCompositor->m_pLastMonitor ? "true" : "false")
|
||||
(m.get() == g_pCompositor->m_pLastMonitor ? "true" : "false"),
|
||||
(m->dpmsStatus ? "true" : "false")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -56,22 +60,17 @@ R"#({
|
||||
result += "]";
|
||||
} else {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\tfocused: %s\n\n",
|
||||
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "yes" : "no"));
|
||||
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tdescription: %s\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\tfocused: %s\n\tdpmsStatus: %i\n\n",
|
||||
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, (m->output->description ? m->output->description : ""), m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string clientsRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
std::string result = "";
|
||||
static std::string getWindowData(CWindow* w, HyprCtl::eHyprCtlOutputFormat format) {
|
||||
if (format == HyprCtl::FORMAT_JSON) {
|
||||
result += "[";
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsMapped) {
|
||||
result += getFormat(
|
||||
return getFormat(
|
||||
R"#({
|
||||
"address": "0x%x",
|
||||
"at": [%i, %i],
|
||||
@@ -90,20 +89,34 @@ R"#({
|
||||
"fullscreen": %s,
|
||||
"fullscreenMode": %i
|
||||
},)#",
|
||||
w.get(),
|
||||
(int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y,
|
||||
(int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y,
|
||||
w,
|
||||
(int)w->m_vRealPosition.goalv().x, (int)w->m_vRealPosition.goalv().y,
|
||||
(int)w->m_vRealSize.goalv().x, (int)w->m_vRealSize.goalv().y,
|
||||
w->m_iWorkspaceID, escapeJSONStrings(w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID))).c_str(),
|
||||
((int)w->m_bIsFloating == 1 ? "true" : "false"),
|
||||
w->m_iMonitorID,
|
||||
escapeJSONStrings(g_pXWaylandManager->getAppIDClass(w.get())).c_str(),
|
||||
escapeJSONStrings(g_pXWaylandManager->getTitle(w.get())).c_str(),
|
||||
escapeJSONStrings(g_pXWaylandManager->getAppIDClass(w)).c_str(),
|
||||
escapeJSONStrings(g_pXWaylandManager->getTitle(w)).c_str(),
|
||||
w->getPID(),
|
||||
((int)w->m_bIsX11 == 1 ? "true" : "false"),
|
||||
(w->m_bPinned ? "true" : "false"),
|
||||
(w->m_bIsFullscreen ? "true" : "false"),
|
||||
(w->m_bIsFullscreen ? (g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_efFullscreenMode : 0) : 0)
|
||||
);
|
||||
} else {
|
||||
return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\txwayland: %i\n\tpinned: %i\n\tfullscreen: %i\n\tfullscreenmode: %i\n\n",
|
||||
w, w->m_szTitle.c_str(), (int)w->m_vRealPosition.goalv().x, (int)w->m_vRealPosition.goalv().y, (int)w->m_vRealSize.goalv().x, (int)w->m_vRealSize.goalv().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w).c_str(), g_pXWaylandManager->getTitle(w).c_str(), w->getPID(), (int)w->m_bIsX11, (int)w->m_bPinned, (int)w->m_bIsFullscreen, (w->m_bIsFullscreen ? (g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_efFullscreenMode : 0) : 0));
|
||||
}
|
||||
}
|
||||
|
||||
std::string clientsRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
std::string result = "";
|
||||
if (format == HyprCtl::FORMAT_JSON) {
|
||||
result += "[";
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsMapped) {
|
||||
result += getWindowData(w.get(), format);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,9 +128,7 @@ R"#({
|
||||
} else {
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsMapped) {
|
||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\txwayland: %i\n\tpinned: %i\n\tfullscreen: %i\n\tfullscreenmode: %i\n\n",
|
||||
w.get(), w->m_szTitle.c_str(), (int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y, (int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w.get()).c_str(), g_pXWaylandManager->getTitle(w.get()).c_str(), w->getPID(), (int)w->m_bIsX11, (int)w->m_bPinned, (int)w->m_bIsFullscreen, (w->m_bIsFullscreen ? (g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_efFullscreenMode : 0) : 0));
|
||||
|
||||
result += getWindowData(w.get(), format);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,38 +183,12 @@ std::string activeWindowRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return format == HyprCtl::FORMAT_JSON ? "{}" : "Invalid";
|
||||
|
||||
if (format == HyprCtl::FORMAT_JSON) {
|
||||
return getFormat(
|
||||
R"#({
|
||||
"address": "0x%x",
|
||||
"at": [%i, %i],
|
||||
"size": [%i, %i],
|
||||
"workspace": {
|
||||
"id": %i,
|
||||
"name": "%s"
|
||||
},
|
||||
"floating": %s,
|
||||
"monitor": %i,
|
||||
"class": "%s",
|
||||
"title": "%s",
|
||||
"pid": %i,
|
||||
"xwayland": %s
|
||||
})#",
|
||||
PWINDOW,
|
||||
(int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y,
|
||||
(int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y,
|
||||
PWINDOW->m_iWorkspaceID, escapeJSONStrings(PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName).c_str(),
|
||||
((int)PWINDOW->m_bIsFloating == 1 ? "true" : "false"),
|
||||
PWINDOW->m_iMonitorID,
|
||||
escapeJSONStrings(g_pXWaylandManager->getAppIDClass(PWINDOW)).c_str(),
|
||||
escapeJSONStrings(g_pXWaylandManager->getTitle(PWINDOW)).c_str(),
|
||||
PWINDOW->getPID(),
|
||||
((int)PWINDOW->m_bIsX11 == 1 ? "true" : "false")
|
||||
);
|
||||
} else {
|
||||
return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\txwayland: %i\n\n",
|
||||
PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating, (int)PWINDOW->m_iMonitorID, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str(), g_pXWaylandManager->getTitle(PWINDOW).c_str(), PWINDOW->getPID(), (int)PWINDOW->m_bIsX11);
|
||||
}
|
||||
auto result = getWindowData(PWINDOW, format);
|
||||
|
||||
if (format == HyprCtl::FORMAT_JSON)
|
||||
result.pop_back();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string layersRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
@@ -402,6 +387,24 @@ R"#( {
|
||||
);
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
if (result[result.size() - 1] == ',')
|
||||
result.pop_back();
|
||||
result += "\n],\n";
|
||||
|
||||
result += "\"switches\": [\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lSwitches) {
|
||||
result += getFormat(
|
||||
R"#( {
|
||||
"address": "0x%x",
|
||||
"name": "%s"
|
||||
},)#",
|
||||
&d,
|
||||
d.pWlrDevice ? d.pWlrDevice->name : ""
|
||||
);
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
if (result[result.size() - 1] == ',')
|
||||
result.pop_back();
|
||||
@@ -442,6 +445,12 @@ R"#( {
|
||||
for (auto& d : g_pInputManager->m_lTouchDevices) {
|
||||
result += getFormat("\tTouch Device at %x:\n\t\t%s\n", &d, d.pWlrDevice ? d.pWlrDevice->name : "");
|
||||
}
|
||||
|
||||
result += "\n\nSwitches:\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lSwitches) {
|
||||
result += getFormat("\tSwitch Device at %x:\n\t\t%s\n", &d, d.pWlrDevice ? d.pWlrDevice->name : "");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -471,7 +480,7 @@ std::string versionRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
R"#({
|
||||
"branch": "%s",
|
||||
"commit": "%s",
|
||||
"dirty": %s
|
||||
"dirty": %s,
|
||||
"commit_message": "%s",
|
||||
"flags": [)#", GIT_BRANCH, GIT_COMMIT_HASH, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), removeBeginEndSpacesTabs(GIT_COMMIT_MESSAGE).c_str());
|
||||
|
||||
@@ -533,7 +542,8 @@ std::string dispatchKeyword(std::string in) {
|
||||
|
||||
if (COMMAND.contains("input") || COMMAND.contains("device:")) {
|
||||
g_pInputManager->setKeyboardLayout(); // update kb layout
|
||||
g_pInputManager->setMouseConfigs(); // update mouse cfgs
|
||||
g_pInputManager->setPointerConfigs(); // update mouse cfgs
|
||||
g_pInputManager->setTouchDeviceConfigs(); // update touch device cfgs
|
||||
}
|
||||
|
||||
if (COMMAND.contains("general:layout"))
|
||||
@@ -572,6 +582,23 @@ std::string splashRequest() {
|
||||
return g_pCompositor->m_szCurrentSplash;
|
||||
}
|
||||
|
||||
std::string cursorPosRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal().floor();
|
||||
|
||||
if (format == HyprCtl::FORMAT_NORMAL) {
|
||||
return getFormat("%i, %i", (int)CURSORPOS.x, (int)CURSORPOS.y);
|
||||
} else {
|
||||
return getFormat(R"#(
|
||||
{
|
||||
"x": %i,
|
||||
"y": %i
|
||||
}
|
||||
)#", (int)CURSORPOS.x, (int)CURSORPOS.y);
|
||||
}
|
||||
|
||||
return "error";
|
||||
}
|
||||
|
||||
std::string getReply(std::string);
|
||||
|
||||
std::string dispatchBatch(std::string request) {
|
||||
@@ -682,13 +709,13 @@ std::string dispatchGetOption(std::string request, HyprCtl::eHyprCtlOutputFormat
|
||||
return "no such option";
|
||||
|
||||
if (format == HyprCtl::eHyprCtlOutputFormat::FORMAT_NORMAL)
|
||||
return getFormat("option %s\n\tint: %i\n\tfloat: %f\n\tstr: \"%s\"", curitem.c_str(), PCFGOPT->intValue, PCFGOPT->floatValue, PCFGOPT->strValue.c_str());
|
||||
return getFormat("option %s\n\tint: %lld\n\tfloat: %f\n\tstr: \"%s\"", curitem.c_str(), PCFGOPT->intValue, PCFGOPT->floatValue, PCFGOPT->strValue.c_str());
|
||||
else {
|
||||
return getFormat(
|
||||
R"#(
|
||||
{
|
||||
"option": "%s",
|
||||
"int": %i,
|
||||
"int": %lld,
|
||||
"float": %f,
|
||||
"str": "%s"
|
||||
}
|
||||
@@ -697,6 +724,86 @@ R"#(
|
||||
}
|
||||
}
|
||||
|
||||
void createOutputIter(wlr_backend* backend, void* data) {
|
||||
const auto DATA = (std::pair<std::string, bool>*)data;
|
||||
|
||||
if (DATA->second)
|
||||
return;
|
||||
|
||||
if (DATA->first.empty() || DATA->first == "auto") {
|
||||
if (wlr_backend_is_wl(backend)) {
|
||||
wlr_wl_output_create(backend);
|
||||
DATA->second = true;
|
||||
} else if (wlr_backend_is_x11(backend)) {
|
||||
wlr_x11_output_create(backend);
|
||||
DATA->second = true;
|
||||
} else if (wlr_backend_is_headless(backend)) {
|
||||
wlr_headless_add_output(backend, 1920, 1080);
|
||||
DATA->second = true;
|
||||
}
|
||||
} else {
|
||||
if (wlr_backend_is_wl(backend) && DATA->first == "wayland") {
|
||||
wlr_wl_output_create(backend);
|
||||
DATA->second = true;
|
||||
} else if (wlr_backend_is_x11(backend) && DATA->first == "x11") {
|
||||
wlr_x11_output_create(backend);
|
||||
DATA->second = true;
|
||||
} else if (wlr_backend_is_headless(backend) && DATA->first == "headless") {
|
||||
wlr_headless_add_output(backend, 1920, 1080);
|
||||
DATA->second = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string dispatchOutput(std::string request) {
|
||||
std::string curitem = "";
|
||||
|
||||
auto nextItem = [&]() {
|
||||
auto idx = request.find_first_of(' ');
|
||||
|
||||
if (idx != std::string::npos) {
|
||||
curitem = request.substr(0, idx);
|
||||
request = request.substr(idx + 1);
|
||||
} else {
|
||||
curitem = request;
|
||||
request = "";
|
||||
}
|
||||
|
||||
curitem = removeBeginEndSpacesTabs(curitem);
|
||||
};
|
||||
|
||||
nextItem();
|
||||
nextItem();
|
||||
|
||||
const auto MODE = curitem;
|
||||
|
||||
nextItem();
|
||||
|
||||
const auto NAME = curitem;
|
||||
|
||||
if (MODE == "create" || MODE == "add") {
|
||||
std::pair<std::string, bool> result = { NAME, false };
|
||||
|
||||
wlr_multi_for_each_backend(g_pCompositor->m_sWLRBackend, createOutputIter, &result);
|
||||
|
||||
if (!result.second)
|
||||
return "no backend replied to the request";
|
||||
|
||||
} else if (MODE == "destroy" || MODE == "remove") {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromName(NAME);
|
||||
|
||||
if (!PMONITOR)
|
||||
return "output not found";
|
||||
|
||||
if (!PMONITOR->createdByUser)
|
||||
return "cannot remove a real display. Use the monitor keyword.";
|
||||
|
||||
wlr_output_destroy(PMONITOR->output);
|
||||
}
|
||||
|
||||
return "ok";
|
||||
}
|
||||
|
||||
std::string getReply(std::string request) {
|
||||
auto format = HyprCtl::FORMAT_NORMAL;
|
||||
|
||||
@@ -738,6 +845,10 @@ std::string getReply(std::string request) {
|
||||
return devicesRequest(format);
|
||||
else if (request == "splash")
|
||||
return splashRequest();
|
||||
else if (request == "cursorpos")
|
||||
return cursorPosRequest(format);
|
||||
else if (request.find("output") == 0)
|
||||
return dispatchOutput(request);
|
||||
else if (request.find("dispatch") == 0)
|
||||
return dispatchRequest(request);
|
||||
else if (request.find("keyword") == 0)
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
#include "wlrunstable/wlr_ext_workspace_v1.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef HYPRLAND_DEBUG
|
||||
#define ISDEBUG true
|
||||
|
@@ -82,6 +82,10 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
|
||||
Debug::log(LOG, "Attached a tablet pad with name %s", DEVICE->name);
|
||||
g_pInputManager->newTabletPad(DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_SWITCH:
|
||||
Debug::log(LOG, "Attached a switch device with name %s", DEVICE->name);
|
||||
g_pInputManager->newSwitch(DEVICE);
|
||||
break;
|
||||
default:
|
||||
Debug::log(WARN, "Unrecognized input device plugged in: %s", DEVICE->name);
|
||||
break;
|
||||
|
@@ -42,6 +42,7 @@ namespace Events {
|
||||
|
||||
// Surface XDG (window)
|
||||
LISTENER(newXDGSurface);
|
||||
LISTENER(activateXDG);
|
||||
|
||||
// Window events
|
||||
DYNLISTENFUNC(commitWindow);
|
||||
@@ -87,7 +88,6 @@ namespace Events {
|
||||
LISTENER(requestMouse);
|
||||
LISTENER(requestSetSel);
|
||||
LISTENER(requestSetPrimarySel);
|
||||
DYNLISTENFUNC(activate);
|
||||
|
||||
// outputMgr
|
||||
LISTENER(outputMgrApply);
|
||||
|
@@ -31,15 +31,17 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
|
||||
WLRLAYERSURFACE->output = PMONITOR->output;
|
||||
}
|
||||
|
||||
const auto PMONITOR = (CMonitor*)g_pCompositor->getMonitorFromOutput(WLRLAYERSURFACE->output);
|
||||
auto PMONITOR = (CMonitor*)g_pCompositor->getMonitorFromOutput(WLRLAYERSURFACE->output);
|
||||
|
||||
if (!WLRLAYERSURFACE->output || !PMONITOR || PMONITOR->pMirrorOf) {
|
||||
PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
||||
WLRLAYERSURFACE->output = PMONITOR->output; // TODO: current mon
|
||||
}
|
||||
|
||||
SLayerSurface* layerSurface = PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].emplace_back(std::make_unique<SLayerSurface>()).get();
|
||||
|
||||
layerSurface->szNamespace = WLRLAYERSURFACE->_namespace;
|
||||
|
||||
if (!WLRLAYERSURFACE->output) {
|
||||
WLRLAYERSURFACE->output = g_pCompositor->m_vMonitors.front()->output; // TODO: current mon
|
||||
}
|
||||
|
||||
layerSurface->hyprListener_commitLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.commit, &Events::listener_commitLayerSurface, layerSurface, "layerSurface");
|
||||
layerSurface->hyprListener_destroyLayerSurface.initCallback(&WLRLAYERSURFACE->events.destroy, &Events::listener_destroyLayerSurface, layerSurface, "layerSurface");
|
||||
layerSurface->hyprListener_mapLayerSurface.initCallback(&WLRLAYERSURFACE->events.map, &Events::listener_mapLayerSurface, layerSurface, "layerSurface");
|
||||
@@ -152,6 +154,8 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
|
||||
layersurface->alpha = 255.f;
|
||||
layersurface->readyToDelete = false;
|
||||
layersurface->fadingOut = false;
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"openlayer", std::string(layersurface->layerSurface->_namespace ? layersurface->layerSurface->_namespace : "")});
|
||||
}
|
||||
|
||||
void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
||||
@@ -159,6 +163,8 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
||||
|
||||
Debug::log(LOG, "LayerSurface %x unmapped", layersurface->layerSurface);
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"closelayer", std::string(layersurface->layerSurface->_namespace ? layersurface->layerSurface->_namespace : "")});
|
||||
|
||||
if (!g_pCompositor->getMonitorFromID(layersurface->monitorID) || g_pCompositor->m_bUnsafeState) {
|
||||
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
|
||||
|
||||
@@ -195,9 +201,30 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
||||
|
||||
// refocus if needed
|
||||
if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus) {
|
||||
|
||||
Vector2D surfaceCoords;
|
||||
SLayerSurface* pFoundLayerSurface = nullptr;
|
||||
wlr_surface* foundSurface = nullptr;
|
||||
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
|
||||
// find LS-es to focus
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
if (!foundSurface)
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
|
||||
if (!foundSurface) {
|
||||
// if there isn't any, focus the last window
|
||||
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow;
|
||||
g_pCompositor->focusWindow(nullptr);
|
||||
g_pCompositor->focusWindow(PLASTWINDOW);
|
||||
} else {
|
||||
// otherwise, full refocus
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
}
|
||||
|
||||
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
|
@@ -45,6 +45,7 @@ void Events::listener_requestSetSel(wl_listener* listener, void* data) {
|
||||
}
|
||||
|
||||
void Events::listener_readyXWayland(wl_listener* listener, void* data) {
|
||||
#ifndef NO_XWAYLAND
|
||||
const auto XCBCONNECTION = xcb_connect(g_pXWaylandManager->m_sWLRXWayland->display_name, NULL);
|
||||
const auto ERR = xcb_connection_has_error(XCBCONNECTION);
|
||||
if (ERR) {
|
||||
@@ -72,6 +73,7 @@ void Events::listener_readyXWayland(wl_listener* listener, void* data) {
|
||||
}
|
||||
|
||||
xcb_disconnect(XCBCONNECTION);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Events::listener_requestDrag(wl_listener* listener, void* data) {
|
||||
|
@@ -37,8 +37,6 @@ void Events::listener_change(wl_listener* listener, void* data) {
|
||||
CONFIGHEAD->state.mode = m->output->current_mode;
|
||||
CONFIGHEAD->state.x = m->vecPosition.x;
|
||||
CONFIGHEAD->state.y = m->vecPosition.y;
|
||||
|
||||
wlr_output_set_custom_mode(m->output, m->vecPixelSize.x, m->vecPixelSize.y, (int)(round(m->refreshRate * 1000)));
|
||||
}
|
||||
|
||||
wlr_output_manager_v1_set_configuration(g_pCompositor->m_sWLROutputMgr, CONFIG);
|
||||
@@ -108,9 +106,10 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
static std::chrono::high_resolution_clock::time_point endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
|
||||
static auto *const PDEBUGOVERLAY = &g_pConfigManager->getConfigValuePtr("debug:overlay")->intValue;
|
||||
static auto *const PDAMAGETRACKINGMODE = &g_pConfigManager->getConfigValuePtr("general:damage_tracking_internal")->intValue;
|
||||
static auto *const PDAMAGETRACKINGMODE = &g_pConfigManager->getConfigValuePtr("debug:damage_tracking")->intValue;
|
||||
static auto *const PDAMAGEBLINK = &g_pConfigManager->getConfigValuePtr("debug:damage_blink")->intValue;
|
||||
static auto *const PNOVFR = &g_pConfigManager->getConfigValuePtr("misc:no_vfr")->intValue;
|
||||
static auto *const PNODIRECTSCANOUT = &g_pConfigManager->getConfigValuePtr("misc:no_direct_scanout")->intValue;
|
||||
|
||||
static int damageBlinkCleanup = 0; // because double-buffered
|
||||
|
||||
@@ -156,6 +155,16 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
||||
}
|
||||
|
||||
// Direct scanout first
|
||||
if (!*PNODIRECTSCANOUT) {
|
||||
if (g_pHyprRenderer->attemptDirectScanout(PMONITOR)) {
|
||||
return;
|
||||
} else if (g_pHyprRenderer->m_pLastScanout) {
|
||||
Debug::log(LOG, "Left a direct scanout.");
|
||||
g_pHyprRenderer->m_pLastScanout = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
@@ -227,8 +236,6 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
|
||||
if (PMONITOR->isMirror()) {
|
||||
g_pHyprOpenGL->renderMirrored();
|
||||
|
||||
Debug::log(LOG, "Mirror frame");
|
||||
} else {
|
||||
g_pHyprOpenGL->clear(CColor(17, 17, 17, 255));
|
||||
g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper"
|
||||
@@ -236,11 +243,11 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now);
|
||||
|
||||
// if correct monitor draw hyprerror
|
||||
if (PMONITOR->ID == 0)
|
||||
if (PMONITOR == g_pCompositor->m_vMonitors.front().get())
|
||||
g_pHyprError->draw();
|
||||
|
||||
// for drawing the debug overlay
|
||||
if (PMONITOR->ID == 0 && *PDEBUGOVERLAY == 1) {
|
||||
if (PMONITOR == g_pCompositor->m_vMonitors.front().get() && *PDEBUGOVERLAY == 1) {
|
||||
startRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
g_pDebugOverlay->draw();
|
||||
endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
@@ -295,7 +302,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
if (*PDEBUGOVERLAY == 1) {
|
||||
const float µs = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - startRender).count() / 1000.f;
|
||||
g_pDebugOverlay->renderData(PMONITOR, µs);
|
||||
if (PMONITOR->ID == 0) {
|
||||
if (PMONITOR == g_pCompositor->m_vMonitors.front().get()) {
|
||||
const float µsNoOverlay = µs - std::chrono::duration_cast<std::chrono::nanoseconds>(endRenderOverlay - startRenderOverlay).count() / 1000.f;
|
||||
g_pDebugOverlay->renderDataNoOverlay(PMONITOR, µsNoOverlay);
|
||||
} else {
|
||||
|
@@ -32,8 +32,8 @@ void addPopupGlobalCoords(void* pPopup, int* x, int* y) {
|
||||
py -= curPopup->popup->base->current.geometry.y;
|
||||
}
|
||||
|
||||
if (curPopup->pSurfaceTree && curPopup->pSurfaceTree->pSurface && !curPopup->parentPopup && !curPopup->parentWindow) {
|
||||
const auto EXTENTSSURFACE = pixman_region32_extents(&curPopup->pSurfaceTree->pSurface->input_region);
|
||||
if (curPopup->popup && !curPopup->parentPopup && !curPopup->parentWindow) {
|
||||
const auto EXTENTSSURFACE = pixman_region32_extents(&curPopup->popup->base->surface->input_region);
|
||||
px -= EXTENTSSURFACE->x1;
|
||||
py -= EXTENTSSURFACE->y1;
|
||||
}
|
||||
|
@@ -65,8 +65,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
if (PWINDOW->m_iX11Type == 2)
|
||||
g_pCompositor->moveUnmanagedX11ToWindows(PWINDOW);
|
||||
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW);
|
||||
|
||||
// Set all windows tiled regardless of anything
|
||||
g_pXWaylandManager->setWindowStyleTiled(PWINDOW, WLR_EDGE_LEFT | WLR_EDGE_RIGHT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM);
|
||||
|
||||
@@ -76,6 +74,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
// checks if the window wants borders and sets the appriopriate flag
|
||||
g_pXWaylandManager->checkBorders(PWINDOW);
|
||||
|
||||
// registers the animated vars and stuff
|
||||
PWINDOW->onMap();
|
||||
|
||||
const auto PWINDOWSURFACE = g_pXWaylandManager->getWindowSurface(PWINDOW);
|
||||
|
||||
if (!PWINDOWSURFACE) {
|
||||
@@ -112,8 +113,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(PWINDOW);
|
||||
std::string requestedWorkspace = "";
|
||||
bool workspaceSilent = false;
|
||||
bool requestsFullscreen = PWINDOW->m_bWantsInitialFullscreen || (!PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xdg->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL && PWINDOW->m_uSurface.xdg->toplevel->requested.fullscreen);
|
||||
bool requestsFullscreen = PWINDOW->m_bWantsInitialFullscreen || (!PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xdg->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL && PWINDOW->m_uSurface.xdg->toplevel->requested.fullscreen) || (PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xwayland->fullscreen);
|
||||
bool shouldFocus = true;
|
||||
bool workspaceSpecial = false;
|
||||
|
||||
for (auto& r : WINDOWRULES) {
|
||||
if (r.szRule.find("monitor") == 0) {
|
||||
@@ -147,6 +149,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
requestedWorkspace = WORKSPACERQ;
|
||||
}
|
||||
|
||||
if (requestedWorkspace == PWORKSPACE->m_szName || requestedWorkspace == "name:" + PWORKSPACE->m_szName)
|
||||
requestedWorkspace = "";
|
||||
|
||||
Debug::log(LOG, "Rule workspace matched by window %x, %s applied.", PWINDOW, r.szValue.c_str());
|
||||
} else if (r.szRule.find("float") == 0) {
|
||||
PWINDOW->m_bIsFloating = true;
|
||||
@@ -156,40 +161,30 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_bIsPseudotiled = true;
|
||||
} else if (r.szRule.find("nofocus") == 0) {
|
||||
PWINDOW->m_bNoFocus = true;
|
||||
} else if (r.szRule == "noblur") {
|
||||
PWINDOW->m_sAdditionalConfigData.forceNoBlur = true;
|
||||
} else if (r.szRule == "fullscreen") {
|
||||
requestsFullscreen = true;
|
||||
} else if (r.szRule == "opaque") {
|
||||
PWINDOW->m_sAdditionalConfigData.forceOpaque = true;
|
||||
} else if (r.szRule == "windowdance") {
|
||||
PWINDOW->m_sAdditionalConfigData.windowDanceCompat = true;
|
||||
} else if (r.szRule == "forceinput") {
|
||||
PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true;
|
||||
} else if (r.szRule == "pin") {
|
||||
PWINDOW->m_bPinned = true;
|
||||
} else if (r.szRule.find("rounding") == 0) {
|
||||
try {
|
||||
PWINDOW->m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Rounding rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
|
||||
}
|
||||
} else if (r.szRule.find("opacity") == 0) {
|
||||
try {
|
||||
std::string alphaPart = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
|
||||
} else if (r.szRule.find("idleinhibit") == 0) {
|
||||
auto IDLERULE = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
|
||||
|
||||
if (alphaPart.contains(' ')) {
|
||||
// we have a comma, 2 values
|
||||
PWINDOW->m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' ')));
|
||||
PWINDOW->m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1));
|
||||
if (IDLERULE == "none") {
|
||||
PWINDOW->m_eIdleInhibitMode = IDLEINHIBIT_NONE;
|
||||
} else if (IDLERULE == "always") {
|
||||
PWINDOW->m_eIdleInhibitMode = IDLEINHIBIT_ALWAYS;
|
||||
} else if (IDLERULE == "focus") {
|
||||
PWINDOW->m_eIdleInhibitMode = IDLEINHIBIT_FOCUS;
|
||||
} else if (IDLERULE == "fullscreen") {
|
||||
PWINDOW->m_eIdleInhibitMode = IDLEINHIBIT_FULLSCREEN;
|
||||
} else {
|
||||
PWINDOW->m_sSpecialRenderData.alpha = std::stof(alphaPart);
|
||||
Debug::log(ERR, "Rule idleinhibit: unknown mode %s", IDLERULE.c_str());
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
Debug::log(ERR, "Opacity rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
|
||||
}
|
||||
} else if (r.szRule.find("animation") == 0) {
|
||||
auto STYLE = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
|
||||
PWINDOW->m_sAdditionalConfigData.animationStyle = STYLE;
|
||||
}
|
||||
PWINDOW->applyDynamicRule(r);
|
||||
}
|
||||
|
||||
// disallow tiled pinned
|
||||
@@ -203,17 +198,18 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
if (requestedWorkspace.contains("silent")) {
|
||||
workspaceSilent = true;
|
||||
shouldFocus = false;
|
||||
}
|
||||
|
||||
requestedWorkspace = requestedWorkspace.substr(0, requestedWorkspace.find_first_of(' '));
|
||||
}
|
||||
|
||||
if (!shouldFocus && requestedWorkspace == std::to_string(PMONITOR->activeWorkspace))
|
||||
shouldFocus = true;
|
||||
}
|
||||
|
||||
if (requestedWorkspace == "special") {
|
||||
workspaceSpecial = true;
|
||||
workspaceSilent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!workspaceSilent) {
|
||||
g_pKeybindManager->m_mDispatchers["workspace"](requestedWorkspace);
|
||||
@@ -223,6 +219,44 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
}
|
||||
}
|
||||
|
||||
if (workspaceSilent) {
|
||||
// get the workspace
|
||||
|
||||
auto PWORKSPACE = g_pCompositor->getWorkspaceByString(requestedWorkspace);
|
||||
|
||||
if (!PWORKSPACE) {
|
||||
std::string workspaceName = "";
|
||||
int workspaceID = 0;
|
||||
|
||||
if (requestedWorkspace.find("name:") == 0) {
|
||||
workspaceName = requestedWorkspace.substr(5);
|
||||
workspaceID = g_pCompositor->getNextAvailableNamedWorkspace();
|
||||
} else if (workspaceSpecial) {
|
||||
workspaceName = "";
|
||||
workspaceID = SPECIAL_WORKSPACE_ID;
|
||||
} else {
|
||||
try {
|
||||
workspaceID = std::stoi(requestedWorkspace);
|
||||
} catch (...) {
|
||||
workspaceID = -1;
|
||||
Debug::log(ERR, "Invalid workspace requested in workspace silent rule!");
|
||||
}
|
||||
|
||||
if (workspaceID < 1) {
|
||||
workspaceID = -1; // means invalid
|
||||
}
|
||||
}
|
||||
|
||||
if (workspaceID != -1)
|
||||
PWORKSPACE = g_pCompositor->createNewWorkspace(workspaceID, PWINDOW->m_iMonitorID, workspaceName);
|
||||
}
|
||||
|
||||
if (PWORKSPACE) {
|
||||
PWINDOW->m_iWorkspaceID = PWORKSPACE->m_iID;
|
||||
PWINDOW->m_iMonitorID = PWORKSPACE->m_iMonitorID;
|
||||
}
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bIsFloating) {
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW);
|
||||
PWINDOW->m_bCreatedOverFullscreen = true;
|
||||
@@ -245,24 +279,96 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY);
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
||||
|
||||
PWINDOW->m_bHidden = false;
|
||||
PWINDOW->setHidden(false);
|
||||
} catch (...) {
|
||||
Debug::log(LOG, "Rule size failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str());
|
||||
}
|
||||
} else if (r.szRule.find("move") == 0) {
|
||||
} else if (r.szRule.find("minsize") == 0) {
|
||||
try {
|
||||
const auto VALUE = r.szRule.substr(r.szRule.find(" ") + 1);
|
||||
const auto POSXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||
const auto POSYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||
const auto SIZEYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||
|
||||
const auto POSX = !POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.x;
|
||||
const auto POSY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y;
|
||||
const auto SIZE = Vector2D(std::max((double)std::stoll(SIZEXSTR), PWINDOW->m_vRealSize.goalv().x), std::max((double)std::stoll(SIZEYSTR), PWINDOW->m_vRealSize.goalv().y));
|
||||
|
||||
PWINDOW->m_vRealSize = SIZE;
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
||||
|
||||
PWINDOW->setHidden(false);
|
||||
} catch (...) {
|
||||
Debug::log(LOG, "Rule minsize failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str());
|
||||
}
|
||||
} else if (r.szRule.find("maxsize") == 0) {
|
||||
try {
|
||||
const auto VALUE = r.szRule.substr(r.szRule.find(" ") + 1);
|
||||
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||
const auto SIZEYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||
|
||||
const auto SIZE = Vector2D(std::min((double)std::stoll(SIZEXSTR), PWINDOW->m_vRealSize.goalv().x), std::min((double)std::stoll(SIZEYSTR), PWINDOW->m_vRealSize.goalv().y));
|
||||
|
||||
PWINDOW->m_vRealSize = SIZE;
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
||||
|
||||
PWINDOW->setHidden(false);
|
||||
} catch (...) {
|
||||
Debug::log(LOG, "Rule maxsize failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str());
|
||||
}
|
||||
} else if (r.szRule.find("move") == 0) {
|
||||
try {
|
||||
auto value = r.szRule.substr(r.szRule.find(" ") + 1);
|
||||
|
||||
const bool CURSOR = value.find("cursor") == 0;
|
||||
|
||||
if (CURSOR)
|
||||
value = value.substr(value.find_first_of(' ') + 1);
|
||||
|
||||
const auto POSXSTR = value.substr(0, value.find(" "));
|
||||
const auto POSYSTR = value.substr(value.find(" ") + 1);
|
||||
|
||||
int posX = 0;
|
||||
int posY = 0;
|
||||
|
||||
if (POSXSTR.find("100%-") == 0) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
const auto POSXRAW = POSXSTR.substr(5);
|
||||
posX = PMONITOR->vecSize.x - (!POSXRAW.contains('%') ? std::stoi(POSXRAW) : std::stoi(POSXRAW.substr(0, POSXRAW.length() - 1)) * 0.01 * PMONITOR->vecSize.x);
|
||||
|
||||
if (CURSOR)
|
||||
Debug::log(ERR, "Cursor is not compatible with 100%-, ignoring cursor!");
|
||||
} else if (!CURSOR) {
|
||||
posX = !POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.x;
|
||||
} else {
|
||||
// cursor
|
||||
if (POSXSTR == "cursor") {
|
||||
posX = g_pInputManager->getMouseCoordsInternal().x - PMONITOR->vecPosition.x;
|
||||
} else {
|
||||
posX = g_pInputManager->getMouseCoordsInternal().x - PMONITOR->vecPosition.x + (!POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize.goalv().x);
|
||||
}
|
||||
}
|
||||
|
||||
if (POSYSTR.find("100%-") == 0) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
const auto POSYRAW = POSYSTR.substr(5);
|
||||
posY = PMONITOR->vecSize.y - (!POSYRAW.contains('%') ? std::stoi(POSYRAW) : std::stoi(POSYRAW.substr(0, POSYRAW.length() - 1)) * 0.01 * PMONITOR->vecSize.y);
|
||||
|
||||
if (CURSOR)
|
||||
Debug::log(ERR, "Cursor is not compatible with 100%-, ignoring cursor!");
|
||||
} else if (!CURSOR) {
|
||||
posY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y;
|
||||
} else {
|
||||
// cursor
|
||||
if (POSYSTR == "cursor") {
|
||||
posY = g_pInputManager->getMouseCoordsInternal().y - PMONITOR->vecPosition.y;
|
||||
} else {
|
||||
posY = g_pInputManager->getMouseCoordsInternal().y - PMONITOR->vecPosition.y + (!POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize.goalv().y);
|
||||
}
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Rule move, applying to window %x", PWINDOW);
|
||||
|
||||
PWINDOW->m_vRealPosition = Vector2D(POSX, POSY) + PMONITOR->vecPosition;
|
||||
PWINDOW->m_vRealPosition = Vector2D(posX, posY) + PMONITOR->vecPosition;
|
||||
|
||||
PWINDOW->m_bHidden = false;
|
||||
PWINDOW->setHidden(false);
|
||||
} catch (...) {
|
||||
Debug::log(LOG, "Rule move failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str());
|
||||
}
|
||||
@@ -276,8 +382,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv();
|
||||
|
||||
g_pCompositor->moveWindowToTop(PWINDOW);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
|
||||
|
||||
// Set the pseudo size here too so that it doesnt end up being 0x0
|
||||
@@ -292,7 +397,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_bX11ShouldntFocus = false;
|
||||
}
|
||||
|
||||
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && PWINDOW->m_iX11Type != 2) {
|
||||
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && PWINDOW->m_iX11Type != 2 && !workspaceSilent) {
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
|
||||
PWINDOW->m_fDimPercent.setValueAndWarp(*PDIMSTRENGTH);
|
||||
@@ -317,6 +422,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->hyprListener_activateX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_activate, &Events::listener_activateX11, PWINDOW, "XWayland Window Late");
|
||||
PWINDOW->hyprListener_configureX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_configure, &Events::listener_configureX11, PWINDOW, "XWayland Window Late");
|
||||
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XWayland Window Late");
|
||||
PWINDOW->hyprListener_requestMinimize.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_minimize, &Events::listener_requestMinimize, PWINDOW, "Xwayland Window Late");
|
||||
PWINDOW->hyprListener_requestMinimize.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_maximize, &Events::listener_requestMaximize, PWINDOW, "Xwayland Window Late");
|
||||
|
||||
if (PWINDOW->m_iX11Type == 2)
|
||||
PWINDOW->hyprListener_setGeometryX11U.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_geometry, &Events::listener_unmanagedSetGeometry, PWINDOW, "XWayland Window Late");
|
||||
@@ -330,22 +437,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
const auto TIMER = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, setAnimToMove, PWINDOW);
|
||||
wl_event_source_timer_update(TIMER, PWINDOW->m_vRealPosition.getDurationLeftMs() + 5);
|
||||
|
||||
if (workspaceSilent) {
|
||||
// move the window
|
||||
const auto OLDWORKSPACE = PWINDOW->m_iWorkspaceID;
|
||||
|
||||
if (g_pCompositor->m_pLastWindow == PWINDOW) {
|
||||
if (requestedWorkspace != "special")
|
||||
g_pKeybindManager->m_mDispatchers["movetoworkspacesilent"](requestedWorkspace);
|
||||
else
|
||||
g_pKeybindManager->m_mDispatchers["movetoworkspace"]("special");
|
||||
} else {
|
||||
Debug::log(ERR, "Tried to set workspace silent rule to a nofocus window!");
|
||||
}
|
||||
|
||||
g_pCompositor->forceReportSizesToWindowsOnWorkspace(OLDWORKSPACE);
|
||||
}
|
||||
|
||||
if (requestsFullscreen) {
|
||||
// fix fullscreen on requested (basically do a switcheroo)
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
@@ -380,39 +471,59 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
// verify swallowing
|
||||
if (*PSWALLOW) {
|
||||
// don't swallow ourselves
|
||||
std::regex rgx(*PSWALLOWREGEX);
|
||||
if (!std::regex_match(g_pXWaylandManager->getAppIDClass(PWINDOW), rgx)) {
|
||||
// check parent
|
||||
int ppid = getPPIDof(PWINDOW->getPID());
|
||||
|
||||
const auto PPPID = getPPIDof(ppid);
|
||||
int curppid = 0;
|
||||
|
||||
// why? no clue. Blame terminals.
|
||||
if (PPPID > 2) {
|
||||
ppid = PPPID;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
curppid = getPPIDof(ppid);
|
||||
|
||||
if (curppid < 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
ppid = curppid;
|
||||
}
|
||||
|
||||
if (ppid) {
|
||||
// get window by pid
|
||||
CWindow* found = nullptr;
|
||||
std::vector<CWindow*> found;
|
||||
CWindow* finalFound = nullptr;
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (!w->m_bIsMapped || w->m_bHidden)
|
||||
if (!w->m_bIsMapped || w->isHidden())
|
||||
continue;
|
||||
|
||||
if (w->getPID() == ppid) {
|
||||
found = w.get();
|
||||
found.push_back(w.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (found.size() > 1) {
|
||||
for (auto& w : found) {
|
||||
// try get the focus, otherwise we'll ignore to avoid swallowing incorrect windows
|
||||
if (w == PFOCUSEDWINDOWPREV) {
|
||||
finalFound = w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (found.size() == 1) {
|
||||
finalFound = found[0];
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if (finalFound) {
|
||||
// check if it's the window we want
|
||||
std::regex rgx(*PSWALLOWREGEX);
|
||||
if (std::regex_match(g_pXWaylandManager->getAppIDClass(found), rgx)) {
|
||||
if (std::regex_match(g_pXWaylandManager->getAppIDClass(finalFound), rgx)) {
|
||||
// swallow
|
||||
PWINDOW->m_pSwallowed = found;
|
||||
PWINDOW->m_pSwallowed = finalFound;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(found);
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(finalFound);
|
||||
|
||||
found->m_bHidden = true;
|
||||
finalFound->setHidden(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -422,6 +533,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName;
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"openwindow", getFormat("%x,%s,%s,%s", PWINDOW, workspaceID.c_str(), g_pXWaylandManager->getAppIDClass(PWINDOW).c_str(), PWINDOW->m_szTitle.c_str())});
|
||||
|
||||
// recalc the values for this window
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW);
|
||||
}
|
||||
|
||||
void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
@@ -448,6 +562,8 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
PWINDOW->hyprListener_configureX11.removeCallback();
|
||||
PWINDOW->hyprListener_setTitleWindow.removeCallback();
|
||||
PWINDOW->hyprListener_setGeometryX11U.removeCallback();
|
||||
PWINDOW->hyprListener_requestMaximize.removeCallback();
|
||||
PWINDOW->hyprListener_requestMinimize.removeCallback();
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bIsFullscreen) {
|
||||
@@ -459,7 +575,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
|
||||
// swallowing
|
||||
if (PWINDOW->m_pSwallowed && g_pCompositor->windowExists(PWINDOW->m_pSwallowed)) {
|
||||
PWINDOW->m_pSwallowed->m_bHidden = false;
|
||||
PWINDOW->m_pSwallowed->setHidden(false);
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW->m_pSwallowed);
|
||||
PWINDOW->m_pSwallowed = nullptr;
|
||||
}
|
||||
@@ -487,13 +603,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
|
||||
// refocus on a new window if needed
|
||||
if (wasLastWindow) {
|
||||
auto PWINDOWCANDIDATE = g_pCompositor->vectorToWindowIdeal(PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f);
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && ((!PWINDOWCANDIDATE || !PWINDOWCANDIDATE->m_bCreatedOverFullscreen) || !PWINDOW->m_bIsFloating))
|
||||
PWINDOWCANDIDATE = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
|
||||
if (!PWINDOWCANDIDATE || PWINDOW == PWINDOWCANDIDATE || !PWINDOWCANDIDATE->m_bIsMapped || PWINDOWCANDIDATE->m_bHidden || PWINDOWCANDIDATE->m_bX11ShouldntFocus || PWINDOWCANDIDATE->m_iX11Type == 2 || PWINDOWCANDIDATE->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)
|
||||
PWINDOWCANDIDATE = nullptr;
|
||||
const auto PWINDOWCANDIDATE = g_pLayoutManager->getCurrentLayout()->getNextWindowCandidate(PWINDOW);
|
||||
|
||||
Debug::log(LOG, "On closed window, new focused candidate is %x", PWINDOWCANDIDATE);
|
||||
|
||||
@@ -502,6 +612,8 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
g_pInputManager->refocus();
|
||||
else
|
||||
g_pCompositor->focusWindow(PWINDOWCANDIDATE);
|
||||
} else {
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
} else {
|
||||
Debug::log(LOG, "Unmapped was not focused, ignoring a refocus.");
|
||||
@@ -536,12 +648,18 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
|
||||
// recheck idle inhibitors
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
|
||||
// force report all sizes (QT sometimes has an issue with this)
|
||||
g_pCompositor->forceReportSizesToWindowsOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
|
||||
// update lastwindow after focus
|
||||
PWINDOW->onUnmap();
|
||||
}
|
||||
|
||||
void Events::listener_commitWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_bHidden || (PWINDOW->m_bIsX11 && !PWINDOW->m_bMappedX11))
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->isHidden() || (PWINDOW->m_bIsX11 && !PWINDOW->m_bMappedX11))
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageSurface(g_pXWaylandManager->getWindowSurface(PWINDOW), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y);
|
||||
@@ -588,6 +706,8 @@ void Events::listener_setTitleWindow(void* owner, void* data) {
|
||||
if (PWINDOW == g_pCompositor->m_pLastWindow) // if it's the active, let's post an event to update others
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(PWINDOW) + "," + PWINDOW->m_szTitle});
|
||||
|
||||
PWINDOW->updateDynamicRules();
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW);
|
||||
PWINDOW->updateToplevel();
|
||||
|
||||
Debug::log(LOG, "Window %x set title to %s", PWINDOW, PWINDOW->m_szTitle.c_str());
|
||||
@@ -601,7 +721,7 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bHidden)
|
||||
if (PWINDOW->isHidden())
|
||||
return;
|
||||
|
||||
if (!PWINDOW->m_bIsX11) {
|
||||
@@ -612,26 +732,50 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
|
||||
|
||||
wlr_xdg_surface_schedule_configure(PWINDOW->m_uSurface.xdg);
|
||||
} else {
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, !PWINDOW->m_bIsFullscreen, FULLSCREEN_FULL);
|
||||
if (!PWINDOW->m_uSurface.xwayland->mapped)
|
||||
return;
|
||||
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, PWINDOW->m_uSurface.xwayland->fullscreen, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
PWINDOW->updateToplevel();
|
||||
|
||||
Debug::log(LOG, "Window %x fullscreen to %i", PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||
|
||||
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||
}
|
||||
|
||||
void Events::listener_activate(void* owner, void* data) {
|
||||
// TODO
|
||||
void Events::listener_activateXDG(wl_listener* listener, void* data) {
|
||||
const auto E = (wlr_xdg_activation_v1_request_activate_event*)data;
|
||||
|
||||
static auto *const PFOCUSONACTIVATE = &g_pConfigManager->getConfigValuePtr("misc:focus_on_activate")->intValue;
|
||||
|
||||
Debug::log(LOG, "Activate request for surface at %x", E->surface);
|
||||
|
||||
if (!*PFOCUSONACTIVATE || !wlr_surface_is_xdg_surface(E->surface))
|
||||
return;
|
||||
|
||||
const auto PWINDOW = g_pCompositor->getWindowFromSurface(E->surface);
|
||||
|
||||
if (!PWINDOW || PWINDOW == g_pCompositor->m_pLastWindow)
|
||||
return;
|
||||
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
Vector2D middle = PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f;
|
||||
g_pCompositor->warpCursorTo(middle);
|
||||
}
|
||||
|
||||
void Events::listener_activateX11(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
const auto PWINDOW = (CWindow*)owner;
|
||||
|
||||
if (PWINDOW->m_iX11Type == 1 /* Managed */) {
|
||||
wlr_xwayland_surface_activate(PWINDOW->m_uSurface.xwayland, 1);
|
||||
}
|
||||
static auto *const PFOCUSONACTIVATE = &g_pConfigManager->getConfigValuePtr("misc:focus_on_activate")->intValue;
|
||||
|
||||
Debug::log(LOG, "X11 Activate request for window %x", PWINDOW);
|
||||
|
||||
if (!*PFOCUSONACTIVATE || PWINDOW->m_iX11Type != 1 || PWINDOW == g_pCompositor->m_pLastWindow)
|
||||
return;
|
||||
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
Vector2D middle = PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f;
|
||||
g_pCompositor->warpCursorTo(middle);
|
||||
}
|
||||
|
||||
void Events::listener_configureX11(void* owner, void* data) {
|
||||
@@ -644,21 +788,21 @@ void Events::listener_configureX11(void* owner, void* data) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
|
||||
if (!PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen) {
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.vec());
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv(), true);
|
||||
g_pInputManager->refocus();
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PWINDOW->m_uSurface.xwayland->mapped) {
|
||||
if (!PWINDOW->m_uSurface.xwayland->mapped || !PWINDOW->m_bMappedX11) {
|
||||
wlr_xwayland_surface_configure(PWINDOW->m_uSurface.xwayland, E->x, E->y, E->width, E->height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (E->width > 1 && E->height > 1)
|
||||
PWINDOW->m_bHidden = false;
|
||||
PWINDOW->setHidden(false);
|
||||
else
|
||||
PWINDOW->m_bHidden = true;
|
||||
PWINDOW->setHidden(true);
|
||||
|
||||
PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(E->x, E->y));
|
||||
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(E->width, E->height));
|
||||
@@ -673,6 +817,7 @@ void Events::listener_configureX11(void* owner, void* data) {
|
||||
|
||||
PWINDOW->m_bCreatedOverFullscreen = true;
|
||||
|
||||
if (!PWINDOW->m_sAdditionalConfigData.windowDanceCompat)
|
||||
g_pInputManager->refocus();
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
@@ -683,16 +828,22 @@ void Events::listener_configureX11(void* owner, void* data) {
|
||||
void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_bHidden)
|
||||
if (!PWINDOW->m_bMappedX11)
|
||||
return;
|
||||
|
||||
const auto POS = PWINDOW->m_vRealPosition.goalv();
|
||||
const auto SIZ = PWINDOW->m_vRealSize.goalv();
|
||||
|
||||
if (PWINDOW->m_uSurface.xwayland->width > 1 && PWINDOW->m_uSurface.xwayland->height > 1)
|
||||
PWINDOW->m_bHidden = false;
|
||||
PWINDOW->setHidden(false);
|
||||
else
|
||||
PWINDOW->m_bHidden = true;
|
||||
PWINDOW->setHidden(true);
|
||||
|
||||
if (PWINDOW->m_bIsFullscreen || !PWINDOW->m_bIsFloating) {
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv(), true);
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
return;
|
||||
}
|
||||
|
||||
if (abs(std::floor(POS.x) - PWINDOW->m_uSurface.xwayland->x) > 2 || abs(std::floor(POS.y) - PWINDOW->m_uSurface.xwayland->y) > 2 || abs(std::floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2) {
|
||||
Debug::log(LOG, "Unmanaged window %x requests geometry update to %i %i %i %i", PWINDOW, (int)PWINDOW->m_uSurface.xwayland->x, (int)PWINDOW->m_uSurface.xwayland->y, (int)PWINDOW->m_uSurface.xwayland->width, (int)PWINDOW->m_uSurface.xwayland->height);
|
||||
@@ -756,15 +907,35 @@ void Events::listener_NewXDGDeco(wl_listener* listener, void* data) {
|
||||
void Events::listener_requestMaximize(void* owner, void* data) {
|
||||
const auto PWINDOW = (CWindow*)owner;
|
||||
|
||||
Debug::log(LOG, "Maximize request for %x", PWINDOW);
|
||||
|
||||
if (!PWINDOW->m_bIsX11) {
|
||||
const auto EV = (wlr_foreign_toplevel_handle_v1_maximized_event*)data;
|
||||
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, EV ? EV->maximized : !PWINDOW->m_bIsFullscreen, FULLSCREEN_MAXIMIZED); // this will be rejected if there already is a fullscreen window
|
||||
|
||||
wlr_xdg_surface_schedule_configure(PWINDOW->m_uSurface.xdg);
|
||||
} else {
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_iX11Type != 1)
|
||||
return;
|
||||
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, !PWINDOW->m_bIsFullscreen, FULLSCREEN_MAXIMIZED);
|
||||
}
|
||||
}
|
||||
|
||||
void Events::listener_requestMinimize(void* owner, void* data) {
|
||||
// ignore
|
||||
const auto PWINDOW = (CWindow*)owner;
|
||||
|
||||
Debug::log(LOG, "Minimize request for %x", PWINDOW);
|
||||
|
||||
if (PWINDOW->m_bIsX11) {
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_iX11Type != 1)
|
||||
return;
|
||||
|
||||
const auto E = (wlr_xwayland_minimize_event*)data;
|
||||
|
||||
wlr_xwayland_surface_set_minimized(PWINDOW->m_uSurface.xwayland, E->minimize && g_pCompositor->m_pLastWindow != PWINDOW); // fucking DXVK
|
||||
}
|
||||
}
|
||||
|
||||
void Events::listener_requestMove(void* owner, void* data) {
|
||||
|
@@ -12,8 +12,6 @@ void CAnimatedVariable::create(ANIMATEDVARTYPE type, SAnimationPropertyConfig* p
|
||||
m_pConfig = pAnimConfig;
|
||||
m_pWindow = pWindow;
|
||||
|
||||
g_pAnimationManager->m_lAnimatedVariables.push_back(this);
|
||||
|
||||
m_bDummy = false;
|
||||
}
|
||||
|
||||
@@ -56,8 +54,20 @@ CAnimatedVariable::~CAnimatedVariable() {
|
||||
|
||||
void CAnimatedVariable::unregister() {
|
||||
g_pAnimationManager->m_lAnimatedVariables.remove(this);
|
||||
m_bIsRegistered = false;
|
||||
}
|
||||
|
||||
void CAnimatedVariable::registerVar() {
|
||||
if (!m_bIsRegistered)
|
||||
g_pAnimationManager->m_lAnimatedVariables.push_back(this);
|
||||
m_bIsRegistered = true;
|
||||
}
|
||||
|
||||
int CAnimatedVariable::getDurationLeftMs() {
|
||||
return std::max((int)(m_pConfig->pValues->internalSpeed * 100) - (int)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - animationBegin).count(), 0);
|
||||
}
|
||||
|
||||
float CAnimatedVariable::getPercent() {
|
||||
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - animationBegin).count();
|
||||
return std::clamp((DURATIONPASSED / 100.f) / m_pConfig->pValues->internalSpeed, 0.f, 1.f);
|
||||
}
|
@@ -21,6 +21,7 @@ class CAnimationManager;
|
||||
class CWorkspace;
|
||||
struct SLayerSurface;
|
||||
struct SAnimationPropertyConfig;
|
||||
class CHyprRenderer;
|
||||
|
||||
class CAnimatedVariable {
|
||||
public:
|
||||
@@ -32,6 +33,7 @@ public:
|
||||
~CAnimatedVariable();
|
||||
|
||||
void unregister();
|
||||
void registerVar();
|
||||
|
||||
// gets the current vector value (real time)
|
||||
const Vector2D& vec() const {
|
||||
@@ -67,18 +69,24 @@ public:
|
||||
m_vGoal = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
|
||||
onAnimationBegin();
|
||||
}
|
||||
|
||||
void operator=(const float& v) {
|
||||
m_fGoal = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_fBegun = m_fValue;
|
||||
|
||||
onAnimationBegin();
|
||||
}
|
||||
|
||||
void operator=(const CColor& v) {
|
||||
m_cGoal = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_cBegun = m_cValue;
|
||||
|
||||
onAnimationBegin();
|
||||
}
|
||||
|
||||
// Sets the actual stored value, without affecting the goal, but resets the timer
|
||||
@@ -86,6 +94,8 @@ public:
|
||||
m_vValue = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
|
||||
onAnimationBegin();
|
||||
}
|
||||
|
||||
// Sets the actual stored value, without affecting the goal, but resets the timer
|
||||
@@ -93,6 +103,8 @@ public:
|
||||
m_fValue = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
|
||||
onAnimationBegin();
|
||||
}
|
||||
|
||||
// Sets the actual stored value, without affecting the goal, but resets the timer
|
||||
@@ -100,6 +112,8 @@ public:
|
||||
m_cValue = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
|
||||
onAnimationBegin();
|
||||
}
|
||||
|
||||
// Sets the actual value and goal
|
||||
@@ -138,7 +152,7 @@ public:
|
||||
return false; // just so that the warning is suppressed
|
||||
}
|
||||
|
||||
void warp() {
|
||||
void warp(bool endCallback = true) {
|
||||
switch (m_eVarType) {
|
||||
case AVARTYPE_FLOAT: {
|
||||
m_fValue = m_fGoal;
|
||||
@@ -155,6 +169,9 @@ public:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
if (endCallback)
|
||||
onAnimationEnd();
|
||||
}
|
||||
|
||||
void setConfig(SAnimationPropertyConfig* pConfig) {
|
||||
@@ -167,6 +184,27 @@ public:
|
||||
|
||||
int getDurationLeftMs();
|
||||
|
||||
/* returns the spent (completion) % */
|
||||
float getPercent();
|
||||
|
||||
/* sets a function to be ran when the animation finishes.
|
||||
if an animation is not running, runs instantly.
|
||||
if "remove" is set to true, will remove the callback when ran. */
|
||||
void setCallbackOnEnd(std::function<void(void* thisptr)> func, bool remove = true) {
|
||||
m_fEndCallback = func;
|
||||
m_bRemoveEndAfterRan = remove;
|
||||
|
||||
if (!isBeingAnimated())
|
||||
onAnimationEnd();
|
||||
}
|
||||
|
||||
/* sets a function to be ran when an animation is started.
|
||||
if "remove" is set to true, will remove the callback when ran. */
|
||||
void setCallbackOnBegin(std::function<void(void* thisptr)> func, bool remove = true) {
|
||||
m_fBeginCallback = func;
|
||||
m_bRemoveBeginAfterRan = remove;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Vector2D m_vValue = Vector2D(0,0);
|
||||
@@ -189,13 +227,37 @@ private:
|
||||
SAnimationPropertyConfig* m_pConfig = nullptr;
|
||||
|
||||
bool m_bDummy = true;
|
||||
bool m_bIsRegistered = false;
|
||||
|
||||
std::chrono::system_clock::time_point animationBegin;
|
||||
|
||||
ANIMATEDVARTYPE m_eVarType = AVARTYPE_INVALID;
|
||||
AVARDAMAGEPOLICY m_eDamagePolicy = AVARDAMAGE_INVALID;
|
||||
|
||||
bool m_bRemoveEndAfterRan = true;
|
||||
bool m_bRemoveBeginAfterRan = true;
|
||||
std::function<void(void* thisptr)> m_fEndCallback;
|
||||
std::function<void(void* thisptr)> m_fBeginCallback;
|
||||
|
||||
// methods
|
||||
void onAnimationEnd() {
|
||||
if (m_fEndCallback) {
|
||||
m_fEndCallback(this);
|
||||
if (m_bRemoveEndAfterRan)
|
||||
m_fEndCallback = nullptr; // reset
|
||||
}
|
||||
}
|
||||
|
||||
void onAnimationBegin() {
|
||||
if (m_fBeginCallback) {
|
||||
m_fBeginCallback(this);
|
||||
if (m_bRemoveBeginAfterRan)
|
||||
m_fBeginCallback = nullptr; // reset
|
||||
}
|
||||
}
|
||||
|
||||
friend class CAnimationManager;
|
||||
friend class CWorkspace;
|
||||
friend struct SLayerSurface;
|
||||
friend class CHyprRenderer;
|
||||
};
|
||||
|
@@ -5,6 +5,31 @@
|
||||
#include <sys/utsname.h>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__) || \
|
||||
defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
# include <sys/sysctl.h>
|
||||
# if defined(__DragonFly__)
|
||||
# include <sys/kinfo.h> // struct kinfo_proc
|
||||
# elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
# include <sys/user.h> // struct kinfo_proc
|
||||
# endif
|
||||
|
||||
# if defined(__NetBSD__)
|
||||
# undef KERN_PROC
|
||||
# define KERN_PROC KERN_PROC2
|
||||
# define KINFO_PROC struct kinfo_proc2
|
||||
# else
|
||||
# define KINFO_PROC struct kinfo_proc
|
||||
# endif
|
||||
# if defined(__DragonFly__)
|
||||
# define KP_PPID(kp) kp.kp_ppid
|
||||
# elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
# define KP_PPID(kp) kp.ki_ppid
|
||||
# else
|
||||
# define KP_PPID(kp) kp.p_ppid
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static const float transforms[][9] = {{
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
@@ -120,6 +145,9 @@ void scaleBox(wlr_box* box, float scale) {
|
||||
}
|
||||
|
||||
std::string removeBeginEndSpacesTabs(std::string str) {
|
||||
if (str.empty())
|
||||
return str;
|
||||
|
||||
int countBefore = 0;
|
||||
while (str[countBefore] == ' ' || str[countBefore] == '\t') {
|
||||
countBefore++;
|
||||
@@ -332,6 +360,15 @@ void logSystemInfo() {
|
||||
Debug::log(LOG, "Release: %s", unameInfo.release);
|
||||
Debug::log(LOG, "Version: %s", unameInfo.version);
|
||||
|
||||
Debug::log(NONE, "\n");
|
||||
|
||||
const std::string GPUINFO = execAndGet("lspci -vnn | grep VGA");
|
||||
Debug::log(LOG, "GPU information:\n%s\n", GPUINFO.c_str());
|
||||
|
||||
if (GPUINFO.contains("NVIDIA")) {
|
||||
Debug::log(WARN, "Warning: you're using an NVIDIA GPU. Make sure you follow the instructions on the wiki if anything is amiss.\n");
|
||||
}
|
||||
|
||||
// log etc
|
||||
Debug::log(LOG, "os-release:");
|
||||
|
||||
@@ -348,8 +385,8 @@ void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) {
|
||||
// Rotation + reflection
|
||||
mat[0] = x * t[0];
|
||||
mat[1] = x * t[1];
|
||||
mat[3] = y * -t[3];
|
||||
mat[4] = y * -t[4];
|
||||
mat[3] = y * t[3];
|
||||
mat[4] = y * t[4];
|
||||
|
||||
// Translation
|
||||
mat[2] = -copysign(1.0f, mat[0] + mat[1]);
|
||||
@@ -360,6 +397,25 @@ void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) {
|
||||
}
|
||||
|
||||
int64_t getPPIDof(int64_t pid) {
|
||||
#if defined(KERN_PROC_PID)
|
||||
int mib[] = {
|
||||
CTL_KERN,
|
||||
KERN_PROC,
|
||||
KERN_PROC_PID,
|
||||
(int)pid,
|
||||
# if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
sizeof(KINFO_PROC),
|
||||
1,
|
||||
# endif
|
||||
};
|
||||
u_int miblen = sizeof(mib) / sizeof(mib[0]);
|
||||
KINFO_PROC kp;
|
||||
size_t sz = sizeof(KINFO_PROC);
|
||||
if (sysctl(mib, miblen, &kp, &sz, NULL, 0) != -1)
|
||||
return KP_PPID(kp);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
std::string dir = "/proc/" + std::to_string(pid) + "/status";
|
||||
FILE* infile;
|
||||
|
||||
@@ -392,4 +448,41 @@ int64_t getPPIDof(int64_t pid) {
|
||||
} catch (std::exception& e) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int64_t configStringToInt(const std::string& VALUE) {
|
||||
if (VALUE.find("0x") == 0) {
|
||||
// Values with 0x are hex
|
||||
const auto VALUEWITHOUTHEX = VALUE.substr(2);
|
||||
return stol(VALUEWITHOUTHEX, nullptr, 16);
|
||||
} else if (VALUE.find("rgba(") == 0 && VALUE.find(")") == VALUE.length() - 1) {
|
||||
const auto VALUEWITHOUTFUNC = VALUE.substr(5, VALUE.length() - 6);
|
||||
|
||||
if (removeBeginEndSpacesTabs(VALUEWITHOUTFUNC).length() != 8) {
|
||||
Debug::log(WARN, "invalid length %i for rgba", VALUEWITHOUTFUNC.length());
|
||||
throw std::invalid_argument("rgba() expects length of 8 characters (4 bytes)");
|
||||
}
|
||||
|
||||
const auto RGBA = std::stol(VALUEWITHOUTFUNC, nullptr, 16);
|
||||
|
||||
// now we need to RGBA -> ARGB. The config holds ARGB only.
|
||||
return (RGBA >> 8) + 0x1000000 * (RGBA & 0xFF);
|
||||
} else if (VALUE.find("rgb(") == 0 && VALUE.find(")") == VALUE.length() - 1) {
|
||||
const auto VALUEWITHOUTFUNC = VALUE.substr(4, VALUE.length() - 5);
|
||||
|
||||
if (removeBeginEndSpacesTabs(VALUEWITHOUTFUNC).length() != 6) {
|
||||
Debug::log(WARN, "invalid length %i for rgb", VALUEWITHOUTFUNC.length());
|
||||
throw std::invalid_argument("rgb() expects length of 6 characters (3 bytes)");
|
||||
}
|
||||
|
||||
const auto RGB = std::stol(VALUEWITHOUTFUNC, nullptr, 16);
|
||||
|
||||
return RGB + 0xFF000000; // 0xFF for opaque
|
||||
} else if (VALUE.find("true") == 0 || VALUE.find("on") == 0 || VALUE.find("yes") == 0) {
|
||||
return 1;
|
||||
} else if (VALUE.find("false") == 0 || VALUE.find("off") == 0 || VALUE.find("no") == 0) {
|
||||
return 0;
|
||||
}
|
||||
return stol(VALUE);
|
||||
}
|
@@ -15,6 +15,7 @@ float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Ve
|
||||
void logSystemInfo();
|
||||
std::string execAndGet(const char*);
|
||||
int64_t getPPIDof(int64_t pid);
|
||||
int64_t configStringToInt(const std::string&);
|
||||
|
||||
float getPlusMinusKeywordResult(std::string in, float relative);
|
||||
|
||||
|
@@ -8,8 +8,11 @@ void CMonitor::onConnect(bool noRule) {
|
||||
|
||||
szName = output->name;
|
||||
|
||||
if (!wlr_backend_is_drm(output->backend))
|
||||
createdByUser = true; // should be true. WL, X11 and Headless backends should be addable / removable
|
||||
|
||||
// get monitor rule that matches
|
||||
SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(output->name);
|
||||
SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(output->name, output->description ? output->description : "");
|
||||
|
||||
hyprListener_monitorFrame.initCallback(&output->events.frame, &Events::listener_monitorFrame, this);
|
||||
hyprListener_monitorDestroy.initCallback(&output->events.destroy, &Events::listener_monitorDestroy, this);
|
||||
@@ -99,10 +102,6 @@ void CMonitor::onConnect(bool noRule) {
|
||||
|
||||
wlr_output_enable(output, 1);
|
||||
|
||||
// TODO: this doesn't seem to set the X and Y correctly,
|
||||
// wlr_output_layout_output_coords returns invalid values, I think...
|
||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, output, monitorRule.offset.x, monitorRule.offset.y);
|
||||
|
||||
// set mode, also applies
|
||||
if (!noRule)
|
||||
g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true);
|
||||
@@ -136,11 +135,14 @@ void CMonitor::onConnect(bool noRule) {
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", szName});
|
||||
|
||||
// ensure VRR (will enable if necessary)
|
||||
g_pConfigManager->ensureVRR(this);
|
||||
}
|
||||
|
||||
void CMonitor::onDisconnect() {
|
||||
|
||||
if (!m_bEnabled)
|
||||
if (!m_bEnabled || g_pCompositor->m_bIsShuttingDown)
|
||||
return;
|
||||
|
||||
// Cleanup everything. Move windows back, snap cursor, shit.
|
||||
@@ -152,6 +154,9 @@ void CMonitor::onDisconnect() {
|
||||
}
|
||||
}
|
||||
|
||||
if (g_pCompositor->m_pLastMonitor == this)
|
||||
g_pCompositor->m_pLastMonitor = BACKUPMON;
|
||||
|
||||
// remove mirror
|
||||
if (pMirrorOf) {
|
||||
pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; }));
|
||||
@@ -297,7 +302,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||
pMirrorOf = nullptr;
|
||||
|
||||
// set rule
|
||||
const auto RULE = g_pConfigManager->getMonitorRuleFor(this->szName);
|
||||
const auto RULE = g_pConfigManager->getMonitorRuleFor(this->szName, this->output->description ? this->output->description : "");
|
||||
|
||||
vecPosition = RULE.offset;
|
||||
|
||||
|
@@ -11,7 +11,7 @@ struct SMonitorRule;
|
||||
|
||||
class CMonitor {
|
||||
public:
|
||||
Vector2D vecPosition = Vector2D(0,0);
|
||||
Vector2D vecPosition = Vector2D(-1,-1); // means unset
|
||||
Vector2D vecSize = Vector2D(0,0);
|
||||
Vector2D vecPixelSize = Vector2D(0,0);
|
||||
Vector2D vecTransformedSize = Vector2D(0,0);
|
||||
@@ -37,6 +37,11 @@ public:
|
||||
bool scheduledRecalc = false;
|
||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
|
||||
bool dpmsStatus = true;
|
||||
bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it.
|
||||
bool enabled10bit = false; // as above, this can be TRUE even if 10 bit failed.
|
||||
bool createdByUser = false;
|
||||
|
||||
// mirroring
|
||||
CMonitor* pMirrorOf = nullptr;
|
||||
std::vector<CMonitor*> mirrors;
|
||||
|
@@ -178,6 +178,9 @@ void Events::listener_unmapSubsurface(void* owner, void* data) {
|
||||
if (subsurface->pChild) {
|
||||
const auto PNODE = subsurface->pChild;
|
||||
|
||||
const auto IT = std::find_if(SubsurfaceTree::surfaceTreeNodes.begin(), SubsurfaceTree::surfaceTreeNodes.end(), [&](const SSurfaceTreeNode& other) { return &other == PNODE; });
|
||||
|
||||
if (IT != SubsurfaceTree::surfaceTreeNodes.end()) {
|
||||
int lx = 0, ly = 0;
|
||||
addSurfaceGlobalOffset(PNODE, &lx, &ly);
|
||||
|
||||
@@ -189,8 +192,9 @@ void Events::listener_unmapSubsurface(void* owner, void* data) {
|
||||
g_pHyprRenderer->damageBox(&extents);
|
||||
}
|
||||
|
||||
//SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
|
||||
//subsurface->pChild = nullptr;
|
||||
// SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
|
||||
// subsurface->pChild = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4,4 +4,5 @@
|
||||
SLayerSurface::SLayerSurface() {
|
||||
alpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), nullptr, AVARDAMAGE_ENTIRE);
|
||||
alpha.m_pLayer = this;
|
||||
alpha.registerVar();
|
||||
}
|
@@ -131,6 +131,8 @@ struct SMouse {
|
||||
|
||||
bool virt = false;
|
||||
|
||||
bool connected = false; // means connected to the cursor
|
||||
|
||||
DYNLISTENER(commitConstraint);
|
||||
DYNLISTENER(destroyMouse);
|
||||
|
||||
@@ -326,9 +328,24 @@ struct SIMEPopup {
|
||||
struct STouchDevice {
|
||||
wlr_input_device* pWlrDevice = nullptr;
|
||||
|
||||
std::string name = "";
|
||||
|
||||
std::string boundOutput = "";
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
|
||||
bool operator==(const STouchDevice& other) {
|
||||
return pWlrDevice == other.pWlrDevice;
|
||||
}
|
||||
};
|
||||
|
||||
struct SSwitchDevice {
|
||||
wlr_input_device* pWlrDevice = nullptr;
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
DYNLISTENER(toggle);
|
||||
|
||||
bool operator==(const SSwitchDevice& other) {
|
||||
return pWlrDevice == other.pWlrDevice;
|
||||
}
|
||||
};
|
||||
|
@@ -31,6 +31,9 @@ CWorkspace::CWorkspace(int monitorID, std::string name, bool special) {
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), nullptr, AVARDAMAGE_ENTIRE);
|
||||
m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
m_vRenderOffset.registerVar();
|
||||
m_fAlpha.registerVar();
|
||||
|
||||
g_pEventManager->postEvent({"createworkspace", m_szName}, true);
|
||||
}
|
||||
|
||||
|
161
src/helpers/XWaylandStubs.hpp
Normal file
161
src/helpers/XWaylandStubs.hpp
Normal file
@@ -0,0 +1,161 @@
|
||||
#pragma once
|
||||
|
||||
#include <wayland-server.h>
|
||||
|
||||
typedef unsigned int xcb_atom_t;
|
||||
struct xcb_icccm_wm_hints_t;
|
||||
typedef struct {
|
||||
/** User specified flags */
|
||||
uint32_t flags;
|
||||
/** User-specified position */
|
||||
int32_t x, y;
|
||||
/** User-specified size */
|
||||
int32_t width, height;
|
||||
/** Program-specified minimum size */
|
||||
int32_t min_width, min_height;
|
||||
/** Program-specified maximum size */
|
||||
int32_t max_width, max_height;
|
||||
/** Program-specified resize increments */
|
||||
int32_t width_inc, height_inc;
|
||||
/** Program-specified minimum aspect ratios */
|
||||
int32_t min_aspect_num, min_aspect_den;
|
||||
/** Program-specified maximum aspect ratios */
|
||||
int32_t max_aspect_num, max_aspect_den;
|
||||
/** Program-specified base size */
|
||||
int32_t base_width, base_height;
|
||||
/** Program-specified window gravity */
|
||||
uint32_t win_gravity;
|
||||
} xcb_size_hints_t;
|
||||
typedef unsigned int xcb_window_t;
|
||||
|
||||
typedef enum xcb_stack_mode_t {
|
||||
XCB_STACK_MODE_ABOVE = 0,
|
||||
XCB_STACK_MODE_BELOW = 1,
|
||||
XCB_STACK_MODE_TOP_IF = 2,
|
||||
XCB_STACK_MODE_BOTTOM_IF = 3,
|
||||
XCB_STACK_MODE_OPPOSITE = 4
|
||||
} xcb_stack_mode_t;
|
||||
|
||||
struct wlr_xwayland {
|
||||
struct wlr_xwayland_server *server;
|
||||
struct wlr_xwm *xwm;
|
||||
struct wlr_xwayland_cursor *cursor;
|
||||
|
||||
const char *display_name;
|
||||
|
||||
struct wl_display *wl_display;
|
||||
struct wlr_compositor *compositor;
|
||||
struct wlr_seat *seat;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct wlr_xwayland_surface {
|
||||
xcb_window_t window_id;
|
||||
struct wlr_xwm *xwm;
|
||||
uint32_t surface_id;
|
||||
|
||||
struct wl_list link;
|
||||
struct wl_list stack_link;
|
||||
struct wl_list unpaired_link;
|
||||
|
||||
struct wlr_surface *surface;
|
||||
int16_t x, y;
|
||||
uint16_t width, height;
|
||||
uint16_t saved_width, saved_height;
|
||||
bool override_redirect;
|
||||
bool mapped;
|
||||
|
||||
char *title;
|
||||
char *_class;
|
||||
char *instance;
|
||||
char *role;
|
||||
char *startup_id;
|
||||
pid_t pid;
|
||||
bool has_utf8_title;
|
||||
|
||||
struct wl_list children; // wlr_xwayland_surface::parent_link
|
||||
struct wlr_xwayland_surface *parent;
|
||||
struct wl_list parent_link; // wlr_xwayland_surface::children
|
||||
|
||||
xcb_atom_t *window_type;
|
||||
size_t window_type_len;
|
||||
|
||||
xcb_atom_t *protocols;
|
||||
size_t protocols_len;
|
||||
|
||||
uint32_t decorations;
|
||||
xcb_icccm_wm_hints_t *hints;
|
||||
xcb_size_hints_t *size_hints;
|
||||
|
||||
bool pinging;
|
||||
struct wl_event_source *ping_timer;
|
||||
|
||||
// _NET_WM_STATE
|
||||
bool modal;
|
||||
bool fullscreen;
|
||||
bool maximized_vert, maximized_horz;
|
||||
bool minimized;
|
||||
|
||||
bool has_alpha;
|
||||
|
||||
struct {
|
||||
struct wl_signal destroy;
|
||||
struct wl_signal request_configure;
|
||||
struct wl_signal request_move;
|
||||
struct wl_signal request_resize;
|
||||
struct wl_signal request_minimize;
|
||||
struct wl_signal request_maximize;
|
||||
struct wl_signal request_fullscreen;
|
||||
struct wl_signal request_activate;
|
||||
|
||||
struct wl_signal map;
|
||||
struct wl_signal unmap;
|
||||
struct wl_signal set_title;
|
||||
struct wl_signal set_class;
|
||||
struct wl_signal set_role;
|
||||
struct wl_signal set_parent;
|
||||
struct wl_signal set_pid;
|
||||
struct wl_signal set_startup_id;
|
||||
struct wl_signal set_window_type;
|
||||
struct wl_signal set_hints;
|
||||
struct wl_signal set_decorations;
|
||||
struct wl_signal set_override_redirect;
|
||||
struct wl_signal set_geometry;
|
||||
struct wl_signal ping_timeout;
|
||||
} events;
|
||||
};
|
||||
|
||||
struct wlr_xwayland_surface_configure_event {
|
||||
struct wlr_xwayland_surface *surface;
|
||||
int16_t x, y;
|
||||
uint16_t width, height;
|
||||
uint16_t mask; // xcb_config_window_t
|
||||
};
|
||||
|
||||
struct wlr_xwayland_minimize_event {
|
||||
struct wlr_xwayland_surface *surface;
|
||||
bool minimize;
|
||||
};
|
||||
|
||||
inline void wlr_xwayland_destroy(wlr_xwayland*) { }
|
||||
|
||||
inline void wlr_xwayland_surface_configure(wlr_xwayland_surface*, int, int, int, int) { }
|
||||
|
||||
inline bool wlr_surface_is_xwayland_surface(void*) { return false; }
|
||||
|
||||
inline void wlr_xwayland_surface_activate(wlr_xwayland_surface*, bool) { }
|
||||
|
||||
inline void wlr_xwayland_surface_restack(wlr_xwayland_surface*, int, xcb_stack_mode_t) { }
|
||||
|
||||
inline wlr_xwayland_surface* wlr_xwayland_surface_from_wlr_surface(void*) { return nullptr; }
|
||||
|
||||
inline void wlr_xwayland_surface_close(wlr_xwayland_surface*) { }
|
||||
|
||||
inline void wlr_xwayland_surface_set_fullscreen(wlr_xwayland_surface*, bool) { }
|
||||
|
||||
inline void wlr_xwayland_surface_set_minimized(wlr_xwayland_surface *, bool) { }
|
||||
|
||||
inline bool wlr_backend_is_x11(void*) { return false; }
|
||||
|
||||
inline void wlr_x11_output_create(void*) { }
|
@@ -67,10 +67,10 @@ void CHyprError::createQueued() {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
#ifndef GLES2
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
|
@@ -22,7 +22,6 @@
|
||||
#include <filesystem>
|
||||
#include <climits>
|
||||
|
||||
|
||||
#if true
|
||||
// wlroots uses dumb-ass shit that makes it not compile on C++, let's fix that.
|
||||
// https://github.com/swaywm/wlroots/issues/682
|
||||
@@ -80,13 +79,11 @@ extern "C" {
|
||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <wlr/xwayland.h>
|
||||
#include <wlr/util/region.h>
|
||||
#include <wlr/types/wlr_tablet_pad.h>
|
||||
#include <wlr/types/wlr_tablet_tool.h>
|
||||
#include <wlr/types/wlr_tablet_v2.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include <wlr/render/egl.h>
|
||||
#include <wlr/render/gles2.h>
|
||||
#include <wlr/render/wlr_texture.h>
|
||||
@@ -101,6 +98,19 @@ extern "C" {
|
||||
#include <wlr/types/wlr_input_method_v2.h>
|
||||
#include <wlr/types/wlr_text_input_v3.h>
|
||||
#include <wlr/types/wlr_touch.h>
|
||||
#include <wlr/types/wlr_switch.h>
|
||||
#include <wlr/config.h>
|
||||
#include <wlr/backend/headless.h>
|
||||
#include <wlr/backend/multi.h>
|
||||
#include <wlr/backend/wayland.h>
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
#ifndef NO_XWAYLAND
|
||||
#include <wlr/backend/x11.h>
|
||||
#include <wlr/xwayland.h>
|
||||
#include <X11/Xproto.h>
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef delete
|
||||
@@ -121,6 +131,7 @@ extern "C" {
|
||||
|
||||
#ifdef NO_XWAYLAND
|
||||
#define XWAYLAND false
|
||||
#include "helpers/XWaylandStubs.hpp"
|
||||
#else
|
||||
#define XWAYLAND true
|
||||
#endif
|
||||
@@ -128,6 +139,3 @@ extern "C" {
|
||||
#include "helpers/Vector2D.hpp"
|
||||
|
||||
#include "ext-workspace-unstable-v1-protocol.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
@@ -69,7 +69,7 @@ SDwindleNodeData* SDwindleNodeData::getGroupVisible() {
|
||||
SDwindleNodeData* current = this->pNextGroupMember;
|
||||
|
||||
while (current != this) {
|
||||
if (!current->pWindow->m_bHidden) {
|
||||
if (!current->pWindow->isHidden()) {
|
||||
return current;
|
||||
}
|
||||
|
||||
@@ -83,11 +83,11 @@ void SDwindleNodeData::setGroupFocusedNode(SDwindleNodeData* pMember) {
|
||||
SDwindleNodeData* current = this->pNextGroupMember;
|
||||
|
||||
while (current != this) {
|
||||
current->pWindow->m_bHidden = current != pMember;
|
||||
current->pWindow->setHidden(current != pMember);
|
||||
current = current->pNextGroupMember;
|
||||
}
|
||||
|
||||
this->pWindow->m_bHidden = pMember != this;
|
||||
this->pWindow->setHidden(pMember != this);
|
||||
}
|
||||
|
||||
int SDwindleNodeData::getGroupMemberCount() {
|
||||
@@ -301,7 +301,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
OPENINGON = getFirstNodeOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
} else if (*PUSEACTIVE) {
|
||||
if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && !g_pCompositor->m_pLastWindow->m_bIsFloating && g_pCompositor->m_pLastWindow != pWindow && g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsMapped) {
|
||||
if (g_pCompositor->m_pLastWindow && !g_pCompositor->m_pLastWindow->m_bIsFloating && g_pCompositor->m_pLastWindow != pWindow && g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsMapped) {
|
||||
OPENINGON = getNodeFromWindow(g_pCompositor->m_pLastWindow);
|
||||
} else {
|
||||
OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal()));
|
||||
@@ -491,7 +491,7 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
PNEXT->setGroupFocusedNode(PNEXT);
|
||||
PNEXT->pWindow->m_bHidden = false;
|
||||
PNEXT->pWindow->setHidden(false);
|
||||
|
||||
m_lDwindleNodesData.remove(*PNODE);
|
||||
|
||||
@@ -829,7 +829,7 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
|
||||
toAddWindows.push_back(PWINDOW);
|
||||
|
||||
PWINDOW->m_bHidden = false;
|
||||
PWINDOW->setHidden(false);
|
||||
}
|
||||
|
||||
if (PHEAD->pPreviousGroupMember)
|
||||
@@ -997,9 +997,9 @@ void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward, CWind
|
||||
pNewNode->pWindow->m_bIsFloating = PNODE->pWindow->m_bIsFloating;
|
||||
|
||||
if (PNODE->pWindow->m_bIsFullscreen) {
|
||||
PNODE->pWindow->m_bHidden = false;
|
||||
PNODE->pWindow->setHidden(false);
|
||||
g_pCompositor->setWindowFullscreen(PNODE->pWindow, false, PWORKSPACE->m_efFullscreenMode);
|
||||
PNODE->pWindow->m_bHidden = true;
|
||||
PNODE->pWindow->setHidden(true);
|
||||
g_pCompositor->setWindowFullscreen(pNewNode->pWindow, true, PWORKSPACE->m_efFullscreenMode);
|
||||
|
||||
pNewNode->pWindow->m_vRealSize.warp();
|
||||
@@ -1181,7 +1181,7 @@ std::string CHyprDwindleLayout::getLayoutName() {
|
||||
|
||||
void CHyprDwindleLayout::onEnable() {
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsFloating || !w->m_bMappedX11 || !w->m_bIsMapped || w->m_bHidden)
|
||||
if (w->m_bIsFloating || !w->m_bMappedX11 || !w->m_bIsMapped || w->isHidden())
|
||||
continue;
|
||||
|
||||
onWindowCreatedTiling(w.get());
|
||||
|
@@ -26,6 +26,9 @@ void IHyprLayout::onWindowRemoved(CWindow* pWindow) {
|
||||
} else {
|
||||
onWindowRemovedTiling(pWindow);
|
||||
}
|
||||
|
||||
if (pWindow == m_pLastTiledWindow)
|
||||
m_pLastTiledWindow = nullptr;
|
||||
}
|
||||
|
||||
void IHyprLayout::onWindowRemovedFloating(CWindow* pWindow) {
|
||||
@@ -47,7 +50,7 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
pWindow->m_vRealSize = Vector2D(PWINDOWSURFACE->current.width, PWINDOWSURFACE->current.height);
|
||||
|
||||
if ((desiredGeometry.width <= 1 || desiredGeometry.height <= 1) && pWindow->m_bIsX11 && pWindow->m_iX11Type == 2) { // XDG windows should be fine. TODO: check for weird atoms?
|
||||
pWindow->m_bHidden = true;
|
||||
pWindow->setHidden(true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -131,6 +134,8 @@ void IHyprLayout::onBeginDragWindow() {
|
||||
return;
|
||||
}
|
||||
|
||||
g_pInputManager->setCursorImageUntilUnset("hand1");
|
||||
|
||||
DRAGGINGWINDOW->m_vRealPosition.setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove"));
|
||||
DRAGGINGWINDOW->m_vRealSize.setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove"));
|
||||
|
||||
@@ -178,12 +183,17 @@ void IHyprLayout::onEndDragWindow() {
|
||||
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW))
|
||||
return;
|
||||
|
||||
g_pInputManager->unsetCursorImage();
|
||||
|
||||
if (DRAGGINGWINDOW->m_bDraggingTiled) {
|
||||
DRAGGINGWINDOW->m_bIsFloating = false;
|
||||
g_pInputManager->refocus();
|
||||
changeWindowFloatingMode(DRAGGINGWINDOW);
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
|
||||
g_pCompositor->focusWindow(DRAGGINGWINDOW);
|
||||
}
|
||||
|
||||
void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
@@ -208,7 +218,12 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
|
||||
if (g_pInputManager->dragMode == MBIND_MOVE) {
|
||||
|
||||
if (*PANIMATE) {
|
||||
DRAGGINGWINDOW->m_vRealPosition = m_vBeginDragPositionXY + DELTA;
|
||||
} else {
|
||||
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA);
|
||||
}
|
||||
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||
} else if (g_pInputManager->dragMode == MBIND_RESIZE) {
|
||||
@@ -288,14 +303,17 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
||||
pWindow->moveToWorkspace(PNEWMON->activeWorkspace);
|
||||
|
||||
// save real pos cuz the func applies the default 5,5 mid
|
||||
const auto PSAVEDPOS = pWindow->m_vRealPosition.vec();
|
||||
const auto PSAVEDSIZE = pWindow->m_vRealSize.vec();
|
||||
const auto PSAVEDPOS = pWindow->m_vRealPosition.goalv();
|
||||
const auto PSAVEDSIZE = pWindow->m_vRealSize.goalv();
|
||||
|
||||
// if the window is pseudo, update its size
|
||||
pWindow->m_vPseudoSize = pWindow->m_vRealSize.vec();
|
||||
pWindow->m_vPseudoSize = pWindow->m_vRealSize.goalv();
|
||||
|
||||
pWindow->m_vLastFloatingSize = PSAVEDSIZE;
|
||||
|
||||
// move to narnia because we don't wanna find our own node. onWindowCreatedTiling should apply the coords back.
|
||||
pWindow->m_vPosition = Vector2D(-999999, -999999);
|
||||
|
||||
onWindowCreatedTiling(pWindow);
|
||||
|
||||
pWindow->m_vRealPosition.setValue(PSAVEDPOS);
|
||||
@@ -303,20 +321,26 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
||||
|
||||
// fix pseudo leaving artifacts
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||
} else {
|
||||
pWindow->m_vSize = pWindow->m_vRealSize.vec();
|
||||
pWindow->m_vPosition = pWindow->m_vRealPosition.vec();
|
||||
|
||||
if (pWindow == g_pCompositor->m_pLastWindow)
|
||||
m_pLastTiledWindow = pWindow;
|
||||
} else {
|
||||
onWindowRemovedTiling(pWindow);
|
||||
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
|
||||
pWindow->m_vRealPosition = pWindow->m_vRealPosition.vec() + (pWindow->m_vRealSize.vec() - pWindow->m_vLastFloatingSize) / 2.f;
|
||||
pWindow->m_vRealPosition = pWindow->m_vRealPosition.goalv() + (pWindow->m_vRealSize.goalv() - pWindow->m_vLastFloatingSize) / 2.f;
|
||||
pWindow->m_vRealSize = pWindow->m_vLastFloatingSize;
|
||||
|
||||
pWindow->m_vSize = pWindow->m_vRealSize.goalv();
|
||||
pWindow->m_vPosition = pWindow->m_vRealPosition.goalv();
|
||||
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||
|
||||
pWindow->m_sSpecialRenderData.rounding = true;
|
||||
|
||||
if (pWindow == m_pLastTiledWindow)
|
||||
m_pLastTiledWindow = nullptr;
|
||||
}
|
||||
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
|
||||
@@ -339,3 +363,47 @@ void IHyprLayout::moveActiveWindow(const Vector2D& delta, CWindow* pWindow) {
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
|
||||
void IHyprLayout::onWindowFocusChange(CWindow* pNewFocus) {
|
||||
m_pLastTiledWindow = pNewFocus && !pNewFocus->m_bIsFloating ? pNewFocus : m_pLastTiledWindow;
|
||||
}
|
||||
|
||||
CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) {
|
||||
// although we don't expect nullptrs here, let's verify jic
|
||||
if (!pWindow)
|
||||
return nullptr;
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
// first of all, if this is a fullscreen workspace,
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow)
|
||||
return g_pCompositor->getFullscreenWindowOnWorkspace(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (pWindow->m_bIsFloating) {
|
||||
// the window was floating, let's try the last tiled window.
|
||||
|
||||
if (m_pLastTiledWindow && m_pLastTiledWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID)
|
||||
return m_pLastTiledWindow;
|
||||
|
||||
// if we don't, let's try to find any window that is in the middle
|
||||
if (const auto PWINDOWCANDIDATE = g_pCompositor->vectorToWindowIdeal(pWindow->m_vRealPosition.goalv() + pWindow->m_vRealSize.goalv() / 2.f); PWINDOWCANDIDATE)
|
||||
return PWINDOWCANDIDATE;
|
||||
|
||||
// if not, floating window
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && !w->m_bX11ShouldntFocus && !w->m_bNoFocus)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
// if there is no candidate, too bad
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// if it was a tiled window, we first try to find the window that will replace it.
|
||||
const auto PWINDOWCANDIDATE = g_pCompositor->vectorToWindowIdeal(pWindow->m_vRealPosition.goalv() + pWindow->m_vRealSize.goalv() / 2.f);
|
||||
|
||||
if (!PWINDOWCANDIDATE || pWindow == PWINDOWCANDIDATE || !PWINDOWCANDIDATE->m_bIsMapped || PWINDOWCANDIDATE->isHidden() || PWINDOWCANDIDATE->m_bX11ShouldntFocus || PWINDOWCANDIDATE->m_iX11Type == 2 || PWINDOWCANDIDATE->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)
|
||||
return nullptr;
|
||||
|
||||
return PWINDOWCANDIDATE;
|
||||
}
|
||||
|
@@ -123,10 +123,22 @@ public:
|
||||
*/
|
||||
virtual std::string getLayoutName() = 0;
|
||||
|
||||
/*
|
||||
Called for getting the next candidate for a focus
|
||||
*/
|
||||
virtual CWindow* getNextWindowCandidate(CWindow*);
|
||||
|
||||
/*
|
||||
Internal: called when window focus changes
|
||||
*/
|
||||
virtual void onWindowFocusChange(CWindow*);
|
||||
|
||||
private:
|
||||
Vector2D m_vBeginDragXY;
|
||||
Vector2D m_vLastDragXY;
|
||||
Vector2D m_vBeginDragPositionXY;
|
||||
Vector2D m_vBeginDragSizeXY;
|
||||
int m_iGrabbedCorner = 0;
|
||||
|
||||
CWindow* m_pLastTiledWindow = nullptr;
|
||||
};
|
||||
|
@@ -20,6 +20,16 @@ int CHyprMasterLayout::getNodesOnWorkspace(const int& ws) {
|
||||
return no;
|
||||
}
|
||||
|
||||
int CHyprMasterLayout::getMastersOnWorkspace(const int& ws) {
|
||||
int no = 0;
|
||||
for (auto& n : m_lMasterNodesData) {
|
||||
if (n.workspaceID == ws && n.isMaster)
|
||||
no++;
|
||||
}
|
||||
|
||||
return no;
|
||||
}
|
||||
|
||||
std::string CHyprMasterLayout::getLayoutName() {
|
||||
return "Master";
|
||||
}
|
||||
@@ -104,10 +114,12 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
if (pWindow->m_bIsFullscreen)
|
||||
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
|
||||
|
||||
if (PNODE->isMaster) {
|
||||
const auto MASTERSLEFT = getMastersOnWorkspace(PNODE->workspaceID);
|
||||
|
||||
if (PNODE->isMaster && MASTERSLEFT < 2) {
|
||||
// find new one
|
||||
for (auto& nd : m_lMasterNodesData) {
|
||||
if (!nd.isMaster) {
|
||||
if (!nd.isMaster && nd.workspaceID == PNODE->workspaceID) {
|
||||
nd.isMaster = true;
|
||||
break;
|
||||
}
|
||||
@@ -116,6 +128,15 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
|
||||
m_lMasterNodesData.remove(*PNODE);
|
||||
|
||||
if (getMastersOnWorkspace(PNODE->workspaceID) == getNodesOnWorkspace(PNODE->workspaceID) && MASTERSLEFT > 1) {
|
||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||
if (it->workspaceID == PNODE->workspaceID) {
|
||||
it->isMaster = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recalculateMonitor(pWindow->m_iMonitorID);
|
||||
}
|
||||
|
||||
@@ -169,32 +190,52 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
|
||||
if (!PMASTERNODE)
|
||||
return;
|
||||
|
||||
const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID);
|
||||
|
||||
if (getNodesOnWorkspace(PWORKSPACE->m_iID) < 2) {
|
||||
PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition;
|
||||
PMASTERNODE->size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x, PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y);
|
||||
applyNodeDataToWindow(PMASTERNODE);
|
||||
return;
|
||||
} else {
|
||||
PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition;
|
||||
PMASTERNODE->size = Vector2D((PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) * PMASTERNODE->percMaster, PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y);
|
||||
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
|
||||
int nodesLeft = MASTERS;
|
||||
float nextY = 0;
|
||||
|
||||
for (auto& n : m_lMasterNodesData) {
|
||||
if (n.workspaceID == PWORKSPACE->m_iID && n.isMaster) {
|
||||
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(0, nextY);
|
||||
float HEIGHT = nodesLeft > 1 ? heightLeft / nodesLeft * n.percSize : heightLeft;
|
||||
if (HEIGHT > heightLeft * 0.9f && nodesLeft > 1)
|
||||
HEIGHT = heightLeft * 0.9f;
|
||||
n.size = Vector2D((PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) * PMASTERNODE->percMaster, HEIGHT);
|
||||
|
||||
nodesLeft--;
|
||||
heightLeft -= HEIGHT;
|
||||
nextY += HEIGHT;
|
||||
|
||||
applyNodeDataToWindow(&n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto SLAVESIZE = 1.f / (getNodesOnWorkspace(PWORKSPACE->m_iID) - 1) * (PMASTERNODE->size.y);
|
||||
int slavesDone = 0;
|
||||
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
|
||||
int slavesLeft = getNodesOnWorkspace(PWORKSPACE->m_iID) - MASTERS;
|
||||
float nextY = 0;
|
||||
|
||||
for (auto& nd : m_lMasterNodesData) {
|
||||
if (nd.workspaceID != PWORKSPACE->m_iID)
|
||||
if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster)
|
||||
continue;
|
||||
|
||||
if (nd == *PMASTERNODE) {
|
||||
applyNodeDataToWindow(PMASTERNODE);
|
||||
continue;
|
||||
}
|
||||
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(PMASTERNODE->percMaster * PMONITOR->vecSize.x, nextY);
|
||||
float HEIGHT = slavesLeft > 1 ? heightLeft / slavesLeft * nd.percSize : heightLeft;
|
||||
if (HEIGHT > heightLeft * 0.9f && slavesLeft > 1)
|
||||
HEIGHT = heightLeft * 0.9f;
|
||||
nd.size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x - PMASTERNODE->size.x, HEIGHT);
|
||||
|
||||
nd.position = Vector2D(PMASTERNODE->size.x + PMASTERNODE->position.x, slavesDone * SLAVESIZE + PMASTERNODE->position.y);
|
||||
nd.size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x - PMASTERNODE->size.x, SLAVESIZE);
|
||||
|
||||
slavesDone++;
|
||||
slavesLeft--;
|
||||
heightLeft -= HEIGHT;
|
||||
nextY += HEIGHT;
|
||||
|
||||
applyNodeDataToWindow(&nd);
|
||||
}
|
||||
@@ -314,8 +355,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* p
|
||||
return;
|
||||
}
|
||||
|
||||
// get master
|
||||
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
// get monitor
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
|
||||
if (getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) < 2)
|
||||
@@ -323,11 +363,24 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* p
|
||||
|
||||
m_bForceWarps = true;
|
||||
|
||||
float delta = pixResize.x / PMONITOR->vecSize.x;
|
||||
double delta = pixResize.x / PMONITOR->vecSize.x;
|
||||
|
||||
PMASTER->percMaster += delta;
|
||||
for (auto& n : m_lMasterNodesData) {
|
||||
if (n.isMaster)
|
||||
n.percMaster = std::clamp(n.percMaster + delta, 0.05, 0.95);
|
||||
}
|
||||
|
||||
std::clamp(PMASTER->percMaster, 0.05f, 0.95f);
|
||||
// check the up/down resize
|
||||
if (pixResize.y != 0) {
|
||||
if (PNODE->isMaster && getMastersOnWorkspace(PNODE->workspaceID) > 1) {
|
||||
// check master size
|
||||
const auto SIZEY = (PMONITOR->vecSize.y - PMONITOR->vecReservedTopLeft.y - PMONITOR->vecReservedBottomRight.y) / getMastersOnWorkspace(PNODE->workspaceID);
|
||||
PNODE->percSize = std::clamp(PNODE->percSize + pixResize.y / SIZEY, 0.05, 1.95);
|
||||
} else if (!PNODE->isMaster && (getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) - getMastersOnWorkspace(PNODE->workspaceID)) > 1) {
|
||||
const auto SIZEY = (PMONITOR->vecSize.y - PMONITOR->vecReservedTopLeft.y - PMONITOR->vecReservedBottomRight.y) / getNodesOnWorkspace(PNODE->workspaceID);
|
||||
PNODE->percSize = std::clamp(PNODE->percSize + pixResize.y / SIZEY, 0.05, 1.95);
|
||||
}
|
||||
}
|
||||
|
||||
recalculateMonitor(PMONITOR->ID);
|
||||
|
||||
@@ -542,9 +595,11 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
};
|
||||
|
||||
if (message == "swapwithmaster") {
|
||||
|
||||
const auto PWINDOW = header.pWindow;
|
||||
|
||||
if (!PWINDOW)
|
||||
return 0;
|
||||
|
||||
if (!isWindowTiled(PWINDOW))
|
||||
return 0;
|
||||
|
||||
@@ -557,14 +612,34 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
|
||||
switchToWindow(PWINDOW);
|
||||
|
||||
return 0;
|
||||
} else if (message == "focusmaster") {
|
||||
const auto PWINDOW = header.pWindow;
|
||||
|
||||
if (!PWINDOW)
|
||||
return 0;
|
||||
|
||||
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
|
||||
if (!PMASTER || PMASTER->pWindow == PWINDOW)
|
||||
return 0;
|
||||
|
||||
switchToWindow(PMASTER->pWindow);
|
||||
|
||||
return 0;
|
||||
} else if (message == "cyclenext") {
|
||||
const auto PWINDOW = header.pWindow;
|
||||
|
||||
if (!PWINDOW)
|
||||
return 0;
|
||||
|
||||
switchToWindow(getNextWindow(PWINDOW, true));
|
||||
} else if (message == "cycleprev") {
|
||||
const auto PWINDOW = header.pWindow;
|
||||
|
||||
if (!PWINDOW)
|
||||
return 0;
|
||||
|
||||
switchToWindow(getNextWindow(PWINDOW, false));
|
||||
} else if (message == "swapnext") {
|
||||
if (!g_pCompositor->windowValidMapped(header.pWindow))
|
||||
@@ -596,6 +671,64 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
|
||||
g_pCompositor->focusWindow(header.pWindow);
|
||||
}
|
||||
} else if (message == "addmaster") {
|
||||
if (!g_pCompositor->windowValidMapped(header.pWindow))
|
||||
return 0;
|
||||
|
||||
if (header.pWindow->m_bIsFloating)
|
||||
return 0;
|
||||
|
||||
const auto PNODE = getNodeFromWindow(header.pWindow);
|
||||
|
||||
const auto WINDOWS = getNodesOnWorkspace(header.pWindow->m_iWorkspaceID);
|
||||
const auto MASTERS = getMastersOnWorkspace(header.pWindow->m_iWorkspaceID);
|
||||
|
||||
if (MASTERS + 2 > WINDOWS)
|
||||
return 0;
|
||||
|
||||
if (!PNODE || PNODE->isMaster) {
|
||||
// first non-master node
|
||||
for (auto& n : m_lMasterNodesData) {
|
||||
if (n.workspaceID == header.pWindow->m_iWorkspaceID && !n.isMaster) {
|
||||
n.isMaster = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PNODE->isMaster = true;
|
||||
}
|
||||
|
||||
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||
|
||||
} else if (message == "removemaster") {
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(header.pWindow))
|
||||
return 0;
|
||||
|
||||
if (header.pWindow->m_bIsFloating)
|
||||
return 0;
|
||||
|
||||
const auto PNODE = getNodeFromWindow(header.pWindow);
|
||||
|
||||
const auto WINDOWS = getNodesOnWorkspace(header.pWindow->m_iWorkspaceID);
|
||||
const auto MASTERS = getMastersOnWorkspace(header.pWindow->m_iWorkspaceID);
|
||||
|
||||
if (WINDOWS < 2 || MASTERS < 2)
|
||||
return 0;
|
||||
|
||||
if (!PNODE || !PNODE->isMaster) {
|
||||
// first non-master node
|
||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||
if (it->workspaceID == header.pWindow->m_iWorkspaceID && it->isMaster) {
|
||||
it->isMaster = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PNODE->isMaster = false;
|
||||
}
|
||||
|
||||
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -603,7 +736,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
|
||||
void CHyprMasterLayout::onEnable() {
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsFloating || !w->m_bMappedX11 || !w->m_bIsMapped || w->m_bHidden)
|
||||
if (w->m_bIsFloating || !w->m_bMappedX11 || !w->m_bIsMapped || w->isHidden())
|
||||
continue;
|
||||
|
||||
onWindowCreatedTiling(w.get());
|
||||
|
@@ -15,6 +15,8 @@ struct SMasterNodeData {
|
||||
Vector2D position;
|
||||
Vector2D size;
|
||||
|
||||
float percSize = 1.f; // size multiplier for resizing children
|
||||
|
||||
int workspaceID = -1;
|
||||
|
||||
bool operator==(const SMasterNodeData& rhs) {
|
||||
@@ -52,6 +54,7 @@ private:
|
||||
SMasterNodeData* getMasterNodeOnWorkspace(const int&);
|
||||
void calculateWorkspace(const int&);
|
||||
CWindow* getNextWindow(CWindow*, bool);
|
||||
int getMastersOnWorkspace(const int&);
|
||||
|
||||
friend struct SMasterNodeData;
|
||||
};
|
@@ -21,18 +21,20 @@ void CAnimationManager::addBezierWithName(std::string name, const Vector2D& p1,
|
||||
|
||||
void CAnimationManager::tick() {
|
||||
|
||||
bool animationsDisabled = false;
|
||||
bool animGlobalDisabled = false;
|
||||
|
||||
static auto *const PANIMENABLED = &g_pConfigManager->getConfigValuePtr("animations:enabled")->intValue;
|
||||
|
||||
if (!*PANIMENABLED)
|
||||
animationsDisabled = true;
|
||||
animGlobalDisabled = true;
|
||||
|
||||
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
static auto *const PSHADOWSENABLED = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||
|
||||
const auto DEFAULTBEZIER = m_mBezierCurves.find("default");
|
||||
|
||||
std::vector<CAnimatedVariable*> animationEndedVars;
|
||||
|
||||
for (auto& av : m_lAnimatedVariables) {
|
||||
|
||||
// first of all, check if we need to update it at all
|
||||
@@ -40,27 +42,25 @@ void CAnimationManager::tick() {
|
||||
continue;
|
||||
|
||||
if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW && !*PSHADOWSENABLED) {
|
||||
av->warp();
|
||||
av->warp(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
// get speed
|
||||
const auto SPEED = av->m_pConfig->pValues->internalSpeed;
|
||||
|
||||
// get the spent % (0 - 1)
|
||||
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - av->animationBegin).count();
|
||||
const float SPENT = std::clamp((DURATIONPASSED / 100.f) / SPEED, 0.f, 1.f);
|
||||
const float SPENT = av->getPercent();
|
||||
|
||||
// window stuff
|
||||
const auto PWINDOW = (CWindow*)av->m_pWindow;
|
||||
const auto PWORKSPACE = (CWorkspace*)av->m_pWorkspace;
|
||||
const auto PLAYER = (SLayerSurface*)av->m_pLayer;
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
bool animationsDisabled = animGlobalDisabled;
|
||||
|
||||
wlr_box WLRBOXPREV = {0,0,0,0};
|
||||
if (PWINDOW) {
|
||||
WLRBOXPREV = PWINDOW->getFullWindowBoundingBox();
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
animationsDisabled = animationsDisabled || PWINDOW->m_sAdditionalConfigData.forceNoAnims;
|
||||
} else if (PWORKSPACE) {
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
WLRBOXPREV = {(int)PMONITOR->vecPosition.x, (int)PMONITOR->vecPosition.y, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y};
|
||||
@@ -76,12 +76,12 @@ void CAnimationManager::tick() {
|
||||
case AVARTYPE_FLOAT: {
|
||||
// for disabled anims just warp
|
||||
if (av->m_pConfig->pValues->internalEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
av->warp(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
av->warp(false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -97,12 +97,12 @@ void CAnimationManager::tick() {
|
||||
case AVARTYPE_VECTOR: {
|
||||
// for disabled anims just warp
|
||||
if (av->m_pConfig->pValues->internalEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
av->warp(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
av->warp(false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -118,12 +118,12 @@ void CAnimationManager::tick() {
|
||||
case AVARTYPE_COLOR: {
|
||||
// for disabled anims just warp
|
||||
if (av->m_pConfig->pValues->internalEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
av->warp(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
av->warp(false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ void CAnimationManager::tick() {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
} else if (PWORKSPACE) {
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (!w->m_bIsMapped || w->m_bHidden)
|
||||
if (!w->m_bIsMapped || w->isHidden())
|
||||
continue;
|
||||
|
||||
if (w->m_iWorkspaceID != PWORKSPACE->m_iID)
|
||||
@@ -164,8 +164,7 @@ void CAnimationManager::tick() {
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AVARDAMAGE_BORDER: {
|
||||
} case AVARDAMAGE_BORDER: {
|
||||
RASSERT(PWINDOW, "Tried to AVARDAMAGE_BORDER a non-window AVAR!");
|
||||
|
||||
// damage only the border.
|
||||
@@ -223,13 +222,21 @@ void CAnimationManager::tick() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// set size and pos if valid, but only if damage policy entire (dont if border for example)
|
||||
if (g_pCompositor->windowValidMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE && PWINDOW->m_iX11Type != 2)
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
||||
|
||||
// manually schedule a frame
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||
|
||||
// check if we did not finish animating. If so, trigger onAnimationEnd.
|
||||
if (!av->isBeingAnimated())
|
||||
animationEndedVars.push_back(av);
|
||||
}
|
||||
|
||||
// do it here, because if this alters the animation vars deque we would be in trouble above.
|
||||
for (auto& ave : animationEndedVars) {
|
||||
ave->onAnimationEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,7 +292,7 @@ void CAnimationManager::animationPopin(CWindow* pWindow, bool close, float minPe
|
||||
}
|
||||
|
||||
void CAnimationManager::animationSlide(CWindow* pWindow, std::string force, bool close) {
|
||||
pWindow->m_vRealSize.warp(); // size we preserve in slide
|
||||
pWindow->m_vRealSize.warp(false); // size we preserve in slide
|
||||
|
||||
const auto GOALPOS = pWindow->m_vRealPosition.goalv();
|
||||
const auto GOALSIZE = pWindow->m_vRealSize.goalv();
|
||||
@@ -359,6 +366,10 @@ void CAnimationManager::onWindowPostCreateClose(CWindow* pWindow, bool close) {
|
||||
if (!pWindow->m_vRealPosition.isBeingAnimated() && !pWindow->m_vRealSize.isBeingAnimated())
|
||||
return;
|
||||
|
||||
// if the animation is disabled and we are leaving, ignore the anim to prevent the snapshot being fucked
|
||||
if (!pWindow->m_vRealPosition.m_pConfig->pValues->internalEnabled)
|
||||
return;
|
||||
|
||||
if (pWindow->m_sAdditionalConfigData.animationStyle != "") {
|
||||
// the window has config'd special anim
|
||||
if (pWindow->m_sAdditionalConfigData.animationStyle.find("slide") == 0) {
|
||||
|
@@ -18,6 +18,23 @@
|
||||
CEventManager::CEventManager() {
|
||||
}
|
||||
|
||||
int fdHandleWrite(int fd, uint32_t mask, void* data) {
|
||||
if (mask & WL_EVENT_ERROR || mask & WL_EVENT_HANGUP) {
|
||||
// remove, hanged up
|
||||
const auto ACCEPTEDFDS = (std::deque<std::pair<int, wl_event_source*>>*)data;
|
||||
for (auto it = ACCEPTEDFDS->begin(); it != ACCEPTEDFDS->end(); ) {
|
||||
if (it->first == fd) {
|
||||
wl_event_source_remove(it->second); // remove this fd listener
|
||||
it = ACCEPTEDFDS->erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CEventManager::startThread() {
|
||||
m_tThread = std::thread([&]() {
|
||||
const auto SOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
@@ -46,15 +63,15 @@ void CEventManager::startThread() {
|
||||
|
||||
if (ACCEPTEDCONNECTION > 0) {
|
||||
// new connection!
|
||||
m_dAcceptedSocketFDs.push_back(ACCEPTEDCONNECTION);
|
||||
|
||||
int flagsNew = fcntl(ACCEPTEDCONNECTION, F_GETFL, 0);
|
||||
fcntl(ACCEPTEDCONNECTION, F_SETFL, flagsNew | O_NONBLOCK);
|
||||
|
||||
Debug::log(LOG, "Socket 2 accepted a new client at FD %d", ACCEPTEDCONNECTION);
|
||||
}
|
||||
|
||||
ensureFDsValid();
|
||||
// add to event loop so we can close it when we need to
|
||||
m_dAcceptedSocketFDs.push_back({ACCEPTEDCONNECTION, wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, ACCEPTEDCONNECTION, WL_EVENT_READABLE, fdHandleWrite, &m_dAcceptedSocketFDs)});
|
||||
}
|
||||
}
|
||||
|
||||
close(SOCKET);
|
||||
@@ -63,34 +80,13 @@ void CEventManager::startThread() {
|
||||
m_tThread.detach();
|
||||
}
|
||||
|
||||
void CEventManager::ensureFDsValid() {
|
||||
static char readBuf[1024] = {0};
|
||||
|
||||
// pong if all FDs valid
|
||||
for (auto it = m_dAcceptedSocketFDs.begin(); it != m_dAcceptedSocketFDs.end();) {
|
||||
auto sizeRead = recv(*it, &readBuf, 1024, 0);
|
||||
|
||||
if (sizeRead != 0) {
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// invalid!
|
||||
Debug::log(LOG, "Removed invalid socket (2) FD: %d", *it);
|
||||
it = m_dAcceptedSocketFDs.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void CEventManager::flushEvents() {
|
||||
|
||||
ensureFDsValid();
|
||||
|
||||
eventQueueMutex.lock();
|
||||
|
||||
for (auto& ev : m_dQueuedEvents) {
|
||||
std::string eventString = (ev.event + ">>" + ev.data).substr(0, 1022) + "\n";
|
||||
for (auto& fd : m_dAcceptedSocketFDs) {
|
||||
write(fd, eventString.c_str(), eventString.length());
|
||||
write(fd.first, eventString.c_str(), eventString.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -26,12 +26,11 @@ public:
|
||||
private:
|
||||
|
||||
void flushEvents();
|
||||
void ensureFDsValid();
|
||||
|
||||
std::mutex eventQueueMutex;
|
||||
std::deque<SHyprIPCEvent> m_dQueuedEvents;
|
||||
|
||||
std::deque<int> m_dAcceptedSocketFDs;
|
||||
std::deque<std::pair<int, wl_event_source*>> m_dAcceptedSocketFDs;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CEventManager> g_pEventManager;
|
@@ -16,6 +16,7 @@ CKeybindManager::CKeybindManager() {
|
||||
m_mDispatchers["pseudo"] = toggleActivePseudo;
|
||||
m_mDispatchers["movefocus"] = moveFocusTo;
|
||||
m_mDispatchers["movewindow"] = moveActiveTo;
|
||||
m_mDispatchers["centerwindow"] = centerWindow;
|
||||
m_mDispatchers["togglegroup"] = toggleGroup;
|
||||
m_mDispatchers["changegroupactive"] = changeGroupActive;
|
||||
m_mDispatchers["togglesplit"] = toggleSplit;
|
||||
@@ -44,6 +45,7 @@ CKeybindManager::CKeybindManager() {
|
||||
m_mDispatchers["swapactiveworkspaces"] = swapActiveWorkspaces;
|
||||
m_mDispatchers["pin"] = pinActive;
|
||||
m_mDispatchers["mouse"] = mouse;
|
||||
m_mDispatchers["bringactivetotop"] = bringActiveToTop;
|
||||
|
||||
m_tScrollTimer.reset();
|
||||
}
|
||||
@@ -163,7 +165,7 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pKeyboard->isVirtual)
|
||||
if (pKeyboard->isVirtual && g_pInputManager->shouldIgnoreVirtualKeyboard(pKeyboard))
|
||||
return true;
|
||||
|
||||
if (!m_pXKBTranslationState) {
|
||||
@@ -202,9 +204,9 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||
m_dPressedKeycodes.push_back(KEYCODE);
|
||||
m_dPressedKeysyms.push_back(keysym);
|
||||
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "", keysym, 0, true, e->time_msec) || found;
|
||||
found = handleKeybinds(MODS, "", keysym, 0, true, e->time_msec) || found;
|
||||
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "", 0, KEYCODE, true, e->time_msec) || found;
|
||||
found = handleKeybinds(MODS, "", 0, KEYCODE, true, e->time_msec) || found;
|
||||
|
||||
if (found)
|
||||
shadowKeybinds(keysym, KEYCODE);
|
||||
@@ -219,9 +221,9 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||
m_dPressedKeycodes.erase(std::remove(m_dPressedKeycodes.begin(), m_dPressedKeycodes.end(), KEYCODE), m_dPressedKeycodes.end());
|
||||
m_dPressedKeysyms.erase(std::remove(m_dPressedKeysyms.begin(), m_dPressedKeysyms.end(), keysym), m_dPressedKeysyms.end());
|
||||
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "", keysym, 0, false, e->time_msec) || found;
|
||||
found = handleKeybinds(MODS, "", keysym, 0, false, e->time_msec) || found;
|
||||
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "", 0, KEYCODE, false, e->time_msec) || found;
|
||||
found = handleKeybinds(MODS, "", 0, KEYCODE, false, e->time_msec) || found;
|
||||
|
||||
shadowKeybinds();
|
||||
}
|
||||
@@ -244,9 +246,9 @@ bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) {
|
||||
bool found = false;
|
||||
if (e->source == WLR_AXIS_SOURCE_WHEEL && e->orientation == WLR_AXIS_ORIENTATION_VERTICAL) {
|
||||
if (e->delta < 0) {
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "mouse_down", 0, 0, true, 0);
|
||||
found = handleKeybinds(MODS, "mouse_down", 0, 0, true, 0);
|
||||
} else {
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "mouse_up", 0, 0, true, 0);
|
||||
found = handleKeybinds(MODS, "mouse_up", 0, 0, true, 0);
|
||||
}
|
||||
|
||||
if (found)
|
||||
@@ -268,12 +270,12 @@ bool CKeybindManager::onMouseEvent(wlr_pointer_button_event* e) {
|
||||
bool mouseBindWasActive = ensureMouseBindState();
|
||||
|
||||
if (e->state == WLR_BUTTON_PRESSED) {
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, true, 0);
|
||||
found = handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, true, 0);
|
||||
|
||||
if (found)
|
||||
shadowKeybinds();
|
||||
} else {
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, false, 0);
|
||||
found = handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, false, 0);
|
||||
|
||||
shadowKeybinds();
|
||||
}
|
||||
@@ -281,6 +283,10 @@ bool CKeybindManager::onMouseEvent(wlr_pointer_button_event* e) {
|
||||
return !found && !mouseBindWasActive;
|
||||
}
|
||||
|
||||
void CKeybindManager::onSwitchEvent(const std::string& switchName) {
|
||||
handleKeybinds(0, "switch:" + switchName, 0, 0, true, 0);
|
||||
}
|
||||
|
||||
int repeatKeyHandler(void* data) {
|
||||
SKeybind** ppActiveKeybind = (SKeybind**)data;
|
||||
|
||||
@@ -419,10 +425,29 @@ bool CKeybindManager::handleVT(xkb_keysym_t keysym) {
|
||||
if (!(keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12))
|
||||
return false;
|
||||
|
||||
const auto PSESSION = wlr_backend_get_session(g_pCompositor->m_sWLRBackend);
|
||||
if (PSESSION) {
|
||||
const int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
||||
wlr_session_change_vt(PSESSION, TTY);
|
||||
// beyond this point, return true to not handle anything else.
|
||||
// we'll avoid printing shit to active windows.
|
||||
|
||||
if (g_pCompositor->m_sWLRSession) {
|
||||
const unsigned int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
||||
|
||||
// vtnr is bugged for some reason.
|
||||
const std::string TTYSTR = execAndGet("head -n 1 /sys/devices/virtual/tty/tty0/active").substr(3);
|
||||
unsigned int ttynum = 0;
|
||||
try {
|
||||
ttynum = std::stoll(TTYSTR);
|
||||
} catch (std::exception &e) {
|
||||
; // oops?
|
||||
}
|
||||
|
||||
if (ttynum == TTY)
|
||||
return true;
|
||||
|
||||
Debug::log(LOG, "Switching from VT %i to VT %i", ttynum, TTY);
|
||||
|
||||
if (!wlr_session_change_vt(g_pCompositor->m_sWLRSession, TTY))
|
||||
return true; // probably same session
|
||||
|
||||
g_pCompositor->m_bSessionActive = false;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
@@ -435,7 +460,7 @@ bool CKeybindManager::handleVT(xkb_keysym_t keysym) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) {
|
||||
@@ -458,6 +483,17 @@ bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) {
|
||||
// Dispatchers
|
||||
|
||||
void CKeybindManager::spawn(std::string args) {
|
||||
|
||||
args = removeBeginEndSpacesTabs(args);
|
||||
|
||||
std::string RULES = "";
|
||||
|
||||
if (args[0] == '[') {
|
||||
// we have exec rules
|
||||
RULES = args.substr(1, args.substr(1).find_first_of(']'));
|
||||
args = args.substr(args.find_first_of(']') + 1);
|
||||
}
|
||||
|
||||
if (g_pXWaylandManager->m_sWLRXWayland)
|
||||
args = "WAYLAND_DISPLAY=" + std::string(g_pCompositor->m_szWLDisplaySocket) + " DISPLAY=" + std::string(g_pXWaylandManager->m_sWLRXWayland->display_name) + " " + args;
|
||||
else
|
||||
@@ -480,6 +516,11 @@ void CKeybindManager::spawn(std::string args) {
|
||||
}
|
||||
if (child == 0) {
|
||||
// run in child
|
||||
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigprocmask(SIG_SETMASK, &set, NULL);
|
||||
|
||||
grandchild = fork();
|
||||
if (grandchild == 0) {
|
||||
// run in grandchild
|
||||
@@ -505,7 +546,18 @@ void CKeybindManager::spawn(std::string args) {
|
||||
Debug::log(LOG, "Fail to create the second fork");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Process Created with pid %d", grandchild);
|
||||
|
||||
if (!RULES.empty()) {
|
||||
const auto RULESLIST = CVarList(RULES, 0, ';');
|
||||
|
||||
for (auto& r : RULESLIST) {
|
||||
g_pConfigManager->addExecRule({r, (unsigned long)grandchild});
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Applied %i rule arguments for exec.", RULESLIST.size());
|
||||
}
|
||||
}
|
||||
|
||||
void CKeybindManager::killActive(std::string args) {
|
||||
@@ -539,7 +591,6 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
if (g_pCompositor->windowValidMapped(PWINDOW)) {
|
||||
// remove drag status
|
||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||
|
||||
@@ -548,14 +599,27 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
|
||||
|
||||
PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating;
|
||||
|
||||
PWINDOW->updateDynamicRules();
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
void CKeybindManager::centerWindow(std::string args) {
|
||||
const auto PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!PWINDOW || !PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen)
|
||||
return;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
|
||||
PWINDOW->m_vRealPosition = PMONITOR->vecPosition + PMONITOR->vecSize / 2.f - PWINDOW->m_vRealSize.goalv() / 2.f;
|
||||
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goalv();
|
||||
}
|
||||
|
||||
void CKeybindManager::toggleActivePseudo(std::string args) {
|
||||
const auto ACTIVEWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(ACTIVEWINDOW))
|
||||
if (!ACTIVEWINDOW)
|
||||
return;
|
||||
|
||||
ACTIVEWINDOW->m_bIsPseudotiled = !ACTIVEWINDOW->m_bIsPseudotiled;
|
||||
@@ -582,16 +646,20 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
|
||||
internal = true;
|
||||
} else if (args.find("previous") == 0) {
|
||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(
|
||||
g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
|
||||
// Do nothing if there's no previous workspace, otherwise switch to it.
|
||||
if (PCURRENTWORKSPACE->m_iPrevWorkspaceID == -1) {
|
||||
Debug::log(LOG, "No previous workspace to change to");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID;
|
||||
|
||||
if (const auto PWORKSPACETOCHANGETO = g_pCompositor->getWorkspaceByID(workspaceToChangeTo); PWORKSPACETOCHANGETO)
|
||||
workspaceName = PWORKSPACETOCHANGETO->m_szName;
|
||||
else
|
||||
workspaceName = std::to_string(workspaceToChangeTo);
|
||||
|
||||
isSwitchingToPrevious = true;
|
||||
|
||||
// If the previous workspace ID isn't reset, cycles can form when continually going
|
||||
@@ -614,18 +682,26 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
static auto *const PBACKANDFORTH = &g_pConfigManager->getConfigValuePtr("binds:workspace_back_and_forth")->intValue;
|
||||
|
||||
if (*PBACKANDFORTH && PCURRENTWORKSPACE->m_iID == workspaceToChangeTo && PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1 && !internal) {
|
||||
if (*PBACKANDFORTH && PCURRENTWORKSPACE && PCURRENTWORKSPACE->m_iID == workspaceToChangeTo && PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1 && !internal) {
|
||||
|
||||
const auto PPREVWORKSPACE = g_pCompositor->getWorkspaceByID(PCURRENTWORKSPACE->m_iPrevWorkspaceID);
|
||||
|
||||
workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID;
|
||||
|
||||
if (PPREVWORKSPACE)
|
||||
workspaceName = PPREVWORKSPACE->m_szName;
|
||||
else
|
||||
workspaceName = std::to_string(workspaceToChangeTo);
|
||||
|
||||
isSwitchingToPrevious = true;
|
||||
|
||||
// If the previous workspace ID isn't reset, cycles can form when continually going
|
||||
// to the previous workspace again and again.
|
||||
static auto *const PALLOWWORKSPACECYCLES = &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue;
|
||||
static auto* const PALLOWWORKSPACECYCLES = &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue;
|
||||
if (!*PALLOWWORKSPACECYCLES)
|
||||
PCURRENTWORKSPACE->m_iPrevWorkspaceID = -1;
|
||||
|
||||
} else if (PCURRENTWORKSPACE->m_iID == workspaceToChangeTo && !internal)
|
||||
} else if (PCURRENTWORKSPACE && PCURRENTWORKSPACE->m_iID == workspaceToChangeTo && !internal)
|
||||
return;
|
||||
|
||||
// remove constraints
|
||||
@@ -683,6 +759,10 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
if (anotherMonitor) {
|
||||
Vector2D middle = PMONITOR->vecPosition + PMONITOR->vecSize / 2.f;
|
||||
g_pCompositor->warpCursorTo(middle);
|
||||
|
||||
// event for focusedmon, as we changed.
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", PMONITOR->szName + "," + PWORKSPACETOCHANGETO->m_szName});
|
||||
g_pCompositor->m_pLastMonitor = PMONITOR;
|
||||
}
|
||||
|
||||
// set active and deactivate all other in wlr
|
||||
@@ -730,7 +810,7 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
if (const auto POLDWORKSPACE = g_pCompositor->getWorkspaceByID(OLDWORKSPACE); POLDWORKSPACE)
|
||||
POLDWORKSPACE->startAnim(false, ANIMTOLEFT);
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(PMONITOR->ID, workspaceName, workspaceToChangeTo == SPECIAL_WORKSPACE_ID)).get();
|
||||
const auto PWORKSPACE = g_pCompositor->createNewWorkspace(workspaceToChangeTo, PMONITOR->ID, workspaceName);
|
||||
|
||||
if (!isSwitchingToPrevious)
|
||||
// Remember previous workspace.
|
||||
@@ -739,13 +819,6 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
// start anim on new workspace
|
||||
PWORKSPACE->startAnim(true, ANIMTOLEFT);
|
||||
|
||||
// We are required to set the name here immediately
|
||||
if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID)
|
||||
wlr_ext_workspace_handle_v1_set_name(PWORKSPACE->m_pWlrHandle, workspaceName.c_str());
|
||||
|
||||
PWORKSPACE->m_iID = workspaceToChangeTo;
|
||||
PWORKSPACE->m_iMonitorID = PMONITOR->ID;
|
||||
|
||||
PMONITOR->specialWorkspaceOpen = false;
|
||||
|
||||
// fix pinned windows
|
||||
@@ -785,7 +858,7 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
void CKeybindManager::fullscreenActive(std::string args) {
|
||||
const auto PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
@@ -805,7 +878,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
}
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
const auto OLDWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
|
||||
@@ -858,7 +931,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
|
||||
// and restore it
|
||||
if (PWINDOW->m_bIsFloating) {
|
||||
PWINDOW->m_vRealSize.setValue(PSAVEDSIZE);
|
||||
PWINDOW->m_vRealSize.setValueAndWarp(PSAVEDSIZE);
|
||||
PWINDOW->m_vRealPosition.setValueAndWarp(PSAVEDPOS - g_pCompositor->getMonitorFromID(OLDWORKSPACE->m_iMonitorID)->vecPosition + g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID)->vecPosition);
|
||||
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec();
|
||||
}
|
||||
@@ -893,7 +966,7 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||
PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
}
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
int workspaceToMoveTo = 0;
|
||||
@@ -988,7 +1061,7 @@ void CKeybindManager::moveFocusTo(std::string args) {
|
||||
Vector2D middle = PWINDOWTOCHANGETO->m_vRealPosition.goalv() + PWINDOWTOCHANGETO->m_vRealSize.goalv() / 2.f;
|
||||
g_pCompositor->warpCursorTo(middle);
|
||||
|
||||
if (PWINDOWTOCHANGETO->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID) {
|
||||
if (PLASTWINDOW->m_iMonitorID != PWINDOWTOCHANGETO->m_iMonitorID) {
|
||||
// event
|
||||
const auto PNEWMON = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID);
|
||||
const auto PNEWWS = g_pCompositor->getWorkspaceByID(PNEWMON->activeWorkspace);
|
||||
@@ -999,16 +1072,6 @@ void CKeybindManager::moveFocusTo(std::string args) {
|
||||
}
|
||||
};
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PLASTWINDOW)) {
|
||||
const auto PWINDOWTOCHANGETO = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
if (!PWINDOWTOCHANGETO)
|
||||
return;
|
||||
|
||||
switchToWindow(PWINDOWTOCHANGETO);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg);
|
||||
|
||||
if (PWINDOWTOCHANGETO) {
|
||||
@@ -1053,12 +1116,12 @@ void CKeybindManager::moveActiveTo(std::string args) {
|
||||
|
||||
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PLASTWINDOW) || PLASTWINDOW->m_bIsFullscreen)
|
||||
if (!PLASTWINDOW || PLASTWINDOW->m_bIsFullscreen)
|
||||
return;
|
||||
|
||||
const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg);
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO))
|
||||
if (!PWINDOWTOCHANGETO)
|
||||
return;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, PWINDOWTOCHANGETO);
|
||||
@@ -1104,7 +1167,7 @@ void CKeybindManager::alterSplitRatio(std::string args) {
|
||||
|
||||
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PLASTWINDOW))
|
||||
if (!PLASTWINDOW)
|
||||
return;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->alterSplitRatioBy(PLASTWINDOW, splitratio);
|
||||
@@ -1113,7 +1176,7 @@ void CKeybindManager::alterSplitRatio(std::string args) {
|
||||
void CKeybindManager::focusMonitor(std::string arg) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromString(arg);
|
||||
|
||||
if (!PMONITOR)
|
||||
if (!PMONITOR || PMONITOR == g_pCompositor->m_pLastMonitor)
|
||||
return;
|
||||
|
||||
changeworkspace("[internal]" + std::to_string(PMONITOR->activeWorkspace));
|
||||
@@ -1134,7 +1197,7 @@ void CKeybindManager::moveCursorToCorner(std::string arg) {
|
||||
|
||||
const auto PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
switch (CORNER) {
|
||||
@@ -1324,7 +1387,7 @@ void CKeybindManager::forceRendererReload(std::string args) {
|
||||
bool overAgain = false;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
auto rule = g_pConfigManager->getMonitorRuleFor(m->szName);
|
||||
auto rule = g_pConfigManager->getMonitorRuleFor(m->szName, m->output->description ? m->output->description : "");
|
||||
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule, true)) {
|
||||
overAgain = true;
|
||||
break;
|
||||
@@ -1336,7 +1399,7 @@ void CKeybindManager::forceRendererReload(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::resizeActive(std::string args) {
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||
if (!g_pCompositor->m_pLastWindow || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||
return;
|
||||
|
||||
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealSize.goalv());
|
||||
@@ -1344,11 +1407,11 @@ void CKeybindManager::resizeActive(std::string args) {
|
||||
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - g_pCompositor->m_pLastWindow->m_vRealSize.goalv());
|
||||
|
||||
if (g_pCompositor->m_pLastWindow->m_vRealSize.goalv().x > 1 && g_pCompositor->m_pLastWindow->m_vRealSize.goalv().y > 1)
|
||||
g_pCompositor->m_pLastWindow->m_bHidden = false;
|
||||
g_pCompositor->m_pLastWindow->setHidden(false);
|
||||
}
|
||||
|
||||
void CKeybindManager::moveActive(std::string args) {
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||
if (!g_pCompositor->m_pLastWindow || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||
return;
|
||||
|
||||
const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealPosition.goalv());
|
||||
@@ -1396,18 +1459,15 @@ void CKeybindManager::resizeWindow(std::string args) {
|
||||
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goalv(), PWINDOW);
|
||||
|
||||
if (PWINDOW->m_vRealSize.goalv().x > 1 && PWINDOW->m_vRealSize.goalv().y > 1)
|
||||
PWINDOW->m_bHidden = false;
|
||||
PWINDOW->setHidden(false);
|
||||
}
|
||||
|
||||
void CKeybindManager::circleNext(std::string arg) {
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||
return;
|
||||
|
||||
auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) {
|
||||
if (PWINDOWTOCHANGETO == g_pCompositor->m_pLastWindow || !PWINDOWTOCHANGETO)
|
||||
return;
|
||||
|
||||
if (g_pCompositor->m_pLastWindow->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsFullscreen) {
|
||||
if (g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsFullscreen) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastWindow->m_iWorkspaceID);
|
||||
const auto FSMODE = PWORKSPACE->m_efFullscreenMode;
|
||||
|
||||
@@ -1425,6 +1485,17 @@ void CKeybindManager::circleNext(std::string arg) {
|
||||
}
|
||||
};
|
||||
|
||||
if (!g_pCompositor->m_pLastWindow) {
|
||||
// if we have a clear focus, find the first window and get the next focusable.
|
||||
if (g_pCompositor->getWindowsOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace) > 0) {
|
||||
const auto PWINDOW = g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace), true);
|
||||
|
||||
switchToWindow(PWINDOW);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||
switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow, true));
|
||||
else
|
||||
@@ -1551,7 +1622,7 @@ void CKeybindManager::layoutmsg(std::string msg) {
|
||||
void CKeybindManager::toggleOpaque(std::string unused) {
|
||||
const auto PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
PWINDOW->m_sAdditionalConfigData.forceOpaque = !PWINDOW->m_sAdditionalConfigData.forceOpaque;
|
||||
@@ -1560,11 +1631,22 @@ void CKeybindManager::toggleOpaque(std::string unused) {
|
||||
}
|
||||
|
||||
void CKeybindManager::dpms(std::string arg) {
|
||||
bool enable = arg == "on";
|
||||
bool enable = arg.find("on") == 0;
|
||||
std::string port = "";
|
||||
|
||||
if (arg.find_first_of(' ') != std::string::npos) {
|
||||
port = arg.substr(arg.find_first_of(' ') + 1);
|
||||
}
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
|
||||
if (!port.empty() && m->szName != port)
|
||||
continue;
|
||||
|
||||
wlr_output_enable(m->output, enable);
|
||||
|
||||
m->dpmsStatus = enable;
|
||||
|
||||
if (!wlr_output_commit(m->output)) {
|
||||
Debug::log(ERR, "Couldn't commit output %s", m->szName.c_str());
|
||||
}
|
||||
@@ -1580,7 +1662,7 @@ void CKeybindManager::swapnext(std::string arg) {
|
||||
|
||||
CWindow* toSwap = nullptr;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||
if (!g_pCompositor->m_pLastWindow)
|
||||
return;
|
||||
|
||||
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow;
|
||||
@@ -1621,12 +1703,15 @@ void CKeybindManager::swapActiveWorkspaces(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::pinActive(std::string args) {
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) || !g_pCompositor->m_pLastWindow->m_bIsFloating || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||
if (!g_pCompositor->m_pLastWindow || !g_pCompositor->m_pLastWindow->m_bIsFloating || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||
return;
|
||||
|
||||
g_pCompositor->m_pLastWindow->m_bPinned = !g_pCompositor->m_pLastWindow->m_bPinned;
|
||||
g_pCompositor->m_pLastWindow->m_iWorkspaceID = g_pCompositor->getMonitorFromID(g_pCompositor->m_pLastWindow->m_iMonitorID)->activeWorkspace;
|
||||
|
||||
g_pCompositor->m_pLastWindow->updateDynamicRules();
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(g_pCompositor->m_pLastWindow);
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastWindow->m_iWorkspaceID);
|
||||
|
||||
PWORKSPACE->m_pLastFocusedWindow = g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal());
|
||||
@@ -1640,7 +1725,7 @@ void CKeybindManager::mouse(std::string args) {
|
||||
if (PRESSED) {
|
||||
g_pKeybindManager->m_bIsMouseBindActive = true;
|
||||
|
||||
g_pInputManager->currentlyDraggedWindow = g_pCompositor->windowFromCursor();
|
||||
g_pInputManager->currentlyDraggedWindow = g_pCompositor->vectorToWindowIdeal(g_pInputManager->getMouseCoordsInternal());
|
||||
g_pInputManager->dragMode = MBIND_MOVE;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onBeginDragWindow();
|
||||
@@ -1657,7 +1742,7 @@ void CKeybindManager::mouse(std::string args) {
|
||||
if (PRESSED) {
|
||||
g_pKeybindManager->m_bIsMouseBindActive = true;
|
||||
|
||||
g_pInputManager->currentlyDraggedWindow = g_pCompositor->windowFromCursor();
|
||||
g_pInputManager->currentlyDraggedWindow = g_pCompositor->vectorToWindowIdeal(g_pInputManager->getMouseCoordsInternal());
|
||||
g_pInputManager->dragMode = MBIND_RESIZE;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onBeginDragWindow();
|
||||
@@ -1672,3 +1757,8 @@ void CKeybindManager::mouse(std::string args) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CKeybindManager::bringActiveToTop(std::string args) {
|
||||
if (g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_bIsFloating)
|
||||
g_pCompositor->moveWindowToTop(g_pCompositor->m_pLastWindow);
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include <functional>
|
||||
|
||||
class CInputManager;
|
||||
class CConfigManager;
|
||||
|
||||
struct SKeybind {
|
||||
std::string key = "";
|
||||
@@ -38,6 +39,7 @@ public:
|
||||
bool onKeyEvent(wlr_keyboard_key_event*, SKeyboard*);
|
||||
bool onAxisEvent(wlr_pointer_axis_event*);
|
||||
bool onMouseEvent(wlr_pointer_button_event*);
|
||||
void onSwitchEvent(const std::string&);
|
||||
|
||||
void addKeybind(SKeybind);
|
||||
void removeKeybind(uint32_t, const std::string&);
|
||||
@@ -91,6 +93,7 @@ private:
|
||||
static void moveActiveToWorkspace(std::string);
|
||||
static void moveActiveToWorkspaceSilent(std::string);
|
||||
static void moveFocusTo(std::string);
|
||||
static void centerWindow(std::string);
|
||||
static void moveActiveTo(std::string);
|
||||
static void toggleGroup(std::string);
|
||||
static void changeGroupActive(std::string);
|
||||
@@ -119,9 +122,11 @@ private:
|
||||
static void swapActiveWorkspaces(std::string);
|
||||
static void pinActive(std::string);
|
||||
static void mouse(std::string);
|
||||
static void bringActiveToTop(std::string);
|
||||
|
||||
friend class CCompositor;
|
||||
friend class CInputManager;
|
||||
friend class CConfigManager;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CKeybindManager> g_pKeybindManager;
|
||||
|
@@ -3,7 +3,7 @@
|
||||
#include "../events/Events.hpp"
|
||||
|
||||
CHyprXWaylandManager::CHyprXWaylandManager() {
|
||||
if (XWAYLAND) {
|
||||
#ifndef NO_XWAYLAND
|
||||
m_sWLRXWayland = wlr_xwayland_create(g_pCompositor->m_sWLDisplay, g_pCompositor->m_sWLRCompositor, 1);
|
||||
|
||||
if (!m_sWLRXWayland) {
|
||||
@@ -17,7 +17,9 @@ CHyprXWaylandManager::CHyprXWaylandManager() {
|
||||
setenv("DISPLAY", m_sWLRXWayland->display_name, 1);
|
||||
|
||||
Debug::log(LOG, "CHyprXWaylandManager started on display %s", m_sWLRXWayland->display_name);
|
||||
}
|
||||
#else
|
||||
unsetenv("DISPLAY"); // unset DISPLAY so that X11 apps do not try to start on a different/invalid DISPLAY
|
||||
#endif
|
||||
}
|
||||
|
||||
CHyprXWaylandManager::~CHyprXWaylandManager() {
|
||||
@@ -51,17 +53,21 @@ void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate)
|
||||
|
||||
void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
|
||||
if (pWindow->m_bIsX11) {
|
||||
if (pWindow->m_uSurface.xwayland->minimized)
|
||||
|
||||
if (activate) {
|
||||
wlr_xwayland_surface_set_minimized(pWindow->m_uSurface.xwayland, false);
|
||||
wlr_xwayland_surface_restack(pWindow->m_uSurface.xwayland, NULL, XCB_STACK_MODE_ABOVE);
|
||||
}
|
||||
|
||||
wlr_xwayland_surface_activate(pWindow->m_uSurface.xwayland, activate);
|
||||
wlr_xwayland_surface_restack(pWindow->m_uSurface.xwayland, NULL, XCB_STACK_MODE_ABOVE);
|
||||
}
|
||||
else
|
||||
wlr_xdg_toplevel_set_activated(pWindow->m_uSurface.xdg->toplevel, activate);
|
||||
|
||||
if (activate) {
|
||||
g_pCompositor->m_pLastFocus = getWindowSurface(pWindow);
|
||||
g_pCompositor->m_pLastWindow = pWindow;
|
||||
}
|
||||
|
||||
if (!pWindow->m_bPinned)
|
||||
g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_pLastFocusedWindow = pWindow;
|
||||
@@ -69,10 +75,19 @@ void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
|
||||
|
||||
void CHyprXWaylandManager::getGeometryForWindow(CWindow* pWindow, wlr_box* pbox) {
|
||||
if (pWindow->m_bIsX11) {
|
||||
const auto SIZEHINTS = pWindow->m_uSurface.xwayland->size_hints;
|
||||
|
||||
if (SIZEHINTS && pWindow->m_iX11Type != 2) {
|
||||
pbox->x = SIZEHINTS->x;
|
||||
pbox->y = SIZEHINTS->y;
|
||||
pbox->width = SIZEHINTS->width;
|
||||
pbox->height = SIZEHINTS->height;
|
||||
} else {
|
||||
pbox->x = pWindow->m_uSurface.xwayland->x;
|
||||
pbox->y = pWindow->m_uSurface.xwayland->y;
|
||||
pbox->width = pWindow->m_uSurface.xwayland->width;
|
||||
pbox->height = pWindow->m_uSurface.xwayland->height;
|
||||
}
|
||||
} else {
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, pbox);
|
||||
}
|
||||
|
@@ -49,6 +49,27 @@ void CInputManager::recheckIdleInhibitorStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
// check manual user-set inhibitors
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_eIdleInhibitMode == IDLEINHIBIT_NONE)
|
||||
continue;
|
||||
|
||||
if (w->m_eIdleInhibitMode == IDLEINHIBIT_ALWAYS) {
|
||||
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (w->m_eIdleInhibitMode == IDLEINHIBIT_FOCUS && g_pCompositor->isWindowActive(w.get())) {
|
||||
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (w->m_eIdleInhibitMode == IDLEINHIBIT_FULLSCREEN && w->m_bIsFullscreen && g_pCompositor->isWorkspaceVisible(w->m_iWorkspaceID)) {
|
||||
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, true);
|
||||
return;
|
||||
}
|
@@ -35,7 +35,16 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
static auto *const PHOGFOCUS = &g_pConfigManager->getConfigValuePtr("misc:layers_hog_keyboard_focus")->intValue;
|
||||
static auto *const PFLOATBEHAVIOR = &g_pConfigManager->getConfigValuePtr("input:float_switch_override_focus")->intValue;
|
||||
|
||||
if (!g_pCompositor->m_bReadyToProcess)
|
||||
m_pFoundSurfaceToFocus = nullptr;
|
||||
m_pFoundLSToFocus = nullptr;
|
||||
m_pFoundWindowToFocus = nullptr;
|
||||
wlr_surface* foundSurface = nullptr;
|
||||
Vector2D surfaceCoords;
|
||||
Vector2D surfacePos = Vector2D(-1337, -1337);
|
||||
CWindow* pFoundWindow = nullptr;
|
||||
SLayerSurface* pFoundLayerSurface = nullptr;
|
||||
|
||||
if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown)
|
||||
return;
|
||||
|
||||
if (!g_pCompositor->m_sSeat.mouse) {
|
||||
@@ -43,9 +52,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_pCompositor->m_sSeat.mouse->virt)
|
||||
return; // don't refocus on virt
|
||||
|
||||
if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS) {
|
||||
// enable dpms
|
||||
g_pKeybindManager->dpms("on");
|
||||
@@ -61,11 +67,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||
|
||||
bool didConstraintOnCursor = false;
|
||||
|
||||
// constraints
|
||||
// All constraints TODO: multiple mice?
|
||||
if (g_pCompositor->m_sSeat.mouse->currentConstraint) {
|
||||
if (g_pCompositor->m_sSeat.mouse->currentConstraint && !g_pCompositor->m_sSeat.exclusiveClient) {
|
||||
// XWayland windows sometimes issue constraints weirdly.
|
||||
// TODO: We probably should search their parent. wlr_xwayland_surface->parent
|
||||
const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
|
||||
@@ -95,15 +99,21 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, newConstrainedCoords.x, newConstrainedCoords.y);
|
||||
|
||||
mouseCoords = newConstrainedCoords;
|
||||
|
||||
didConstraintOnCursor = true;
|
||||
}
|
||||
} else {
|
||||
if ((!CONSTRAINTWINDOW->m_bIsX11 && PMONITOR && CONSTRAINTWINDOW->m_iWorkspaceID == PMONITOR->activeWorkspace) || (CONSTRAINTWINDOW->m_bIsX11)) {
|
||||
g_pCompositor->m_sSeat.mouse->constraintActive = true;
|
||||
didConstraintOnCursor = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (CONSTRAINTWINDOW->m_bIsX11) {
|
||||
foundSurface = g_pXWaylandManager->getWindowSurface(CONSTRAINTWINDOW);
|
||||
surfacePos = CONSTRAINTWINDOW->m_vRealPosition.vec();
|
||||
} else {
|
||||
g_pCompositor->vectorWindowToSurface(mouseCoords, CONSTRAINTWINDOW, surfaceCoords);
|
||||
}
|
||||
|
||||
pFoundWindow = CONSTRAINTWINDOW;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,12 +122,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onMouseMove(getMouseCoordsInternal());
|
||||
|
||||
// focus
|
||||
wlr_surface* foundSurface = nullptr;
|
||||
|
||||
if (didConstraintOnCursor)
|
||||
return; // don't process when cursor constrained
|
||||
|
||||
if (PMONITOR && PMONITOR != g_pCompositor->m_pLastMonitor) {
|
||||
g_pCompositor->m_pLastMonitor = PMONITOR;
|
||||
|
||||
@@ -130,11 +134,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", PMONITOR->szName + "," + ACTIVEWORKSPACE->m_szName});
|
||||
}
|
||||
|
||||
Vector2D surfaceCoords;
|
||||
Vector2D surfacePos = Vector2D(-1337, -1337);
|
||||
CWindow* pFoundWindow = nullptr;
|
||||
SLayerSurface* pFoundLayerSurface = nullptr;
|
||||
|
||||
// overlay is above fullscreen
|
||||
if (!foundSurface)
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfaceCoords, &pFoundLayerSurface);
|
||||
@@ -153,14 +152,14 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow);
|
||||
surfacePos = pFoundWindow->m_vRealPosition.vec();
|
||||
|
||||
// only check floating because tiled cant be over fullscreen
|
||||
for (auto w = g_pCompositor->m_vWindows.rbegin(); w != g_pCompositor->m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((((*w)->m_bIsFloating && (*w)->m_bIsMapped && ((*w)->m_bCreatedOverFullscreen || (*w)->m_bPinned)) || ((*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden) {
|
||||
if ((((*w)->m_bIsFloating && (*w)->m_bIsMapped && ((*w)->m_bCreatedOverFullscreen || (*w)->m_bPinned)) || ((*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->isHidden()) {
|
||||
pFoundWindow = (*w).get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pFoundWindow->m_bIsX11) {
|
||||
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
|
||||
@@ -169,10 +168,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow);
|
||||
surfacePos = pFoundWindow->m_vRealPosition.vec();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// then windows
|
||||
@@ -264,14 +259,21 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
}
|
||||
}
|
||||
|
||||
// set the values for use
|
||||
if (refocus) {
|
||||
m_pFoundLSToFocus = pFoundLayerSurface;
|
||||
m_pFoundWindowToFocus = pFoundWindow;
|
||||
m_pFoundSurfaceToFocus = foundSurface;
|
||||
}
|
||||
|
||||
if (pFoundWindow) {
|
||||
if (*PFOLLOWMOUSE != 1 && !refocus) {
|
||||
if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating && *PFLOATBEHAVIOR) {
|
||||
if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow && ((pFoundWindow->m_bIsFloating && *PFLOATBEHAVIOR == 2) || (g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating && *PFLOATBEHAVIOR != 0))) {
|
||||
// enter if change floating style
|
||||
if (*PFOLLOWMOUSE != 3 && allowKeyboardRefocus)
|
||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
} else if (*PFOLLOWMOUSE == 2) {
|
||||
} else if (*PFOLLOWMOUSE == 2 || *PFOLLOWMOUSE == 3) {
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
}
|
||||
|
||||
@@ -300,7 +302,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
} else {
|
||||
if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive && *PFOLLOWMOUSE != 3 && allowKeyboardRefocus) {
|
||||
g_pCompositor->focusSurface(foundSurface);
|
||||
g_pCompositor->m_pLastWindow = nullptr; // reset last window as we have a full focus on a LS
|
||||
}
|
||||
|
||||
if (pFoundLayerSurface)
|
||||
@@ -338,6 +339,10 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even
|
||||
g_pHyprRenderer->m_bWindowRequestedCursorHide = false;
|
||||
}
|
||||
|
||||
if (m_bCursorImageOverriden) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ecbClickBehavior == CLICKMODE_KILL) {
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "crosshair", g_pCompositor->m_sWLRCursor);
|
||||
return;
|
||||
@@ -386,17 +391,21 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
|
||||
// notify the keybind manager
|
||||
static auto *const PPASSMOUSE = &g_pConfigManager->getConfigValuePtr("binds:pass_mouse_when_bound")->intValue;
|
||||
const auto PASS = g_pKeybindManager->onMouseEvent(e);
|
||||
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||
|
||||
if (!PASS && !*PPASSMOUSE)
|
||||
return;
|
||||
|
||||
switch (e->state) {
|
||||
case WLR_BUTTON_PRESSED:
|
||||
if (*PFOLLOWMOUSE == 3) // don't refocus on full loose
|
||||
break;
|
||||
|
||||
if (!g_pCompositor->m_sSeat.mouse->currentConstraint)
|
||||
refocus();
|
||||
|
||||
// if clicked on a floating window make it top
|
||||
if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_bIsFloating)
|
||||
if (g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_bIsFloating)
|
||||
g_pCompositor->moveWindowToTop(g_pCompositor->m_pLastWindow);
|
||||
|
||||
break;
|
||||
@@ -415,7 +424,7 @@ void CInputManager::processMouseDownKill(wlr_pointer_button_event* e) {
|
||||
case WLR_BUTTON_PRESSED: {
|
||||
const auto PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW)){
|
||||
if (!PWINDOW) {
|
||||
Debug::log(ERR, "Cannot kill invalid window!");
|
||||
break;
|
||||
}
|
||||
@@ -435,12 +444,17 @@ void CInputManager::processMouseDownKill(wlr_pointer_button_event* e) {
|
||||
}
|
||||
|
||||
void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) {
|
||||
static auto *const PSCROLLFACTOR = &g_pConfigManager->getConfigValuePtr("input:touchpad:scroll_factor")->floatValue;
|
||||
|
||||
auto factor = (*PSCROLLFACTOR <= 0.f || e->source != WLR_AXIS_SOURCE_FINGER ? 1.f : *PSCROLLFACTOR);
|
||||
|
||||
bool passEvent = g_pKeybindManager->onAxisEvent(e);
|
||||
|
||||
wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat);
|
||||
|
||||
if (passEvent) {
|
||||
wlr_seat_pointer_notify_axis(g_pCompositor->m_sSeat.seat, e->time_msec, e->orientation, e->delta, e->delta_discrete, e->source);
|
||||
wlr_seat_pointer_notify_axis(g_pCompositor->m_sSeat.seat, e->time_msec, e->orientation, factor * e->delta,
|
||||
std::round(factor * e->delta_discrete), e->source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,12 +676,14 @@ void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
|
||||
Debug::log(LOG, "New mouse has libinput sens %.2f (%.2f) with accel profile %i (%i)", libinput_device_config_accel_get_speed(LIBINPUTDEV), libinput_device_config_accel_get_default_speed(LIBINPUTDEV), libinput_device_config_accel_get_profile(LIBINPUTDEV), libinput_device_config_accel_get_default_profile(LIBINPUTDEV));
|
||||
}
|
||||
|
||||
setMouseConfigs();
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, mouse);
|
||||
|
||||
PMOUSE->connected = true;
|
||||
|
||||
setPointerConfigs();
|
||||
|
||||
PMOUSE->hyprListener_destroyMouse.initCallback(&mouse->events.destroy, &Events::listener_destroyMouse, PMOUSE, "Mouse");
|
||||
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, mouse);
|
||||
|
||||
g_pCompositor->m_sSeat.mouse = PMOUSE;
|
||||
|
||||
m_tmrLastCursorMovement.reset();
|
||||
@@ -675,15 +691,26 @@ void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
|
||||
Debug::log(LOG, "New mouse created, pointer WLR: %x", mouse);
|
||||
}
|
||||
|
||||
void CInputManager::setMouseConfigs() {
|
||||
void CInputManager::setPointerConfigs() {
|
||||
for (auto& m : m_lMice) {
|
||||
const auto PMOUSE = &m;
|
||||
const auto PPOINTER = &m;
|
||||
|
||||
auto devname = PMOUSE->name;
|
||||
auto devname = PPOINTER->name;
|
||||
transform(devname.begin(), devname.end(), devname.begin(), ::tolower);
|
||||
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
|
||||
|
||||
if (HASCONFIG) {
|
||||
const auto ENABLED = g_pConfigManager->getDeviceInt(devname, "enabled");
|
||||
if (ENABLED && !m.connected) {
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, m.mouse);
|
||||
m.connected = true;
|
||||
} else if (!ENABLED && m.connected) {
|
||||
wlr_cursor_detach_input_device(g_pCompositor->m_sWLRCursor, m.mouse);
|
||||
m.connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (wlr_input_device_is_libinput(m.mouse)) {
|
||||
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(m.mouse);
|
||||
|
||||
@@ -692,6 +719,11 @@ void CInputManager::setMouseConfigs() {
|
||||
else
|
||||
libinput_device_config_click_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
|
||||
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "left_handed") : g_pConfigManager->getInt("input:left_handed")) == 0)
|
||||
libinput_device_config_left_handed_set(LIBINPUTDEV, 0);
|
||||
else
|
||||
libinput_device_config_left_handed_set(LIBINPUTDEV, 1);
|
||||
|
||||
if (libinput_device_config_middle_emulation_is_available(LIBINPUTDEV)) { // middleclick on r+l mouse button pressed
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "middle_button_emulation") : g_pConfigManager->getInt("input:touchpad:middle_button_emulation")) == 1)
|
||||
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
|
||||
@@ -699,6 +731,21 @@ void CInputManager::setMouseConfigs() {
|
||||
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
|
||||
}
|
||||
|
||||
const auto SCROLLMETHOD = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "scroll_method") : g_pConfigManager->getString("input:scroll_method");
|
||||
if (SCROLLMETHOD == "" || SCROLLMETHOD == STRVAL_EMPTY) {
|
||||
libinput_device_config_scroll_set_method(LIBINPUTDEV, libinput_device_config_scroll_get_default_method(LIBINPUTDEV));
|
||||
} else if (SCROLLMETHOD == "no_scroll") {
|
||||
libinput_device_config_scroll_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
|
||||
} else if (SCROLLMETHOD == "2fg") {
|
||||
libinput_device_config_scroll_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_SCROLL_2FG);
|
||||
} else if (SCROLLMETHOD == "edge") {
|
||||
libinput_device_config_scroll_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_SCROLL_EDGE);
|
||||
} else if (SCROLLMETHOD == "on_button_down") {
|
||||
libinput_device_config_scroll_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
|
||||
} else {
|
||||
Debug::log(WARN, "Scroll method unknown");
|
||||
}
|
||||
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "drag_lock") : g_pConfigManager->getInt("input:touchpad:drag_lock")) == 0)
|
||||
libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
|
||||
else
|
||||
@@ -723,10 +770,20 @@ void CInputManager::setMouseConfigs() {
|
||||
}
|
||||
|
||||
const auto LIBINPUTSENS = std::clamp((HASCONFIG ? g_pConfigManager->getDeviceFloat(devname, "sensitivity") : g_pConfigManager->getFloat("input:sensitivity")), -1.f, 1.f);
|
||||
|
||||
libinput_device_config_accel_set_profile(LIBINPUTDEV, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
|
||||
libinput_device_config_accel_set_speed(LIBINPUTDEV, LIBINPUTSENS);
|
||||
|
||||
const auto ACCELPROFILE = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "accel_profile") : g_pConfigManager->getString("input:accel_profile");
|
||||
|
||||
if (ACCELPROFILE == "" || ACCELPROFILE == STRVAL_EMPTY) {
|
||||
libinput_device_config_accel_set_profile(LIBINPUTDEV, libinput_device_config_accel_get_default_profile(LIBINPUTDEV));
|
||||
} else if (ACCELPROFILE == "adaptive") {
|
||||
libinput_device_config_accel_set_profile(LIBINPUTDEV, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
|
||||
} else if (ACCELPROFILE == "flat") {
|
||||
libinput_device_config_accel_set_profile(LIBINPUTDEV, LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
|
||||
} else {
|
||||
Debug::log(WARN, "Unknown acceleration profile, falling back to default");
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Applied config to mouse %s, sens %.2f", m.name.c_str(), LIBINPUTSENS);
|
||||
}
|
||||
}
|
||||
@@ -765,6 +822,31 @@ void CInputManager::destroyMouse(wlr_input_device* mouse) {
|
||||
unconstrainMouse();
|
||||
}
|
||||
|
||||
|
||||
void CInputManager::updateKeyboardsLeds(wlr_input_device* pKeyboard) {
|
||||
auto keyboard = wlr_keyboard_from_input_device(pKeyboard);
|
||||
|
||||
if (keyboard->xkb_state == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t leds = 0;
|
||||
for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) {
|
||||
if (xkb_state_led_index_is_active(keyboard->xkb_state,
|
||||
keyboard->led_indexes[i])) {
|
||||
leds |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& kb : m_lKeyboards) {
|
||||
if ((kb.isVirtual && shouldIgnoreVirtualKeyboard(&kb)) || kb.keyboard == pKeyboard)
|
||||
continue;
|
||||
|
||||
wlr_keyboard_led_update(wlr_keyboard_from_input_device(kb.keyboard), leds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
|
||||
bool passEvent = g_pKeybindManager->onKeyEvent(e, pKeyboard);
|
||||
|
||||
@@ -781,6 +863,8 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e->time_msec, e->keycode, e->state);
|
||||
}
|
||||
|
||||
updateKeyboardsLeds(pKeyboard->keyboard);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -800,6 +884,8 @@ void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &MODS);
|
||||
}
|
||||
|
||||
updateKeyboardsLeds(pKeyboard->keyboard);
|
||||
|
||||
const auto PWLRKB = wlr_keyboard_from_input_device(pKeyboard->keyboard);
|
||||
|
||||
if (PWLRKB->modifiers.group != pKeyboard->activeLayout) {
|
||||
@@ -809,6 +895,10 @@ void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CInputManager::shouldIgnoreVirtualKeyboard(SKeyboard* pKeyboard) {
|
||||
return !pKeyboard || (m_sIMERelay.m_pKeyboardGrab && wl_resource_get_client(m_sIMERelay.m_pKeyboardGrab->pWlrKbGrab->resource) == wl_resource_get_client(wlr_input_device_get_virtual_keyboard(pKeyboard->keyboard)->resource));
|
||||
}
|
||||
|
||||
void CInputManager::refocus() {
|
||||
mouseMoveUnified(0, true);
|
||||
}
|
||||
@@ -950,7 +1040,7 @@ uint32_t CInputManager::accumulateModsFromAllKBs() {
|
||||
uint32_t finalMask = 0;
|
||||
|
||||
for (auto& kb : m_lKeyboards) {
|
||||
if (kb.isVirtual)
|
||||
if (kb.isVirtual && shouldIgnoreVirtualKeyboard(&kb))
|
||||
continue;
|
||||
|
||||
finalMask |= wlr_keyboard_get_modifiers(wlr_keyboard_from_input_device(kb.keyboard));
|
||||
@@ -992,6 +1082,13 @@ void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
|
||||
const auto PNEWDEV = &m_lTouchDevices.emplace_back();
|
||||
PNEWDEV->pWlrDevice = pDevice;
|
||||
|
||||
try {
|
||||
PNEWDEV->name = std::string(pDevice->name);
|
||||
} catch(std::exception& e) {
|
||||
Debug::log(ERR, "Touch Device had no name???"); // logic error
|
||||
}
|
||||
|
||||
setTouchDeviceConfigs();
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, pDevice);
|
||||
|
||||
Debug::log(LOG, "New touch device added at %x", PNEWDEV);
|
||||
@@ -1001,8 +1098,107 @@ void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
|
||||
}, PNEWDEV, "TouchDevice");
|
||||
}
|
||||
|
||||
void CInputManager::setTouchDeviceConfigs() {
|
||||
// The third row is always 0 0 1 and is not expected by `libinput_device_config_calibration_set_matrix`
|
||||
static const float MATRICES[8][6] = {
|
||||
{ // normal
|
||||
1, 0, 0,
|
||||
0, 1, 0
|
||||
},
|
||||
{ // rotation 90°
|
||||
0, -1, 1,
|
||||
1, 0, 0
|
||||
},
|
||||
{ // rotation 180°
|
||||
-1, 0, 1,
|
||||
0, -1, 1
|
||||
},
|
||||
{ // rotation 270°
|
||||
0, 1, 0,
|
||||
-1, 0, 1
|
||||
},
|
||||
{ // flipped
|
||||
-1, 0, 1,
|
||||
0, 1, 0
|
||||
},
|
||||
{ // flipped + rotation 90°
|
||||
0, 1, 0,
|
||||
1, 0, 0
|
||||
},
|
||||
{ // flipped + rotation 180°
|
||||
1, 0, 0,
|
||||
0, -1, 1
|
||||
},
|
||||
{ // flipped + rotation 270°
|
||||
0, -1, 1,
|
||||
-1, 0, 1
|
||||
}
|
||||
};
|
||||
for (auto& m : m_lTouchDevices) {
|
||||
const auto PTOUCHDEV = &m;
|
||||
|
||||
auto devname = PTOUCHDEV->name;
|
||||
transform(devname.begin(), devname.end(), devname.begin(), ::tolower);
|
||||
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
|
||||
|
||||
if (wlr_input_device_is_libinput(m.pWlrDevice)) {
|
||||
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(m.pWlrDevice);
|
||||
|
||||
const int ROTATION = std::clamp(HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "touch_transform") : g_pConfigManager->getInt("input:touchdevice:transform"), 0, 7);
|
||||
libinput_device_config_calibration_set_matrix(LIBINPUTDEV, MATRICES[ROTATION]);
|
||||
|
||||
const auto OUTPUT = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "touch_output") : g_pConfigManager->getString("input:touchdevice:output");
|
||||
if (!OUTPUT.empty() && OUTPUT != STRVAL_EMPTY)
|
||||
PTOUCHDEV->boundOutput = OUTPUT;
|
||||
else
|
||||
PTOUCHDEV->boundOutput = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::destroyTouchDevice(STouchDevice* pDevice) {
|
||||
Debug::log(LOG, "Touch device at %x removed", pDevice);
|
||||
|
||||
m_lTouchDevices.remove(*pDevice);
|
||||
}
|
||||
|
||||
void CInputManager::newSwitch(wlr_input_device* pDevice) {
|
||||
const auto PNEWDEV = &m_lSwitches.emplace_back();
|
||||
PNEWDEV->pWlrDevice = pDevice;
|
||||
|
||||
Debug::log(LOG, "New switch with name \"%s\" added", pDevice->name);
|
||||
|
||||
PNEWDEV->hyprListener_destroy.initCallback(&pDevice->events.destroy, [&](void* owner, void* data) {
|
||||
destroySwitch((SSwitchDevice*)owner);
|
||||
}, PNEWDEV, "SwitchDevice");
|
||||
|
||||
const auto PSWITCH = wlr_switch_from_input_device(pDevice);
|
||||
|
||||
PNEWDEV->hyprListener_toggle.initCallback(&PSWITCH->events.toggle, [&](void* owner, void* data) {
|
||||
const auto PDEVICE = (SSwitchDevice*)owner;
|
||||
const auto NAME = std::string(PDEVICE->pWlrDevice->name);
|
||||
|
||||
Debug::log(LOG, "Switch %s fired, triggering binds.", NAME.c_str());
|
||||
|
||||
g_pKeybindManager->onSwitchEvent(NAME);
|
||||
}, PNEWDEV, "SwitchDevice");
|
||||
}
|
||||
|
||||
void CInputManager::destroySwitch(SSwitchDevice* pDevice) {
|
||||
m_lSwitches.remove(*pDevice);
|
||||
}
|
||||
|
||||
void CInputManager::setCursorImageUntilUnset(std::string name) {
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, name.c_str(), g_pCompositor->m_sWLRCursor);
|
||||
m_bCursorImageOverriden = true;
|
||||
}
|
||||
|
||||
void CInputManager::unsetCursorImage() {
|
||||
if (!m_bCursorImageOverriden)
|
||||
return;
|
||||
|
||||
m_bCursorImageOverriden = false;
|
||||
if (!g_pHyprRenderer->m_bWindowRequestedCursorHide)
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", g_pCompositor->m_sWLRCursor);
|
||||
}
|
||||
|
@@ -20,6 +20,8 @@ enum eMouseBindMode {
|
||||
|
||||
struct STouchData {
|
||||
CWindow* touchFocusWindow = nullptr;
|
||||
SLayerSurface* touchFocusLS = nullptr;
|
||||
wlr_surface* touchFocusSurface = nullptr;
|
||||
Vector2D touchSurfaceOrigin;
|
||||
};
|
||||
|
||||
@@ -37,9 +39,11 @@ public:
|
||||
void newVirtualKeyboard(wlr_input_device*);
|
||||
void newMouse(wlr_input_device*, bool virt = false);
|
||||
void newTouchDevice(wlr_input_device*);
|
||||
void newSwitch(wlr_input_device*);
|
||||
void destroyTouchDevice(STouchDevice*);
|
||||
void destroyKeyboard(SKeyboard*);
|
||||
void destroyMouse(wlr_input_device*);
|
||||
void destroySwitch(SSwitchDevice*);
|
||||
|
||||
void constrainMouse(SMouse*, wlr_pointer_constraint_v1*);
|
||||
void recheckConstraint(SMouse*);
|
||||
@@ -50,7 +54,8 @@ public:
|
||||
void refocus();
|
||||
|
||||
void setKeyboardLayout();
|
||||
void setMouseConfigs();
|
||||
void setPointerConfigs();
|
||||
void setTouchDeviceConfigs();
|
||||
|
||||
void updateDragIcon();
|
||||
void updateCapabilities(wlr_input_device*);
|
||||
@@ -89,6 +94,9 @@ public:
|
||||
// Touch devices
|
||||
std::list<STouchDevice> m_lTouchDevices;
|
||||
|
||||
// Switches
|
||||
std::list<SSwitchDevice> m_lSwitches;
|
||||
|
||||
void newTabletTool(wlr_input_device*);
|
||||
void newTabletPad(wlr_input_device*);
|
||||
void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false);
|
||||
@@ -107,13 +115,24 @@ public:
|
||||
|
||||
CInputMethodRelay m_sIMERelay;
|
||||
|
||||
void updateKeyboardsLeds(wlr_input_device* pKeyboard);
|
||||
|
||||
// for shared mods
|
||||
uint32_t accumulateModsFromAllKBs();
|
||||
|
||||
CWindow* m_pFollowOnDnDBegin = nullptr;
|
||||
|
||||
// for virtual keyboards: whether we should respect them as normal ones
|
||||
bool shouldIgnoreVirtualKeyboard(SKeyboard*);
|
||||
|
||||
// for special cursors that we choose
|
||||
void setCursorImageUntilUnset(std::string);
|
||||
void unsetCursorImage();
|
||||
|
||||
private:
|
||||
|
||||
bool m_bCursorImageOverriden = false;
|
||||
|
||||
// for click behavior override
|
||||
eClickBehaviorMode m_ecbClickBehavior = CLICKMODE_DEFAULT;
|
||||
bool m_bEmptyFocusCursorSet = false;
|
||||
@@ -134,6 +153,14 @@ private:
|
||||
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
|
||||
|
||||
void applyConfigToKeyboard(SKeyboard*);
|
||||
|
||||
// this will be set after a refocus()
|
||||
wlr_surface* m_pFoundSurfaceToFocus = nullptr;
|
||||
SLayerSurface* m_pFoundLSToFocus = nullptr;
|
||||
CWindow* m_pFoundWindowToFocus = nullptr;
|
||||
|
||||
// swipe
|
||||
void beginWorkspaceSwipe();
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CInputManager> g_pInputManager;
|
||||
|
@@ -301,7 +301,7 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput) {
|
||||
const auto PINPUT = (STextInput*)owner;
|
||||
|
||||
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
|
||||
Debug::log(ERR, "Enabling TextInput on no IME!");
|
||||
// Debug::log(WARN, "Enabling TextInput on no IME!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -317,12 +317,12 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput) {
|
||||
const auto PINPUT = (STextInput*)owner;
|
||||
|
||||
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
|
||||
Debug::log(ERR, "Committing TextInput on no IME!");
|
||||
// Debug::log(WARN, "Committing TextInput on no IME!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PINPUT->pWlrInput->current_enabled) {
|
||||
Debug::log(ERR, "Disabled TextInput commit?");
|
||||
Debug::log(WARN, "Disabled TextInput commit?");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput) {
|
||||
const auto PINPUT = (STextInput*)owner;
|
||||
|
||||
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
|
||||
Debug::log(ERR, "Disabling TextInput on no IME!");
|
||||
// Debug::log(WARN, "Disabling TextInput on no IME!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -352,7 +352,7 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput) {
|
||||
const auto PINPUT = (STextInput*)owner;
|
||||
|
||||
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
|
||||
Debug::log(ERR, "Disabling TextInput on no IME!");
|
||||
// Debug::log(WARN, "Disabling TextInput on no IME!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,8 @@
|
||||
#include "../../defines.hpp"
|
||||
#include "../../helpers/WLClasses.hpp"
|
||||
|
||||
class CInputManager;
|
||||
|
||||
class CInputMethodRelay {
|
||||
public:
|
||||
CInputMethodRelay();
|
||||
@@ -45,4 +47,5 @@ private:
|
||||
void createNewTextInput(wlr_text_input_v3*);
|
||||
|
||||
friend class CHyprRenderer;
|
||||
friend class CInputManager;
|
||||
};
|
@@ -4,6 +4,7 @@
|
||||
void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
||||
static auto *const PSWIPE = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe")->intValue;
|
||||
static auto *const PSWIPEFINGERS = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_fingers")->intValue;
|
||||
static auto *const PSWIPENEW = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_create_new")->intValue;
|
||||
|
||||
if (e->fingers != *PSWIPEFINGERS || *PSWIPE == 0)
|
||||
return;
|
||||
@@ -15,9 +16,13 @@ void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (onMonitor < 2)
|
||||
if (onMonitor < 2 && !*PSWIPENEW)
|
||||
return; // disallow swiping when there's 1 workspace on a monitor
|
||||
|
||||
beginWorkspaceSwipe();
|
||||
}
|
||||
|
||||
void CInputManager::beginWorkspaceSwipe() {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
|
||||
Debug::log(LOG, "Starting a swipe from %s", PWORKSPACE->m_szName.c_str());
|
||||
@@ -42,13 +47,19 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
static auto *const PSWIPEPERC = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_cancel_ratio")->floatValue;
|
||||
static auto *const PSWIPEDIST = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance")->intValue;
|
||||
static auto *const PSWIPEFORC = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_min_speed_to_force")->intValue;
|
||||
static auto *const PSWIPENEW = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_create_new")->intValue;
|
||||
const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert";
|
||||
|
||||
// commit
|
||||
std::string wsname = "";
|
||||
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
|
||||
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
|
||||
|
||||
const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
if ((workspaceIDRight <= m_sActiveSwipe.pWorkspaceBegin->m_iID || (workspaceIDRight == workspaceIDLeft && workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID)) && *PSWIPENEW) {
|
||||
workspaceIDRight = m_sActiveSwipe.pWorkspaceBegin->m_iID > 0 ? m_sActiveSwipe.pWorkspaceBegin->m_iID + 1 : 1;
|
||||
}
|
||||
|
||||
auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); // not guaranteed if PSWIPENEW
|
||||
const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.vec();
|
||||
@@ -59,14 +70,21 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
// revert
|
||||
if (abs(m_sActiveSwipe.delta) < 2) {
|
||||
PWORKSPACEL->m_vRenderOffset.setValueAndWarp(Vector2D(0,0));
|
||||
if (PWORKSPACER)
|
||||
PWORKSPACER->m_vRenderOffset.setValueAndWarp(Vector2D(0,0));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0,0));
|
||||
} else {
|
||||
if (m_sActiveSwipe.delta < 0) {
|
||||
// to left
|
||||
if (VERTANIMS)
|
||||
PWORKSPACEL->m_vRenderOffset = Vector2D({0, -m_sActiveSwipe.pMonitor->vecSize.y});
|
||||
else
|
||||
PWORKSPACEL->m_vRenderOffset = Vector2D({-m_sActiveSwipe.pMonitor->vecSize.x, 0});
|
||||
} else {
|
||||
} else if (PWORKSPACER) {
|
||||
// to right
|
||||
if (VERTANIMS)
|
||||
PWORKSPACER->m_vRenderOffset = Vector2D({0, m_sActiveSwipe.pMonitor->vecSize.y});
|
||||
else
|
||||
PWORKSPACER->m_vRenderOffset = Vector2D({m_sActiveSwipe.pMonitor->vecSize.x, 0});
|
||||
}
|
||||
|
||||
@@ -84,6 +102,9 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
PWORKSPACEL->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValue(RENDEROFFSETMIDDLE);
|
||||
if (VERTANIMS)
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(0, m_sActiveSwipe.pMonitor->vecSize.y);
|
||||
else
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(m_sActiveSwipe.pMonitor->vecSize.x, 0);
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
@@ -94,14 +115,23 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
pSwitchedTo = PWORKSPACEL;
|
||||
} else {
|
||||
// switch to right
|
||||
const auto RENDEROFFSET = PWORKSPACER->m_vRenderOffset.vec();
|
||||
const auto RENDEROFFSET = PWORKSPACER ? PWORKSPACER->m_vRenderOffset.vec() : Vector2D();
|
||||
|
||||
if (PWORKSPACER)
|
||||
g_pKeybindManager->m_mDispatchers["workspace"]("[internal]" + std::to_string(workspaceIDRight));
|
||||
else
|
||||
g_pKeybindManager->m_mDispatchers["workspace"](std::to_string(workspaceIDRight)); // so that the ID is created properly
|
||||
|
||||
if (!PWORKSPACER)
|
||||
PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); // not guaranteed on PSWIPENEW
|
||||
|
||||
PWORKSPACER->m_vRenderOffset.setValue(RENDEROFFSET);
|
||||
PWORKSPACER->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValue(RENDEROFFSETMIDDLE);
|
||||
if (VERTANIMS)
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(0, -m_sActiveSwipe.pMonitor->vecSize.y);
|
||||
else
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(-m_sActiveSwipe.pMonitor->vecSize.x, 0);
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
@@ -115,6 +145,7 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||
|
||||
PWORKSPACEL->m_bForceRendering = false;
|
||||
if (PWORKSPACER)
|
||||
PWORKSPACER->m_bForceRendering = false;
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = false;
|
||||
|
||||
@@ -124,7 +155,7 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
|
||||
// apply alpha
|
||||
for (auto& ls : g_pCompositor->m_pLastMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
ls->alpha = pSwitchedTo->m_bHasFullscreenWindow ? 0.f : 255.f;
|
||||
ls->alpha = pSwitchedTo->m_bHasFullscreenWindow && pSwitchedTo->m_efFullscreenMode == FULLSCREEN_FULL ? 0.f : 255.f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,8 +165,12 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
|
||||
static auto *const PSWIPEDIST = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance")->intValue;
|
||||
static auto *const PSWIPEINVR = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_invert")->intValue;
|
||||
static auto *const PSWIPENEW = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_create_new")->intValue;
|
||||
static auto *const PSWIPEFOREVER = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_forever")->intValue;
|
||||
|
||||
m_sActiveSwipe.delta += *PSWIPEINVR ? -e->dx : e->dx;
|
||||
const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert";
|
||||
|
||||
m_sActiveSwipe.delta += VERTANIMS ? (*PSWIPEINVR ? -e->dy : e->dy) : (*PSWIPEINVR ? -e->dx : e->dx);
|
||||
|
||||
m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(e->dx)) / (m_sActiveSwipe.speedPoints + 1);
|
||||
m_sActiveSwipe.speedPoints++;
|
||||
@@ -144,7 +179,7 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
|
||||
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
|
||||
|
||||
if (workspaceIDLeft == INT_MAX || workspaceIDRight == INT_MAX || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID) {
|
||||
if ((workspaceIDLeft == INT_MAX || workspaceIDRight == INT_MAX || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID) && !*PSWIPENEW) {
|
||||
m_sActiveSwipe.pWorkspaceBegin = nullptr; // invalidate the swipe
|
||||
return;
|
||||
}
|
||||
@@ -153,8 +188,13 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
|
||||
m_sActiveSwipe.delta = std::clamp(m_sActiveSwipe.delta, (double)-*PSWIPEDIST, (double)*PSWIPEDIST);
|
||||
|
||||
if (((m_sActiveSwipe.pWorkspaceBegin->m_iID == workspaceIDLeft || m_sActiveSwipe.pWorkspaceBegin->m_iID == workspaceIDRight) && *PSWIPENEW && (m_sActiveSwipe.delta < 0)) || (m_sActiveSwipe.delta > 0 && g_pCompositor->getWindowsOnWorkspace(m_sActiveSwipe.pWorkspaceBegin->m_iID) == 0 && workspaceIDRight <= m_sActiveSwipe.pWorkspaceBegin->m_iID)) {
|
||||
m_sActiveSwipe.delta = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_sActiveSwipe.delta < 0) {
|
||||
if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID){
|
||||
if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID && !*PSWIPENEW){
|
||||
m_sActiveSwipe.delta = 0;
|
||||
return;
|
||||
}
|
||||
@@ -171,12 +211,28 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
PWORKSPACER->m_fAlpha.setValueAndWarp(0.f);
|
||||
}
|
||||
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x - m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
if (VERTANIMS) {
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.y - m_sActiveSwipe.pMonitor->vecSize.y));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.y));
|
||||
} else {
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x - m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
}
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDLeft);
|
||||
} else {
|
||||
if (workspaceIDRight < m_sActiveSwipe.pWorkspaceBegin->m_iID){
|
||||
if (workspaceIDRight < m_sActiveSwipe.pWorkspaceBegin->m_iID) {
|
||||
if (*PSWIPENEW) {
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||
|
||||
if (VERTANIMS)
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.y));
|
||||
else
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID);
|
||||
return;
|
||||
}
|
||||
m_sActiveSwipe.delta = 0;
|
||||
return;
|
||||
}
|
||||
@@ -193,8 +249,13 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
PWORKSPACEL->m_fAlpha.setValueAndWarp(0.f);
|
||||
}
|
||||
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x + m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
if (VERTANIMS) {
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.y + m_sActiveSwipe.pMonitor->vecSize.y));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.y));
|
||||
} else {
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x + m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
}
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDRight);
|
||||
}
|
||||
@@ -202,4 +263,11 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID);
|
||||
|
||||
if (*PSWIPEFOREVER) {
|
||||
if (abs(m_sActiveSwipe.delta) >= *PSWIPEDIST) {
|
||||
onSwipeEnd(nullptr);
|
||||
beginWorkspaceSwipe();
|
||||
}
|
||||
}
|
||||
}
|
@@ -219,7 +219,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||
void CInputManager::focusTablet(STablet* pTab, wlr_tablet_tool* pTool, bool motion) {
|
||||
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(pTool);
|
||||
|
||||
if (const auto PWINDOW = g_pCompositor->m_pLastWindow; g_pCompositor->windowValidMapped(PWINDOW)) {
|
||||
if (const auto PWINDOW = g_pCompositor->m_pLastWindow; PWINDOW) {
|
||||
const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal();
|
||||
|
||||
const auto LOCAL = CURSORPOS - PWINDOW->m_vRealPosition.goalv();
|
||||
|
@@ -2,42 +2,68 @@
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
void CInputManager::onTouchDown(wlr_touch_down_event* e) {
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, g_pCompositor->m_pLastMonitor->vecPosition.x + e->x * g_pCompositor->m_pLastMonitor->vecSize.x, g_pCompositor->m_pLastMonitor->vecPosition.y + e->y * g_pCompositor->m_pLastMonitor->vecSize.y);
|
||||
auto PMONITOR = g_pCompositor->getMonitorFromName(e->touch->output_name ? e->touch->output_name : "");
|
||||
|
||||
const auto PDEVIT = std::find_if(m_lTouchDevices.begin(), m_lTouchDevices.end(), [&](const STouchDevice& other) { return other.pWlrDevice == &e->touch->base; });
|
||||
|
||||
if (PDEVIT != m_lTouchDevices.end() && !PDEVIT->boundOutput.empty())
|
||||
PMONITOR = g_pCompositor->getMonitorFromName(PDEVIT->boundOutput);
|
||||
|
||||
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_pLastMonitor;
|
||||
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, PMONITOR->vecPosition.x + e->x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e->y * PMONITOR->vecSize.y);
|
||||
|
||||
refocus();
|
||||
|
||||
m_sTouchData.touchFocusWindow = nullptr;
|
||||
m_sTouchData.touchFocusWindow = m_pFoundWindowToFocus;
|
||||
m_sTouchData.touchFocusSurface = m_pFoundSurfaceToFocus;
|
||||
m_sTouchData.touchFocusLS = m_pFoundLSToFocus;
|
||||
|
||||
if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow)) {
|
||||
Vector2D local;
|
||||
if (g_pCompositor->m_pLastWindow->m_bIsX11) {
|
||||
local = g_pInputManager->getMouseCoordsInternal() - g_pCompositor->m_pLastWindow->m_vRealPosition.goalv();
|
||||
|
||||
if (m_sTouchData.touchFocusWindow) {
|
||||
if (m_sTouchData.touchFocusWindow->m_bIsX11) {
|
||||
local = g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchFocusWindow->m_vRealPosition.goalv();
|
||||
} else {
|
||||
g_pCompositor->vectorWindowToSurface(g_pInputManager->getMouseCoordsInternal(), g_pCompositor->m_pLastWindow, local);
|
||||
g_pCompositor->vectorWindowToSurface(g_pInputManager->getMouseCoordsInternal(), m_sTouchData.touchFocusWindow, local);
|
||||
}
|
||||
|
||||
m_sTouchData.touchSurfaceOrigin = g_pInputManager->getMouseCoordsInternal() - local;
|
||||
} else if (m_sTouchData.touchFocusLS) {
|
||||
local = g_pInputManager->getMouseCoordsInternal() - Vector2D(m_sTouchData.touchFocusLS->geometry.x, m_sTouchData.touchFocusLS->geometry.y) - g_pCompositor->m_pLastMonitor->vecPosition;
|
||||
|
||||
wlr_seat_touch_notify_down(g_pCompositor->m_sSeat.seat, g_pCompositor->m_pLastFocus, e->time_msec, e->touch_id, local.x, local.y);
|
||||
|
||||
m_sTouchData.touchFocusWindow = g_pCompositor->m_pLastWindow;
|
||||
m_sTouchData.touchSurfaceOrigin = g_pInputManager->getMouseCoordsInternal() - local;
|
||||
} else {
|
||||
return; // oops, nothing found.
|
||||
}
|
||||
|
||||
wlr_seat_touch_notify_down(g_pCompositor->m_sSeat.seat, m_sTouchData.touchFocusSurface, e->time_msec, e->touch_id, local.x, local.y);
|
||||
|
||||
wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat);
|
||||
}
|
||||
|
||||
void CInputManager::onTouchUp(wlr_touch_up_event* e){
|
||||
if (m_sTouchData.touchFocusWindow) {
|
||||
if (m_sTouchData.touchFocusSurface) {
|
||||
wlr_seat_touch_notify_up(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id);
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::onTouchMove(wlr_touch_motion_event* e){
|
||||
if (g_pCompositor->windowValidMapped(m_sTouchData.touchFocusWindow)) {
|
||||
if (m_sTouchData.touchFocusWindow && g_pCompositor->windowValidMapped(m_sTouchData.touchFocusWindow)) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusWindow->m_iMonitorID);
|
||||
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PMONITOR->vecPosition.x + e->x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e->y * PMONITOR->vecSize.y);
|
||||
|
||||
const auto local = g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchSurfaceOrigin;
|
||||
|
||||
wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id, local.x, local.y);
|
||||
} else if (m_sTouchData.touchFocusLS) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusLS->monitorID);
|
||||
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PMONITOR->vecPosition.x + e->x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e->y * PMONITOR->vecSize.y);
|
||||
|
||||
const auto local = g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchSurfaceOrigin;
|
||||
|
||||
wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id, local.x, local.y);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
globber = run_command('find', '-name', '*.cpp', check: true)
|
||||
globber = run_command('find', '.', '-name', '*.cpp', check: true)
|
||||
src = globber.stdout().strip().split('\n')
|
||||
|
||||
executable('Hyprland', src,
|
||||
@@ -18,7 +18,7 @@ executable('Hyprland', src,
|
||||
xcb_dep,
|
||||
|
||||
dependency('pixman-1'),
|
||||
dependency('GL'),
|
||||
dependency('gl', 'opengl'),
|
||||
dependency('threads')
|
||||
],
|
||||
install : true
|
||||
|
@@ -27,7 +27,6 @@ bool CFramebuffer::alloc(int w, int h) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iFb);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_cTex.m_iTexID, 0);
|
||||
|
||||
|
||||
// TODO: Allow this with gles2
|
||||
#ifndef GLES2
|
||||
if (m_pStencilTex) {
|
||||
@@ -74,8 +73,13 @@ void CFramebuffer::release() {
|
||||
|
||||
m_cTex.m_iTexID = 0;
|
||||
m_iFb = -1;
|
||||
m_Size = Vector2D();
|
||||
}
|
||||
|
||||
CFramebuffer::~CFramebuffer() {
|
||||
release();
|
||||
}
|
||||
|
||||
bool CFramebuffer::isAllocated() {
|
||||
return m_iFb != (GLuint)-1;
|
||||
}
|
@@ -12,6 +12,7 @@ public:
|
||||
void bind();
|
||||
void release();
|
||||
void reset();
|
||||
bool isAllocated();
|
||||
|
||||
Vector2D m_Position;
|
||||
Vector2D m_Size;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
#include "Shaders.hpp"
|
||||
#include "OpenGL.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
@@ -24,15 +25,9 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||
Debug::log(WARN, "!RENDERER: Using the legacy GLES2 renderer!");
|
||||
#endif
|
||||
|
||||
// End shaders
|
||||
|
||||
pixman_region32_init(&m_rOriginalDamageRegion);
|
||||
|
||||
// End
|
||||
|
||||
RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT), "Couldn't unset current EGL!");
|
||||
|
||||
// Done!
|
||||
}
|
||||
|
||||
GLuint CHyprOpenGLImpl::createProgram(const std::string& vert, const std::string& frag) {
|
||||
@@ -150,9 +145,7 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.proj = glGetUniformLocation(prog, "proj");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.color = glGetUniformLocation(prog, "color");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
@@ -166,7 +159,6 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.discardOpaque = glGetUniformLocation(prog, "discardOpaque");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
@@ -182,7 +174,6 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.discardOpaque = glGetUniformLocation(prog, "discardOpaque");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
@@ -198,7 +189,6 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shEXT.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.discardOpaque = glGetUniformLocation(prog, "discardOpaque");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
@@ -314,6 +304,7 @@ void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
|
||||
if(pixman_region32_not_empty(m_RenderData.pDamage))
|
||||
renderRectWithDamage(box, col, m_RenderData.pDamage, round);
|
||||
}
|
||||
|
||||
@@ -326,27 +317,31 @@ void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixm
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
|
||||
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glUseProgram(m_RenderData.pCurrentMonData->m_shQUAD.program);
|
||||
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shQUAD.proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shQUAD.proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shQUAD.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f);
|
||||
|
||||
const auto TOPLEFT = Vector2D(round, round);
|
||||
const auto BOTTOMRIGHT = Vector2D(box->width - round, box->height - round);
|
||||
const auto FULLSIZE = Vector2D(box->width, box->height);
|
||||
wlr_box transformedBox;
|
||||
wlr_box_transform(&transformedBox, box, wlr_output_transform_invert(m_RenderData.pMonitor->transform),
|
||||
m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
|
||||
const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y);
|
||||
const auto FULLSIZE = Vector2D(transformedBox.width, transformedBox.height);
|
||||
|
||||
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shQUAD.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shQUAD.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shQUAD.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shQUAD.radius, round);
|
||||
glUniform1i(m_RenderData.pCurrentMonData->m_shQUAD.primitiveMultisample, (int)(*PMULTISAMPLEEDGES == 1 && round != 0));
|
||||
@@ -357,7 +352,21 @@ void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixm
|
||||
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shQUAD.posAttrib);
|
||||
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shQUAD.texAttrib);
|
||||
|
||||
if (pixman_region32_not_empty(damage)) {
|
||||
if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) {
|
||||
pixman_region32_t damageClip;
|
||||
pixman_region32_init(&damageClip);
|
||||
pixman_region32_intersect_rect(&damageClip, damage, m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height);
|
||||
|
||||
if (pixman_region32_not_empty(&damageClip)) {
|
||||
PIXMAN_DAMAGE_FOREACH(&damageClip) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
scissor(&RECT);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
pixman_region32_fini(&damageClip);
|
||||
} else {
|
||||
PIXMAN_DAMAGE_FOREACH(damage) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
scissor(&RECT);
|
||||
@@ -389,6 +398,9 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||
|
||||
if (!pixman_region32_not_empty(m_RenderData.pDamage))
|
||||
return;
|
||||
|
||||
static auto *const PDIMINACTIVE = &g_pConfigManager->getConfigValuePtr("decoration:dim_inactive")->intValue;
|
||||
|
||||
// get transform
|
||||
@@ -398,9 +410,6 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
|
||||
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
|
||||
CShader* shader = nullptr;
|
||||
|
||||
@@ -428,23 +437,27 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
|
||||
glUseProgram(shader->program);
|
||||
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform1i(shader->tex, 0);
|
||||
glUniform1f(shader->alpha, alpha / 255.f);
|
||||
glUniform1i(shader->discardOpaque, (int)discardOpaque);
|
||||
|
||||
// round is in px
|
||||
// so we need to do some maf
|
||||
wlr_box transformedBox;
|
||||
wlr_box_transform(&transformedBox, pBox, wlr_output_transform_invert(m_RenderData.pMonitor->transform),
|
||||
m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
|
||||
const auto TOPLEFT = Vector2D(round, round);
|
||||
const auto BOTTOMRIGHT = Vector2D(pBox->width - round, pBox->height - round);
|
||||
const auto FULLSIZE = Vector2D(pBox->width, pBox->height);
|
||||
const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y);
|
||||
const auto FULLSIZE = Vector2D(transformedBox.width, transformedBox.height);
|
||||
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(shader->topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(shader->bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(shader->fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform2f(shader->topLeft, TOPLEFT.x, TOPLEFT.y);
|
||||
glUniform2f(shader->fullSize, FULLSIZE.x ,FULLSIZE.y);
|
||||
glUniform1f(shader->radius, round);
|
||||
glUniform1i(shader->primitiveMultisample, (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !noAA));
|
||||
|
||||
@@ -474,8 +487,22 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
glEnableVertexAttribArray(shader->posAttrib);
|
||||
glEnableVertexAttribArray(shader->texAttrib);
|
||||
|
||||
if (pixman_region32_not_empty(m_RenderData.pDamage)) {
|
||||
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) {
|
||||
if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) {
|
||||
pixman_region32_t damageClip;
|
||||
pixman_region32_init(&damageClip);
|
||||
pixman_region32_intersect_rect(&damageClip, damage, m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height);
|
||||
|
||||
if (pixman_region32_not_empty(&damageClip)) {
|
||||
PIXMAN_DAMAGE_FOREACH(&damageClip) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
scissor(&RECT);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
pixman_region32_fini(&damageClip);
|
||||
} else {
|
||||
PIXMAN_DAMAGE_FOREACH(damage) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
scissor(&RECT);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
@@ -505,8 +532,6 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
|
||||
// get the config settings
|
||||
static auto *const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_size")->intValue;
|
||||
@@ -541,7 +566,12 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||
glUseProgram(pShader->program);
|
||||
|
||||
// prep two shaders
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(pShader->proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform1f(pShader->radius, *PBLURSIZE * (a / 255.f)); // this makes the blursize change with a
|
||||
if (pShader == &m_RenderData.pCurrentMonData->m_shBLUR1)
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shBLUR1.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
|
||||
@@ -621,7 +651,7 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) {
|
||||
bool has = false;
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == pMonitor->activeWorkspace && w->m_bIsMapped && !w->m_bHidden && !w->m_bIsFloating) {
|
||||
if (w->m_iWorkspaceID == pMonitor->activeWorkspace && w->m_bIsMapped && !w->isHidden() && !w->m_bIsFloating) {
|
||||
has = true;
|
||||
break;
|
||||
}
|
||||
@@ -649,6 +679,8 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() {
|
||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 255, &fakeDamage, 0, false, true, false);
|
||||
m_bEndFrame = false;
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
|
||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
||||
|
||||
m_RenderData.pCurrentMonData->blurFBDirty = false;
|
||||
@@ -662,7 +694,7 @@ void CHyprOpenGLImpl::preWindowPass() {
|
||||
|
||||
bool hasWindows = false;
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == m_RenderData.pMonitor->activeWorkspace && !w->m_bHidden && w->m_bIsMapped && !w->m_bIsFloating) {
|
||||
if (w->m_iWorkspaceID == m_RenderData.pMonitor->activeWorkspace && !w->isHidden() && w->m_bIsMapped && !w->m_bIsFloating) {
|
||||
hasWindows = true;
|
||||
break;
|
||||
}
|
||||
@@ -682,16 +714,19 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
static auto *const PNOBLUROVERSIZED = &g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized")->intValue;
|
||||
static auto *const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
|
||||
|
||||
if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) || (m_pCurrentWindow && m_pCurrentWindow->m_sAdditionalConfigData.forceNoBlur)) {
|
||||
renderTexture(tex, pBox, a, round, false, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// make a damage region for this window
|
||||
pixman_region32_t damage;
|
||||
pixman_region32_init(&damage);
|
||||
pixman_region32_intersect_rect(&damage, m_RenderData.pDamage, pBox->x, pBox->y, pBox->width, pBox->height); // clip it to the box
|
||||
|
||||
if(!pixman_region32_not_empty(&damage))
|
||||
return;
|
||||
|
||||
if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) || (m_pCurrentWindow && m_pCurrentWindow->m_sAdditionalConfigData.forceNoBlur)) {
|
||||
renderTexture(tex, pBox, a, round, false, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// amazing hack: the surface has an opaque region!
|
||||
pixman_region32_t inverseOpaque;
|
||||
pixman_region32_init(&inverseOpaque);
|
||||
@@ -742,7 +777,6 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
|
||||
// stencil done. Render everything.
|
||||
wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
if (pixman_region32_not_empty(&damage)) {
|
||||
// render our great blurred FB
|
||||
static auto *const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur_ignore_opacity")->intValue;
|
||||
m_bEndFrame = true; // fix transformed
|
||||
@@ -756,7 +790,6 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
// draw window
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true, true);
|
||||
}
|
||||
|
||||
glStencilMask(-1);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
@@ -775,6 +808,9 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
|
||||
RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!");
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
|
||||
|
||||
if (!pixman_region32_not_empty(m_RenderData.pDamage) || (m_pCurrentWindow && m_pCurrentWindow->m_sAdditionalConfigData.forceNoBorder))
|
||||
return;
|
||||
|
||||
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
static auto *const PMULTISAMPLE = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||
|
||||
@@ -810,16 +846,18 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
|
||||
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glUseProgram(m_RenderData.pCurrentMonData->m_shBORDER1.program);
|
||||
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBORDER1.proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBORDER1.proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shBORDER1.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f);
|
||||
|
||||
const auto TOPLEFT = Vector2D(round, round);
|
||||
@@ -839,7 +877,21 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
|
||||
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBORDER1.posAttrib);
|
||||
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBORDER1.texAttrib);
|
||||
|
||||
if (pixman_region32_not_empty(m_RenderData.pDamage)) {
|
||||
if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) {
|
||||
pixman_region32_t damageClip;
|
||||
pixman_region32_init(&damageClip);
|
||||
pixman_region32_intersect_rect(&damageClip, m_RenderData.pDamage, m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height);
|
||||
|
||||
if (pixman_region32_not_empty(&damageClip)) {
|
||||
PIXMAN_DAMAGE_FOREACH(&damageClip) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
scissor(&RECT);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
pixman_region32_fini(&damageClip);
|
||||
} else {
|
||||
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
scissor(&RECT);
|
||||
@@ -853,6 +905,61 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::makeRawWindowSnapshot(CWindow* pWindow, CFramebuffer* pFramebuffer) {
|
||||
// we trust the window is valid.
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
wlr_output_attach_render(PMONITOR->output, nullptr);
|
||||
|
||||
// we need to "damage" the entire monitor
|
||||
// so that we render the entire window
|
||||
// this is temporary, doesnt mess with the actual wlr damage
|
||||
pixman_region32_t fakeDamage;
|
||||
pixman_region32_init(&fakeDamage);
|
||||
pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||
|
||||
begin(PMONITOR, &fakeDamage, true);
|
||||
|
||||
clear(CColor(0, 0, 0, 0)); // JIC
|
||||
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
// this is a hack but it works :P
|
||||
// we need to disable blur or else we will get a black background, as the shader
|
||||
// will try to copy the bg to apply blur.
|
||||
// this isn't entirely correct, but like, oh well.
|
||||
// small todo: maybe make this correct? :P
|
||||
const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
|
||||
g_pConfigManager->setInt("decoration:blur", 0);
|
||||
|
||||
// TODO: how can we make this the size of the window? setting it to window's size makes the entire screen render with the wrong res forever more. odd.
|
||||
glViewport(0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
|
||||
pFramebuffer->m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex;
|
||||
|
||||
pFramebuffer->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
|
||||
pFramebuffer->bind();
|
||||
|
||||
clear(CColor(0, 0, 0, 0)); // JIC
|
||||
|
||||
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, false, RENDER_PASS_ALL, true);
|
||||
|
||||
g_pConfigManager->setInt("decoration:blur", BLURVAL);
|
||||
|
||||
// restore original fb
|
||||
#ifndef GLES2
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_iCurrentOutputFb);
|
||||
#else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iCurrentOutputFb);
|
||||
#endif
|
||||
end();
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
|
||||
wlr_output_rollback(PMONITOR->output);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
// we trust the window is valid.
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
@@ -867,7 +974,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
|
||||
begin(PMONITOR, &fakeDamage, true);
|
||||
|
||||
clear(CColor(0,0,0,0)); // JIC
|
||||
clear(CColor(0, 0, 0, 0)); // JIC
|
||||
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
@@ -880,10 +987,9 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
|
||||
g_pConfigManager->setInt("decoration:blur", 0);
|
||||
|
||||
// render onto the window fb
|
||||
const auto PFRAMEBUFFER = &m_mWindowFramebuffers[pWindow];
|
||||
glViewport(0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y);
|
||||
|
||||
glViewport(0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y);
|
||||
const auto PFRAMEBUFFER = &m_mWindowFramebuffers[pWindow];
|
||||
|
||||
PFRAMEBUFFER->m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex;
|
||||
|
||||
@@ -897,12 +1003,12 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
|
||||
g_pConfigManager->setInt("decoration:blur", BLURVAL);
|
||||
|
||||
// restore original fb
|
||||
#ifndef GLES2
|
||||
// restore original fb
|
||||
#ifndef GLES2
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_iCurrentOutputFb);
|
||||
#else
|
||||
#else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iCurrentOutputFb);
|
||||
#endif
|
||||
#endif
|
||||
end();
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
@@ -937,9 +1043,14 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
const auto BLURLSSTATUS = pLayer->forceBlur;
|
||||
pLayer->forceBlur = false;
|
||||
|
||||
// draw the layer
|
||||
g_pHyprRenderer->renderLayer(pLayer, PMONITOR, &now);
|
||||
|
||||
pLayer->forceBlur = BLURLSSTATUS;
|
||||
|
||||
// TODO: WARN:
|
||||
// revise if any stencil-requiring rendering is done to the layers.
|
||||
|
||||
@@ -957,6 +1068,32 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
|
||||
wlr_output_rollback(PMONITOR->output);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::onWindowResizeStart(CWindow* pWindow) {
|
||||
static auto *const PTRANSITIONS = &g_pConfigManager->getConfigValuePtr("animations:use_resize_transitions")->intValue;
|
||||
static auto *const PENABLED = &g_pConfigManager->getConfigValuePtr("animations:enabled")->intValue;
|
||||
|
||||
if (!*PTRANSITIONS || !*PENABLED)
|
||||
return;
|
||||
|
||||
if (pWindow->m_vRealSize.vec().x < 5 || pWindow->m_vRealSize.vec().y < 5)
|
||||
return;
|
||||
|
||||
// make a fb and render a snapshot
|
||||
const auto PFRAMEBUFFER = &m_mWindowResizeFramebuffers[pWindow];
|
||||
makeRawWindowSnapshot(pWindow, PFRAMEBUFFER);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::onWindowResizeEnd(CWindow* pWindow) {
|
||||
static auto *const PTRANSITIONS = &g_pConfigManager->getConfigValuePtr("animations:use_resize_transitions")->intValue;
|
||||
static auto *const PENABLED = &g_pConfigManager->getConfigValuePtr("animations:enabled")->intValue;
|
||||
|
||||
if (!*PTRANSITIONS || !*PENABLED)
|
||||
return;
|
||||
|
||||
// remove the fb
|
||||
m_mWindowResizeFramebuffers.erase(pWindow);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render snapshot rect without begin()!");
|
||||
const auto PWINDOW = *pWindow;
|
||||
@@ -1040,6 +1177,9 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
|
||||
RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!");
|
||||
RASSERT(m_pCurrentWindow, "Tried to render shadow without a window!");
|
||||
|
||||
if (!pixman_region32_not_empty(m_RenderData.pDamage))
|
||||
return;
|
||||
|
||||
static auto *const PSHADOWPOWER = &g_pConfigManager->getConfigValuePtr("decoration:shadow_render_power")->intValue;
|
||||
|
||||
const auto SHADOWPOWER = std::clamp((int)*PSHADOWPOWER, 1, 4);
|
||||
@@ -1051,16 +1191,18 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
|
||||
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glUseProgram(m_RenderData.pCurrentMonData->m_shSHADOW.program);
|
||||
|
||||
#ifndef GLES2
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shSHADOW.proj, 1, GL_TRUE, glMatrix);
|
||||
#else
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shSHADOW.proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shSHADOW.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f * a);
|
||||
|
||||
const auto TOPLEFT = Vector2D(range + round, range + round);
|
||||
@@ -1081,7 +1223,21 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
|
||||
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib);
|
||||
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib);
|
||||
|
||||
if (pixman_region32_not_empty(m_RenderData.pDamage)) {
|
||||
if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) {
|
||||
pixman_region32_t damageClip;
|
||||
pixman_region32_init(&damageClip);
|
||||
pixman_region32_intersect_rect(&damageClip, m_RenderData.pDamage, m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height);
|
||||
|
||||
if (pixman_region32_not_empty(&damageClip)) {
|
||||
PIXMAN_DAMAGE_FOREACH(&damageClip) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
scissor(&RECT);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
pixman_region32_fini(&damageClip);
|
||||
} else {
|
||||
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
scissor(&RECT);
|
||||
@@ -1225,17 +1381,32 @@ void CHyprOpenGLImpl::clearWithTex() {
|
||||
static auto *const PRENDERTEX = &g_pConfigManager->getConfigValuePtr("misc:disable_hyprland_logo")->intValue;
|
||||
|
||||
if (!*PRENDERTEX) {
|
||||
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &m_mMonitorRenderResources[m_RenderData.pMonitor].backgroundTexBox, 255, 0);
|
||||
auto TEXIT = m_mMonitorBGTextures.find(m_RenderData.pMonitor);
|
||||
|
||||
if (TEXIT == m_mMonitorBGTextures.end()) {
|
||||
createBGTextureForMonitor(m_RenderData.pMonitor);
|
||||
TEXIT = m_mMonitorBGTextures.find(m_RenderData.pMonitor);
|
||||
}
|
||||
|
||||
if (TEXIT != m_mMonitorBGTextures.end())
|
||||
renderTexture(TEXIT->second, &m_mMonitorRenderResources[m_RenderData.pMonitor].backgroundTexBox, 255, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) {
|
||||
wlr_output_attach_render(pMonitor->output, nullptr);
|
||||
|
||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].mirrorFB.release();
|
||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].primaryFB.release();
|
||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].mirrorSwapFB.release();
|
||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].monitorMirrorFB.release();
|
||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].blurFB.release();
|
||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].stencilTex.destroyTexture();
|
||||
g_pHyprOpenGL->m_mMonitorBGTextures[pMonitor].destroyTexture();
|
||||
g_pHyprOpenGL->m_mMonitorRenderResources.erase(pMonitor);
|
||||
g_pHyprOpenGL->m_mMonitorBGTextures.erase(pMonitor);
|
||||
|
||||
Debug::log(LOG, "Monitor %s -> destroyed all render data", pMonitor->szName.c_str());
|
||||
|
||||
wlr_output_rollback(pMonitor->output);
|
||||
}
|
||||
|
@@ -12,11 +12,8 @@
|
||||
#include "Texture.hpp"
|
||||
#include "Framebuffer.hpp"
|
||||
|
||||
inline const float matrixFlip180[] = {
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, -1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
class CHyprRenderer;
|
||||
|
||||
inline const float fullVerts[] = {
|
||||
1, 0, // top right
|
||||
0, 0, // top left
|
||||
@@ -67,6 +64,8 @@ struct SCurrentRenderData {
|
||||
|
||||
Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
|
||||
wlr_box clipBox = {};
|
||||
};
|
||||
|
||||
class CHyprOpenGLImpl {
|
||||
@@ -86,6 +85,7 @@ public:
|
||||
void renderBorder(wlr_box*, const CColor&, int round);
|
||||
|
||||
void makeWindowSnapshot(CWindow*);
|
||||
void makeRawWindowSnapshot(CWindow*, CFramebuffer*);
|
||||
void makeLayerSnapshot(SLayerSurface*);
|
||||
void renderSnapshot(CWindow**);
|
||||
void renderSnapshot(SLayerSurface**);
|
||||
@@ -106,6 +106,9 @@ public:
|
||||
void saveBufferForMirror();
|
||||
void renderMirrored();
|
||||
|
||||
void onWindowResizeStart(CWindow*);
|
||||
void onWindowResizeEnd(CWindow*);
|
||||
|
||||
SCurrentRenderData m_RenderData;
|
||||
|
||||
GLint m_iCurrentOutputFb = 0;
|
||||
@@ -116,6 +119,7 @@ public:
|
||||
pixman_region32_t m_rOriginalDamageRegion; // used for storing the pre-expanded region
|
||||
|
||||
std::unordered_map<CWindow*, CFramebuffer> m_mWindowFramebuffers;
|
||||
std::unordered_map<CWindow*, CFramebuffer> m_mWindowResizeFramebuffers;
|
||||
std::unordered_map<SLayerSurface*, CFramebuffer> m_mLayerFramebuffers;
|
||||
std::unordered_map<CMonitor*, SMonitorRenderData> m_mMonitorRenderResources;
|
||||
std::unordered_map<CMonitor*, CTexture> m_mMonitorBGTextures;
|
||||
@@ -142,6 +146,8 @@ private:
|
||||
void renderSplash(cairo_t *const, cairo_surface_t *const, double);
|
||||
|
||||
void preBlurForCurrentMonitor();
|
||||
|
||||
friend class CHyprRenderer;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include "Renderer.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "linux-dmabuf-unstable-v1-protocol.h"
|
||||
|
||||
void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
const auto TEXTURE = wlr_surface_get_texture(surface);
|
||||
@@ -84,9 +85,7 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) {
|
||||
return true;
|
||||
|
||||
// if not, check if it maybe is active on a different monitor.
|
||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) ||
|
||||
(PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_bForceRendering) || // vvvv might be in animation progress vvvvv
|
||||
(PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */)
|
||||
return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors
|
||||
|
||||
if (pMonitor->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
@@ -169,6 +168,12 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWor
|
||||
pWorkspaceWindow = w.get();
|
||||
}
|
||||
|
||||
if (!pWorkspaceWindow) {
|
||||
// ?? happens sometimes...
|
||||
pWorkspace->m_bHasFullscreenWindow = false;
|
||||
return; // this will produce one blank frame. Oh well.
|
||||
}
|
||||
|
||||
// then render windows over fullscreen.
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || !w->m_bIsMapped)
|
||||
@@ -210,8 +215,8 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWor
|
||||
g_pHyprError->draw();
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode) {
|
||||
if (pWindow->m_bHidden)
|
||||
void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode, bool ignorePosition) {
|
||||
if (pWindow->isHidden())
|
||||
return;
|
||||
|
||||
if (pWindow->m_bFadingOut) {
|
||||
@@ -222,9 +227,15 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
const auto REALPOS = pWindow->m_vRealPosition.vec() + (pWindow->m_bPinned ? Vector2D{} : PWORKSPACE->m_vRenderOffset.vec());
|
||||
static const auto PNOFLOATINGBORDERS = &g_pConfigManager->getConfigValuePtr("general:no_border_on_floating")->intValue;
|
||||
static auto *const PNOFLOATINGBORDERS = &g_pConfigManager->getConfigValuePtr("general:no_border_on_floating")->intValue;
|
||||
static auto *const PTRANSITIONS = &g_pConfigManager->getConfigValuePtr("animations:use_resize_transitions")->intValue;
|
||||
|
||||
SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y};
|
||||
if (ignorePosition) {
|
||||
renderdata.x = pMonitor->vecPosition.x;
|
||||
renderdata.y = pMonitor->vecPosition.y;
|
||||
}
|
||||
|
||||
renderdata.surface = g_pXWaylandManager->getWindowSurface(pWindow);
|
||||
renderdata.w = std::max(pWindow->m_vRealSize.vec().x, 5.0); // clamp the size to min 5,
|
||||
renderdata.h = std::max(pWindow->m_vRealSize.vec().y, 5.0); // otherwise we'll have issues later with invalid boxes
|
||||
@@ -248,14 +259,61 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||
|
||||
g_pHyprOpenGL->m_pCurrentWindow = pWindow;
|
||||
|
||||
// render window decorations first, if not fullscreen full
|
||||
// clip box for animated offsets
|
||||
Vector2D offset;
|
||||
if (!ignorePosition && pWindow->m_bIsFloating) {
|
||||
if (PWORKSPACE->m_vRenderOffset.vec().x != 0) {
|
||||
const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
const auto PROGRESS = PWORKSPACE->m_vRenderOffset.vec().x / PWSMON->vecSize.x;
|
||||
const auto WINBB = pWindow->getFullWindowBoundingBox();
|
||||
|
||||
if (WINBB.x < PWSMON->vecPosition.x) {
|
||||
offset.x = (PWSMON->vecPosition.x - WINBB.x) * PROGRESS;
|
||||
} else if (WINBB.x + WINBB.width > PWSMON->vecPosition.x + PWSMON->vecSize.x) {
|
||||
offset.x = (WINBB.x + WINBB.width - PWSMON->vecPosition.x - PWSMON->vecSize.x) * PROGRESS;
|
||||
}
|
||||
} else if (PWORKSPACE->m_vRenderOffset.vec().y) {
|
||||
const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
const auto PROGRESS = PWORKSPACE->m_vRenderOffset.vec().y / PWSMON->vecSize.y;
|
||||
const auto WINBB = pWindow->getFullWindowBoundingBox();
|
||||
|
||||
if (WINBB.y < PWSMON->vecPosition.y) {
|
||||
offset.y = (PWSMON->vecPosition.y - WINBB.y) * PROGRESS;
|
||||
} else if (WINBB.y + WINBB.height > PWSMON->vecPosition.y + PWSMON->vecSize.y) {
|
||||
offset.y = (WINBB.y + WINBB.width - PWSMON->vecPosition.y - PWSMON->vecSize.y) * PROGRESS;
|
||||
}
|
||||
}
|
||||
|
||||
renderdata.x += offset.x;
|
||||
renderdata.y += offset.y;
|
||||
}
|
||||
|
||||
// render window decorations first, if not fullscreen full
|
||||
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) {
|
||||
if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
|
||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
|
||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f, offset);
|
||||
|
||||
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
|
||||
|
||||
if (*PTRANSITIONS && !ignorePosition /* ignorePosition probably means we are rendering the snapshot rn */) {
|
||||
const auto PFB = g_pHyprOpenGL->m_mWindowResizeFramebuffers.find(pWindow);
|
||||
|
||||
if (PFB != g_pHyprOpenGL->m_mWindowResizeFramebuffers.end() && PFB->second.isAllocated()) {
|
||||
wlr_box box = {renderdata.x - pMonitor->vecPosition.x, renderdata.y - pMonitor->vecPosition.y, renderdata.w, renderdata.h};
|
||||
|
||||
// adjust UV (remove when I figure out how to change the size of the fb)
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = {0, 0};
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = { pWindow->m_vRealSize.m_vBegun.x / pMonitor->vecPixelSize.x, pWindow->m_vRealSize.m_vBegun.y / pMonitor->vecPixelSize.y};
|
||||
|
||||
g_pHyprOpenGL->m_bEndFrame = true;
|
||||
g_pHyprOpenGL->renderTexture(PFB->second.m_cTex, &box, (1.f - pWindow->m_vRealSize.getPercent()) * 84.f, 0, false, true);
|
||||
g_pHyprOpenGL->m_bEndFrame = false;
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (renderdata.decorate && pWindow->m_sSpecialRenderData.border) {
|
||||
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
|
||||
@@ -289,6 +347,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->m_pCurrentWindow = nullptr;
|
||||
g_pHyprOpenGL->m_RenderData.clipBox = { 0, 0, 0, 0 };
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, timespec* time) {
|
||||
@@ -351,7 +410,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
|
||||
// Non-floating main
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
if (w->isHidden() && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
if (w->m_bIsFloating)
|
||||
@@ -369,7 +428,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
|
||||
// Non-floating popup
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
if (w->isHidden() && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
if (w->m_bIsFloating)
|
||||
@@ -387,7 +446,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
|
||||
// floating on top
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
if (w->isHidden() && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
if (!w->m_bIsFloating)
|
||||
@@ -405,7 +464,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
|
||||
// and then special
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
if (w->isHidden() && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
if (w->m_iWorkspaceID != SPECIAL_WORKSPACE_ID)
|
||||
@@ -501,6 +560,154 @@ void CHyprRenderer::calculateUVForWindowSurface(CWindow* pWindow, wlr_surface* p
|
||||
}
|
||||
}
|
||||
|
||||
void countSubsurfacesIter(wlr_surface* pSurface, int x, int y, void* data) {
|
||||
*(int*)data += 1;
|
||||
}
|
||||
|
||||
bool CHyprRenderer::attemptDirectScanout(CMonitor* pMonitor) {
|
||||
if (!pMonitor->mirrors.empty())
|
||||
return false; // do not DS if this monitor is being mirrored. Will break the functionality.
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pMonitor->activeWorkspace);
|
||||
|
||||
if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || g_pInputManager->m_sDrag.drag || g_pCompositor->m_sSeat.exclusiveClient)
|
||||
return false;
|
||||
|
||||
const auto PCANDIDATE = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
|
||||
if (!PCANDIDATE)
|
||||
return false; // ????
|
||||
|
||||
if (PCANDIDATE->m_fAlpha.fl() != 255.f || PCANDIDATE->m_fActiveInactiveAlpha.fl() != 1.f || PWORKSPACE->m_fAlpha.fl() != 255.f)
|
||||
return false;
|
||||
|
||||
if (PCANDIDATE->m_vRealSize.vec() != pMonitor->vecSize || PCANDIDATE->m_vRealPosition.vec() != pMonitor->vecPosition || PCANDIDATE->m_vRealPosition.isBeingAnimated() || PCANDIDATE->m_vRealSize.isBeingAnimated())
|
||||
return false;
|
||||
|
||||
if (!pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY].empty())
|
||||
return false;
|
||||
|
||||
for (auto& topls : pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
if (topls->alpha.fl() != 0.f)
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if it did not open any subsurfaces or shit
|
||||
int surfaceCount = 0;
|
||||
if (PCANDIDATE->m_bIsX11) {
|
||||
surfaceCount = 1;
|
||||
|
||||
// check opaque
|
||||
if (PCANDIDATE->m_uSurface.xwayland->has_alpha)
|
||||
return false;
|
||||
} else {
|
||||
wlr_xdg_surface_for_each_surface(PCANDIDATE->m_uSurface.xdg, countSubsurfacesIter, &surfaceCount);
|
||||
wlr_xdg_surface_for_each_popup_surface(PCANDIDATE->m_uSurface.xdg, countSubsurfacesIter, &surfaceCount);
|
||||
|
||||
if (!PCANDIDATE->m_uSurface.xdg->surface->opaque)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (surfaceCount != 1)
|
||||
return false;
|
||||
|
||||
const auto PSURFACE = g_pXWaylandManager->getWindowSurface(PCANDIDATE);
|
||||
|
||||
if (!PSURFACE || PSURFACE->current.scale != pMonitor->output->scale || PSURFACE->current.transform != pMonitor->output->transform)
|
||||
return false;
|
||||
|
||||
// finally, we should be GTG.
|
||||
wlr_output_attach_buffer(pMonitor->output, &PSURFACE->buffer->base);
|
||||
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
wlr_surface_send_frame_done(PSURFACE, &now);
|
||||
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, PSURFACE, pMonitor->output);
|
||||
|
||||
if (wlr_output_commit(pMonitor->output)) {
|
||||
if (!m_pLastScanout) {
|
||||
m_pLastScanout = PCANDIDATE;
|
||||
Debug::log(LOG, "Entered a direct scanout to %x: \"%s\"", PCANDIDATE, PCANDIDATE->m_szTitle.c_str());
|
||||
}
|
||||
} else {
|
||||
m_pLastScanout = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CHyprRenderer::setWindowScanoutMode(CWindow* pWindow) {
|
||||
if (!g_pCompositor->m_sWLRLinuxDMABuf)
|
||||
return;
|
||||
|
||||
if (!pWindow->m_bIsFullscreen) {
|
||||
wlr_linux_dmabuf_v1_set_surface_feedback(g_pCompositor->m_sWLRLinuxDMABuf, g_pXWaylandManager->getWindowSurface(pWindow), nullptr);
|
||||
Debug::log(LOG, "Scanout mode OFF set for %x", pWindow);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto RENDERERDRMFD = wlr_renderer_get_drm_fd(g_pCompositor->m_sWLRRenderer);
|
||||
const auto BACKENDDRMFD = wlr_backend_get_drm_fd(g_pCompositor->m_sWLRBackend);
|
||||
|
||||
if (RENDERERDRMFD < 0 || BACKENDDRMFD < 0)
|
||||
return;
|
||||
|
||||
auto deviceIDFromFD = [](int fd, unsigned long* deviceID) -> bool {
|
||||
struct stat stat;
|
||||
if (fstat(fd, &stat) != 0) {
|
||||
return false;
|
||||
}
|
||||
*deviceID = stat.st_rdev;
|
||||
return true;
|
||||
};
|
||||
|
||||
unsigned long rendererDevice, scanoutDevice;
|
||||
if (!deviceIDFromFD(RENDERERDRMFD, &rendererDevice) || !deviceIDFromFD(BACKENDDRMFD, &scanoutDevice))
|
||||
return;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
|
||||
const auto POUTPUTFORMATS = wlr_output_get_primary_formats(PMONITOR->output, WLR_BUFFER_CAP_DMABUF);
|
||||
if (!POUTPUTFORMATS)
|
||||
return;
|
||||
|
||||
const auto PRENDERERFORMATS = wlr_renderer_get_dmabuf_texture_formats(g_pCompositor->m_sWLRRenderer);
|
||||
wlr_drm_format_set scanoutFormats = { 0 };
|
||||
|
||||
if (!wlr_drm_format_set_intersect(&scanoutFormats, POUTPUTFORMATS, PRENDERERFORMATS))
|
||||
return;
|
||||
|
||||
const wlr_linux_dmabuf_feedback_v1_tranche TRANCHES[] = {
|
||||
{
|
||||
.target_device = scanoutDevice,
|
||||
.flags = ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT,
|
||||
.formats = &scanoutFormats
|
||||
}, {
|
||||
.target_device = rendererDevice,
|
||||
.formats = PRENDERERFORMATS
|
||||
}
|
||||
};
|
||||
|
||||
const wlr_linux_dmabuf_feedback_v1 FEEDBACK = {
|
||||
.main_device = rendererDevice,
|
||||
.tranches_len = sizeof(TRANCHES) / sizeof(TRANCHES[0]),
|
||||
.tranches = TRANCHES
|
||||
};
|
||||
|
||||
if (!wlr_linux_dmabuf_v1_set_surface_feedback(g_pCompositor->m_sWLRLinuxDMABuf, g_pXWaylandManager->getWindowSurface(pWindow), &FEEDBACK)) {
|
||||
Debug::log(ERR, "Error in scanout mode setting: wlr_linux_dmabuf_v1_set_surface_feedback returned false.");
|
||||
}
|
||||
|
||||
wlr_drm_format_set_finish(&scanoutFormats);
|
||||
|
||||
Debug::log(LOG, "Scanout mode ON set for %x", pWindow);
|
||||
}
|
||||
|
||||
void CHyprRenderer::outputMgrApplyTest(wlr_output_configuration_v1* config, bool test) {
|
||||
wlr_output_configuration_head_v1* head;
|
||||
bool noError = true;
|
||||
@@ -528,9 +735,17 @@ void CHyprRenderer::outputMgrApplyTest(wlr_output_configuration_v1* config, bool
|
||||
|
||||
commandForCfg += std::to_string(head->state.x) + "x" + std::to_string(head->state.y) + "," + std::to_string(head->state.scale);
|
||||
|
||||
if (!test)
|
||||
if (!test) {
|
||||
g_pConfigManager->parseKeyword("monitor", commandForCfg, true);
|
||||
|
||||
std::string transformStr = std::string(OUTPUT->name) + ",transform," + std::to_string((int)OUTPUT->transform);
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromName(OUTPUT->name);
|
||||
|
||||
if (!PMONITOR || OUTPUT->transform != PMONITOR->transform)
|
||||
g_pConfigManager->parseKeyword("monitor", transformStr);
|
||||
}
|
||||
|
||||
noError = wlr_output_test(OUTPUT);
|
||||
|
||||
if (!noError)
|
||||
@@ -728,9 +943,15 @@ void CHyprRenderer::arrangeLayersForMonitor(const int& monitor) {
|
||||
PMONITOR->vecReservedTopLeft = Vector2D(usableArea.x, usableArea.y) - PMONITOR->vecPosition;
|
||||
PMONITOR->vecReservedBottomRight = PMONITOR->vecSize - Vector2D(usableArea.width, usableArea.height) - PMONITOR->vecReservedTopLeft;
|
||||
|
||||
const auto ENTRY = g_pConfigManager->m_mAdditionalReservedAreas[PMONITOR->szName];
|
||||
PMONITOR->vecReservedTopLeft = PMONITOR->vecReservedTopLeft + Vector2D(ENTRY.left, ENTRY.top);
|
||||
PMONITOR->vecReservedBottomRight = PMONITOR->vecReservedBottomRight + Vector2D(ENTRY.right, ENTRY.bottom);
|
||||
auto ADDITIONALRESERVED = g_pConfigManager->m_mAdditionalReservedAreas.find(PMONITOR->szName);
|
||||
if (ADDITIONALRESERVED == g_pConfigManager->m_mAdditionalReservedAreas.end()) {
|
||||
ADDITIONALRESERVED = g_pConfigManager->m_mAdditionalReservedAreas.find(""); // glob wildcard
|
||||
}
|
||||
|
||||
if (ADDITIONALRESERVED != g_pConfigManager->m_mAdditionalReservedAreas.end()) {
|
||||
PMONITOR->vecReservedTopLeft = PMONITOR->vecReservedTopLeft + Vector2D(ADDITIONALRESERVED->second.left, ADDITIONALRESERVED->second.top);
|
||||
PMONITOR->vecReservedBottomRight = PMONITOR->vecReservedBottomRight + Vector2D(ADDITIONALRESERVED->second.right, ADDITIONALRESERVED->second.bottom);
|
||||
}
|
||||
|
||||
// damage the monitor if can
|
||||
if (PMONITOR->damage)
|
||||
@@ -808,7 +1029,7 @@ void CHyprRenderer::damageMonitor(CMonitor* pMonitor) {
|
||||
if (g_pCompositor->m_bUnsafeState || pMonitor->isMirror())
|
||||
return;
|
||||
|
||||
wlr_box damageBox = {0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y};
|
||||
wlr_box damageBox = { 0, 0, INT16_MAX, INT16_MAX };
|
||||
pMonitor->addDamage(&damageBox);
|
||||
|
||||
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
@@ -912,7 +1133,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
&& DELTALESSTHAN(pMonitor->refreshRate, pMonitorRule->refreshRate, 1)
|
||||
&& pMonitor->scale == pMonitorRule->scale
|
||||
&& ((DELTALESSTHAN(pMonitor->vecPosition.x, pMonitorRule->offset.x, 1) && DELTALESSTHAN(pMonitor->vecPosition.y, pMonitorRule->offset.y, 1)) || pMonitorRule->offset == Vector2D(-1, -1))
|
||||
&& pMonitor->transform == pMonitorRule->transform) {
|
||||
&& pMonitor->transform == pMonitorRule->transform
|
||||
&& pMonitorRule->enable10bit == pMonitor->enabled10bit) {
|
||||
|
||||
Debug::log(LOG, "Not applying a new rule to %s because it's already applied!", pMonitor->szName.c_str());
|
||||
return true;
|
||||
@@ -921,8 +1143,6 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
wlr_output_set_scale(pMonitor->output, pMonitorRule->scale);
|
||||
pMonitor->scale = pMonitorRule->scale;
|
||||
|
||||
pMonitor->vecPosition = pMonitorRule->offset;
|
||||
|
||||
// loop over modes and choose an appropriate one.
|
||||
if (pMonitorRule->resolution != Vector2D() && pMonitorRule->resolution != Vector2D(-1,-1) && pMonitorRule->resolution != Vector2D(-1,-2)) {
|
||||
if (!wl_list_empty(&pMonitor->output->modes)) {
|
||||
@@ -1117,22 +1337,37 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
}
|
||||
}
|
||||
|
||||
pMonitor->vrrActive = pMonitor->output->pending.adaptive_sync_enabled; // disabled here, will be tested in CConfigManager::ensureVRR()
|
||||
|
||||
wlr_output_set_transform(pMonitor->output, pMonitorRule->transform);
|
||||
pMonitor->transform = pMonitorRule->transform;
|
||||
|
||||
pMonitor->vecPixelSize = pMonitor->vecSize;
|
||||
|
||||
// Adaptive sync (VRR)
|
||||
wlr_output_enable_adaptive_sync(pMonitor->output, 1);
|
||||
if (pMonitorRule->enable10bit) {
|
||||
// try 10b RGB
|
||||
wlr_output_set_render_format(pMonitor->output, DRM_FORMAT_XRGB2101010);
|
||||
pMonitor->enabled10bit = true;
|
||||
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
Debug::log(LOG, "Pending output %s does not accept VRR.", pMonitor->output->name);
|
||||
wlr_output_enable_adaptive_sync(pMonitor->output, 0);
|
||||
}
|
||||
Debug::log(ERR, "Output %s -> 10 bit enabled, but failed format DRM_FORMAT_XRGB2101010. Trying BGR.", pMonitor->output->name);
|
||||
|
||||
// update renderer
|
||||
g_pHyprOpenGL->destroyMonitorResources(pMonitor);
|
||||
wlr_output_set_render_format(pMonitor->output, DRM_FORMAT_XBGR2101010);
|
||||
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
Debug::log(ERR, "Output %s -> 10 bit enabled, but failed format DRM_FORMAT_XBGR2101010. Falling back to 8 bit.", pMonitor->output->name);
|
||||
|
||||
wlr_output_set_render_format(pMonitor->output, DRM_FORMAT_XRGB8888);
|
||||
} else {
|
||||
Debug::log(LOG, "10bit format DRM_FORMAT_XBGR2101010 succeeded for output %s", pMonitor->output->name);
|
||||
}
|
||||
} else {
|
||||
Debug::log(LOG, "10bit format DRM_FORMAT_XRGB2101010 succeeded for output %s", pMonitor->output->name);
|
||||
}
|
||||
} else {
|
||||
wlr_output_set_render_format(pMonitor->output, DRM_FORMAT_XRGB8888);
|
||||
pMonitor->enabled10bit = false;
|
||||
}
|
||||
|
||||
if (!wlr_output_commit(pMonitor->output)) {
|
||||
Debug::log(ERR, "Couldn't commit output named %s", pMonitor->output->name);
|
||||
@@ -1144,7 +1379,14 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
pMonitor->vecSize = (Vector2D(x, y) / pMonitor->scale).floor();
|
||||
pMonitor->vecTransformedSize = Vector2D(x,y);
|
||||
|
||||
if (pMonitorRule->offset == Vector2D(-1, -1)) {
|
||||
if (pMonitor->createdByUser) {
|
||||
wlr_box transformedBox = { 0, 0, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y };
|
||||
wlr_box_transform(&transformedBox, &transformedBox, wlr_output_transform_invert(pMonitor->output->transform), (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y);
|
||||
|
||||
pMonitor->vecPixelSize = Vector2D(transformedBox.width, transformedBox.height);
|
||||
}
|
||||
|
||||
if (pMonitorRule->offset == Vector2D(-1, -1) && pMonitor->vecPosition == Vector2D(-1, -1)) {
|
||||
// let's find manually a sensible position for it, to the right.
|
||||
Vector2D finalPos;
|
||||
|
||||
@@ -1158,14 +1400,17 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
}
|
||||
|
||||
pMonitor->vecPosition = finalPos;
|
||||
} else if (pMonitorRule->offset != Vector2D(-1, -1)) {
|
||||
pMonitor->vecPosition = pMonitorRule->offset;
|
||||
}
|
||||
|
||||
if (!pMonitor->isMirror())
|
||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitor->vecPosition.x, (int)pMonitor->vecPosition.y);
|
||||
|
||||
wlr_output_enable(pMonitor->output, true);
|
||||
|
||||
// update renderer (here because it will call rollback, so we cannot do this before committing)
|
||||
g_pHyprOpenGL->destroyMonitorResources(pMonitor);
|
||||
|
||||
// updato wlroots
|
||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitor->vecPosition.x, (int)pMonitor->vecPosition.y);
|
||||
Events::listener_change(nullptr, nullptr);
|
||||
|
||||
// updato us
|
||||
|
@@ -44,13 +44,17 @@ public:
|
||||
void calculateUVForWindowSurface(CWindow*, wlr_surface*, bool main = false);
|
||||
|
||||
bool m_bWindowRequestedCursorHide = false;
|
||||
CWindow* m_pLastScanout = nullptr;
|
||||
|
||||
DAMAGETRACKINGMODES damageTrackingModeFromStr(const std::string&);
|
||||
|
||||
bool attemptDirectScanout(CMonitor*);
|
||||
void setWindowScanoutMode(CWindow*);
|
||||
|
||||
private:
|
||||
void arrangeLayerArray(CMonitor*, const std::vector<std::unique_ptr<SLayerSurface>>&, bool, wlr_box*);
|
||||
void renderWorkspaceWithFullscreenWindow(CMonitor*, CWorkspace*, timespec*);
|
||||
void renderWindow(CWindow*, CMonitor*, timespec*, bool, eRenderPassMode);
|
||||
void renderWindow(CWindow*, CMonitor*, timespec*, bool, eRenderPassMode, bool ignorePosition = false);
|
||||
void renderLayer(SLayerSurface*, CMonitor*, timespec*);
|
||||
void renderDragIcon(CMonitor*, timespec*);
|
||||
void renderIMEPopup(SIMEPopup*, CMonitor*, timespec*);
|
||||
|
@@ -14,7 +14,5 @@ GLint CShader::getUniformLocation(const std::string& unif) {
|
||||
|
||||
CShader::~CShader() {
|
||||
// destroy shader
|
||||
if (program) {
|
||||
glDeleteProgram(program);
|
||||
}
|
||||
}
|
@@ -48,7 +48,7 @@ void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(m_pWindow))
|
||||
return;
|
||||
@@ -59,10 +59,14 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
||||
return;
|
||||
|
||||
if (m_pWindow->m_sAdditionalConfigData.forceNoShadow)
|
||||
return;
|
||||
|
||||
static auto *const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||
static auto *const PSHADOWSIZE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_range")->intValue;
|
||||
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
static auto *const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
|
||||
static auto *const PSHADOWSCALE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_scale")->floatValue;
|
||||
static auto *const PSHADOWOFFSET = &g_pConfigManager->getConfigValuePtr("decoration:shadow_offset")->vecValue;
|
||||
|
||||
if (*PSHADOWS != 1)
|
||||
@@ -70,19 +74,48 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
|
||||
const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ? 0 : (m_pWindow->m_sAdditionalConfigData.rounding == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding);
|
||||
|
||||
// update the extents
|
||||
m_seExtents = {{*PSHADOWSIZE + 2 - PSHADOWOFFSET->x, *PSHADOWSIZE + 2 - PSHADOWOFFSET->y}, {*PSHADOWSIZE + 2 + PSHADOWOFFSET->x, *PSHADOWSIZE + 2 + PSHADOWOFFSET->y}};
|
||||
|
||||
// draw the shadow
|
||||
wlr_box fullBox = {m_vLastWindowPos.x - m_seExtents.topLeft.x + 2, m_vLastWindowPos.y - m_seExtents.topLeft.y + 2, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x - 4, m_vLastWindowSize.y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y - 4};
|
||||
wlr_box fullBox = { m_vLastWindowPos.x - *PSHADOWSIZE, m_vLastWindowPos.y - *PSHADOWSIZE,
|
||||
m_vLastWindowSize.x + 2.0 * *PSHADOWSIZE, m_vLastWindowSize.y + 2.0 * *PSHADOWSIZE };
|
||||
|
||||
fullBox.x -= pMonitor->vecPosition.x;
|
||||
fullBox.y -= pMonitor->vecPosition.y;
|
||||
|
||||
const float SHADOWSCALE = std::clamp(*PSHADOWSCALE, 0.f, 1.f);
|
||||
|
||||
// scale the box in relation to the center of the box
|
||||
const Vector2D NEWSIZE = Vector2D { fullBox.width, fullBox.height } * SHADOWSCALE;
|
||||
fullBox.width = NEWSIZE.x;
|
||||
fullBox.height = NEWSIZE.y;
|
||||
|
||||
if (PSHADOWOFFSET->x < 0) {
|
||||
fullBox.x += PSHADOWOFFSET->x;
|
||||
} else if (PSHADOWOFFSET->x > 0) {
|
||||
fullBox.x = m_vLastWindowPos.x + m_vLastWindowSize.x - fullBox.width + (SHADOWSCALE * *PSHADOWSIZE) + PSHADOWOFFSET->x - pMonitor->vecPosition.x;
|
||||
} else {
|
||||
fullBox.x += ((m_vLastWindowSize.x + 2.0 * *PSHADOWSIZE) - NEWSIZE.x) / 2.0;
|
||||
}
|
||||
|
||||
if (PSHADOWOFFSET->y < 0) {
|
||||
fullBox.y += PSHADOWOFFSET->y;
|
||||
} else if (PSHADOWOFFSET->y > 0) {
|
||||
fullBox.y = m_vLastWindowPos.y + m_vLastWindowSize.y - fullBox.height + (SHADOWSCALE * *PSHADOWSIZE) + PSHADOWOFFSET->y - pMonitor->vecPosition.y;
|
||||
} else {
|
||||
fullBox.y += ((m_vLastWindowSize.y + 2.0 * *PSHADOWSIZE) - NEWSIZE.y) / 2.0;
|
||||
}
|
||||
|
||||
m_seExtents = { { m_vLastWindowPos.x - fullBox.x - pMonitor->vecPosition.x + 2,
|
||||
m_vLastWindowPos.y - fullBox.y - pMonitor->vecPosition.y + 2},
|
||||
{ fullBox.x + fullBox.width + pMonitor->vecPosition.x - m_vLastWindowPos.x - m_vLastWindowSize.x + 2,
|
||||
fullBox.y + fullBox.height + pMonitor->vecPosition.y - m_vLastWindowPos.y - m_vLastWindowSize.y + 2} };
|
||||
|
||||
fullBox.x += offset.x;
|
||||
fullBox.y += offset.y;
|
||||
|
||||
if (fullBox.width < 1 || fullBox.height < 1)
|
||||
return; // don't draw invisible shadows
|
||||
|
||||
g_pHyprOpenGL->scissor((wlr_box *)nullptr);
|
||||
g_pHyprOpenGL->scissor((wlr_box*)nullptr);
|
||||
|
||||
if (*PSHADOWIGNOREWINDOW) {
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
@@ -9,7 +9,7 @@ public:
|
||||
|
||||
virtual SWindowDecorationExtents getWindowDecorationExtents();
|
||||
|
||||
virtual void draw(CMonitor*, float a);
|
||||
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
||||
|
||||
virtual eDecorationType getDecorationType();
|
||||
|
||||
|
@@ -63,11 +63,11 @@ void CHyprGroupBarDecoration::damageEntire() {
|
||||
g_pHyprRenderer->damageBox(&dm);
|
||||
}
|
||||
|
||||
void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
||||
// get how many bars we will draw
|
||||
int barsToDraw = m_dwGroupMembers.size();
|
||||
|
||||
if (barsToDraw < 1 || m_pWindow->m_bHidden || !g_pCompositor->windowValidMapped(m_pWindow))
|
||||
if (barsToDraw < 1 || m_pWindow->isHidden() || !g_pCompositor->windowValidMapped(m_pWindow))
|
||||
return;
|
||||
|
||||
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
||||
@@ -80,7 +80,7 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
int xoff = 0;
|
||||
|
||||
for (int i = 0; i < barsToDraw; ++i) {
|
||||
wlr_box rect = {m_vLastWindowPos.x + xoff - pMonitor->vecPosition.x, m_vLastWindowPos.y - m_seExtents.topLeft.y - pMonitor->vecPosition.y, BARW, 3};
|
||||
wlr_box rect = {m_vLastWindowPos.x + xoff - pMonitor->vecPosition.x + offset.x, m_vLastWindowPos.y - m_seExtents.topLeft.y - pMonitor->vecPosition.y + offset.y, BARW, 3};
|
||||
|
||||
if (rect.width <= 0 || rect.height <= 0)
|
||||
break;
|
||||
|
@@ -10,7 +10,7 @@ public:
|
||||
|
||||
virtual SWindowDecorationExtents getWindowDecorationExtents();
|
||||
|
||||
virtual void draw(CMonitor*, float a);
|
||||
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
||||
|
||||
virtual eDecorationType getDecorationType();
|
||||
|
||||
|
@@ -22,7 +22,7 @@ public:
|
||||
|
||||
virtual SWindowDecorationExtents getWindowDecorationExtents() = 0;
|
||||
|
||||
virtual void draw(CMonitor*, float a) = 0;
|
||||
virtual void draw(CMonitor*, float a, const Vector2D& offset = Vector2D()) = 0;
|
||||
|
||||
virtual eDecorationType getDecorationType() = 0;
|
||||
|
||||
|
@@ -4,139 +4,37 @@
|
||||
|
||||
inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVarName) -> std::string {
|
||||
return R"#(
|
||||
if (pixCoord[0] < topLeft[0]) {
|
||||
// we're close left
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
|
||||
if (ignoreCorners == 1) {
|
||||
// branchless baby!
|
||||
highp vec2 pixCoord = vec2(gl_FragCoord);
|
||||
pixCoord -= topLeft + fullSize * 0.5;
|
||||
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
|
||||
pixCoord -= fullSize * 0.5 - radius;
|
||||
|
||||
if (pixCoord.x + pixCoord.y > radius) {
|
||||
|
||||
float dist = length(pixCoord);
|
||||
|
||||
if (dist > radius)
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
float topLeftDistance = distance(topLeft, pixCoord);
|
||||
|
||||
if (topLeftDistance > radius - 1.0) {
|
||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||
discard;
|
||||
return;
|
||||
} else if (primitiveMultisample == 1) {
|
||||
if (primitiveMultisample == 1 && dist > radius - 1.0) {
|
||||
float distances = 0.0;
|
||||
if (distance(topLeft, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(topLeft, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(topLeft, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(topLeft, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
distances += float(length(pixCoord + vec2(0.25, 0.25)) < radius);
|
||||
distances += float(length(pixCoord + vec2(0.75, 0.25)) < radius);
|
||||
distances += float(length(pixCoord + vec2(0.25, 0.75)) < radius);
|
||||
distances += float(length(pixCoord + vec2(0.75, 0.75)) < radius);
|
||||
|
||||
if (distances == 0.0) {
|
||||
if (distances == 0.0)
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
distances = distances / 4.0;
|
||||
distances /= 4.0;
|
||||
|
||||
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
|
||||
}
|
||||
|
||||
}
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom
|
||||
|
||||
if (ignoreCorners == 1) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
|
||||
|
||||
if (topLeftDistance > radius - 1.0) {
|
||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||
discard;
|
||||
return;
|
||||
} else if (primitiveMultisample == 1) {
|
||||
float distances = 0.0;
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
|
||||
if (distances == 0.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
distances = distances / 4.0;
|
||||
|
||||
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pixCoord[0] > bottomRight[0]) {
|
||||
// we're close right
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
|
||||
if (ignoreCorners == 1) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
|
||||
|
||||
if (topLeftDistance > radius - 1.0) {
|
||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||
discard;
|
||||
return;
|
||||
} else if (primitiveMultisample == 1) {
|
||||
float distances = 0.0;
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
|
||||
if (distances == 0.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
distances = distances / 4.0;
|
||||
|
||||
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
|
||||
}
|
||||
}
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom
|
||||
|
||||
if (ignoreCorners == 1) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
float topLeftDistance = distance(bottomRight, pixCoord);
|
||||
|
||||
if (topLeftDistance > radius - 1.0) {
|
||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||
discard;
|
||||
return;
|
||||
} else if (primitiveMultisample == 1) {
|
||||
float distances = 0.0;
|
||||
if (distance(bottomRight, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(bottomRight, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(bottomRight, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(bottomRight, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
|
||||
if (distances == 0.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
distances = distances / 4.0;
|
||||
|
||||
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)#";
|
||||
)#";
|
||||
};
|
||||
|
||||
inline const std::string QUADVERTSRC = R"#(
|
||||
@@ -156,27 +54,20 @@ void main() {
|
||||
inline const std::string QUADFRAGSRC = R"#(
|
||||
precision mediump float;
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texcoord;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
void main() {
|
||||
if (radius == 0.0) {
|
||||
gl_FragColor = v_color;
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 pixColor = v_color;
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
if (radius > 0.0) {
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
})#";
|
||||
@@ -199,7 +90,6 @@ uniform sampler2D tex;
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
|
||||
@@ -209,16 +99,14 @@ uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) {
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
@@ -226,10 +114,7 @@ void main() {
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||
R"#(
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
@@ -241,7 +126,6 @@ uniform sampler2D tex;
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
|
||||
@@ -251,14 +135,11 @@ uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
void main() {
|
||||
|
||||
if (discardOpaque == 1 && alpha == 1.0) {
|
||||
if (discardOpaque == 1 && alpha == 1.0)
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||
|
||||
@@ -268,10 +149,7 @@ void main() {
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||
R"#(
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
@@ -293,6 +171,7 @@ void main() {
|
||||
sum += texture2D(tex, uv + halfpixel.xy * radius);
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||
sum += texture2D(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||
|
||||
gl_FragColor = sum / 8.0;
|
||||
}
|
||||
)#";
|
||||
@@ -332,7 +211,6 @@ uniform samplerExternalOES texture0;
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
|
||||
@@ -342,16 +220,13 @@ uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) {
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
@@ -359,10 +234,8 @@ void main() {
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||
R"#(
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
}
|
||||
)#";
|
||||
|
Submodule subprojects/wlroots updated: 50cc1ef4d3...627a5c5112
Reference in New Issue
Block a user