Compare commits

..

109 Commits

Author SHA1 Message Date
vaxerski
9f1d7f7fc7 properly scan for subsurfaces in fullscreen input refocus 2022-10-30 12:28:37 +00:00
vaxerski
6245c92bd0 avoid creating bound WS-es in moveWorkspaceToMonitor 2022-10-30 12:14:12 +00:00
vaxerski
2e32e202e9 set lastmonitor in onDisconnect 2022-10-29 22:45:01 +01:00
vaxerski
d994ad75e8 revert output smart layout reporting 2022-10-29 17:32:03 +01:00
vaxerski
2caebb3b10 fix default 0 in box passing test 2022-10-29 14:37:33 +01:00
vaxerski
05f3eebd96 avoid layout changes when unnecessary in applyMonitorRule 2022-10-29 12:24:44 +01:00
vaxerski
74d05d0adc ensure VRR for current display only in onConnect 2022-10-28 23:48:48 +01:00
vaxerski
341a0616aa avoid applying offset twice in onConnect 2022-10-28 23:23:23 +01:00
vaxerski
ea7f617df6 remove redundant check 2022-10-28 22:33:47 +01:00
vaxerski
644c64d79d lower IME errors to WARNs 2022-10-28 21:47:08 +01:00
vaxerski
d193d70ecf guard primaryFB tex in end() 2022-10-28 21:46:19 +01:00
vaxerski
9e227a52c0 allow cyclenext on null focus 2022-10-28 21:31:39 +01:00
vaxerski
1a767b021b fix minor focus oopsie 2022-10-28 20:12:17 +01:00
vaxerski
83e4006b16 properly find the constraint window 2022-10-28 19:35:02 +01:00
vaxerski
1759b0483c constrain mouse on focus change 2022-10-28 19:20:12 +01:00
vaxerski
f7174acc48 minor fixes for xwayland refocus 2022-10-28 19:18:10 +01:00
vaxerski
c2cd718e89 ignore pointer constraints in touch 2022-10-27 23:44:23 +01:00
Hilton Chain
c21808dd2d meson: Fallback to 'opengl' when 'GL' is not found.
This patch adds 'opengl' as a fallback to 'GL' for dependency lookup, to
link with libglvnd configured without X11 support.

For OpenGL, libglvnd provides two pkg-config files: `gl.pc' with GLX
support while `opengl.pc' not.  When building without X11 support, the
former won't be installed.
2022-10-28 00:50:58 +03:00
Vaxry
2c2e35eec1 Merge pull request #912 from riley-martin/hyprctl
Improve several hyprctl commands
2022-10-27 16:17:15 +01:00
Riley Martin
c064711d2a Improve hyprctl
Added better help for some hyprctl commands.
Failed commands should now 'fail' by returning a nonzero status to the shell

Fix typos
2022-10-27 10:39:21 -04:00
vaxerski
7d6ccca695 add 10bit support to displays 2022-10-27 13:26:47 +01:00
vaxerski
28c81fc71e add disabling pointer devices 2022-10-27 12:58:10 +01:00
Vaxry
d5a0610ea2 No xwayland overhaul (#920) 2022-10-27 11:26:35 +01:00
vaxerski
4aebb73de0 Added hyprctl cursorpos 2022-10-26 13:19:37 +01:00
vaxerski
46e51a81c4 unrestrict hyprctl message size 2022-10-26 13:11:05 +01:00
vaxerski
83ad59fae7 Allow 100%- for move rule 2022-10-26 12:34:26 +01:00
vaxerski
f9a7b6bf26 default focus_on_activate to false 2022-10-25 18:53:18 +01:00
vaxerski
cdb331076a allow # escaping in config 2022-10-25 14:32:25 +01:00
vaxerski
ba9a8a9ded unify LS unmap focus 2022-10-25 14:19:24 +01:00
vaxerski
34bd2cf803 respect wsbind in workspace silent rules 2022-10-25 10:30:25 +01:00
vaxerski
69f1d7b360 Rework workspace rules 2022-10-24 18:36:31 +01:00
vaxerski
e0bc952c83 minor fix to silent ws rules 2022-10-24 17:00:08 +01:00
vaxerski
cf869d9636 allow nofocus + workspace silent 2022-10-24 12:37:07 +01:00
vaxerski
077c1491a8 respect nofocus in candidate searching 2022-10-24 12:28:41 +01:00
vaxerski
c04563734e Rework candidate finding on close window 2022-10-24 12:25:36 +01:00
vaxerski
1d0d350fc3 fix silent + size windowrules 2022-10-24 12:03:15 +01:00
vaxerski
d55338a3f5 fix debug nest black screen 2022-10-24 11:58:07 +01:00
vaxerski
c6a3092b45 more safety around shutting down and mouse movements 2022-10-24 00:14:42 +01:00
vaxerski
10303259f7 always report sizes after a window unmap 2022-10-22 22:10:34 +01:00
Mihai Fufezan
3dca2fd61e Nix: override wayland-protocols 2022-10-23 00:01:55 +03:00
vaxerski
47eac4be1c disable adaptive sync with no_vfr off 2022-10-22 21:45:17 +01:00
vaxerski
2995867760 Transpose matrices on LEGACY_RENDERER 2022-10-22 21:10:49 +01:00
vaxerski
c132f5a91f [gha] bump flake inputs 2022-10-22 20:02:58 +00:00
vaxerski
24587492dd update wlroots dep 2022-10-22 21:01:45 +01:00
vaxerski
44cee0f5f8 more safety for focus requests 2022-10-22 16:45:33 +01:00
vaxerski
2c714eace5 handle activate requests 2022-10-22 16:43:47 +01:00
vaxerski
0d7d7a970d fix crash in event manager on hangup 2022-10-22 16:15:52 +01:00
Vaxry
3a27ef5e12 Merge pull request #893 from wael444/main
meson.build,CMakeLists.txt: use sh instead of bash
2022-10-22 11:57:36 +01:00
wael
6d273c8e44 CMakeLists.txt: use sh instead of bash 2022-10-22 09:23:52 +03:00
wael
c775153e01 meson.build: use sh instead of bash 2022-10-22 09:23:26 +03:00
vaxerski
b71d7c9007 minor workspace rule parsing fixes 2022-10-21 10:45:12 +01:00
vaxerski
ce5f025428 T1C: window dance compat 2022-10-20 22:38:49 +01:00
vaxerski
6df6aea1ba fix swipe with fullscreen maximized 2022-10-20 20:37:37 +01:00
Kainoa Kanter
ca2d2db0ef Add windowrules for noblur and noshadow (#884) 2022-10-20 20:36:27 +01:00
vaxerski
1ccb0b5f96 bump xdg ver to 5 2022-10-20 18:04:21 +01:00
vaxerski
c2545b3ae6 fix refocus on last window 2022-10-20 18:00:29 +01:00
vaxerski
dada872981 minor swipe on new fixes 2022-10-20 17:52:17 +01:00
vaxerski
1eec5161bd minor fix for swipes from empty workspaces 2022-10-20 15:47:35 +01:00
vaxerski
53c3644c29 fix minor anim issue with swipe new 2022-10-20 15:02:46 +01:00
vaxerski
6d66dde208 added swipe create new 2022-10-20 14:54:32 +01:00
vaxerski
1b349f79ac don't set custom mode in change 2022-10-19 22:12:02 +01:00
vaxerski
da8be82c9a Fix self-noding in changeWindowFloatingMode 2022-10-19 21:32:30 +01:00
vaxerski
8ffd244ef6 fix animate_manual_resizes with moves 2022-10-19 21:17:49 +01:00
vaxerski
bf9d31ce49 fix maximized windows not hiding tiled 2022-10-19 15:17:35 +01:00
vaxerski
98a32f5e52 render layer snapshot without blur 2022-10-19 11:00:59 +01:00
vaxerski
dc1737f128 allow glob wildcard in addreserved 2022-10-17 23:23:07 +01:00
Mihai Fufezan
48634d7e4a Nix & meson: 0.15.3 -> 0.16.0 2022-10-18 01:16:44 +03:00
vaxerski
ecf0cdaba4 a bit more default config nice addons 2022-10-17 16:59:52 +01:00
vaxerski
286cb90c48 ignore OR windows' size hints 2022-10-17 14:26:18 +01:00
vaxerski
3f77cde50e set XCURSOR_SIZE if not set in init 2022-10-17 14:01:04 +01:00
vaxerski
1145654987 default & example config overhaul 2022-10-17 13:48:21 +01:00
vaxerski
da4cfb9c32 use size hints when available in xwayland default geom 2022-10-17 11:18:45 +01:00
vaxerski
58375bc87a Add support for rgba() and rgb() colors in the config 2022-10-16 22:26:02 +01:00
Vaxry
83d99ce5bd Merge pull request #857 from K1llf0rce/max_size_rule
add maxsize window rule
2022-10-15 20:09:14 +01:00
K1llf0rce
dca30815b0 add maxsize window rule 2022-10-15 17:04:57 +02:00
vaxerski
edeb759bb1 add loose focus behavior 2022-10-15 14:13:21 +01:00
Mihai Fufezan
610d4d9473 Nix: update nixpkgs 2022-10-15 02:21:13 +03:00
Mihai Fufezan
f30e572e00 Nix & meson: 0.15.0beta -> 0.15.3beta
Nix: remove merged libdrm update
2022-10-15 01:40:25 +03:00
vaxerski
34cd8b125a rework focus system to be more safe and faster 2022-10-14 20:46:32 +01:00
vaxerski
b0544dbfff remove old log 2022-10-14 14:25:28 +01:00
vaxerski
a7bdfc06ca added bringactivetotop dispatcher 2022-10-14 14:22:31 +01:00
Narice
7e7cb40909 Nix modules: fix environment variables 2022-10-14 16:19:14 +03:00
vaxerski
724fa4a7d4 add touch binding to output 2022-10-14 12:38:44 +01:00
Vaxry
cee0645fd1 Merge pull request #813 from histausse/touch_dev_rotation
Add input:touchdevice:transform config
2022-10-14 12:26:31 +01:00
vaxerski
df9409b8a2 rename transform in DC to touch_transform 2022-10-14 12:23:11 +01:00
Vaxry
f274a70edf Merge pull request #852 from NotAShelf/patch-1
add `PKGBUILD` to ignored files
2022-10-14 11:11:28 +01:00
NotAShelf
ef24a27ade add PKGBUILD to ignored files 2022-10-14 11:46:34 +03:00
vaxerski
670d6ce8f4 fix windowsOut disabled with fadeOut enabled 2022-10-13 21:32:28 +01:00
Vaxry
f3917f2122 Merge pull request #844 from brodi1/hyprctl-json-fix
fix invalid json output by adding a missing comma
2022-10-13 15:32:46 +01:00
Brodi
5d6e56b67c fix invalid json output by adding a missing comma 2022-10-13 16:21:58 +02:00
vaxerski
624303bfb9 check for same workspace in workspace rule 2022-10-13 15:19:30 +01:00
vaxerski
eb3c132fc5 set workspace name in previous 2022-10-13 15:17:16 +01:00
vaxerski
170def35d7 simplify shouldRenderWindow and fix one cond 2022-10-12 18:37:11 +01:00
vaxerski
2ee9fb0675 don't recalc offset on monitor reload offset auto 2022-10-12 15:16:31 +01:00
vaxerski
1396d2a39b fix crash in renderWorkspaceWithFullscreenWindow 2022-10-11 20:29:51 +01:00
vaxerski
7ecc41db9c unsetenv on no XWayland 2022-10-11 12:00:06 +01:00
vaxerski
7ffe4eda12 [gha] build man pages 2022-10-11 10:58:53 +00:00
Simplykyle
25756afad5 Add debug coredump instructions (#812) 2022-10-11 11:58:26 +01:00
vaxerski
8880298f50 [gha] bump flake inputs 2022-10-11 09:33:36 +00:00
vaxerski
d89355f0a6 update wlroots 2022-10-11 10:32:11 +01:00
Vaxry
ae91f6610f Merge pull request #825 from Dickby/Fix_nproc_in_Makefile
Replace $(nproc) with $(shell nproc).
2022-10-10 22:36:10 +01:00
Felix Dick
6e7143e0f5 Replace $(nproc) with $(shell nproc). 2022-10-10 17:13:56 +02:00
Vaxry
f55f56f260 Merge pull request #823 from Dickby/simplify_matrix_calculations
Simplify matrix calculations
2022-10-10 15:59:25 +01:00
Histausse
6287f2b71b use static for transformation matrices 2022-10-10 12:52:12 +02:00
Felix Dick
7e781f24c5 Merge branch 'main' into simplify_matrix_calculations 2022-10-10 02:45:40 +02:00
Felix Dick
3bf7c5aea1 Change matrixProjection function stop use matrixFlip180 everywhere. 2022-10-10 01:35:42 +02:00
Felix Dick
092dbda88a Let openGL transpose the matrixes for us. 2022-10-10 01:32:04 +02:00
Histausse
406b2fe6dc Add additionnal matrices and rename config var 2022-10-09 00:45:34 +02:00
Histausse
32ae0c51f0 Add input:touchdevice:td_rotation config
Add support for touch device roation. The rotation is
set globally with `input:touchdevice:td_rotation config` and by
device with `td_rotation` in a device block.
2022-10-08 15:25:46 +02:00
57 changed files with 1497 additions and 570 deletions

View File

@@ -62,7 +62,7 @@ jobs:
run: | run: |
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
pacman --noconfirm --noprogressbar -Syyu 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 - name: Checkout Hyprland
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
@@ -73,13 +73,23 @@ jobs:
-Ddefault_library=static -Ddefault_library=static
- name: Compile - name: Compile
run: ninja -C obj-x86_64-pc-linux-gnu run: ninja -C obj-x86_64-pc-linux-gnu
# - name: Compress artifacts
# run: | noxwayland:
# mkdir x86_64-pc-linux-gnu name: "Build Hyprland in pure Wayland (Arch)"
# DESTDIR=$PWD/x86_64-pc-linux-gnu meson install -C obj-x86_64-pc-linux-gnu --tags runtime runs-on: ubuntu-latest
# tar -cvf x86_64-pc-linux-gnu.tar.xz x86_64-pc-linux-gnu container:
# - name: Upload artifacts image: archlinux
# uses: actions/upload-artifact@v3 steps:
# with: - name: Download dependencies
# name: Build artifacts (x86_64-pc-linux-gnu) run: |
# path: x86_64-pc-linux-gnu.tar.xz 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

2
.gitignore vendored
View File

@@ -25,3 +25,5 @@ hyprctl/hyprctl
gmon.out gmon.out
*.out *.out
*.tar.gz *.tar.gz
PKGBUILD

View File

@@ -5,7 +5,7 @@ project(Hyprland
set(CMAKE_MESSAGE_LOG_LEVEL "STATUS") set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
message(STATUS "Configuring Hyprland!") message(STATUS "Gathering git info")
# Get git info # Get git info
# hash and branch # hash and branch
@@ -22,27 +22,38 @@ execute_process(
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process( 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"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_MESSAGE OUTPUT_VARIABLE GIT_COMMIT_MESSAGE
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process( 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} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_DIRTY OUTPUT_VARIABLE GIT_DIRTY
OUTPUT_STRIP_TRAILING_WHITESPACE) 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/include/")
include_directories(. PRIVATE "subprojects/wlroots/build/include/") include_directories(. PRIVATE "subprojects/wlroots/build/include/")
add_compile_options(-std=c++23 -DWLR_USE_UNSTABLE ) 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) 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(Threads REQUIRED)
find_package(PkgConfig 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") file(GLOB_RECURSE SRCFILES "src/*.cpp")
@@ -56,15 +67,11 @@ ENDIF(LEGACY_RENDERER MATCHES true)
IF(NO_XWAYLAND MATCHES true) IF(NO_XWAYLAND MATCHES true)
message(STATUS "Using the NO_XWAYLAND flag, disabling XWayland!") message(STATUS "Using the NO_XWAYLAND flag, disabling XWayland!")
add_definitions( -DNO_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() ELSE()
add_compile_options( -O3 ) message(STATUS "XWAYLAND Enabled (NO_XWAYLAND not defined) checking deps...")
message(STATUS "Configuring Hyprland in Release with CMake!") pkg_check_modules(xcbdep REQUIRED xcb)
ENDIF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) 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_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"")
target_compile_definitions(Hyprland PRIVATE "-DGIT_BRANCH=\"${GIT_BRANCH}\"") target_compile_definitions(Hyprland PRIVATE "-DGIT_BRANCH=\"${GIT_BRANCH}\"")
@@ -77,6 +84,8 @@ set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack) include(CPack)
message(STATUS "Setting link libraries")
target_link_libraries(Hyprland PkgConfig::deps) target_link_libraries(Hyprland PkgConfig::deps)
target_link_libraries(Hyprland target_link_libraries(Hyprland
@@ -90,6 +99,8 @@ target_link_libraries(Hyprland
) )
IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) 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_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_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") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg -no-pie -fno-builtin")

View File

@@ -93,19 +93,19 @@ wlr-output-power-management-unstable-v1-protocol.o: wlr-output-power-management-
legacyrenderer: legacyrenderer:
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DLEGACY_RENDERER:STRING=true -H./ -B./build -G Ninja 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: legacyrendererdebug:
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DLEGACY_RENDERER:STRING=true -H./ -B./build -G Ninja 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: release:
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -H./ -B./build -G Ninja 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: debug:
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -H./ -B./build -G Ninja 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: clear:
rm -rf build rm -rf build

View File

@@ -1,6 +1,6 @@
.\" Automatically generated by Pandoc 2.5 .\" 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 .hy
.SH NAME .SH NAME
.PP .PP

View File

@@ -57,3 +57,15 @@ coredumpctl info [PID]
``` ```
where `[PID]` is the PID you remembered. 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.

View File

@@ -1,6 +1,6 @@
.\" Automatically generated by Pandoc 2.5 .\" 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 .hy
.SH NAME .SH NAME
.PP .PP

View File

@@ -1,117 +1,158 @@
# This is an example Hyprland config file. # 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. # Refer to the wiki for more information.
# #
# Please note not all available settings / options are set here. # 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 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 { input {
kb_file= kb_layout = us
kb_layout= kb_variant =
kb_variant= kb_model =
kb_model= kb_options =
kb_options= kb_rules =
kb_rules=
follow_mouse=1 follow_mouse = 1
touchpad { 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 { general {
gaps_in=5 # See https://wiki.hyprland.org/Configuring/Variables/ for more
gaps_out=20
border_size=2
col.active_border=0x66ee1111
col.inactive_border=0x66333333
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 { decoration {
rounding=10 # See https://wiki.hyprland.org/Configuring/Variables/ for more
blur=1
blur_size=3 # minimum 1 rounding = 10
blur_passes=1 # minimum 1 blur = yes
blur_new_optimizations=1 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 { animations {
enabled=1 enabled = yes
animation=windows,1,7,default
animation=border,1,10,default # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
animation=fade,1,10,default
animation=workspaces,1,6,default 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 { 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 { gestures {
workspace_swipe=no # See https://wiki.hyprland.org/Configuring/Variables/ for more
workspace_swipe = off
} }
# example window rules # Example per-device config
# for windows named/classed as abc and xyz # See https://wiki.hyprland.org/Configuring/Keywords/#executing for more
#windowrule=move 69 420,abc device:epic mouse V1 {
#windowrule=size 420 69,abc sensitivity = -0.5
#windowrule=tile,xyz }
#windowrule=float,abc
#windowrule=pseudo,abc
#windowrule=monitor 0,xyz
# some nice mouse binds # Example windowrule v1
bindm=SUPER,mouse:272,movewindow # windowrule = float, ^(kitty)$
bindm=SUPER,mouse:273,resizewindow # 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 # See https://wiki.hyprland.org/Configuring/Keywords/ for more
bind=SUPER,right,movefocus,r $mainMod = SUPER
bind=SUPER,up,movefocus,u
bind=SUPER,down,movefocus,d
bind=SUPER,1,workspace,1 # Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
bind=SUPER,2,workspace,2 bind = $mainMod, Q, exec, kitty
bind=SUPER,3,workspace,3 bind = $mainMod, C, killactive,
bind=SUPER,4,workspace,4 bind = $mainMod, M, exit,
bind=SUPER,5,workspace,5 bind = $mainMod, E, exec, dolphin
bind=SUPER,6,workspace,6 bind = $mainMod, V, togglefloating,
bind=SUPER,7,workspace,7 bind = $mainMod, R, exec, wofi --show drun
bind=SUPER,8,workspace,8 bind = $mainMod, P, pseudo, # dwindle
bind=SUPER,9,workspace,9 bind = $mainMod, J, togglesplit, # dwindle
bind=SUPER,0,workspace,10
bind=ALT,1,movetoworkspace,1 # Move focus with mainMod + arrow keys
bind=ALT,2,movetoworkspace,2 bind = $mainMod, left, movefocus, l
bind=ALT,3,movetoworkspace,3 bind = $mainMod, right, movefocus, r
bind=ALT,4,movetoworkspace,4 bind = $mainMod, up, movefocus, u
bind=ALT,5,movetoworkspace,5 bind = $mainMod, down, movefocus, d
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
bind=SUPER,mouse_down,workspace,e+1 # Switch workspaces with mainMod + [0-9]
bind=SUPER,mouse_up,workspace,e-1 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
View File

@@ -2,11 +2,11 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1665259268, "lastModified": 1666377499,
"narHash": "sha256-ONFhHBLv5nZKhwV/F2GOH16197PbvpyWhoO0AOyktkU=", "narHash": "sha256-dZZCGvWcxc7oGnUgFVf0UeNHsJ4VhkTM0v5JRe8EwR8=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c5924154f000e6306030300592f4282949b2db6c", "rev": "301aada7a64812853f2e2634a530ef5d34505048",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -26,11 +26,11 @@
"flake": false, "flake": false,
"locked": { "locked": {
"host": "gitlab.freedesktop.org", "host": "gitlab.freedesktop.org",
"lastModified": 1665331677, "lastModified": 1666466001,
"narHash": "sha256-3Dh1i11mHK80jx5figC1oh1V0rCjieh0Mj+MajXdbPw=", "narHash": "sha256-ZjxAnqtcGmHQHKL1Z9sIraDnzIqrJleWcJXfPtzAm74=",
"owner": "wlroots", "owner": "wlroots",
"repo": "wlroots", "repo": "wlroots",
"rev": "ab8341975e62b1f668d8c9779ec8e72d04718a99", "rev": "c2d2773df57750081b16d56da13b5015d752cbd7",
"type": "gitlab" "type": "gitlab"
}, },
"original": { "original": {

View File

@@ -20,35 +20,24 @@
"aarch64-linux" "aarch64-linux"
"x86_64-linux" "x86_64-linux"
]; ];
pkgsFor = genSystems (system:
import nixpkgs { pkgsFor = genSystems (system: import nixpkgs {
inherit system; inherit system;
overlays = [ overlays = [(_: prev: {
(_: prev: { wayland-protocols = prev.wayland-protocols.overrideAttrs (old: rec {
libdrm = prev.libdrm.overrideAttrs (old: rec { version = "1.27";
version = "2.4.113";
src = prev.fetchurl { src = prev.fetchurl {
url = "https://dri.freedesktop.org/${old.pname}/${old.pname}-${version}.tar.xz"; url = "https://gitlab.freedesktop.org/wayland/${old.pname}/-/releases/${version}/downloads/${old.pname}-${version}.tar.xz";
sha256 = "sha256-f9frKWf2O+tGBvItUOJ32ZNIDQXvdd2Iqb2OZ3Mj5eE="; hash = "sha256-kEbxCkJdTioAlloDrPtrP7V1pWUDrHLCuGghxpZTN1w=";
}; };
mesonFlags =
[
"-Dinstall-test-programs=true"
"-Domap=enabled"
"-Dcairo-tests=disabled"
]
++ lib.optionals prev.stdenv.hostPlatform.isAarch [
"-Dtegra=enabled"
"-Detnaviv=enabled"
];
}); });
}) })];
];
}); });
mkDate = longDate: (lib.concatStringsSep "-" [ mkDate = longDate: (lib.concatStringsSep "-" [
(__substring 0 4 longDate) (builtins.substring 0 4 longDate)
(__substring 4 2 longDate) (builtins.substring 4 2 longDate)
(__substring 6 2 longDate) (builtins.substring 6 2 longDate)
]); ]);
in { in {
overlays.default = _: prev: rec { overlays.default = _: prev: rec {
@@ -58,7 +47,7 @@
}; };
hyprland = prev.callPackage ./nix/default.nix { hyprland = prev.callPackage ./nix/default.nix {
stdenv = prev.gcc12Stdenv; stdenv = prev.gcc12Stdenv;
version = "0.15.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty"); version = "0.16.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
wlroots = wlroots-hyprland; wlroots = wlroots-hyprland;
}; };
hyprland-debug = hyprland.override {debug = true;}; hyprland-debug = hyprland.override {debug = true;};

View File

@@ -36,6 +36,7 @@ commands:
reload reload
setcursor setcursor
getoption getoption
cursorpos
flags: flags:
-j -> output in JSON -j -> output in JSON
@@ -80,6 +81,7 @@ void request(std::string arg) {
return; return;
} }
std::string reply = "";
char buffer[8192] = {0}; char buffer[8192] = {0};
sizeWritten = read(SERVERSOCKET, buffer, 8192); sizeWritten = read(SERVERSOCKET, buffer, 8192);
@@ -89,9 +91,20 @@ void request(std::string arg) {
return; 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); close(SERVERSOCKET);
std::cout << std::string(buffer); std::cout << reply;
} }
void requestHyprpaper(std::string arg) { void requestHyprpaper(std::string arg) {
@@ -145,11 +158,12 @@ void requestHyprpaper(std::string arg) {
std::cout << std::string(buffer); std::cout << std::string(buffer);
} }
void dispatchRequest(int argc, char** argv) { int dispatchRequest(int argc, char** argv) {
if (argc < 4) { if (argc < 4) {
std::cout << "dispatch requires 2 params"; std::cout << "Usage: hyprctl dispatch <dispatcher> <arg>\n\
return; Execute a hyprland keybind dispatcher with the given argument";
return 1;
} }
std::string rq = "/dispatch"; std::string rq = "/dispatch";
@@ -158,12 +172,14 @@ void dispatchRequest(int argc, char** argv) {
rq += " " + std::string(argv[i]); rq += " " + std::string(argv[i]);
request(rq); request(rq);
return 0;
} }
void keywordRequest(int argc, char** argv) { int keywordRequest(int argc, char** argv) {
if (argc < 4) { if (argc < 4) {
std::cout << "keyword requires 2 params"; std::cout << "Usage: hyprctl keyword <keyword> <arg>\n\
return; Execute a hyprland keyword with the given argument";
return 1;
} }
std::string rq = "/keyword"; std::string rq = "/keyword";
@@ -172,28 +188,33 @@ void keywordRequest(int argc, char** argv) {
rq += " " + std::string(argv[i]); rq += " " + std::string(argv[i]);
request(rq); request(rq);
return 0;
} }
void hyprpaperRequest(int argc, char** argv) { int hyprpaperRequest(int argc, char** argv) {
if (argc < 4) { if (argc < 4) {
std::cout << "hyprpaper requires 2 params"; std::cout << "Usage: hyprctl hyprpaper <command> <arg>\n\
return; Execute a hyprpaper command with the given argument";
return 1;
} }
std::string rq = std::string(argv[2]) + " " + std::string(argv[3]); std::string rq = std::string(argv[2]) + " " + std::string(argv[3]);
requestHyprpaper(rq); requestHyprpaper(rq);
return 0;
} }
void setcursorRequest(int argc, char** argv) { int setcursorRequest(int argc, char** argv) {
if (argc < 4) { if (argc < 4) {
std::cout << "setcursor requires 2 params"; std::cout << "Usage: hyprctl setcursor <theme> <size>\n\
return; 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]); std::string rq = "setcursor " + std::string(argv[2]) + " " + std::string(argv[3]);
request(rq); request(rq);
return 0;
} }
void batchRequest(std::string arg) { void batchRequest(std::string arg) {
@@ -254,6 +275,8 @@ int main(int argc, char** argv) {
fullRequest = fullArgs + "/" + fullRequest; fullRequest = fullArgs + "/" + fullRequest;
int exitStatus = 0;
if (fullRequest.contains("/--batch")) batchRequest(fullRequest); if (fullRequest.contains("/--batch")) batchRequest(fullRequest);
else if (fullRequest.contains("/monitors")) request(fullRequest); else if (fullRequest.contains("/monitors")) request(fullRequest);
else if (fullRequest.contains("/clients")) request(fullRequest); else if (fullRequest.contains("/clients")) request(fullRequest);
@@ -266,10 +289,11 @@ int main(int argc, char** argv) {
else if (fullRequest.contains("/devices")) request(fullRequest); else if (fullRequest.contains("/devices")) request(fullRequest);
else if (fullRequest.contains("/reload")) request(fullRequest); else if (fullRequest.contains("/reload")) request(fullRequest);
else if (fullRequest.contains("/getoption")) request(fullRequest); else if (fullRequest.contains("/getoption")) request(fullRequest);
else if (fullRequest.contains("/setcursor")) setcursorRequest(argc, argv); else if (fullRequest.contains("/cursorpos")) request(fullRequest);
else if (fullRequest.contains("/dispatch")) dispatchRequest(argc, argv); else if (fullRequest.contains("/setcursor")) exitStatus = setcursorRequest(argc, argv);
else if (fullRequest.contains("/keyword")) keywordRequest(argc, argv); else if (fullRequest.contains("/dispatch")) exitStatus = dispatchRequest(argc, argv);
else if (fullRequest.contains("/hyprpaper")) hyprpaperRequest(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 if (fullRequest.contains("/--help")) printf("%s", USAGE.c_str());
else { else {
printf("%s\n", USAGE.c_str()); printf("%s\n", USAGE.c_str());
@@ -277,5 +301,5 @@ int main(int argc, char** argv) {
} }
printf("\n"); printf("\n");
return 0; return exitStatus;
} }

View File

@@ -1,5 +1,5 @@
project('Hyprland', 'cpp', 'c', project('Hyprland', 'cpp', 'c',
version : '0.15.0beta', version : '0.16.0beta',
default_options : [ default_options : [
'warning_level=2', 'warning_level=2',
'default_library=static', 'default_library=static',
@@ -20,8 +20,8 @@ endif
GIT_BRANCH = run_command('git', 'rev-parse', '--abbrev-ref', 'HEAD', check: false).stdout().strip() 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_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_COMMIT_MESSAGE = run_command('sh', '-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_DIRTY = run_command('sh', '-c', 'git diff-index --quiet HEAD -- || echo "dirty"', check: false).stdout().strip()
add_project_arguments( add_project_arguments(
[ [

View File

@@ -92,7 +92,7 @@ in {
++ lib.optional cfg.xwayland.enable pkgs.xwayland; ++ lib.optional cfg.xwayland.enable pkgs.xwayland;
home.sessionVariables = lib.mkIf cfg.recommendedEnvironment { home.sessionVariables = lib.mkIf cfg.recommendedEnvironment {
GDK_BACKEND = "wayland"; GDK_BACKEND = "wayland,x11";
_JAVA_AWT_WM_NONREPARENTING = "1"; _JAVA_AWT_WM_NONREPARENTING = "1";
NIXOS_OZONE_WL = "1"; NIXOS_OZONE_WL = "1";
XCURSOR_SIZE = toString config.home.pointerCursor.size or "24"; XCURSOR_SIZE = toString config.home.pointerCursor.size or "24";

View File

@@ -47,7 +47,7 @@ in {
systemPackages = lib.optional (cfg.package != null) cfg.package; systemPackages = lib.optional (cfg.package != null) cfg.package;
sessionVariables = mkIf cfg.recommendedEnvironment { sessionVariables = mkIf cfg.recommendedEnvironment {
GDK_BACKEND = "wayland"; GDK_BACKEND = "wayland,x11";
_JAVA_AWT_WM_NONREPARENTING = "1"; _JAVA_AWT_WM_NONREPARENTING = "1";
NIXOS_OZONE_WL = "1"; NIXOS_OZONE_WL = "1";
XCURSOR_SIZE = "24"; XCURSOR_SIZE = "24";

View File

@@ -107,7 +107,7 @@ CCompositor::CCompositor() {
m_sWLRScene = wlr_scene_create(); m_sWLRScene = wlr_scene_create();
wlr_scene_attach_output_layout(m_sWLRScene, m_sWLROutputLayout); 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(); m_sWLRCursor = wlr_cursor_create();
wlr_cursor_attach_output_layout(m_sWLRCursor, m_sWLROutputLayout); wlr_cursor_attach_output_layout(m_sWLRCursor, m_sWLROutputLayout);
@@ -115,6 +115,9 @@ CCompositor::CCompositor() {
m_sWLRXCursorMgr = wlr_xcursor_manager_create(nullptr, 24); m_sWLRXCursorMgr = wlr_xcursor_manager_create(nullptr, 24);
wlr_xcursor_manager_load(m_sWLRXCursorMgr, 1); 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_sSeat.seat = wlr_seat_create(m_sWLDisplay, "seat0");
m_sWLRPresentation = wlr_presentation_create(m_sWLDisplay, m_sWLRBackend); m_sWLRPresentation = wlr_presentation_create(m_sWLDisplay, m_sWLRBackend);
@@ -167,6 +170,8 @@ CCompositor::CCompositor() {
m_sWLRTextInputMgr = wlr_text_input_manager_v3_create(m_sWLDisplay); m_sWLRTextInputMgr = wlr_text_input_manager_v3_create(m_sWLDisplay);
m_sWLRIMEMgr = wlr_input_method_manager_v2_create(m_sWLDisplay); m_sWLRIMEMgr = wlr_input_method_manager_v2_create(m_sWLDisplay);
m_sWLRActivation = wlr_xdg_activation_v1_create(m_sWLDisplay);
} }
CCompositor::~CCompositor() { CCompositor::~CCompositor() {
@@ -223,6 +228,7 @@ void CCompositor::initAllSignals() {
addWLSignal(&m_sWLROutputPowerMgr->events.set_mode, &Events::listen_powerMgrSetMode, m_sWLROutputPowerMgr, "PowerMgr"); 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_sWLRIMEMgr->events.input_method, &Events::listen_newIME, m_sWLRIMEMgr, "IMEMgr");
addWLSignal(&m_sWLRTextInputMgr->events.text_input, &Events::listen_newTextInput, m_sWLRTextInputMgr, "TextInputMgr"); 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) if(m_sWRLDRMLeaseMgr)
addWLSignal(&m_sWRLDRMLeaseMgr->events.request, &Events::listen_leaseRequest, &m_sWRLDRMLeaseMgr, "DRM"); addWLSignal(&m_sWRLDRMLeaseMgr->events.request, &Events::listen_leaseRequest, &m_sWRLDRMLeaseMgr, "DRM");
@@ -235,12 +241,14 @@ void CCompositor::cleanup() {
if (!m_sWLDisplay || m_bIsShuttingDown) if (!m_sWLDisplay || m_bIsShuttingDown)
return; return;
m_bIsShuttingDown = true;
m_pLastFocus = nullptr; m_pLastFocus = nullptr;
m_pLastWindow = nullptr; m_pLastWindow = nullptr;
// accumulate all PIDs for killing, also request closing. // accumulate all PIDs for killing, also request closing.
for (auto& w : m_vWindows) { for (auto& w : m_vWindows) {
if (w->m_bIsMapped && !w->m_bHidden) if (w->m_bIsMapped && !w->isHidden())
m_dProcessPIDsOnShutdown.push_back(w->getPID()); m_dProcessPIDsOnShutdown.push_back(w->getPID());
} }
@@ -250,8 +258,6 @@ void CCompositor::cleanup() {
m_vWorkspaces.clear(); m_vWorkspaces.clear();
m_vWindows.clear(); m_vWindows.clear();
m_bIsShuttingDown = true;
for (auto& m : m_vMonitors) { for (auto& m : m_vMonitors) {
g_pHyprOpenGL->destroyMonitorResources(m.get()); g_pHyprOpenGL->destroyMonitorResources(m.get());
@@ -445,13 +451,13 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
if (PMONITOR->specialWorkspaceOpen) { if (PMONITOR->specialWorkspaceOpen) {
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { 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}; 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(); return (*w).get();
} }
for (auto& w : m_vWindows) { 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}; 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(); return w.get();
} }
} }
@@ -459,20 +465,20 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
// pinned // pinned
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { 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}; 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(); return w->get();
} }
// first loop over floating cuz they're above, m_vWindows should be sorted bottom->top, for tiled it doesn't matter. // 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++) { 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}; 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(); return w->get();
} }
for (auto& w : m_vWindows) { 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}; 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(); return w.get();
} }
@@ -485,14 +491,14 @@ CWindow* CCompositor::vectorToWindowTiled(const Vector2D& pos) {
if (PMONITOR->specialWorkspaceOpen) { if (PMONITOR->specialWorkspaceOpen) {
for (auto& w : m_vWindows) { for (auto& w : m_vWindows) {
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y}; 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(); return w.get();
} }
} }
for (auto& w : m_vWindows) { for (auto& w : m_vWindows) {
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y}; 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(); return w.get();
} }
@@ -515,13 +521,13 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
if (PMONITOR->specialWorkspaceOpen) { if (PMONITOR->specialWorkspaceOpen) {
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { 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}; 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(); return (*w).get();
} }
for (auto& w : m_vWindows) { for (auto& w : m_vWindows) {
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y}; 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(); return w.get();
} }
} }
@@ -529,7 +535,7 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
// pinned windows on top of floating regardless // pinned windows on top of floating regardless
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { 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}; 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)) if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y))
return w->get(); return w->get();
@@ -548,7 +554,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. // 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++) { 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}; 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 // OR windows should add focus to parent
if ((*w)->m_bX11ShouldntFocus && (*w)->m_iX11Type != 2) if ((*w)->m_bX11ShouldntFocus && (*w)->m_iX11Type != 2)
continue; continue;
@@ -578,7 +584,7 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
// for windows, we need to check their extensions too, first. // for windows, we need to check their extensions too, first.
for (auto& w : m_vWindows) { 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; wlr_surface* resultSurf = nullptr;
Vector2D origin = w->m_vRealPosition.vec(); Vector2D origin = w->m_vRealPosition.vec();
SExtensionFindingData data = {origin, pos, &resultSurf}; SExtensionFindingData data = {origin, pos, &resultSurf};
@@ -590,7 +596,7 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
} }
for (auto& w : m_vWindows) { for (auto& w : m_vWindows) {
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y}; 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(); return w.get();
} }
@@ -603,7 +609,7 @@ CWindow* CCompositor::windowFromCursor() {
if (PMONITOR->specialWorkspaceOpen) { if (PMONITOR->specialWorkspaceOpen) {
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { 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}; 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(); return (*w).get();
} }
@@ -640,13 +646,13 @@ CWindow* CCompositor::windowFromCursor() {
CWindow* CCompositor::windowFloatingFromCursor() { CWindow* CCompositor::windowFloatingFromCursor() {
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { 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}; 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(); return w->get();
} }
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { 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}; 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(); return w->get();
} }
@@ -709,6 +715,8 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
if (windowValidMapped(PLASTWINDOW)) { if (windowValidMapped(PLASTWINDOW)) {
updateWindowAnimatedDecorationValues(PLASTWINDOW); updateWindowAnimatedDecorationValues(PLASTWINDOW);
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
if (PLASTWINDOW->m_phForeignToplevel) if (PLASTWINDOW->m_phForeignToplevel)
wlr_foreign_toplevel_handle_v1_set_activated(PLASTWINDOW->m_phForeignToplevel, false); wlr_foreign_toplevel_handle_v1_set_activated(PLASTWINDOW->m_phForeignToplevel, false);
} }
@@ -717,6 +725,8 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr);
m_pLastFocus = nullptr; m_pLastFocus = nullptr;
return; return;
} }
@@ -742,10 +752,8 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
if (windowValidMapped(PLASTWINDOW)) { if (windowValidMapped(PLASTWINDOW)) {
updateWindowAnimatedDecorationValues(PLASTWINDOW); updateWindowAnimatedDecorationValues(PLASTWINDOW);
if (PLASTWINDOW->m_bIsX11) { if (!pWindow->m_bIsX11 || pWindow->m_iX11Type == 1)
wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat); g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
wlr_seat_pointer_clear_focus(m_sSeat.seat);
}
if (PLASTWINDOW->m_phForeignToplevel) if (PLASTWINDOW->m_phForeignToplevel)
wlr_foreign_toplevel_handle_v1_set_activated(PLASTWINDOW->m_phForeignToplevel, false); wlr_foreign_toplevel_handle_v1_set_activated(PLASTWINDOW->m_phForeignToplevel, false);
@@ -768,8 +776,18 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
// Send an event // Send an event
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(pWindow) + "," + pWindow->m_szTitle}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(pWindow) + "," + pWindow->m_szTitle});
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(pWindow);
if (pWindow->m_phForeignToplevel) if (pWindow->m_phForeignToplevel)
wlr_foreign_toplevel_handle_v1_set_activated(pWindow->m_phForeignToplevel, true); 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);
}
} }
void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) { void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
@@ -778,7 +796,7 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
return; // Don't focus when already focused on this. return; // Don't focus when already focused on this.
// Unfocus last surface if should // 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); g_pXWaylandManager->activateSurface(m_pLastFocus, false);
if (!pSurface) { if (!pSurface) {
@@ -815,6 +833,9 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
} }
bool CCompositor::windowValidMapped(CWindow* pWindow) { bool CCompositor::windowValidMapped(CWindow* pWindow) {
if (!pWindow)
return false;
if (!windowExists(pWindow)) if (!windowExists(pWindow))
return false; return false;
@@ -824,7 +845,7 @@ bool CCompositor::windowValidMapped(CWindow* pWindow) {
if (!pWindow->m_bIsMapped) if (!pWindow->m_bIsMapped)
return false; return false;
if (pWindow->m_bHidden) if (pWindow->isHidden())
return false; return false;
return true; return true;
@@ -934,7 +955,7 @@ int CCompositor::getWindowsOnWorkspace(const int& id) {
CWindow* CCompositor::getFirstWindowOnWorkspace(const int& id) { CWindow* CCompositor::getFirstWindowOnWorkspace(const int& id) {
for (auto& w : m_vWindows) { 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(); return w.get();
} }
@@ -980,7 +1001,7 @@ void CCompositor::moveWindowToTop(CWindow* pWindow) {
std::deque<CWindow*> toMove; std::deque<CWindow*> toMove;
for (auto& w : m_vWindows) { 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()); toMove.emplace_back(w.get());
} }
} }
@@ -1103,7 +1124,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
CWindow* longestIntersectWindow = nullptr; CWindow* longestIntersectWindow = nullptr;
for (auto& w : m_vWindows) { 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; continue;
const auto BWINDOWIDEALBB = w->getWindowIdealBoundingBoxIgnoreReserved(); const auto BWINDOWIDEALBB = w->getWindowIdealBoundingBoxIgnoreReserved();
@@ -1177,12 +1198,12 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow, bool focusableO
continue; 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(); return w.get();
} }
for (auto& w : m_vWindows) { 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(); return w.get();
} }
@@ -1200,12 +1221,12 @@ CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow, bool focusableO
continue; 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(); return it->get();
} }
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) { 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(); return it->get();
} }
@@ -1255,6 +1276,11 @@ bool CCompositor::isPointOnAnyMonitor(const Vector2D& point) {
return false; 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) { CWindow* CCompositor::getConstraintWindow(SMouse* pMouse) {
if (!pMouse->currentConstraint) if (!pMouse->currentConstraint)
return nullptr; return nullptr;
@@ -1262,10 +1288,17 @@ CWindow* CCompositor::getConstraintWindow(SMouse* pMouse) {
const auto PSURFACE = pMouse->currentConstraint->surface; const auto PSURFACE = pMouse->currentConstraint->surface;
for (auto& w : m_vWindows) { for (auto& w : m_vWindows) {
if (PSURFACE == g_pXWaylandManager->getWindowSurface(w.get())) { if (w->isHidden() || !w->m_bMappedX11 || !w->m_bIsMapped || !g_pXWaylandManager->getWindowSurface(w.get()))
if (!w->m_bIsX11 && w->m_bIsMapped && !w->m_bHidden)
continue; 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(); return w.get();
} }
} }
@@ -1543,7 +1576,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
if (nextWorkspaceOnMonitorID == -1) { if (nextWorkspaceOnMonitorID == -1) {
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++; nextWorkspaceOnMonitorID++;
Debug::log(LOG, "moveWorkspaceToMonitor: Plugging gap with new %d", nextWorkspaceOnMonitorID); Debug::log(LOG, "moveWorkspaceToMonitor: Plugging gap with new %d", nextWorkspaceOnMonitorID);
@@ -1564,7 +1597,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
w->m_iMonitorID = pMonitor->ID; w->m_iMonitorID = pMonitor->ID;
// additionally, move floating and fs windows manually // additionally, move floating and fs windows manually
if (w->m_bIsMapped && !w->m_bHidden) { if (w->m_bIsMapped && !w->isHidden()) {
if (w->m_bIsFloating) if (w->m_bIsFloating)
w->m_vRealPosition = w->m_vRealPosition.vec() - POLDMON->vecPosition + pMonitor->vecPosition; w->m_vRealPosition = w->m_vRealPosition.vec() - POLDMON->vecPosition + pMonitor->vecPosition;
@@ -1646,7 +1679,7 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID) { if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID) {
w->m_bCreatedOverFullscreen = false; w->m_bCreatedOverFullscreen = false;
if (w.get() != pWindow && !w->m_bFadingOut && !w->m_bPinned) 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;
} }
} }
@@ -1718,7 +1751,7 @@ CWindow* CCompositor::getWindowByRegex(const std::string& regexp) {
} }
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (!w->m_bIsMapped || w->m_bHidden) if (!w->m_bIsMapped || w->isHidden())
continue; continue;
switch (mode) { switch (mode) {
@@ -1846,7 +1879,7 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con
void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) { void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) {
for (auto& w : m_vWindows) { 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); g_pXWaylandManager->setWindowSize(w.get(), w->m_vRealSize.vec(), true);
} }
} }
@@ -1862,3 +1895,24 @@ bool CCompositor::cursorOnReservedArea() {
return !VECINRECT(CURSORPOS, XY1.x, XY1.y, XY2.x, XY2.y); 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;
}

View File

@@ -69,6 +69,7 @@ public:
wlr_output_power_manager_v1* m_sWLROutputPowerMgr; wlr_output_power_manager_v1* m_sWLROutputPowerMgr;
wlr_input_method_manager_v2* m_sWLRIMEMgr; wlr_input_method_manager_v2* m_sWLRIMEMgr;
wlr_text_input_manager_v3* m_sWLRTextInputMgr; wlr_text_input_manager_v3* m_sWLRTextInputMgr;
wlr_xdg_activation_v1* m_sWLRActivation;
// ------------------------------------------------- // // ------------------------------------------------- //
@@ -165,6 +166,7 @@ public:
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&); Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
void forceReportSizesToWindowsOnWorkspace(const int&); void forceReportSizesToWindowsOnWorkspace(const int&);
bool cursorOnReservedArea(); 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; std::string explicitConfigPath;

View File

@@ -244,3 +244,20 @@ void CWindow::removeDecorationByType(eDecorationType type) {
updateWindowDecos(); updateWindowDecos();
} }
void CWindow::onUnmap() {
if (g_pCompositor->m_pLastWindow == this)
g_pCompositor->m_pLastWindow = nullptr;
}
void CWindow::setHidden(bool hidden) {
m_bHidden = hidden;
if (hidden) {
onUnmap();
}
}
bool CWindow::isHidden() {
return m_bHidden;
}

View File

@@ -24,6 +24,9 @@ struct SWindowAdditionalConfigData {
bool forceOpaque = false; bool forceOpaque = false;
bool forceAllowsInput = false; bool forceAllowsInput = false;
bool forceNoAnims = false; bool forceNoAnims = false;
bool forceNoBorder = false;
bool forceNoShadow = false;
bool windowDanceCompat = false;
}; };
class CWindow { class CWindow {
@@ -118,9 +121,6 @@ public:
Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in
Vector2D m_vOriginalClosedSize; // drawing the closing animations Vector2D m_vOriginalClosedSize; // drawing the closing animations
// For hidden windows and stuff
bool m_bHidden = false;
// For pinned (sticky) windows // For pinned (sticky) windows
bool m_bPinned = false; bool m_bPinned = false;
@@ -172,4 +172,12 @@ public:
void updateSurfaceOutputs(); void updateSurfaceOutputs();
void moveToWorkspace(int); void moveToWorkspace(int);
CWindow* X11TransientFor(); CWindow* X11TransientFor();
void onUnmap();
void setHidden(bool hidden);
bool isHidden();
private:
// For hidden windows and stuff
bool m_bHidden = false;
}; };

View File

@@ -60,6 +60,7 @@ void CConfigManager::setDefaultVars() {
configValues["misc:disable_autoreload"].intValue = 0; configValues["misc:disable_autoreload"].intValue = 0;
configValues["misc:enable_swallow"].intValue = 0; configValues["misc:enable_swallow"].intValue = 0;
configValues["misc:swallow_regex"].strValue = STRVAL_EMPTY; configValues["misc:swallow_regex"].strValue = STRVAL_EMPTY;
configValues["misc:focus_on_activate"].intValue = 0;
configValues["debug:int"].intValue = 0; configValues["debug:int"].intValue = 0;
configValues["debug:log_damage"].intValue = 0; configValues["debug:log_damage"].intValue = 0;
@@ -147,6 +148,8 @@ void CConfigManager::setDefaultVars() {
configValues["input:touchpad:tap-to-click"].intValue = 1; configValues["input:touchpad:tap-to-click"].intValue = 1;
configValues["input:touchpad:drag_lock"].intValue = 0; configValues["input:touchpad:drag_lock"].intValue = 0;
configValues["input:touchpad:scroll_factor"].floatValue = 1.f; 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:pass_mouse_when_bound"].intValue = 0;
configValues["binds:scroll_event_delay"].intValue = 300; configValues["binds:scroll_event_delay"].intValue = 300;
@@ -159,6 +162,7 @@ void CConfigManager::setDefaultVars() {
configValues["gestures:workspace_swipe_invert"].intValue = 1; configValues["gestures:workspace_swipe_invert"].intValue = 1;
configValues["gestures:workspace_swipe_min_speed_to_force"].intValue = 30; configValues["gestures:workspace_swipe_min_speed_to_force"].intValue = 30;
configValues["gestures:workspace_swipe_cancel_ratio"].floatValue = 0.5f; configValues["gestures:workspace_swipe_cancel_ratio"].floatValue = 0.5f;
configValues["gestures:workspace_swipe_create_new"].intValue = 1;
configValues["input:follow_mouse"].intValue = 1; configValues["input:follow_mouse"].intValue = 1;
@@ -187,6 +191,9 @@ void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
cfgValues["drag_lock"].intValue = 0; cfgValues["drag_lock"].intValue = 0;
cfgValues["left_handed"].intValue = 0; cfgValues["left_handed"].intValue = 0;
cfgValues["scroll_method"].strValue = STRVAL_EMPTY; 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() { void CConfigManager::setDefaultAnimationVars() {
@@ -307,6 +314,31 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
// Values with 0x are hex // Values with 0x are hex
const auto VALUEWITHOUTHEX = VALUE.substr(2); const auto VALUEWITHOUTHEX = VALUE.substr(2);
CONFIGENTRY->intValue = stol(VALUEWITHOUTHEX, nullptr, 16); CONFIGENTRY->intValue = 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());
parseError = "rgba() expects length of 8 characters (4 bytes)";
return;
}
const auto RGBA = std::stol(VALUEWITHOUTFUNC, nullptr, 16);
// now we need to RGBA -> ARGB. The config holds ARGB only.
CONFIGENTRY->intValue = (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());
parseError = "rgb() expects length of 6 characters (3 bytes)";
return;
}
const auto RGB = std::stol(VALUEWITHOUTFUNC, nullptr, 16);
CONFIGENTRY->intValue = RGB + 0xFF000000; // 0xFF for opaque
} else if (VALUE.find("true") == 0 || VALUE.find("on") == 0 || VALUE.find("yes") == 0) { } else if (VALUE.find("true") == 0 || VALUE.find("on") == 0 || VALUE.find("yes") == 0) {
CONFIGENTRY->intValue = 1; CONFIGENTRY->intValue = 1;
} else if (VALUE.find("false") == 0 || VALUE.find("off") == 0 || VALUE.find("no") == 0) { } else if (VALUE.find("false") == 0 || VALUE.find("off") == 0 || VALUE.find("no") == 0) {
@@ -500,6 +532,9 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
if (ARGS[argno] == "mirror") { if (ARGS[argno] == "mirror") {
newrule.mirrorOf = ARGS[argno + 1]; newrule.mirrorOf = ARGS[argno + 1];
argno++; argno++;
} else if (ARGS[argno] == "bitdepth") {
newrule.enable10bit = ARGS[argno + 1] == "10";
argno++;
} else { } else {
Debug::log(ERR, "Config error: invalid monitor syntax"); Debug::log(ERR, "Config error: invalid monitor syntax");
parseError = "invalid syntax at \"" + ARGS[argno] + "\""; parseError = "invalid syntax at \"" + ARGS[argno] + "\"";
@@ -718,16 +753,20 @@ bool windowRuleValid(const std::string& RULE) {
&& RULE.find("move") != 0 && RULE.find("move") != 0
&& RULE.find("size") != 0 && RULE.find("size") != 0
&& RULE.find("minsize") != 0 && RULE.find("minsize") != 0
&& RULE.find("maxsize") != 0
&& RULE.find("pseudo") != 0 && RULE.find("pseudo") != 0
&& RULE.find("monitor") != 0 && RULE.find("monitor") != 0
&& RULE != "nofocus" && RULE != "nofocus"
&& RULE != "noblur" && RULE != "noblur"
&& RULE != "noshadow"
&& RULE != "noborder"
&& RULE != "center" && RULE != "center"
&& RULE != "opaque" && RULE != "opaque"
&& RULE != "forceinput" && RULE != "forceinput"
&& RULE != "fullscreen" && RULE != "fullscreen"
&& RULE != "pin" && RULE != "pin"
&& RULE != "noanim" && RULE != "noanim"
&& RULE != "windowdance"
&& RULE.find("animation") != 0 && RULE.find("animation") != 0
&& RULE.find("rounding") != 0 && RULE.find("rounding") != 0
&& RULE.find("workspace") != 0); && RULE.find("workspace") != 0);
@@ -981,13 +1020,26 @@ void CConfigManager::applyUserDefinedVars(std::string& line, const size_t equals
void CConfigManager::parseLine(std::string& line) { void CConfigManager::parseLine(std::string& line) {
// first check if its not a comment // first check if its not a comment
const auto COMMENTSTART = line.find_first_of('#'); if (line[0] == '#')
if (COMMENTSTART == 0)
return; return;
// now, cut the comment off // now, cut the comment off. ## is an escape.
if (COMMENTSTART != std::string::npos) for (long unsigned int i = 1; i < line.length(); ++i) {
line = line.substr(0, COMMENTSTART); 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) {
line.replace(startPos, 2, "#");
startPos++;
}
// remove shit at the beginning // remove shit at the beginning
while (line[0] == ' ' || line[0] == '\t') { while (line[0] == ' ' || line[0] == '\t') {
@@ -1139,6 +1191,7 @@ void CConfigManager::loadConfigLoadVars() {
if (!isFirstLaunch) { if (!isFirstLaunch) {
g_pInputManager->setKeyboardLayout(); g_pInputManager->setKeyboardLayout();
g_pInputManager->setPointerConfigs(); g_pInputManager->setPointerConfigs();
g_pInputManager->setTouchDeviceConfigs();
} }
// Calculate the internal vars // Calculate the internal vars
@@ -1168,6 +1221,7 @@ void CConfigManager::loadConfigLoadVars() {
// check // check
ensureDPMS(); ensureDPMS();
ensureVRR();
} }
// Update window border colors // Update window border colors
@@ -1424,6 +1478,7 @@ void CConfigManager::dispatchExecOnce() {
// set input, fixes some certain issues // set input, fixes some certain issues
g_pInputManager->setKeyboardLayout(); g_pInputManager->setKeyboardLayout();
g_pInputManager->setPointerConfigs(); g_pInputManager->setPointerConfigs();
g_pInputManager->setTouchDeviceConfigs();
// set ws names again // set ws names again
for (auto& ws : g_pCompositor->m_vWorkspaces) { for (auto& ws : g_pCompositor->m_vWorkspaces) {
@@ -1498,6 +1553,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) { SAnimationPropertyConfig* CConfigManager::getAnimationPropertyConfig(const std::string& name) {
return &animationConfig[name]; return &animationConfig[name];
} }

View File

@@ -38,6 +38,7 @@ struct SMonitorRule {
bool disabled = false; bool disabled = false;
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
std::string mirrorOf = ""; std::string mirrorOf = "";
bool enable10bit = false;
}; };
struct SMonitorAdditionalReservedArea { struct SMonitorAdditionalReservedArea {
@@ -151,6 +152,7 @@ public:
bool m_bForceReload = false; bool m_bForceReload = false;
bool m_bNoMonitorReload = false; bool m_bNoMonitorReload = false;
void ensureDPMS(); void ensureDPMS();
void ensureVRR(CMonitor* pMonitor = nullptr);
std::string parseKeyword(const std::string&, const std::string&, bool dynamic = false); std::string parseKeyword(const std::string&, const std::string&, bool dynamic = false);

View File

@@ -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. OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
######################################################################################## ########################################################################################
# #
# Please note not all available settings / options are set here. # 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 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 { 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 { general {
main_mod=SUPER # See https://wiki.hyprland.org/Configuring/Variables/ for more
gaps_in=5 gaps_in = 5
gaps_out=20 gaps_out = 20
border_size=2 border_size = 2
col.active_border=0x66ee1111 col.active_border = rgba(1affffee)
col.inactive_border=0x66333333 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) layout = dwindle
damage_tracking=full # leave it on full unless you hate your GPU and want to make it suffer
} }
decoration { decoration {
rounding=10 # See https://wiki.hyprland.org/Configuring/Variables/ for more
blur=1
blur_size=3 # minimum 1 rounding = 10
blur_passes=1 # minimum 1 blur = yes
blur_new_optimizations=1 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 { animations {
enabled=1 enabled = yes
animation=windows,1,7,default
animation=border,1,10,default # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
animation=fade,1,10,default
animation=workspaces,1,6,default 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 { 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 { gestures {
workspace_swipe=no # See https://wiki.hyprland.org/Configuring/Variables/ for more
workspace_swipe = off
} }
# example window rules # Example per-device config
# for windows named/classed as abc and xyz # See https://wiki.hyprland.org/Configuring/Keywords/#executing for more
#windowrule=move 69 420,abc device:epic mouse V1 {
#windowrule=size 420 69,abc sensitivity = -0.5
#windowrule=tile,xyz }
#windowrule=float,abc
#windowrule=pseudo,abc
#windowrule=monitor 0,xyz
# some nice mouse binds # Example windowrule v1
bindm=SUPER,mouse:272,movewindow # windowrule = float, ^(kitty)$
bindm=SUPER,mouse:273,resizewindow # 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 # See https://wiki.hyprland.org/Configuring/Keywords/ for more
bind=SUPER,right,movefocus,r $mainMod = SUPER
bind=SUPER,up,movefocus,u
bind=SUPER,down,movefocus,d
bind=SUPER,1,workspace,1 # Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
bind=SUPER,2,workspace,2 bind = $mainMod, Q, exec, kitty
bind=SUPER,3,workspace,3 bind = $mainMod, C, killactive,
bind=SUPER,4,workspace,4 bind = $mainMod, M, exit,
bind=SUPER,5,workspace,5 bind = $mainMod, E, exec, dolphin
bind=SUPER,6,workspace,6 bind = $mainMod, V, togglefloating,
bind=SUPER,7,workspace,7 bind = $mainMod, R, exec, wofi --show drun
bind=SUPER,8,workspace,8 bind = $mainMod, P, pseudo, # dwindle
bind=SUPER,9,workspace,9 bind = $mainMod, J, togglesplit, # dwindle
bind=SUPER,0,workspace,10
bind=ALT,1,movetoworkspace,1 # Move focus with mainMod + arrow keys
bind=ALT,2,movetoworkspace,2 bind = $mainMod, left, movefocus, l
bind=ALT,3,movetoworkspace,3 bind = $mainMod, right, movefocus, r
bind=ALT,4,movetoworkspace,4 bind = $mainMod, up, movefocus, u
bind=ALT,5,movetoworkspace,5 bind = $mainMod, down, movefocus, d
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
bind=SUPER,mouse_down,workspace,e+1 # Switch workspaces with mainMod + [0-9]
bind=SUPER,mouse_up,workspace,e-1 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
)#"; )#";

View File

@@ -499,7 +499,7 @@ std::string versionRequest(HyprCtl::eHyprCtlOutputFormat format) {
R"#({ R"#({
"branch": "%s", "branch": "%s",
"commit": "%s", "commit": "%s",
"dirty": %s "dirty": %s,
"commit_message": "%s", "commit_message": "%s",
"flags": [)#", GIT_BRANCH, GIT_COMMIT_HASH, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), removeBeginEndSpacesTabs(GIT_COMMIT_MESSAGE).c_str()); "flags": [)#", GIT_BRANCH, GIT_COMMIT_HASH, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), removeBeginEndSpacesTabs(GIT_COMMIT_MESSAGE).c_str());
@@ -562,6 +562,7 @@ std::string dispatchKeyword(std::string in) {
if (COMMAND.contains("input") || COMMAND.contains("device:")) { if (COMMAND.contains("input") || COMMAND.contains("device:")) {
g_pInputManager->setKeyboardLayout(); // update kb layout g_pInputManager->setKeyboardLayout(); // update kb layout
g_pInputManager->setPointerConfigs(); // update mouse cfgs g_pInputManager->setPointerConfigs(); // update mouse cfgs
g_pInputManager->setTouchDeviceConfigs(); // update touch device cfgs
} }
if (COMMAND.contains("general:layout")) if (COMMAND.contains("general:layout"))
@@ -600,6 +601,23 @@ std::string splashRequest() {
return g_pCompositor->m_szCurrentSplash; 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 getReply(std::string);
std::string dispatchBatch(std::string request) { std::string dispatchBatch(std::string request) {
@@ -766,6 +784,8 @@ std::string getReply(std::string request) {
return devicesRequest(format); return devicesRequest(format);
else if (request == "splash") else if (request == "splash")
return splashRequest(); return splashRequest();
else if (request == "cursorpos")
return cursorPosRequest(format);
else if (request.find("dispatch") == 0) else if (request.find("dispatch") == 0)
return dispatchRequest(request); return dispatchRequest(request);
else if (request.find("keyword") == 0) else if (request.find("keyword") == 0)

View File

@@ -42,6 +42,7 @@ namespace Events {
// Surface XDG (window) // Surface XDG (window)
LISTENER(newXDGSurface); LISTENER(newXDGSurface);
LISTENER(activateXDG);
// Window events // Window events
DYNLISTENFUNC(commitWindow); DYNLISTENFUNC(commitWindow);
@@ -87,7 +88,6 @@ namespace Events {
LISTENER(requestMouse); LISTENER(requestMouse);
LISTENER(requestSetSel); LISTENER(requestSetSel);
LISTENER(requestSetPrimarySel); LISTENER(requestSetPrimarySel);
DYNLISTENFUNC(activate);
// outputMgr // outputMgr
LISTENER(outputMgrApply); LISTENER(outputMgrApply);

View File

@@ -199,9 +199,30 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
// refocus if needed // refocus if needed
if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus) { if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus) {
Vector2D surfaceCoords;
SLayerSurface* pFoundLayerSurface = nullptr;
wlr_surface* foundSurface = nullptr;
g_pCompositor->m_pLastFocus = 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(); g_pInputManager->refocus();
} }
}
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height}; 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); g_pHyprRenderer->damageBox(&geomFixed);

View File

@@ -45,6 +45,7 @@ void Events::listener_requestSetSel(wl_listener* listener, void* data) {
} }
void Events::listener_readyXWayland(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 XCBCONNECTION = xcb_connect(g_pXWaylandManager->m_sWLRXWayland->display_name, NULL);
const auto ERR = xcb_connection_has_error(XCBCONNECTION); const auto ERR = xcb_connection_has_error(XCBCONNECTION);
if (ERR) { if (ERR) {
@@ -72,6 +73,7 @@ void Events::listener_readyXWayland(wl_listener* listener, void* data) {
} }
xcb_disconnect(XCBCONNECTION); xcb_disconnect(XCBCONNECTION);
#endif
} }
void Events::listener_requestDrag(wl_listener* listener, void* data) { void Events::listener_requestDrag(wl_listener* listener, void* data) {

View File

@@ -37,8 +37,6 @@ void Events::listener_change(wl_listener* listener, void* data) {
CONFIGHEAD->state.mode = m->output->current_mode; CONFIGHEAD->state.mode = m->output->current_mode;
CONFIGHEAD->state.x = m->vecPosition.x; CONFIGHEAD->state.x = m->vecPosition.x;
CONFIGHEAD->state.y = m->vecPosition.y; 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); wlr_output_manager_v1_set_configuration(g_pCompositor->m_sWLROutputMgr, CONFIG);
@@ -227,8 +225,6 @@ void Events::listener_monitorFrame(void* owner, void* data) {
if (PMONITOR->isMirror()) { if (PMONITOR->isMirror()) {
g_pHyprOpenGL->renderMirrored(); g_pHyprOpenGL->renderMirrored();
Debug::log(LOG, "Mirror frame");
} else { } else {
g_pHyprOpenGL->clear(CColor(17, 17, 17, 255)); g_pHyprOpenGL->clear(CColor(17, 17, 17, 255));
g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper" g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper"

View File

@@ -114,6 +114,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
bool workspaceSilent = false; 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);
bool shouldFocus = true; bool shouldFocus = true;
bool workspaceSpecial = false;
for (auto& r : WINDOWRULES) { for (auto& r : WINDOWRULES) {
if (r.szRule.find("monitor") == 0) { if (r.szRule.find("monitor") == 0) {
@@ -147,6 +148,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
requestedWorkspace = WORKSPACERQ; 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()); Debug::log(LOG, "Rule workspace matched by window %x, %s applied.", PWINDOW, r.szValue.c_str());
} else if (r.szRule.find("float") == 0) { } else if (r.szRule.find("float") == 0) {
PWINDOW->m_bIsFloating = true; PWINDOW->m_bIsFloating = true;
@@ -158,10 +162,16 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_bNoFocus = true; PWINDOW->m_bNoFocus = true;
} else if (r.szRule == "noblur") { } else if (r.szRule == "noblur") {
PWINDOW->m_sAdditionalConfigData.forceNoBlur = true; PWINDOW->m_sAdditionalConfigData.forceNoBlur = true;
} else if (r.szRule == "noborder") {
PWINDOW->m_sAdditionalConfigData.forceNoBorder = true;
} else if (r.szRule == "noshadow") {
PWINDOW->m_sAdditionalConfigData.forceNoShadow = true;
} else if (r.szRule == "fullscreen") { } else if (r.szRule == "fullscreen") {
requestsFullscreen = true; requestsFullscreen = true;
} else if (r.szRule == "opaque") { } else if (r.szRule == "opaque") {
PWINDOW->m_sAdditionalConfigData.forceOpaque = true; PWINDOW->m_sAdditionalConfigData.forceOpaque = true;
} else if (r.szRule == "windowdance") {
PWINDOW->m_sAdditionalConfigData.windowDanceCompat = true;
} else if (r.szRule == "forceinput") { } else if (r.szRule == "forceinput") {
PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true; PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true;
} else if (r.szRule == "pin") { } else if (r.szRule == "pin") {
@@ -205,17 +215,18 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (requestedWorkspace.contains("silent")) { if (requestedWorkspace.contains("silent")) {
workspaceSilent = true; workspaceSilent = true;
shouldFocus = false; shouldFocus = false;
}
requestedWorkspace = requestedWorkspace.substr(0, requestedWorkspace.find_first_of(' ')); requestedWorkspace = requestedWorkspace.substr(0, requestedWorkspace.find_first_of(' '));
}
if (!shouldFocus && requestedWorkspace == std::to_string(PMONITOR->activeWorkspace)) if (!shouldFocus && requestedWorkspace == std::to_string(PMONITOR->activeWorkspace))
shouldFocus = true; shouldFocus = true;
}
if (requestedWorkspace == "special") { if (requestedWorkspace == "special") {
workspaceSpecial = true;
workspaceSilent = true; workspaceSilent = true;
} }
}
if (!workspaceSilent) { if (!workspaceSilent) {
g_pKeybindManager->m_mDispatchers["workspace"](requestedWorkspace); g_pKeybindManager->m_mDispatchers["workspace"](requestedWorkspace);
@@ -225,6 +236,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) { if (PWINDOW->m_bIsFloating) {
g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW); g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW);
PWINDOW->m_bCreatedOverFullscreen = true; PWINDOW->m_bCreatedOverFullscreen = true;
@@ -247,7 +296,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY); PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY);
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
PWINDOW->m_bHidden = false; PWINDOW->setHidden(false);
} catch (...) { } catch (...) {
Debug::log(LOG, "Rule size failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str()); Debug::log(LOG, "Rule size failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str());
} }
@@ -262,24 +311,55 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_vRealSize = SIZE; PWINDOW->m_vRealSize = SIZE;
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
PWINDOW->m_bHidden = false; PWINDOW->setHidden(false);
} catch (...) { } catch (...) {
Debug::log(LOG, "Rule minsize failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str()); 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) { } else if (r.szRule.find("move") == 0) {
try { try {
const auto VALUE = r.szRule.substr(r.szRule.find(" ") + 1); const auto VALUE = r.szRule.substr(r.szRule.find(" ") + 1);
const auto POSXSTR = VALUE.substr(0, VALUE.find(" ")); const auto POSXSTR = VALUE.substr(0, VALUE.find(" "));
const auto POSYSTR = VALUE.substr(VALUE.find(" ") + 1); const auto POSYSTR = 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; int posX = 0;
const auto POSY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y; 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);
} else {
posX = !POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.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);
} else {
posY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y;
}
Debug::log(LOG, "Rule move, applying to window %x", PWINDOW); 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 (...) { } catch (...) {
Debug::log(LOG, "Rule move failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str()); Debug::log(LOG, "Rule move failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str());
} }
@@ -293,8 +373,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv(); PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv();
g_pCompositor->moveWindowToTop(PWINDOW); g_pCompositor->moveWindowToTop(PWINDOW);
} } else {
else {
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW); g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
// Set the pseudo size here too so that it doesnt end up being 0x0 // Set the pseudo size here too so that it doesnt end up being 0x0
@@ -309,7 +388,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_bX11ShouldntFocus = false; 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); g_pCompositor->focusWindow(PWINDOW);
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA); PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
PWINDOW->m_fDimPercent.setValueAndWarp(*PDIMSTRENGTH); PWINDOW->m_fDimPercent.setValueAndWarp(*PDIMSTRENGTH);
@@ -334,6 +413,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_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_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_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) if (PWINDOW->m_iX11Type == 2)
PWINDOW->hyprListener_setGeometryX11U.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_geometry, &Events::listener_unmanagedSetGeometry, PWINDOW, "XWayland Window Late"); PWINDOW->hyprListener_setGeometryX11U.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_geometry, &Events::listener_unmanagedSetGeometry, PWINDOW, "XWayland Window Late");
@@ -347,22 +428,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
const auto TIMER = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, setAnimToMove, PWINDOW); 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); 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) { if (requestsFullscreen) {
// fix fullscreen on requested (basically do a switcheroo) // fix fullscreen on requested (basically do a switcheroo)
if (PWORKSPACE->m_bHasFullscreenWindow) { if (PWORKSPACE->m_bHasFullscreenWindow) {
@@ -420,7 +485,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
std::vector<CWindow*> found; std::vector<CWindow*> found;
CWindow* finalFound = nullptr; CWindow* finalFound = nullptr;
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (!w->m_bIsMapped || w->m_bHidden) if (!w->m_bIsMapped || w->isHidden())
continue; continue;
if (w->getPID() == ppid) { if (w->getPID() == ppid) {
@@ -448,7 +513,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(finalFound); g_pLayoutManager->getCurrentLayout()->onWindowRemoved(finalFound);
finalFound->m_bHidden = true; finalFound->setHidden(true);
} }
} }
} }
@@ -485,6 +550,8 @@ void Events::listener_unmapWindow(void* owner, void* data) {
PWINDOW->hyprListener_configureX11.removeCallback(); PWINDOW->hyprListener_configureX11.removeCallback();
PWINDOW->hyprListener_setTitleWindow.removeCallback(); PWINDOW->hyprListener_setTitleWindow.removeCallback();
PWINDOW->hyprListener_setGeometryX11U.removeCallback(); PWINDOW->hyprListener_setGeometryX11U.removeCallback();
PWINDOW->hyprListener_requestMaximize.removeCallback();
PWINDOW->hyprListener_requestMinimize.removeCallback();
} }
if (PWINDOW->m_bIsFullscreen) { if (PWINDOW->m_bIsFullscreen) {
@@ -496,7 +563,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
// swallowing // swallowing
if (PWINDOW->m_pSwallowed && g_pCompositor->windowExists(PWINDOW->m_pSwallowed)) { 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); g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW->m_pSwallowed);
PWINDOW->m_pSwallowed = nullptr; PWINDOW->m_pSwallowed = nullptr;
} }
@@ -524,13 +591,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
// refocus on a new window if needed // refocus on a new window if needed
if (wasLastWindow) { if (wasLastWindow) {
auto PWINDOWCANDIDATE = g_pCompositor->vectorToWindowIdeal(PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f); const auto PWINDOWCANDIDATE = g_pLayoutManager->getCurrentLayout()->getNextWindowCandidate(PWINDOW);
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;
Debug::log(LOG, "On closed window, new focused candidate is %x", PWINDOWCANDIDATE); Debug::log(LOG, "On closed window, new focused candidate is %x", PWINDOWCANDIDATE);
@@ -539,11 +600,16 @@ void Events::listener_unmapWindow(void* owner, void* data) {
g_pInputManager->refocus(); g_pInputManager->refocus();
else else
g_pCompositor->focusWindow(PWINDOWCANDIDATE); g_pCompositor->focusWindow(PWINDOWCANDIDATE);
} else {
g_pInputManager->refocus();
} }
} else { } else {
Debug::log(LOG, "Unmapped was not focused, ignoring a refocus."); Debug::log(LOG, "Unmapped was not focused, ignoring a refocus.");
} }
// update lastwindow after focus
PWINDOW->onUnmap();
Debug::log(LOG, "Destroying the SubSurface tree of unmapped window %x", PWINDOW); Debug::log(LOG, "Destroying the SubSurface tree of unmapped window %x", PWINDOW);
SubsurfaceTree::destroySurfaceTree(PWINDOW->m_pSurfaceTree); SubsurfaceTree::destroySurfaceTree(PWINDOW->m_pSurfaceTree);
@@ -573,12 +639,15 @@ void Events::listener_unmapWindow(void* owner, void* data) {
// recheck idle inhibitors // recheck idle inhibitors
g_pInputManager->recheckIdleInhibitorStatus(); g_pInputManager->recheckIdleInhibitorStatus();
// force report all sizes (QT sometimes has an issue with this)
g_pCompositor->forceReportSizesToWindowsOnWorkspace(PWINDOW->m_iWorkspaceID);
} }
void Events::listener_commitWindow(void* owner, void* data) { void Events::listener_commitWindow(void* owner, void* data) {
CWindow* PWINDOW = (CWindow*)owner; 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; return;
g_pHyprRenderer->damageSurface(g_pXWaylandManager->getWindowSurface(PWINDOW), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y); g_pHyprRenderer->damageSurface(g_pXWaylandManager->getWindowSurface(PWINDOW), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y);
@@ -638,7 +707,7 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
return; return;
} }
if (PWINDOW->m_bHidden) if (PWINDOW->isHidden())
return; return;
if (!PWINDOW->m_bIsX11) { if (!PWINDOW->m_bIsX11) {
@@ -649,26 +718,50 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
wlr_xdg_surface_schedule_configure(PWINDOW->m_uSurface.xdg); wlr_xdg_surface_schedule_configure(PWINDOW->m_uSurface.xdg);
} else { } 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(); PWINDOW->updateToplevel();
Debug::log(LOG, "Window %x fullscreen to %i", PWINDOW, PWINDOW->m_bIsFullscreen); 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) { void Events::listener_activateXDG(wl_listener* listener, void* data) {
// TODO 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) { void Events::listener_activateX11(void* owner, void* data) {
CWindow* PWINDOW = (CWindow*)owner; const auto PWINDOW = (CWindow*)owner;
if (PWINDOW->m_iX11Type == 1 /* Managed */) { static auto *const PFOCUSONACTIVATE = &g_pConfigManager->getConfigValuePtr("misc:focus_on_activate")->intValue;
wlr_xwayland_surface_activate(PWINDOW->m_uSurface.xwayland, 1);
} 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) { void Events::listener_configureX11(void* owner, void* data) {
@@ -687,15 +780,15 @@ void Events::listener_configureX11(void* owner, void* data) {
return; 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); wlr_xwayland_surface_configure(PWINDOW->m_uSurface.xwayland, E->x, E->y, E->width, E->height);
return; return;
} }
if (E->width > 1 && E->height > 1) if (E->width > 1 && E->height > 1)
PWINDOW->m_bHidden = false; PWINDOW->setHidden(false);
else else
PWINDOW->m_bHidden = true; PWINDOW->setHidden(true);
PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(E->x, E->y)); PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(E->x, E->y));
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(E->width, E->height)); PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(E->width, E->height));
@@ -710,6 +803,7 @@ void Events::listener_configureX11(void* owner, void* data) {
PWINDOW->m_bCreatedOverFullscreen = true; PWINDOW->m_bCreatedOverFullscreen = true;
if (!PWINDOW->m_sAdditionalConfigData.windowDanceCompat)
g_pInputManager->refocus(); g_pInputManager->refocus();
g_pHyprRenderer->damageWindow(PWINDOW); g_pHyprRenderer->damageWindow(PWINDOW);
@@ -720,16 +814,16 @@ void Events::listener_configureX11(void* owner, void* data) {
void Events::listener_unmanagedSetGeometry(void* owner, void* data) { void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
CWindow* PWINDOW = (CWindow*)owner; CWindow* PWINDOW = (CWindow*)owner;
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_bHidden) if (!PWINDOW->m_bMappedX11)
return; return;
const auto POS = PWINDOW->m_vRealPosition.goalv(); const auto POS = PWINDOW->m_vRealPosition.goalv();
const auto SIZ = PWINDOW->m_vRealSize.goalv(); const auto SIZ = PWINDOW->m_vRealSize.goalv();
if (PWINDOW->m_uSurface.xwayland->width > 1 && PWINDOW->m_uSurface.xwayland->height > 1) if (PWINDOW->m_uSurface.xwayland->width > 1 && PWINDOW->m_uSurface.xwayland->height > 1)
PWINDOW->m_bHidden = false; PWINDOW->setHidden(false);
else else
PWINDOW->m_bHidden = true; PWINDOW->setHidden(true);
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) { 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); 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);
@@ -793,15 +887,35 @@ void Events::listener_NewXDGDeco(wl_listener* listener, void* data) {
void Events::listener_requestMaximize(void* owner, void* data) { void Events::listener_requestMaximize(void* owner, void* data) {
const auto PWINDOW = (CWindow*)owner; 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; 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 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); 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) { 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) { void Events::listener_requestMove(void* owner, void* data) {

View File

@@ -357,8 +357,8 @@ void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) {
// Rotation + reflection // Rotation + reflection
mat[0] = x * t[0]; mat[0] = x * t[0];
mat[1] = x * t[1]; mat[1] = x * t[1];
mat[3] = y * -t[3]; mat[3] = y * t[3];
mat[4] = y * -t[4]; mat[4] = y * t[4];
// Translation // Translation
mat[2] = -copysign(1.0f, mat[0] + mat[1]); mat[2] = -copysign(1.0f, mat[0] + mat[1]);

View File

@@ -99,10 +99,6 @@ void CMonitor::onConnect(bool noRule) {
wlr_output_enable(output, 1); 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 // set mode, also applies
if (!noRule) if (!noRule)
g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true); g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true);
@@ -136,6 +132,9 @@ void CMonitor::onConnect(bool noRule) {
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", szName}); g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", szName});
// ensure VRR (will enable if necessary)
g_pConfigManager->ensureVRR(this);
} }
void CMonitor::onDisconnect() { void CMonitor::onDisconnect() {
@@ -152,6 +151,9 @@ void CMonitor::onDisconnect() {
} }
} }
if (g_pCompositor->m_pLastMonitor == this)
g_pCompositor->m_pLastMonitor = BACKUPMON;
// remove mirror // remove mirror
if (pMirrorOf) { if (pMirrorOf) {
pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; })); pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; }));

View File

@@ -11,7 +11,7 @@ struct SMonitorRule;
class CMonitor { class CMonitor {
public: public:
Vector2D vecPosition = Vector2D(0,0); Vector2D vecPosition = Vector2D(-1,-1); // means unset
Vector2D vecSize = Vector2D(0,0); Vector2D vecSize = Vector2D(0,0);
Vector2D vecPixelSize = Vector2D(0,0); Vector2D vecPixelSize = Vector2D(0,0);
Vector2D vecTransformedSize = Vector2D(0,0); Vector2D vecTransformedSize = Vector2D(0,0);
@@ -38,6 +38,8 @@ public:
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
bool dpmsStatus = true; 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.
// mirroring // mirroring
CMonitor* pMirrorOf = nullptr; CMonitor* pMirrorOf = nullptr;

View File

@@ -131,6 +131,8 @@ struct SMouse {
bool virt = false; bool virt = false;
bool connected = false; // means connected to the cursor
DYNLISTENER(commitConstraint); DYNLISTENER(commitConstraint);
DYNLISTENER(destroyMouse); DYNLISTENER(destroyMouse);
@@ -326,6 +328,10 @@ struct SIMEPopup {
struct STouchDevice { struct STouchDevice {
wlr_input_device* pWlrDevice = nullptr; wlr_input_device* pWlrDevice = nullptr;
std::string name = "";
std::string boundOutput = "";
DYNLISTENER(destroy); DYNLISTENER(destroy);
bool operator==(const STouchDevice& other) { bool operator==(const STouchDevice& other) {

View File

@@ -0,0 +1,152 @@
#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
};
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) {}

View File

@@ -22,7 +22,6 @@
#include <filesystem> #include <filesystem>
#include <climits> #include <climits>
#if true #if true
// wlroots uses dumb-ass shit that makes it not compile on C++, let's fix that. // wlroots uses dumb-ass shit that makes it not compile on C++, let's fix that.
// https://github.com/swaywm/wlroots/issues/682 // 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_foreign_toplevel_management_v1.h>
#include <wlr/types/wlr_idle_inhibit_v1.h> #include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include <wlr/xwayland.h>
#include <wlr/util/region.h> #include <wlr/util/region.h>
#include <wlr/types/wlr_tablet_pad.h> #include <wlr/types/wlr_tablet_pad.h>
#include <wlr/types/wlr_tablet_tool.h> #include <wlr/types/wlr_tablet_tool.h>
#include <wlr/types/wlr_tablet_v2.h> #include <wlr/types/wlr_tablet_v2.h>
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include <X11/Xproto.h>
#include <wlr/render/egl.h> #include <wlr/render/egl.h>
#include <wlr/render/gles2.h> #include <wlr/render/gles2.h>
#include <wlr/render/wlr_texture.h> #include <wlr/render/wlr_texture.h>
@@ -102,6 +99,13 @@ extern "C" {
#include <wlr/types/wlr_text_input_v3.h> #include <wlr/types/wlr_text_input_v3.h>
#include <wlr/types/wlr_touch.h> #include <wlr/types/wlr_touch.h>
#include <wlr/types/wlr_switch.h> #include <wlr/types/wlr_switch.h>
#include <drm_fourcc.h>
#ifndef NO_XWAYLAND
#include <wlr/xwayland.h>
#include <X11/Xproto.h>
#endif
} }
#undef delete #undef delete
@@ -122,6 +126,7 @@ extern "C" {
#ifdef NO_XWAYLAND #ifdef NO_XWAYLAND
#define XWAYLAND false #define XWAYLAND false
#include "helpers/XWaylandStubs.hpp"
#else #else
#define XWAYLAND true #define XWAYLAND true
#endif #endif

View File

@@ -69,7 +69,7 @@ SDwindleNodeData* SDwindleNodeData::getGroupVisible() {
SDwindleNodeData* current = this->pNextGroupMember; SDwindleNodeData* current = this->pNextGroupMember;
while (current != this) { while (current != this) {
if (!current->pWindow->m_bHidden) { if (!current->pWindow->isHidden()) {
return current; return current;
} }
@@ -83,11 +83,11 @@ void SDwindleNodeData::setGroupFocusedNode(SDwindleNodeData* pMember) {
SDwindleNodeData* current = this->pNextGroupMember; SDwindleNodeData* current = this->pNextGroupMember;
while (current != this) { while (current != this) {
current->pWindow->m_bHidden = current != pMember; current->pWindow->setHidden(current != pMember);
current = current->pNextGroupMember; current = current->pNextGroupMember;
} }
this->pWindow->m_bHidden = pMember != this; this->pWindow->setHidden(pMember != this);
} }
int SDwindleNodeData::getGroupMemberCount() { int SDwindleNodeData::getGroupMemberCount() {
@@ -301,7 +301,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
OPENINGON = getFirstNodeOnWorkspace(PMONITOR->activeWorkspace); OPENINGON = getFirstNodeOnWorkspace(PMONITOR->activeWorkspace);
} else if (*PUSEACTIVE) { } 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); OPENINGON = getNodeFromWindow(g_pCompositor->m_pLastWindow);
} else { } else {
OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal())); OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal()));
@@ -491,7 +491,7 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
} }
PNEXT->setGroupFocusedNode(PNEXT); PNEXT->setGroupFocusedNode(PNEXT);
PNEXT->pWindow->m_bHidden = false; PNEXT->pWindow->setHidden(false);
m_lDwindleNodesData.remove(*PNODE); m_lDwindleNodesData.remove(*PNODE);
@@ -829,7 +829,7 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
toAddWindows.push_back(PWINDOW); toAddWindows.push_back(PWINDOW);
PWINDOW->m_bHidden = false; PWINDOW->setHidden(false);
} }
if (PHEAD->pPreviousGroupMember) if (PHEAD->pPreviousGroupMember)
@@ -997,9 +997,9 @@ void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward, CWind
pNewNode->pWindow->m_bIsFloating = PNODE->pWindow->m_bIsFloating; pNewNode->pWindow->m_bIsFloating = PNODE->pWindow->m_bIsFloating;
if (PNODE->pWindow->m_bIsFullscreen) { if (PNODE->pWindow->m_bIsFullscreen) {
PNODE->pWindow->m_bHidden = false; PNODE->pWindow->setHidden(false);
g_pCompositor->setWindowFullscreen(PNODE->pWindow, false, PWORKSPACE->m_efFullscreenMode); 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); g_pCompositor->setWindowFullscreen(pNewNode->pWindow, true, PWORKSPACE->m_efFullscreenMode);
pNewNode->pWindow->m_vRealSize.warp(); pNewNode->pWindow->m_vRealSize.warp();
@@ -1181,7 +1181,7 @@ std::string CHyprDwindleLayout::getLayoutName() {
void CHyprDwindleLayout::onEnable() { void CHyprDwindleLayout::onEnable() {
for (auto& w : g_pCompositor->m_vWindows) { 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; continue;
onWindowCreatedTiling(w.get()); onWindowCreatedTiling(w.get());

View File

@@ -26,6 +26,9 @@ void IHyprLayout::onWindowRemoved(CWindow* pWindow) {
} else { } else {
onWindowRemovedTiling(pWindow); onWindowRemovedTiling(pWindow);
} }
if (pWindow == m_pLastTiledWindow)
m_pLastTiledWindow = nullptr;
} }
void IHyprLayout::onWindowRemovedFloating(CWindow* pWindow) { void IHyprLayout::onWindowRemovedFloating(CWindow* pWindow) {
@@ -47,7 +50,7 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
pWindow->m_vRealSize = Vector2D(PWINDOWSURFACE->current.width, PWINDOWSURFACE->current.height); 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? 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; return;
} }
@@ -208,7 +211,12 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW); g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
if (g_pInputManager->dragMode == MBIND_MOVE) { if (g_pInputManager->dragMode == MBIND_MOVE) {
if (*PANIMATE) {
DRAGGINGWINDOW->m_vRealPosition = m_vBeginDragPositionXY + DELTA;
} else {
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA); DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA);
}
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
} else if (g_pInputManager->dragMode == MBIND_RESIZE) { } else if (g_pInputManager->dragMode == MBIND_RESIZE) {
@@ -296,6 +304,9 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
pWindow->m_vLastFloatingSize = PSAVEDSIZE; 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); onWindowCreatedTiling(pWindow);
pWindow->m_vRealPosition.setValue(PSAVEDPOS); pWindow->m_vRealPosition.setValue(PSAVEDPOS);
@@ -303,6 +314,9 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
// fix pseudo leaving artifacts // fix pseudo leaving artifacts
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID)); g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
if (pWindow == g_pCompositor->m_pLastWindow)
m_pLastTiledWindow = pWindow;
} else { } else {
pWindow->m_vSize = pWindow->m_vRealSize.vec(); pWindow->m_vSize = pWindow->m_vRealSize.vec();
pWindow->m_vPosition = pWindow->m_vRealPosition.vec(); pWindow->m_vPosition = pWindow->m_vRealPosition.vec();
@@ -317,6 +331,9 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID)); g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
pWindow->m_sSpecialRenderData.rounding = true; pWindow->m_sSpecialRenderData.rounding = true;
if (pWindow == m_pLastTiledWindow)
m_pLastTiledWindow = nullptr;
} }
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow); g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
@@ -339,3 +356,47 @@ void IHyprLayout::moveActiveWindow(const Vector2D& delta, CWindow* pWindow) {
g_pHyprRenderer->damageWindow(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;
}

View File

@@ -123,10 +123,22 @@ public:
*/ */
virtual std::string getLayoutName() = 0; 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: private:
Vector2D m_vBeginDragXY; Vector2D m_vBeginDragXY;
Vector2D m_vLastDragXY; Vector2D m_vLastDragXY;
Vector2D m_vBeginDragPositionXY; Vector2D m_vBeginDragPositionXY;
Vector2D m_vBeginDragSizeXY; Vector2D m_vBeginDragSizeXY;
int m_iGrabbedCorner = 0; int m_iGrabbedCorner = 0;
CWindow* m_pLastTiledWindow = nullptr;
}; };

View File

@@ -603,7 +603,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
void CHyprMasterLayout::onEnable() { void CHyprMasterLayout::onEnable() {
for (auto& w : g_pCompositor->m_vWindows) { 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; continue;
onWindowCreatedTiling(w.get()); onWindowCreatedTiling(w.get());

View File

@@ -153,7 +153,7 @@ void CAnimationManager::tick() {
g_pHyprRenderer->damageWindow(PWINDOW); g_pHyprRenderer->damageWindow(PWINDOW);
} else if (PWORKSPACE) { } else if (PWORKSPACE) {
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (!w->m_bIsMapped || w->m_bHidden) if (!w->m_bIsMapped || w->isHidden())
continue; continue;
if (w->m_iWorkspaceID != PWORKSPACE->m_iID) if (w->m_iWorkspaceID != PWORKSPACE->m_iID)
@@ -361,6 +361,10 @@ void CAnimationManager::onWindowPostCreateClose(CWindow* pWindow, bool close) {
if (!pWindow->m_vRealPosition.isBeingAnimated() && !pWindow->m_vRealSize.isBeingAnimated()) if (!pWindow->m_vRealPosition.isBeingAnimated() && !pWindow->m_vRealSize.isBeingAnimated())
return; 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 != "") { if (pWindow->m_sAdditionalConfigData.animationStyle != "") {
// the window has config'd special anim // the window has config'd special anim
if (pWindow->m_sAdditionalConfigData.animationStyle.find("slide") == 0) { if (pWindow->m_sAdditionalConfigData.animationStyle.find("slide") == 0) {

View File

@@ -18,6 +18,23 @@
CEventManager::CEventManager() { 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() { void CEventManager::startThread() {
m_tThread = std::thread([&]() { m_tThread = std::thread([&]() {
const auto SOCKET = socket(AF_UNIX, SOCK_STREAM, 0); const auto SOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -46,12 +63,14 @@ void CEventManager::startThread() {
if (ACCEPTEDCONNECTION > 0) { if (ACCEPTEDCONNECTION > 0) {
// new connection! // new connection!
m_dAcceptedSocketFDs.push_back(ACCEPTEDCONNECTION);
int flagsNew = fcntl(ACCEPTEDCONNECTION, F_GETFL, 0); int flagsNew = fcntl(ACCEPTEDCONNECTION, F_GETFL, 0);
fcntl(ACCEPTEDCONNECTION, F_SETFL, flagsNew | O_NONBLOCK); fcntl(ACCEPTEDCONNECTION, F_SETFL, flagsNew | O_NONBLOCK);
Debug::log(LOG, "Socket 2 accepted a new client at FD %d", ACCEPTEDCONNECTION); Debug::log(LOG, "Socket 2 accepted a new client at FD %d", ACCEPTEDCONNECTION);
// 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)});
} }
ensureFDsValid(); ensureFDsValid();
@@ -68,7 +87,7 @@ void CEventManager::ensureFDsValid() {
// pong if all FDs valid // pong if all FDs valid
for (auto it = m_dAcceptedSocketFDs.begin(); it != m_dAcceptedSocketFDs.end();) { for (auto it = m_dAcceptedSocketFDs.begin(); it != m_dAcceptedSocketFDs.end();) {
auto sizeRead = recv(*it, &readBuf, 1024, 0); auto sizeRead = recv(it->first, &readBuf, 1024, 0);
if (sizeRead != 0) { if (sizeRead != 0) {
it++; it++;
@@ -90,7 +109,7 @@ void CEventManager::flushEvents() {
for (auto& ev : m_dQueuedEvents) { for (auto& ev : m_dQueuedEvents) {
std::string eventString = (ev.event + ">>" + ev.data).substr(0, 1022) + "\n"; std::string eventString = (ev.event + ">>" + ev.data).substr(0, 1022) + "\n";
for (auto& fd : m_dAcceptedSocketFDs) { for (auto& fd : m_dAcceptedSocketFDs) {
write(fd, eventString.c_str(), eventString.length()); write(fd.first, eventString.c_str(), eventString.length());
} }
} }

View File

@@ -31,7 +31,7 @@ private:
std::mutex eventQueueMutex; std::mutex eventQueueMutex;
std::deque<SHyprIPCEvent> m_dQueuedEvents; 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; inline std::unique_ptr<CEventManager> g_pEventManager;

View File

@@ -44,6 +44,7 @@ CKeybindManager::CKeybindManager() {
m_mDispatchers["swapactiveworkspaces"] = swapActiveWorkspaces; m_mDispatchers["swapactiveworkspaces"] = swapActiveWorkspaces;
m_mDispatchers["pin"] = pinActive; m_mDispatchers["pin"] = pinActive;
m_mDispatchers["mouse"] = mouse; m_mDispatchers["mouse"] = mouse;
m_mDispatchers["bringactivetotop"] = bringActiveToTop;
m_tScrollTimer.reset(); m_tScrollTimer.reset();
} }
@@ -567,7 +568,6 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
if (!PWINDOW) if (!PWINDOW)
return; return;
if (g_pCompositor->windowValidMapped(PWINDOW)) {
// remove drag status // remove drag status
g_pInputManager->currentlyDraggedWindow = nullptr; g_pInputManager->currentlyDraggedWindow = nullptr;
@@ -577,13 +577,12 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating; PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating;
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW); g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW);
}
} }
void CKeybindManager::toggleActivePseudo(std::string args) { void CKeybindManager::toggleActivePseudo(std::string args) {
const auto ACTIVEWINDOW = g_pCompositor->m_pLastWindow; const auto ACTIVEWINDOW = g_pCompositor->m_pLastWindow;
if (!g_pCompositor->windowValidMapped(ACTIVEWINDOW)) if (!ACTIVEWINDOW)
return; return;
ACTIVEWINDOW->m_bIsPseudotiled = !ACTIVEWINDOW->m_bIsPseudotiled; ACTIVEWINDOW->m_bIsPseudotiled = !ACTIVEWINDOW->m_bIsPseudotiled;
@@ -610,16 +609,20 @@ void CKeybindManager::changeworkspace(std::string args) {
internal = true; internal = true;
} else if (args.find("previous") == 0) { } else if (args.find("previous") == 0) {
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID( const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
g_pCompositor->m_pLastMonitor->activeWorkspace);
// Do nothing if there's no previous workspace, otherwise switch to it. // Do nothing if there's no previous workspace, otherwise switch to it.
if (PCURRENTWORKSPACE->m_iPrevWorkspaceID == -1) { if (PCURRENTWORKSPACE->m_iPrevWorkspaceID == -1) {
Debug::log(LOG, "No previous workspace to change to"); Debug::log(LOG, "No previous workspace to change to");
return; return;
} } else {
else {
workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID; 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; isSwitchingToPrevious = true;
// If the previous workspace ID isn't reset, cycles can form when continually going // If the previous workspace ID isn't reset, cycles can form when continually going
@@ -766,7 +769,7 @@ void CKeybindManager::changeworkspace(std::string args) {
if (const auto POLDWORKSPACE = g_pCompositor->getWorkspaceByID(OLDWORKSPACE); POLDWORKSPACE) if (const auto POLDWORKSPACE = g_pCompositor->getWorkspaceByID(OLDWORKSPACE); POLDWORKSPACE)
POLDWORKSPACE->startAnim(false, ANIMTOLEFT); 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) if (!isSwitchingToPrevious)
// Remember previous workspace. // Remember previous workspace.
@@ -775,13 +778,6 @@ void CKeybindManager::changeworkspace(std::string args) {
// start anim on new workspace // start anim on new workspace
PWORKSPACE->startAnim(true, ANIMTOLEFT); 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; PMONITOR->specialWorkspaceOpen = false;
// fix pinned windows // fix pinned windows
@@ -821,7 +817,7 @@ void CKeybindManager::changeworkspace(std::string args) {
void CKeybindManager::fullscreenActive(std::string args) { void CKeybindManager::fullscreenActive(std::string args) {
const auto PWINDOW = g_pCompositor->m_pLastWindow; const auto PWINDOW = g_pCompositor->m_pLastWindow;
if (!g_pCompositor->windowValidMapped(PWINDOW)) if (!PWINDOW)
return; return;
if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
@@ -841,7 +837,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
PWINDOW = g_pCompositor->m_pLastWindow; PWINDOW = g_pCompositor->m_pLastWindow;
} }
if (!g_pCompositor->windowValidMapped(PWINDOW)) if (!PWINDOW)
return; return;
const auto OLDWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); const auto OLDWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
@@ -894,7 +890,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
// and restore it // and restore it
if (PWINDOW->m_bIsFloating) { 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_vRealPosition.setValueAndWarp(PSAVEDPOS - g_pCompositor->getMonitorFromID(OLDWORKSPACE->m_iMonitorID)->vecPosition + g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID)->vecPosition);
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec(); PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec();
} }
@@ -929,7 +925,7 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
PWINDOW = g_pCompositor->m_pLastWindow; PWINDOW = g_pCompositor->m_pLastWindow;
} }
if (!g_pCompositor->windowValidMapped(PWINDOW)) if (!PWINDOW)
return; return;
int workspaceToMoveTo = 0; int workspaceToMoveTo = 0;
@@ -1035,16 +1031,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); const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg);
if (PWINDOWTOCHANGETO) { if (PWINDOWTOCHANGETO) {
@@ -1089,12 +1075,12 @@ void CKeybindManager::moveActiveTo(std::string args) {
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; const auto PLASTWINDOW = g_pCompositor->m_pLastWindow;
if (!g_pCompositor->windowValidMapped(PLASTWINDOW) || PLASTWINDOW->m_bIsFullscreen) if (!PLASTWINDOW || PLASTWINDOW->m_bIsFullscreen)
return; return;
const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg); const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg);
if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO)) if (!PWINDOWTOCHANGETO)
return; return;
g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, PWINDOWTOCHANGETO); g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, PWINDOWTOCHANGETO);
@@ -1140,7 +1126,7 @@ void CKeybindManager::alterSplitRatio(std::string args) {
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; const auto PLASTWINDOW = g_pCompositor->m_pLastWindow;
if (!g_pCompositor->windowValidMapped(PLASTWINDOW)) if (!PLASTWINDOW)
return; return;
g_pLayoutManager->getCurrentLayout()->alterSplitRatioBy(PLASTWINDOW, splitratio); g_pLayoutManager->getCurrentLayout()->alterSplitRatioBy(PLASTWINDOW, splitratio);
@@ -1170,7 +1156,7 @@ void CKeybindManager::moveCursorToCorner(std::string arg) {
const auto PWINDOW = g_pCompositor->m_pLastWindow; const auto PWINDOW = g_pCompositor->m_pLastWindow;
if (!g_pCompositor->windowValidMapped(PWINDOW)) if (!PWINDOW)
return; return;
switch (CORNER) { switch (CORNER) {
@@ -1372,7 +1358,7 @@ void CKeybindManager::forceRendererReload(std::string args) {
} }
void CKeybindManager::resizeActive(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; return;
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealSize.goalv()); const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealSize.goalv());
@@ -1380,11 +1366,11 @@ void CKeybindManager::resizeActive(std::string args) {
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - g_pCompositor->m_pLastWindow->m_vRealSize.goalv()); 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) 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) { 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; return;
const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealPosition.goalv()); const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealPosition.goalv());
@@ -1432,13 +1418,10 @@ void CKeybindManager::resizeWindow(std::string args) {
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goalv(), PWINDOW); g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goalv(), PWINDOW);
if (PWINDOW->m_vRealSize.goalv().x > 1 && PWINDOW->m_vRealSize.goalv().y > 1) 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) { void CKeybindManager::circleNext(std::string arg) {
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
return;
auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) { auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) {
if (PWINDOWTOCHANGETO == g_pCompositor->m_pLastWindow || !PWINDOWTOCHANGETO) if (PWINDOWTOCHANGETO == g_pCompositor->m_pLastWindow || !PWINDOWTOCHANGETO)
return; return;
@@ -1461,6 +1444,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") if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow, true)); switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow, true));
else else
@@ -1587,7 +1581,7 @@ void CKeybindManager::layoutmsg(std::string msg) {
void CKeybindManager::toggleOpaque(std::string unused) { void CKeybindManager::toggleOpaque(std::string unused) {
const auto PWINDOW = g_pCompositor->m_pLastWindow; const auto PWINDOW = g_pCompositor->m_pLastWindow;
if (!g_pCompositor->windowValidMapped(PWINDOW)) if (!PWINDOW)
return; return;
PWINDOW->m_sAdditionalConfigData.forceOpaque = !PWINDOW->m_sAdditionalConfigData.forceOpaque; PWINDOW->m_sAdditionalConfigData.forceOpaque = !PWINDOW->m_sAdditionalConfigData.forceOpaque;
@@ -1627,7 +1621,7 @@ void CKeybindManager::swapnext(std::string arg) {
CWindow* toSwap = nullptr; CWindow* toSwap = nullptr;
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow)) if (!g_pCompositor->m_pLastWindow)
return; return;
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; const auto PLASTWINDOW = g_pCompositor->m_pLastWindow;
@@ -1668,7 +1662,7 @@ void CKeybindManager::swapActiveWorkspaces(std::string args) {
} }
void CKeybindManager::pinActive(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; return;
g_pCompositor->m_pLastWindow->m_bPinned = !g_pCompositor->m_pLastWindow->m_bPinned; g_pCompositor->m_pLastWindow->m_bPinned = !g_pCompositor->m_pLastWindow->m_bPinned;
@@ -1719,3 +1713,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);
}

View File

@@ -120,6 +120,7 @@ private:
static void swapActiveWorkspaces(std::string); static void swapActiveWorkspaces(std::string);
static void pinActive(std::string); static void pinActive(std::string);
static void mouse(std::string); static void mouse(std::string);
static void bringActiveToTop(std::string);
friend class CCompositor; friend class CCompositor;
friend class CInputManager; friend class CInputManager;

View File

@@ -3,7 +3,7 @@
#include "../events/Events.hpp" #include "../events/Events.hpp"
CHyprXWaylandManager::CHyprXWaylandManager() { CHyprXWaylandManager::CHyprXWaylandManager() {
if (XWAYLAND) { #ifndef NO_XWAYLAND
m_sWLRXWayland = wlr_xwayland_create(g_pCompositor->m_sWLDisplay, g_pCompositor->m_sWLRCompositor, 1); m_sWLRXWayland = wlr_xwayland_create(g_pCompositor->m_sWLDisplay, g_pCompositor->m_sWLRCompositor, 1);
if (!m_sWLRXWayland) { if (!m_sWLRXWayland) {
@@ -17,7 +17,9 @@ CHyprXWaylandManager::CHyprXWaylandManager() {
setenv("DISPLAY", m_sWLRXWayland->display_name, 1); setenv("DISPLAY", m_sWLRXWayland->display_name, 1);
Debug::log(LOG, "CHyprXWaylandManager started on display %s", m_sWLRXWayland->display_name); 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() { CHyprXWaylandManager::~CHyprXWaylandManager() {
@@ -51,17 +53,21 @@ void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate)
void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) { void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
if (pWindow->m_bIsX11) { 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_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_activate(pWindow->m_uSurface.xwayland, activate);
wlr_xwayland_surface_restack(pWindow->m_uSurface.xwayland, NULL, XCB_STACK_MODE_ABOVE);
} }
else else
wlr_xdg_toplevel_set_activated(pWindow->m_uSurface.xdg->toplevel, activate); wlr_xdg_toplevel_set_activated(pWindow->m_uSurface.xdg->toplevel, activate);
if (activate) {
g_pCompositor->m_pLastFocus = getWindowSurface(pWindow); g_pCompositor->m_pLastFocus = getWindowSurface(pWindow);
g_pCompositor->m_pLastWindow = pWindow; g_pCompositor->m_pLastWindow = pWindow;
}
if (!pWindow->m_bPinned) if (!pWindow->m_bPinned)
g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_pLastFocusedWindow = pWindow; 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) { void CHyprXWaylandManager::getGeometryForWindow(CWindow* pWindow, wlr_box* pbox) {
if (pWindow->m_bIsX11) { 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->x = pWindow->m_uSurface.xwayland->x;
pbox->y = pWindow->m_uSurface.xwayland->y; pbox->y = pWindow->m_uSurface.xwayland->y;
pbox->width = pWindow->m_uSurface.xwayland->width; pbox->width = pWindow->m_uSurface.xwayland->width;
pbox->height = pWindow->m_uSurface.xwayland->height; pbox->height = pWindow->m_uSurface.xwayland->height;
}
} else { } else {
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, pbox); wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, pbox);
} }

View File

@@ -35,7 +35,11 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
static auto *const PHOGFOCUS = &g_pConfigManager->getConfigValuePtr("misc:layers_hog_keyboard_focus")->intValue; 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; 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;
if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown)
return; return;
if (!g_pCompositor->m_sSeat.mouse) { if (!g_pCompositor->m_sSeat.mouse) {
@@ -153,14 +157,14 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
return; return;
} }
foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow);
surfacePos = pFoundWindow->m_vRealPosition.vec();
// only check floating because tiled cant be over fullscreen // only check floating because tiled cant be over fullscreen
for (auto w = g_pCompositor->m_vWindows.rbegin(); w != g_pCompositor->m_vWindows.rend(); w++) { 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}; 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(); pFoundWindow = (*w).get();
break;
}
}
if (!pFoundWindow->m_bIsX11) { if (!pFoundWindow->m_bIsX11) {
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords); foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
@@ -169,10 +173,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow); foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow);
surfacePos = pFoundWindow->m_vRealPosition.vec(); surfacePos = pFoundWindow->m_vRealPosition.vec();
} }
break;
}
}
} }
// then windows // then windows
@@ -264,9 +264,16 @@ 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 (pFoundWindow) {
if (*PFOLLOWMOUSE != 1 && !refocus) { 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 // enter if change floating style
if (*PFOLLOWMOUSE != 3 && allowKeyboardRefocus) if (*PFOLLOWMOUSE != 3 && allowKeyboardRefocus)
g_pCompositor->focusWindow(pFoundWindow, foundSurface); g_pCompositor->focusWindow(pFoundWindow, foundSurface);
@@ -300,7 +307,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
} else { } else {
if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive && *PFOLLOWMOUSE != 3 && allowKeyboardRefocus) { if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive && *PFOLLOWMOUSE != 3 && allowKeyboardRefocus) {
g_pCompositor->focusSurface(foundSurface); g_pCompositor->focusSurface(foundSurface);
g_pCompositor->m_pLastWindow = nullptr; // reset last window as we have a full focus on a LS
} }
if (pFoundLayerSurface) if (pFoundLayerSurface)
@@ -396,7 +402,7 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
refocus(); refocus();
// if clicked on a floating window make it top // 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); g_pCompositor->moveWindowToTop(g_pCompositor->m_pLastWindow);
break; break;
@@ -415,7 +421,7 @@ void CInputManager::processMouseDownKill(wlr_pointer_button_event* e) {
case WLR_BUTTON_PRESSED: { case WLR_BUTTON_PRESSED: {
const auto PWINDOW = g_pCompositor->m_pLastWindow; const auto PWINDOW = g_pCompositor->m_pLastWindow;
if (!g_pCompositor->windowValidMapped(PWINDOW)){ if (!PWINDOW) {
Debug::log(ERR, "Cannot kill invalid window!"); Debug::log(ERR, "Cannot kill invalid window!");
break; break;
} }
@@ -673,6 +679,8 @@ void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, mouse); wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, mouse);
PMOUSE->connected = true;
g_pCompositor->m_sSeat.mouse = PMOUSE; g_pCompositor->m_sSeat.mouse = PMOUSE;
m_tmrLastCursorMovement.reset(); m_tmrLastCursorMovement.reset();
@@ -689,6 +697,17 @@ void CInputManager::setPointerConfigs() {
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname); 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)) { if (wlr_input_device_is_libinput(m.mouse)) {
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(m.mouse); const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(m.mouse);
@@ -1027,6 +1046,13 @@ void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
const auto PNEWDEV = &m_lTouchDevices.emplace_back(); const auto PNEWDEV = &m_lTouchDevices.emplace_back();
PNEWDEV->pWlrDevice = pDevice; 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); wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, pDevice);
Debug::log(LOG, "New touch device added at %x", PNEWDEV); Debug::log(LOG, "New touch device added at %x", PNEWDEV);
@@ -1036,6 +1062,65 @@ void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
}, PNEWDEV, "TouchDevice"); }, 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) { void CInputManager::destroyTouchDevice(STouchDevice* pDevice) {
Debug::log(LOG, "Touch device at %x removed", pDevice); Debug::log(LOG, "Touch device at %x removed", pDevice);

View File

@@ -20,6 +20,8 @@ enum eMouseBindMode {
struct STouchData { struct STouchData {
CWindow* touchFocusWindow = nullptr; CWindow* touchFocusWindow = nullptr;
SLayerSurface* touchFocusLS = nullptr;
wlr_surface* touchFocusSurface = nullptr;
Vector2D touchSurfaceOrigin; Vector2D touchSurfaceOrigin;
}; };
@@ -53,6 +55,7 @@ public:
void setKeyboardLayout(); void setKeyboardLayout();
void setPointerConfigs(); void setPointerConfigs();
void setTouchDeviceConfigs();
void updateDragIcon(); void updateDragIcon();
void updateCapabilities(wlr_input_device*); void updateCapabilities(wlr_input_device*);
@@ -139,6 +142,11 @@ private:
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*); STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
void applyConfigToKeyboard(SKeyboard*); void applyConfigToKeyboard(SKeyboard*);
// this will be set after a refocus()
wlr_surface* m_pFoundSurfaceToFocus = nullptr;
SLayerSurface* m_pFoundLSToFocus = nullptr;
CWindow* m_pFoundWindowToFocus = nullptr;
}; };
inline std::unique_ptr<CInputManager> g_pInputManager; inline std::unique_ptr<CInputManager> g_pInputManager;

View File

@@ -301,7 +301,7 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput) {
const auto PINPUT = (STextInput*)owner; const auto PINPUT = (STextInput*)owner;
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
Debug::log(ERR, "Enabling TextInput on no IME!"); Debug::log(WARN, "Enabling TextInput on no IME!");
return; return;
} }
@@ -317,12 +317,12 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput) {
const auto PINPUT = (STextInput*)owner; const auto PINPUT = (STextInput*)owner;
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
Debug::log(ERR, "Committing TextInput on no IME!"); Debug::log(WARN, "Committing TextInput on no IME!");
return; return;
} }
if (!PINPUT->pWlrInput->current_enabled) { if (!PINPUT->pWlrInput->current_enabled) {
Debug::log(ERR, "Disabled TextInput commit?"); Debug::log(WARN, "Disabled TextInput commit?");
return; return;
} }
@@ -335,7 +335,7 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput) {
const auto PINPUT = (STextInput*)owner; const auto PINPUT = (STextInput*)owner;
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
Debug::log(ERR, "Disabling TextInput on no IME!"); Debug::log(WARN, "Disabling TextInput on no IME!");
return; return;
} }
@@ -352,7 +352,7 @@ void CInputMethodRelay::createNewTextInput(wlr_text_input_v3* pInput) {
const auto PINPUT = (STextInput*)owner; const auto PINPUT = (STextInput*)owner;
if (!g_pInputManager->m_sIMERelay.m_pWLRIME) { if (!g_pInputManager->m_sIMERelay.m_pWLRIME) {
Debug::log(ERR, "Disabling TextInput on no IME!"); Debug::log(WARN, "Disabling TextInput on no IME!");
return; return;
} }

View File

@@ -4,6 +4,7 @@
void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) { void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
static auto *const PSWIPE = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe")->intValue; 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 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) if (e->fingers != *PSWIPEFINGERS || *PSWIPE == 0)
return; return;
@@ -15,7 +16,7 @@ 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 return; // disallow swiping when there's 1 workspace on a monitor
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
@@ -42,6 +43,7 @@ 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 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 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 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"; const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert";
// commit // commit
@@ -49,7 +51,11 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname); auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
auto workspaceIDRight = 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) && *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 PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.vec(); const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.vec();
@@ -60,6 +66,7 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
// revert // revert
if (abs(m_sActiveSwipe.delta) < 2) { if (abs(m_sActiveSwipe.delta) < 2) {
PWORKSPACEL->m_vRenderOffset.setValueAndWarp(Vector2D(0,0)); PWORKSPACEL->m_vRenderOffset.setValueAndWarp(Vector2D(0,0));
if (PWORKSPACER)
PWORKSPACER->m_vRenderOffset.setValueAndWarp(Vector2D(0,0)); PWORKSPACER->m_vRenderOffset.setValueAndWarp(Vector2D(0,0));
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0,0)); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0,0));
} else { } else {
@@ -69,7 +76,7 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
PWORKSPACEL->m_vRenderOffset = Vector2D({0, -m_sActiveSwipe.pMonitor->vecSize.y}); PWORKSPACEL->m_vRenderOffset = Vector2D({0, -m_sActiveSwipe.pMonitor->vecSize.y});
else else
PWORKSPACEL->m_vRenderOffset = Vector2D({-m_sActiveSwipe.pMonitor->vecSize.x, 0}); PWORKSPACEL->m_vRenderOffset = Vector2D({-m_sActiveSwipe.pMonitor->vecSize.x, 0});
} else { } else if (PWORKSPACER) {
// to right // to right
if (VERTANIMS) if (VERTANIMS)
PWORKSPACER->m_vRenderOffset = Vector2D({0, m_sActiveSwipe.pMonitor->vecSize.y}); PWORKSPACER->m_vRenderOffset = Vector2D({0, m_sActiveSwipe.pMonitor->vecSize.y});
@@ -104,9 +111,15 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
pSwitchedTo = PWORKSPACEL; pSwitchedTo = PWORKSPACEL;
} else { } else {
// switch to right // 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)); 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_vRenderOffset.setValue(RENDEROFFSET);
PWORKSPACER->m_fAlpha.setValueAndWarp(255.f); PWORKSPACER->m_fAlpha.setValueAndWarp(255.f);
@@ -128,6 +141,7 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor); g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
PWORKSPACEL->m_bForceRendering = false; PWORKSPACEL->m_bForceRendering = false;
if (PWORKSPACER)
PWORKSPACER->m_bForceRendering = false; PWORKSPACER->m_bForceRendering = false;
m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = false; m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = false;
@@ -137,7 +151,7 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
// apply alpha // apply alpha
for (auto& ls : g_pCompositor->m_pLastMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { 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;
} }
} }
@@ -147,6 +161,7 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
static auto *const PSWIPEDIST = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance")->intValue; 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 PSWIPEINVR = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_invert")->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"; const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert";
@@ -159,7 +174,7 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname); auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
auto workspaceIDRight = 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 m_sActiveSwipe.pWorkspaceBegin = nullptr; // invalidate the swipe
return; return;
} }
@@ -168,8 +183,13 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
m_sActiveSwipe.delta = std::clamp(m_sActiveSwipe.delta, (double)-*PSWIPEDIST, (double)*PSWIPEDIST); 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 (m_sActiveSwipe.delta < 0) {
if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID){ if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID && !*PSWIPENEW){
m_sActiveSwipe.delta = 0; m_sActiveSwipe.delta = 0;
return; return;
} }
@@ -196,7 +216,18 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDLeft); g_pCompositor->updateWorkspaceWindowDecos(workspaceIDLeft);
} else { } 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; m_sActiveSwipe.delta = 0;
return; return;
} }

View File

@@ -219,7 +219,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
void CInputManager::focusTablet(STablet* pTab, wlr_tablet_tool* pTool, bool motion) { void CInputManager::focusTablet(STablet* pTab, wlr_tablet_tool* pTool, bool motion) {
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(pTool); 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 CURSORPOS = g_pInputManager->getMouseCoordsInternal();
const auto LOCAL = CURSORPOS - PWINDOW->m_vRealPosition.goalv(); const auto LOCAL = CURSORPOS - PWINDOW->m_vRealPosition.goalv();

View File

@@ -3,44 +3,65 @@
void CInputManager::onTouchDown(wlr_touch_down_event* e) { void CInputManager::onTouchDown(wlr_touch_down_event* e) {
auto PMONITOR = g_pCompositor->getMonitorFromName(e->touch->output_name ? e->touch->output_name : ""); 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; PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_pLastMonitor;
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); 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(); 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; 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 { } 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; 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.touchSurfaceOrigin = g_pInputManager->getMouseCoordsInternal() - local;
} else {
m_sTouchData.touchFocusWindow = g_pCompositor->m_pLastWindow; 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);
} }
void CInputManager::onTouchUp(wlr_touch_up_event* e){ 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); wlr_seat_touch_notify_up(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id);
} }
} }
void CInputManager::onTouchMove(wlr_touch_motion_event* e){ 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); 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); 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; 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); wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id, local.x, local.y);
} }
} }

View File

@@ -18,7 +18,7 @@ executable('Hyprland', src,
xcb_dep, xcb_dep,
dependency('pixman-1'), dependency('pixman-1'),
dependency('GL'), dependency('GL', 'opengl'),
dependency('threads') dependency('threads')
], ],
install : true install : true

View File

@@ -74,6 +74,7 @@ void CFramebuffer::release() {
m_cTex.m_iTexID = 0; m_cTex.m_iTexID = 0;
m_iFb = -1; m_iFb = -1;
m_Size = Vector2D();
} }
CFramebuffer::~CFramebuffer() { CFramebuffer::~CFramebuffer() {

View File

@@ -323,16 +323,18 @@ void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixm
float glMatrix[9]; float glMatrix[9];
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
wlr_matrix_transpose(glMatrix, glMatrix);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(m_RenderData.pCurrentMonData->m_shQUAD.program); 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); 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); glUniform4f(m_RenderData.pCurrentMonData->m_shQUAD.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f);
wlr_box transformedBox; wlr_box transformedBox;
@@ -414,9 +416,6 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
float glMatrix[9]; float glMatrix[9];
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
wlr_matrix_transpose(glMatrix, glMatrix);
CShader* shader = nullptr; CShader* shader = nullptr;
@@ -444,7 +443,12 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
glUseProgram(shader->program); 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); glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix);
#endif
glUniform1i(shader->tex, 0); glUniform1i(shader->tex, 0);
glUniform1f(shader->alpha, alpha / 255.f); glUniform1f(shader->alpha, alpha / 255.f);
glUniform1i(shader->discardOpaque, (int)discardOpaque); glUniform1i(shader->discardOpaque, (int)discardOpaque);
@@ -534,8 +538,6 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
float glMatrix[9]; float glMatrix[9];
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
wlr_matrix_transpose(glMatrix, glMatrix);
// get the config settings // get the config settings
static auto *const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_size")->intValue; static auto *const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_size")->intValue;
@@ -570,7 +572,12 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
glUseProgram(pShader->program); glUseProgram(pShader->program);
// prep two shaders // 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); glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
#endif
glUniform1f(pShader->radius, *PBLURSIZE * (a / 255.f)); // this makes the blursize change with a glUniform1f(pShader->radius, *PBLURSIZE * (a / 255.f)); // this makes the blursize change with a
if (pShader == &m_RenderData.pCurrentMonData->m_shBLUR1) 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)); 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));
@@ -650,7 +657,7 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) {
bool has = false; bool has = false;
for (auto& w : g_pCompositor->m_vWindows) { 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; has = true;
break; break;
} }
@@ -693,7 +700,7 @@ void CHyprOpenGLImpl::preWindowPass() {
bool hasWindows = false; bool hasWindows = false;
for (auto& w : g_pCompositor->m_vWindows) { 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; hasWindows = true;
break; break;
} }
@@ -807,7 +814,7 @@ 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((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!");
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!"); RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
if (!pixman_region32_not_empty(m_RenderData.pDamage)) if (!pixman_region32_not_empty(m_RenderData.pDamage) || (m_pCurrentWindow && m_pCurrentWindow->m_sAdditionalConfigData.forceNoBorder))
return; return;
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue; static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
@@ -845,16 +852,18 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
float glMatrix[9]; float glMatrix[9];
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
wlr_matrix_transpose(glMatrix, glMatrix);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(m_RenderData.pCurrentMonData->m_shBORDER1.program); 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); 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); 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); const auto TOPLEFT = Vector2D(round, round);
@@ -986,9 +995,14 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
timespec now; timespec now;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
const auto BLURLSSTATUS = pLayer->forceBlur;
pLayer->forceBlur = false;
// draw the layer // draw the layer
g_pHyprRenderer->renderLayer(pLayer, PMONITOR, &now); g_pHyprRenderer->renderLayer(pLayer, PMONITOR, &now);
pLayer->forceBlur = BLURLSSTATUS;
// TODO: WARN: // TODO: WARN:
// revise if any stencil-requiring rendering is done to the layers. // revise if any stencil-requiring rendering is done to the layers.
@@ -1103,16 +1117,18 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
float glMatrix[9]; float glMatrix[9];
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
wlr_matrix_transpose(glMatrix, glMatrix);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(m_RenderData.pCurrentMonData->m_shSHADOW.program); 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); 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); 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); const auto TOPLEFT = Vector2D(range + round, range + round);

View File

@@ -12,11 +12,6 @@
#include "Texture.hpp" #include "Texture.hpp"
#include "Framebuffer.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,
};
inline const float fullVerts[] = { inline const float fullVerts[] = {
1, 0, // top right 1, 0, // top right
0, 0, // top left 0, 0, // top left

View File

@@ -84,9 +84,7 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) {
return true; return true;
// if not, check if it maybe is active on a different monitor. // if not, check if it maybe is active on a different monitor.
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */)
(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())))
return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors
if (pMonitor->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) if (pMonitor->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
@@ -169,6 +167,12 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWor
pWorkspaceWindow = w.get(); 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. // then render windows over fullscreen.
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || !w->m_bIsMapped) if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || !w->m_bIsMapped)
@@ -211,7 +215,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWor
} }
void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode) { void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode) {
if (pWindow->m_bHidden) if (pWindow->isHidden())
return; return;
if (pWindow->m_bFadingOut) { if (pWindow->m_bFadingOut) {
@@ -379,7 +383,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
// Non-floating main // Non-floating main
for (auto& w : g_pCompositor->m_vWindows) { 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; continue;
if (w->m_bIsFloating) if (w->m_bIsFloating)
@@ -397,7 +401,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
// Non-floating popup // Non-floating popup
for (auto& w : g_pCompositor->m_vWindows) { 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; continue;
if (w->m_bIsFloating) if (w->m_bIsFloating)
@@ -415,7 +419,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
// floating on top // floating on top
for (auto& w : g_pCompositor->m_vWindows) { 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; continue;
if (!w->m_bIsFloating) if (!w->m_bIsFloating)
@@ -433,7 +437,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
// and then special // and then special
for (auto& w : g_pCompositor->m_vWindows) { 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; continue;
if (w->m_iWorkspaceID != SPECIAL_WORKSPACE_ID) if (w->m_iWorkspaceID != SPECIAL_WORKSPACE_ID)
@@ -756,9 +760,15 @@ void CHyprRenderer::arrangeLayersForMonitor(const int& monitor) {
PMONITOR->vecReservedTopLeft = Vector2D(usableArea.x, usableArea.y) - PMONITOR->vecPosition; PMONITOR->vecReservedTopLeft = Vector2D(usableArea.x, usableArea.y) - PMONITOR->vecPosition;
PMONITOR->vecReservedBottomRight = PMONITOR->vecSize - Vector2D(usableArea.width, usableArea.height) - PMONITOR->vecReservedTopLeft; PMONITOR->vecReservedBottomRight = PMONITOR->vecSize - Vector2D(usableArea.width, usableArea.height) - PMONITOR->vecReservedTopLeft;
const auto ENTRY = g_pConfigManager->m_mAdditionalReservedAreas[PMONITOR->szName]; auto ADDITIONALRESERVED = g_pConfigManager->m_mAdditionalReservedAreas.find(PMONITOR->szName);
PMONITOR->vecReservedTopLeft = PMONITOR->vecReservedTopLeft + Vector2D(ENTRY.left, ENTRY.top); if (ADDITIONALRESERVED == g_pConfigManager->m_mAdditionalReservedAreas.end()) {
PMONITOR->vecReservedBottomRight = PMONITOR->vecReservedBottomRight + Vector2D(ENTRY.right, ENTRY.bottom); 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 // damage the monitor if can
if (PMONITOR->damage) if (PMONITOR->damage)
@@ -940,7 +950,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
&& DELTALESSTHAN(pMonitor->refreshRate, pMonitorRule->refreshRate, 1) && DELTALESSTHAN(pMonitor->refreshRate, pMonitorRule->refreshRate, 1)
&& pMonitor->scale == pMonitorRule->scale && 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)) && ((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()); Debug::log(LOG, "Not applying a new rule to %s because it's already applied!", pMonitor->szName.c_str());
return true; return true;
@@ -949,8 +960,6 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
wlr_output_set_scale(pMonitor->output, pMonitorRule->scale); wlr_output_set_scale(pMonitor->output, pMonitorRule->scale);
pMonitor->scale = pMonitorRule->scale; pMonitor->scale = pMonitorRule->scale;
pMonitor->vecPosition = pMonitorRule->offset;
// loop over modes and choose an appropriate one. // loop over modes and choose an appropriate one.
if (pMonitorRule->resolution != Vector2D() && pMonitorRule->resolution != Vector2D(-1,-1) && pMonitorRule->resolution != Vector2D(-1,-2)) { if (pMonitorRule->resolution != Vector2D() && pMonitorRule->resolution != Vector2D(-1,-1) && pMonitorRule->resolution != Vector2D(-1,-2)) {
if (!wl_list_empty(&pMonitor->output->modes)) { if (!wl_list_empty(&pMonitor->output->modes)) {
@@ -1145,18 +1154,36 @@ 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); wlr_output_set_transform(pMonitor->output, pMonitorRule->transform);
pMonitor->transform = pMonitorRule->transform; pMonitor->transform = pMonitorRule->transform;
pMonitor->vecPixelSize = pMonitor->vecSize; pMonitor->vecPixelSize = pMonitor->vecSize;
// Adaptive sync (VRR) if (pMonitorRule->enable10bit) {
wlr_output_enable_adaptive_sync(pMonitor->output, 1); // try 10b RGB
wlr_output_set_render_format(pMonitor->output, DRM_FORMAT_XRGB2101010);
pMonitor->enabled10bit = true;
if (!wlr_output_test(pMonitor->output)) { if (!wlr_output_test(pMonitor->output)) {
Debug::log(LOG, "Pending output %s does not accept VRR.", pMonitor->output->name); Debug::log(ERR, "Output %s -> 10 bit enabled, but failed format DRM_FORMAT_XRGB2101010. Trying BGR.", pMonitor->output->name);
wlr_output_enable_adaptive_sync(pMonitor->output, 0);
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)) { if (!wlr_output_commit(pMonitor->output)) {
@@ -1169,7 +1196,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
pMonitor->vecSize = (Vector2D(x, y) / pMonitor->scale).floor(); pMonitor->vecSize = (Vector2D(x, y) / pMonitor->scale).floor();
pMonitor->vecTransformedSize = Vector2D(x,y); pMonitor->vecTransformedSize = Vector2D(x,y);
if (pMonitorRule->offset == Vector2D(-1, -1)) { if (pMonitorRule->offset == Vector2D(-1, -1) && pMonitor->vecPosition == Vector2D(-1, -1)) {
// let's find manually a sensible position for it, to the right. // let's find manually a sensible position for it, to the right.
Vector2D finalPos; Vector2D finalPos;
@@ -1183,17 +1210,17 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
} }
pMonitor->vecPosition = finalPos; 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); wlr_output_enable(pMonitor->output, true);
// update renderer (here because it will call rollback, so we cannot do this before committing) // update renderer (here because it will call rollback, so we cannot do this before committing)
g_pHyprOpenGL->destroyMonitorResources(pMonitor); g_pHyprOpenGL->destroyMonitorResources(pMonitor);
// updato wlroots // 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); Events::listener_change(nullptr, nullptr);
// updato us // updato us

View File

@@ -59,6 +59,9 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
if (!m_pWindow->m_sSpecialRenderData.decorate) if (!m_pWindow->m_sSpecialRenderData.decorate)
return; return;
if (m_pWindow->m_sAdditionalConfigData.forceNoShadow)
return;
static auto *const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue; 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 PSHADOWSIZE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_range")->intValue;
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue; static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;

View File

@@ -67,7 +67,7 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D&
// get how many bars we will draw // get how many bars we will draw
int barsToDraw = m_dwGroupMembers.size(); 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; return;
if (!m_pWindow->m_sSpecialRenderData.decorate) if (!m_pWindow->m_sSpecialRenderData.decorate)