mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-15 20:13:49 -07:00
Compare commits
152 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
12f9a0d0b9 | ||
|
fab0f426b5 | ||
|
e735eae4ad | ||
|
57cf6d81a9 | ||
|
77b9d03c3f | ||
|
53e8513000 | ||
|
7976bfa2df | ||
|
a77ffa8cb8 | ||
|
a4a1ad1f9b | ||
|
737b51d032 | ||
|
b3251f2961 | ||
|
c4a77b8da7 | ||
|
38b6f3babb | ||
|
ace7ece4f2 | ||
|
0557b2ed8c | ||
|
9728a39b2e | ||
|
7120dde3d1 | ||
|
e7ab2d8533 | ||
|
a425fbebe4 | ||
|
cca227a53e | ||
|
b9c439a55e | ||
|
726d697821 | ||
|
0ccc0ace88 | ||
|
f43d4a8638 | ||
|
4c7a2faf85 | ||
|
3b66351eeb | ||
|
e58e97b0a3 | ||
|
2dd0b2af71 | ||
|
2ec2b3bfb3 | ||
|
0ec128e5ed | ||
|
083a5cf3c1 | ||
|
8f42401aa8 | ||
|
97a309b784 | ||
|
3bf6f78dad | ||
|
e4ab28b1fb | ||
|
81ad218b8b | ||
|
64c46db087 | ||
|
0920572e70 | ||
|
55ccb1a8cf | ||
|
d1638a09ba | ||
|
e3882b23d0 | ||
|
88e9e03945 | ||
|
0fb9a04526 | ||
|
44899cd548 | ||
|
cd0d049126 | ||
|
180c26ada6 | ||
|
5833abbbd1 | ||
|
514e0ff509 | ||
|
40081cb330 | ||
|
32b18179dd | ||
|
29e7dc6428 | ||
|
3c0605c68e | ||
|
d8b865366a | ||
|
3852418d24 | ||
|
c4d214c42d | ||
|
93b4478e70 | ||
|
7c7a84ff60 | ||
|
a0b2169ed6 | ||
|
ee91df62f0 | ||
|
12c1bb936d | ||
|
5f721dce36 | ||
|
d679d20029 | ||
|
7188ee4f99 | ||
|
c7315617eb | ||
|
d49a1334a8 | ||
|
2c481202ef | ||
|
6cf193e166 | ||
|
b1120ec433 | ||
|
5d4b54b012 | ||
|
b6e226c320 | ||
|
f9b52203f5 | ||
|
a3d3b4fd64 | ||
|
f3f7d3629a | ||
|
c356e42500 | ||
|
0b29caf9ab | ||
|
3dd8db83f1 | ||
|
d5689bb539 | ||
|
e5384774a8 | ||
|
f0e023bff2 | ||
|
3cec45d821 | ||
|
7f46680ab1 | ||
|
f603a22af0 | ||
|
cdac64970e | ||
|
6e0aadc585 | ||
|
2b6ff6837e | ||
|
29997ef4ba | ||
|
5e96d738e6 | ||
|
9df0f0b66c | ||
|
4093b993a2 | ||
|
08cc063e17 | ||
|
a17850e41c | ||
|
6a5c342063 | ||
|
f044e4c951 | ||
|
ce3ba798df | ||
|
0eaf3581a3 | ||
|
62ee5cc273 | ||
|
48bf32c5de | ||
|
904f9b6aee | ||
|
e5d3a71263 | ||
|
0e630e9e74 | ||
|
5f30cb7753 | ||
|
495b92fb53 | ||
|
b57086aa43 | ||
|
09581d32fd | ||
|
86e9f69a69 | ||
|
781828a56e | ||
|
0baf166d39 | ||
|
ace803948a | ||
|
01c2ff34dd | ||
|
22b1370ae5 | ||
|
f309681d4a | ||
|
ce62521883 | ||
|
e7fd0f5aec | ||
|
abfd550ee2 | ||
|
8e51a36c7f | ||
|
5c3bd8e93d | ||
|
05a5e0b4f1 | ||
|
b61d4c3636 | ||
|
e79d3cd2ef | ||
|
1822707c7e | ||
|
c3f7c9bbb5 | ||
|
ee8116ac5d | ||
|
f5db483973 | ||
|
7564b26b7d | ||
|
178a300eea | ||
|
d655a10381 | ||
|
b65773bea9 | ||
|
c4eb194033 | ||
|
6ae89940c7 | ||
|
3d28879c26 | ||
|
223dcc8bac | ||
|
6ce07ee864 | ||
|
bc299928ad | ||
|
ac658500fb | ||
|
8cced091f5 | ||
|
91299f7039 | ||
|
60308a2bb5 | ||
|
613eac4603 | ||
|
e4a26f4f1d | ||
|
57b632ead8 | ||
|
1bf63dfdcd | ||
|
e0cfbec66b | ||
|
b3a7e3109b | ||
|
45e82199fb | ||
|
4711796d38 | ||
|
0d70c44253 | ||
|
a364df4c9e | ||
|
46d990f1b6 | ||
|
5bf7b1e1fa | ||
|
97444ed7a8 | ||
|
4e41cda27e | ||
|
da86aac0f5 |
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@@ -39,7 +39,7 @@ jobs:
|
||||
tar -cvf Hyprland.tar.xz hyprland
|
||||
|
||||
- name: Release
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Build archive
|
||||
path: Hyprland.tar.xz
|
||||
|
4
.github/workflows/man-update.yaml
vendored
4
.github/workflows/man-update.yaml
vendored
@@ -17,14 +17,14 @@ jobs:
|
||||
run: sudo apt install pandoc
|
||||
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.PAT }}
|
||||
|
||||
- name: Build man pages
|
||||
run: make man
|
||||
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
||||
name: Commit
|
||||
with:
|
||||
commit_message: "[gha] build man pages"
|
||||
|
4
.github/workflows/nix-update-inputs.yml
vendored
4
.github/workflows/nix-update-inputs.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.PAT }}
|
||||
|
||||
@@ -22,6 +22,6 @@ jobs:
|
||||
run: nix/update-inputs.sh
|
||||
|
||||
- name: Commit
|
||||
uses: stefanzweifel/git-auto-commit-action@v4
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "[gha] Nix: update inputs"
|
||||
|
3
.github/workflows/release.yaml
vendored
3
.github/workflows/release.yaml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout Hyprland
|
||||
id: checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -20,7 +20,6 @@ jobs:
|
||||
run: |
|
||||
git fetch --unshallow || echo "failed unshallowing"
|
||||
bash -c scripts/generateVersion.sh
|
||||
mv scripts/generateVersion.sh scripts/generateVersion.sh.bak
|
||||
|
||||
- name: Create tarball with submodules
|
||||
id: tar
|
||||
|
2
.github/workflows/security-checks.yml
vendored
2
.github/workflows/security-checks.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
security-events: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Scan with Flawfinder
|
||||
uses: david-a-wheeler/flawfinder@8e4a779ad59dbfaee5da586aa9210853b701959c
|
||||
|
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
repo-token: ${{ secrets.STALEBOT_PAT }}
|
||||
stale-issue-label: "stale"
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -14,6 +14,7 @@ _deps
|
||||
|
||||
build/
|
||||
result*
|
||||
/.pre-commit-config.yaml
|
||||
/.vscode/
|
||||
/.idea/
|
||||
.envrc
|
||||
@@ -39,3 +40,6 @@ PKGBUILD
|
||||
src/version.h
|
||||
hyprpm/Makefile
|
||||
hyprctl/Makefile
|
||||
|
||||
**/.#*.*
|
||||
**/#*.*#
|
||||
|
@@ -15,6 +15,7 @@ include(GNUInstallDirs)
|
||||
set(HYPRLAND_VERSION ${VER})
|
||||
set(PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
set(INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
set(BINDIR ${CMAKE_INSTALL_BINDIR})
|
||||
configure_file(hyprland.pc.in hyprland.pc @ONLY)
|
||||
|
||||
set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
|
||||
@@ -71,6 +72,8 @@ else()
|
||||
message(STATUS "Configuring Hyprland in Release with CMake")
|
||||
endif()
|
||||
|
||||
add_compile_definitions(HYPRLAND_VERSION="${HYPRLAND_VERSION}")
|
||||
|
||||
include_directories(. "src/" "protocols/")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 26)
|
||||
@@ -100,7 +103,7 @@ find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
|
||||
|
||||
pkg_check_modules(hyprctl_deps REQUIRED IMPORTED_TARGET hyprutils>=0.2.1)
|
||||
|
||||
pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine)
|
||||
pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.2)
|
||||
|
||||
add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}")
|
||||
|
||||
@@ -219,6 +222,16 @@ if(NO_SYSTEMD)
|
||||
else()
|
||||
message(STATUS "SYSTEMD support is requested (NO_SYSTEMD not defined)...")
|
||||
add_compile_definitions(USES_SYSTEMD)
|
||||
configure_file(systemd/hyprland-session.service.in
|
||||
systemd/hyprland-session.service @ONLY)
|
||||
|
||||
# session file -systemd
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/systemd/hyprland-systemd.desktop
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions)
|
||||
|
||||
# install systemd service
|
||||
install(FILES ${CMAKE_BINARY_DIR}/systemd/hyprland-session.service
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/systemd/user)
|
||||
endif()
|
||||
|
||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||
@@ -274,7 +287,7 @@ endfunction()
|
||||
|
||||
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads)
|
||||
|
||||
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.2.0)
|
||||
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.4.0)
|
||||
if(hyprland_protocols_dep_FOUND)
|
||||
pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir)
|
||||
message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}")
|
||||
@@ -301,6 +314,8 @@ protocolnew("protocols" "wlr-data-control-unstable-v1" true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-focus-grab-v1" true)
|
||||
protocolnew("protocols" "wlr-layer-shell-unstable-v1" true)
|
||||
protocolnew("protocols" "wayland-drm" true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-ctm-control-v1" true)
|
||||
|
||||
protocolnew("staging/tearing-control" "tearing-control-v1" false)
|
||||
protocolnew("staging/fractional-scale" "fractional-scale-v1" false)
|
||||
protocolnew("unstable/xdg-output" "xdg-output-unstable-v1" false)
|
||||
@@ -331,6 +346,7 @@ protocolnew("staging/drm-lease" "drm-lease-v1" false)
|
||||
protocolnew("staging/linux-drm-syncobj" "linux-drm-syncobj-v1" false)
|
||||
protocolnew("staging/xdg-dialog" "xdg-dialog-v1" false)
|
||||
protocolnew("staging/single-pixel-buffer" "single-pixel-buffer-v1" false)
|
||||
protocolnew("staging/security-context" "security-context-v1" false)
|
||||
|
||||
protocolwayland()
|
||||
|
||||
|
7
Makefile
7
Makefile
@@ -1,12 +1,15 @@
|
||||
PREFIX = /usr/local
|
||||
|
||||
stub:
|
||||
@echo "Do not run $(MAKE) directly without any arguments. Please refer to the wiki on how to compile Hyprland."
|
||||
|
||||
legacyrenderer:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./buildZ
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
||||
legacyrendererdebug:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
cmake --build ./build --config Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
||||
release:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build
|
||||
|
@@ -100,7 +100,7 @@ easy IPC, much more QoL stuff than other compositors and more...
|
||||
|
||||
<!----------------------------------------------------------------------------->
|
||||
|
||||
[Configure]: https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
||||
[Configure]: https://wiki.hyprland.org/Configuring/
|
||||
[Stars]: https://starchart.cc/hyprwm/Hyprland
|
||||
[Hypr]: https://github.com/hyprwm/Hypr
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
First of all, please remember to:
|
||||
- Check that your issue is not a duplicate
|
||||
- Read the [FAQ](https://wiki.hyprland.org/FAQ/)
|
||||
- Read the [Configuring Page](https://wiki.hyprland.org/Configuring/Configuring-Hyprland)
|
||||
- Read the [Configuring Page](https://wiki.hyprland.org/Configuring/)
|
||||
|
||||
<br/>
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# This is an example Hyprland config file.
|
||||
# Refer to the wiki for more information.
|
||||
# https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
||||
# https://wiki.hyprland.org/Configuring/
|
||||
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki
|
||||
@@ -86,10 +86,12 @@ decoration {
|
||||
active_opacity = 1.0
|
||||
inactive_opacity = 1.0
|
||||
|
||||
drop_shadow = true
|
||||
shadow_range = 4
|
||||
shadow_render_power = 3
|
||||
col.shadow = rgba(1a1a1aee)
|
||||
shadow {
|
||||
enabled = true
|
||||
range = 4
|
||||
render_power = 3
|
||||
color = rgba(1a1a1aee)
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#blur
|
||||
blur {
|
||||
@@ -103,20 +105,44 @@ decoration {
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
||||
animations {
|
||||
enabled = true
|
||||
enabled = yes, please :)
|
||||
|
||||
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||
|
||||
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
|
||||
bezier = easeOutQuint,0.23,1,0.32,1
|
||||
bezier = easeInOutCubic,0.65,0.05,0.36,1
|
||||
bezier = linear,0,0,1,1
|
||||
bezier = almostLinear,0.5,0.5,0.75,1.0
|
||||
bezier = quick,0.15,0,0.1,1
|
||||
|
||||
animation = windows, 1, 7, myBezier
|
||||
animation = windowsOut, 1, 7, default, popin 80%
|
||||
animation = border, 1, 10, default
|
||||
animation = borderangle, 1, 8, default
|
||||
animation = fade, 1, 7, default
|
||||
animation = workspaces, 1, 6, default
|
||||
animation = global, 1, 10, default
|
||||
animation = border, 1, 5.39, easeOutQuint
|
||||
animation = windows, 1, 4.79, easeOutQuint
|
||||
animation = windowsIn, 1, 4.1, easeOutQuint, popin 87%
|
||||
animation = windowsOut, 1, 1.49, linear, popin 87%
|
||||
animation = fadeIn, 1, 1.73, almostLinear
|
||||
animation = fadeOut, 1, 1.46, almostLinear
|
||||
animation = fade, 1, 3.03, quick
|
||||
animation = layers, 1, 3.81, easeOutQuint
|
||||
animation = layersIn, 1, 4, easeOutQuint, fade
|
||||
animation = layersOut, 1, 1.5, linear, fade
|
||||
animation = fadeLayersIn, 1, 1.79, almostLinear
|
||||
animation = fadeLayersOut, 1, 1.39, almostLinear
|
||||
animation = workspaces, 1, 1.94, almostLinear, fade
|
||||
animation = workspacesIn, 1, 1.21, almostLinear, fade
|
||||
animation = workspacesOut, 1, 1.94, almostLinear, fade
|
||||
}
|
||||
|
||||
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
|
||||
# "Smart gaps" / "No gaps when only"
|
||||
# uncomment all if you wish to use that.
|
||||
# workspace = w[tv1], gapsout:0, gapsin:0
|
||||
# workspace = f[1], gapsout:0, gapsin:0
|
||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[tv1]
|
||||
# windowrulev2 = rounding 0, floating:0, onworkspace:w[tv1]
|
||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:f[1]
|
||||
# windowrulev2 = rounding 0, floating:0, onworkspace:f[1]
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||
dwindle {
|
||||
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||
@@ -255,4 +281,8 @@ bindl = , XF86AudioPrev, exec, playerctl previous
|
||||
# Example windowrule v2
|
||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||
|
||||
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
|
||||
# Ignore maximize requests from apps. You'll probably like this.
|
||||
windowrulev2 = suppressevent maximize, class:.*
|
||||
|
||||
# Fix some dragging issues with XWayland
|
||||
windowrulev2 = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
|
||||
|
@@ -2,4 +2,6 @@
|
||||
Name=Hyprland
|
||||
Comment=An intelligent dynamic tiling Wayland compositor
|
||||
Exec=Hyprland
|
||||
Type=Application
|
||||
Type=Application
|
||||
DesktopNames=Hyprland
|
||||
Keywords=tiling;wayland;compositor;
|
||||
|
148
flake.lock
generated
148
flake.lock
generated
@@ -16,11 +16,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1727261104,
|
||||
"narHash": "sha256-rxDI7WrxIRV9it9mDCHcLa7xQykf1JloXnoXr5xQ8zI=",
|
||||
"lastModified": 1731959031,
|
||||
"narHash": "sha256-TGcvIjftziC1CjuiHCzrYDwmOoSFYIhdiKmLetzB5L0=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "aquamarine",
|
||||
"rev": "b82fdaff917582a9d568969e15e61b398c71e990",
|
||||
"rev": "4468981c1c50999f315baa1508f0e53c4ee70c52",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -29,6 +29,43 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"pre-commit-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprcursor": {
|
||||
"inputs": {
|
||||
"hyprlang": [
|
||||
@@ -42,11 +79,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1727532803,
|
||||
"narHash": "sha256-ZaZ7h7PY8mQc4vtGmVqWLAq9CAO02gHMyNR5yY8zDmM=",
|
||||
"lastModified": 1728669738,
|
||||
"narHash": "sha256-EDNAU9AYcx8OupUzbTbWE1d3HYdeG0wO6Msg3iL1muk=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprcursor",
|
||||
"rev": "b98726e431d4d3ed58bd58bee1047cdb81cec69f",
|
||||
"rev": "0264e698149fcb857a66a53018157b41f8d97bb0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -65,36 +102,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1727451107,
|
||||
"narHash": "sha256-qV9savtHwmZUa0eJE294WYJjKPGB2+bJhwByFShsVyo=",
|
||||
"lastModified": 1728345020,
|
||||
"narHash": "sha256-xGbkc7U/Roe0/Cv3iKlzijIaFBNguasI31ynL2IlEoM=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"rev": "6b3261ee13a6d2b99de79a31d352f6996e35bde3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-protocols_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"xdph",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"xdph",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1721326555,
|
||||
"narHash": "sha256-zCu4R0CSHEactW9JqYki26gy8h9f6rHmSwj4XJmlHgg=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"rev": "5a11232266bf1a1f5952d5b179c3f4b2facaaa84",
|
||||
"rev": "a7c183800e74f337753de186522b9017a07a8cee",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -116,11 +128,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1725997860,
|
||||
"narHash": "sha256-d/rZ/fHR5l1n7PeyLw0StWMNLXVU9c4HFyfskw568so=",
|
||||
"lastModified": 1728168612,
|
||||
"narHash": "sha256-AnB1KfiXINmuiW7BALYrKqcjCnsLZPifhb/7BsfPbns=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"rev": "dfeb5811dd6485490cce18d6cc1e38a055eea876",
|
||||
"rev": "f054f2e44d6a0b74607a6bc0f52dba337a3db38e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -139,11 +151,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1727300645,
|
||||
"narHash": "sha256-OvAtVLaSRPnbXzOwlR1fVqCXR7i+ICRX3aPMCdIiv+c=",
|
||||
"lastModified": 1731702627,
|
||||
"narHash": "sha256-+JeO9gevnXannQxMfR5xzZtF4sYmSlWkX/BPmPx0mWk=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "3f5293432b6dc6a99f26aca2eba3876d2660665c",
|
||||
"rev": "e911361a687753bbbdfe3b6a9eab755ecaf1d9e1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -177,11 +189,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1727348695,
|
||||
"narHash": "sha256-J+PeFKSDV+pHL7ukkfpVzCOO7mBSrrpJ3svwBFABbhI=",
|
||||
"lastModified": 1731676054,
|
||||
"narHash": "sha256-OZiZ3m8SCMfh3B6bfGC/Bm4x3qc1m2SVEAlkV6iY7Yg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1925c603f17fc89f4c8f6bf6f631a802ad85d784",
|
||||
"rev": "5e4fbfb6b3de1aa2872b76d49fafc942626e2add",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -191,6 +203,45 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1730741070,
|
||||
"narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1732021966,
|
||||
"narHash": "sha256-mnTbjpdqF0luOkou8ZFi2asa1N3AA2CchR/RqCNmsGE=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "3308484d1a443fc5bc92012435d79e80458fe43c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"aquamarine": "aquamarine",
|
||||
@@ -200,6 +251,7 @@
|
||||
"hyprutils": "hyprutils",
|
||||
"hyprwayland-scanner": "hyprwayland-scanner",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pre-commit-hooks": "pre-commit-hooks",
|
||||
"systems": "systems",
|
||||
"xdph": "xdph"
|
||||
}
|
||||
@@ -221,7 +273,9 @@
|
||||
},
|
||||
"xdph": {
|
||||
"inputs": {
|
||||
"hyprland-protocols": "hyprland-protocols_2",
|
||||
"hyprland-protocols": [
|
||||
"hyprland-protocols"
|
||||
],
|
||||
"hyprlang": [
|
||||
"hyprlang"
|
||||
],
|
||||
@@ -239,11 +293,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1727524473,
|
||||
"narHash": "sha256-1DGktDtSWIJpnDbVoj/qpvJSH5zg6JbOfuh6xqZMap0=",
|
||||
"lastModified": 1731703417,
|
||||
"narHash": "sha256-rheDc/7C+yI+QspYr9J2z9kQ5P9F4ATapI7qyFAe1XA=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "xdg-desktop-portal-hyprland",
|
||||
"rev": "7e500e679ede40e79cf2d89b5f5fa3e34923bd26",
|
||||
"rev": "8070f36deec723de71e7557441acb17e478204d3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
27
flake.nix
27
flake.nix
@@ -51,10 +51,16 @@
|
||||
url = "github:hyprwm/xdg-desktop-portal-hyprland";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.systems.follows = "systems";
|
||||
inputs.hyprland-protocols.follows = "hyprland-protocols";
|
||||
inputs.hyprlang.follows = "hyprlang";
|
||||
inputs.hyprutils.follows = "hyprutils";
|
||||
inputs.hyprwayland-scanner.follows = "hyprwayland-scanner";
|
||||
};
|
||||
|
||||
pre-commit-hooks = {
|
||||
url = "github:cachix/git-hooks.nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = inputs @ {
|
||||
@@ -76,7 +82,7 @@
|
||||
pkgsCrossFor = eachSystem (system: crossSystem:
|
||||
import nixpkgs {
|
||||
localSystem = system;
|
||||
crossSystem = crossSystem;
|
||||
inherit crossSystem;
|
||||
overlays = with self.overlays; [
|
||||
hyprland-packages
|
||||
hyprland-extras
|
||||
@@ -91,6 +97,18 @@
|
||||
self.packages.${system})
|
||||
// {
|
||||
inherit (self.packages.${system}) xdg-desktop-portal-hyprland;
|
||||
pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
|
||||
src = ./.;
|
||||
hooks = {
|
||||
hyprland-treewide-formatter = {
|
||||
enable = true;
|
||||
entry = "${self.formatter.${system}}/bin/hyprland-treewide-formatter";
|
||||
pass_filenames = false;
|
||||
excludes = ["subprojects"];
|
||||
always_run = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
packages = eachSystem (system: {
|
||||
@@ -98,13 +116,13 @@
|
||||
inherit
|
||||
(pkgsFor.${system})
|
||||
# hyprland-packages
|
||||
|
||||
|
||||
hyprland
|
||||
hyprland-debug
|
||||
hyprland-legacy-renderer
|
||||
hyprland-unwrapped
|
||||
# hyprland-extras
|
||||
|
||||
|
||||
xdg-desktop-portal-hyprland
|
||||
;
|
||||
hyprland-cross = (pkgsCrossFor.${system} "aarch64-linux").hyprland;
|
||||
@@ -119,10 +137,11 @@
|
||||
hardeningDisable = ["fortify"];
|
||||
inputsFrom = [pkgsFor.${system}.hyprland];
|
||||
packages = [pkgsFor.${system}.clang-tools];
|
||||
inherit (self.checks.${system}.pre-commit-check) shellHook;
|
||||
};
|
||||
});
|
||||
|
||||
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||
formatter = eachSystem (system: pkgsFor.${system}.callPackage ./nix/formatter.nix {});
|
||||
|
||||
nixosModules.default = import ./nix/module.nix inputs;
|
||||
homeManagerModules.default = import ./nix/hm-module.nix self;
|
||||
|
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
const std::string_view USAGE = R"#(usage: hyprctl [flags] <command> [args...|--help]
|
||||
|
||||
commands:
|
||||
|
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <print>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -44,11 +45,11 @@ struct SInstanceData {
|
||||
bool valid = true;
|
||||
};
|
||||
|
||||
void log(std::string str) {
|
||||
void log(const std::string& str) {
|
||||
if (quiet)
|
||||
return;
|
||||
|
||||
std::cout << str << "\n";
|
||||
std::println("{}", str);
|
||||
}
|
||||
|
||||
std::string getRuntimeDir() {
|
||||
@@ -105,7 +106,7 @@ std::vector<SInstanceData> instances() {
|
||||
static volatile bool sigintReceived = false;
|
||||
void intHandler(int sig) {
|
||||
sigintReceived = true;
|
||||
std::cout << "[hyprctl] SIGINT received, closing connection" << std::endl;
|
||||
std::println("[hyprctl] SIGINT received, closing connection");
|
||||
}
|
||||
|
||||
int rollingRead(const int socket) {
|
||||
@@ -115,12 +116,12 @@ int rollingRead(const int socket) {
|
||||
constexpr size_t BUFFER_SIZE = 8192;
|
||||
std::array<char, BUFFER_SIZE> buffer = {0};
|
||||
long sizeWritten = 0;
|
||||
std::cout << "[hyprctl] reading from socket following up log:" << std::endl;
|
||||
std::println("[hyprctl] reading from socket following up log:");
|
||||
while (!sigintReceived) {
|
||||
sizeWritten = read(socket, buffer.data(), BUFFER_SIZE);
|
||||
if (sizeWritten < 0 && errno != EAGAIN) {
|
||||
if (errno != EINTR)
|
||||
std::cout << "Couldn't read (5) " << strerror(errno) << ":" << errno << std::endl;
|
||||
std::println("Couldn't read (5): {}: {}", strerror(errno), errno);
|
||||
close(socket);
|
||||
return 5;
|
||||
}
|
||||
@@ -129,7 +130,7 @@ int rollingRead(const int socket) {
|
||||
break;
|
||||
|
||||
if (sizeWritten > 0) {
|
||||
std::cout << std::string(buffer.data(), sizeWritten);
|
||||
std::println("{}", std::string(buffer.data(), sizeWritten));
|
||||
buffer.fill('\0');
|
||||
}
|
||||
|
||||
@@ -323,7 +324,7 @@ int main(int argc, char** argv) {
|
||||
bool parseArgs = true;
|
||||
|
||||
if (argc < 2) {
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -360,7 +361,7 @@ int main(int argc, char** argv) {
|
||||
++i;
|
||||
|
||||
if (i >= ARGS.size()) {
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -371,24 +372,24 @@ int main(int argc, char** argv) {
|
||||
const std::string& cmd = ARGS[0];
|
||||
|
||||
if (cmd == "hyprpaper") {
|
||||
std::cout << HYPRPAPER_HELP << std::endl;
|
||||
std::println("{}", HYPRPAPER_HELP);
|
||||
} else if (cmd == "notify") {
|
||||
std::cout << NOTIFY_HELP << std::endl;
|
||||
std::println("{}", NOTIFY_HELP);
|
||||
} else if (cmd == "output") {
|
||||
std::cout << OUTPUT_HELP << std::endl;
|
||||
std::println("{}", OUTPUT_HELP);
|
||||
} else if (cmd == "plugin") {
|
||||
std::cout << PLUGIN_HELP << std::endl;
|
||||
std::println("{}", PLUGIN_HELP);
|
||||
} else if (cmd == "setprop") {
|
||||
std::cout << SETPROP_HELP << std::endl;
|
||||
std::println("{}", SETPROP_HELP);
|
||||
} else if (cmd == "switchxkblayout") {
|
||||
std::cout << SWITCHXKBLAYOUT_HELP << std::endl;
|
||||
std::println("{}", SWITCHXKBLAYOUT_HELP);
|
||||
} else {
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -399,7 +400,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
if (fullRequest.empty()) {
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -476,7 +477,7 @@ int main(int argc, char** argv) {
|
||||
else if (fullRequest.contains("/decorations"))
|
||||
exitStatus = request(fullRequest, 1);
|
||||
else if (fullRequest.contains("/--help"))
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
else if (fullRequest.contains("/rollinglog") && needRoll)
|
||||
exitStatus = request(fullRequest, 0, true);
|
||||
else {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include "DataState.hpp"
|
||||
#include <toml++/toml.hpp>
|
||||
#include <iostream>
|
||||
#include <print>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include "PluginManager.hpp"
|
||||
@@ -8,7 +8,7 @@
|
||||
std::string DataState::getDataStatePath() {
|
||||
const auto HOME = getenv("HOME");
|
||||
if (!HOME) {
|
||||
std::cerr << "DataState: no $HOME\n";
|
||||
std::println(stderr, "DataState: no $HOME");
|
||||
throw std::runtime_error("no $HOME");
|
||||
return "";
|
||||
}
|
||||
@@ -242,4 +242,4 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -1,12 +1,15 @@
|
||||
#include "PluginManager.hpp"
|
||||
#include "../helpers/Colors.hpp"
|
||||
#include "../helpers/StringUtils.hpp"
|
||||
#include "../progress/CProgressBar.hpp"
|
||||
#include "Manifest.hpp"
|
||||
#include "DataState.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <print>
|
||||
#include <thread>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
@@ -31,6 +34,7 @@ static std::string execAndGet(std::string cmd) {
|
||||
if (!pipe)
|
||||
return "";
|
||||
|
||||
result.reserve(buffer.size());
|
||||
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
|
||||
result += buffer.data();
|
||||
}
|
||||
@@ -47,10 +51,10 @@ SHyprlandVersion CPluginManager::getHyprlandVersion() {
|
||||
once = true;
|
||||
const auto HLVERCALL = execAndGet("hyprctl version");
|
||||
if (m_bVerbose)
|
||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "version returned: " << HLVERCALL << "\n";
|
||||
std::println("{}", verboseString("version returned: {}", HLVERCALL));
|
||||
|
||||
if (!HLVERCALL.contains("Tag:")) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " You don't seem to be running Hyprland.";
|
||||
std::println(stderr, "\n{}", failureString("You don't seem to be running Hyprland."));
|
||||
return SHyprlandVersion{};
|
||||
}
|
||||
|
||||
@@ -76,7 +80,7 @@ SHyprlandVersion CPluginManager::getHyprlandVersion() {
|
||||
} catch (...) { ; }
|
||||
|
||||
if (m_bVerbose)
|
||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "parsed commit " << hlcommit << " at branch " << hlbranch << " on " << hldate << ", commits " << commits << "\n";
|
||||
std::println("{}", verboseString("parsed commit {} at branch {} on {}, commits {}", hlcommit, hlbranch, hldate, commits));
|
||||
|
||||
ver = SHyprlandVersion{hlbranch, hlcommit, hldate, commits};
|
||||
return ver;
|
||||
@@ -102,20 +106,21 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||
const auto HLVER = getHyprlandVersion();
|
||||
|
||||
if (!hasDeps()) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not clone the plugin repository. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio\n";
|
||||
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DataState::pluginRepoExists(url)) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not clone the plugin repository. Repository already installed.\n";
|
||||
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. Repository already installed."));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto GLOBALSTATE = DataState::getGlobalState();
|
||||
if (!GLOBALSTATE.dontWarnInstall) {
|
||||
std::cout << Colors::YELLOW << "!" << Colors::RED << " Disclaimer:\n " << Colors::RESET
|
||||
<< "plugins, especially not official, have no guarantee of stability, availablity or security.\n Run them at your own risk.\n "
|
||||
<< "This message will not appear again.\n";
|
||||
std::println("{}!{} Disclaimer: {}", Colors::YELLOW, Colors::RED, Colors::RESET);
|
||||
std::println("plugins, especially not official, have no guarantee of stability, availablity or security.\n"
|
||||
"Run them at your own risk.\n"
|
||||
"This message will not appear again.");
|
||||
GLOBALSTATE.dontWarnInstall = true;
|
||||
DataState::updateGlobalState(GLOBALSTATE);
|
||||
}
|
||||
@@ -129,7 +134,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||
std::getline(std::cin, input);
|
||||
|
||||
if (input.size() > 0 && input[0] != 'Y' && input[0] != 'y') {
|
||||
std::cout << "Aborting.\n";
|
||||
std::println(stderr, "Aborting.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -144,7 +149,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||
std::filesystem::create_directory("/tmp/hyprpm");
|
||||
std::filesystem::permissions("/tmp/hyprpm", std::filesystem::perms::all, std::filesystem::perm_options::replace);
|
||||
} else if (!std::filesystem::is_directory("/tmp/hyprpm")) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not prepare working dir for hyprpm\n";
|
||||
std::println(stderr, "\n{}", failureString("Could not prepare working dir for hyprpm"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -153,59 +158,59 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||
m_szWorkingPluginDirectory = "/tmp/hyprpm/" + USERNAME;
|
||||
|
||||
if (!createSafeDirectory(m_szWorkingPluginDirectory)) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not prepare working dir for repo\n";
|
||||
std::println(stderr, "\n{}", failureString("Could not prepare working dir for repo"));
|
||||
return false;
|
||||
}
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Cloning " + url);
|
||||
progress.printMessageAbove(infoString("Cloning {}", url));
|
||||
|
||||
std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + url + " " + USERNAME);
|
||||
|
||||
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not clone the plugin repository. shell returned:\n" << ret << "\n";
|
||||
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. shell returned:\n{}", ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rev.empty()) {
|
||||
std::string ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " reset --hard --recurse-submodules " + rev);
|
||||
if (ret.compare(0, 6, "fatal:") == 0) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not check out revision " << rev << ". shell returned:\n" << ret << "\n";
|
||||
std::println(stderr, "\n{}", failureString("Could not check out revision {}. shell returned:\n{}", rev, ret));
|
||||
return false;
|
||||
}
|
||||
ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " submodule update --init");
|
||||
if (m_bVerbose)
|
||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "git submodule update --init returned: " << ret << "\n";
|
||||
std::println("{}", verboseString("git submodule update --init returned: {}", ret));
|
||||
}
|
||||
|
||||
progress.m_iSteps = 1;
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " cloned");
|
||||
progress.printMessageAbove(successString("cloned"));
|
||||
progress.m_szCurrentMessage = "Reading the manifest";
|
||||
progress.print();
|
||||
|
||||
std::unique_ptr<CManifest> pManifest;
|
||||
|
||||
if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprpm manifest");
|
||||
progress.printMessageAbove(successString("found hyprpm manifest"));
|
||||
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, m_szWorkingPluginDirectory + "/hyprpm.toml");
|
||||
} else if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprload.toml")) {
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprload manifest");
|
||||
progress.printMessageAbove(successString("found hyprload manifest"));
|
||||
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
|
||||
}
|
||||
|
||||
if (!pManifest) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " The provided plugin repository does not have a valid manifest\n";
|
||||
std::println(stderr, "\n{}", failureString("The provided plugin repository does not have a valid manifest"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pManifest->m_bGood) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " The provided plugin repository has a corrupted manifest\n";
|
||||
std::println(stderr, "\n{}", failureString("The provided plugin repository has a corrupted manifest"));
|
||||
return false;
|
||||
}
|
||||
|
||||
progress.m_iSteps = 2;
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " parsed manifest, found " + std::to_string(pManifest->m_vPlugins.size()) + " plugins:");
|
||||
progress.printMessageAbove(successString("parsed manifest, found " + std::to_string(pManifest->m_vPlugins.size()) + " plugins:"));
|
||||
for (auto const& pl : pManifest->m_vPlugins) {
|
||||
std::string message = std::string{Colors::RESET} + " → " + pl.name + " by ";
|
||||
std::string message = "→ " + pl.name + " by ";
|
||||
for (auto const& a : pl.authors) {
|
||||
message += a + ", ";
|
||||
}
|
||||
@@ -220,19 +225,19 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||
if (!pManifest->m_sRepository.commitPins.empty()) {
|
||||
// check commit pins
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Manifest has " + std::to_string(pManifest->m_sRepository.commitPins.size()) + " pins, checking");
|
||||
progress.printMessageAbove(infoString("Manifest has {} pins, checking", pManifest->m_sRepository.commitPins.size()));
|
||||
|
||||
for (auto const& [hl, plugin] : pManifest->m_sRepository.commitPins) {
|
||||
if (hl != HLVER.hash)
|
||||
continue;
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " commit pin " + plugin + " matched hl, resetting");
|
||||
progress.printMessageAbove(successString("commit pin {} matched hl, resetting", plugin));
|
||||
|
||||
execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
|
||||
|
||||
ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " submodule update --init");
|
||||
if (m_bVerbose)
|
||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "git submodule update --init returned: " << ret << "\n";
|
||||
std::println("{}", verboseString("git submodule update --init returned: {}", ret));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -244,12 +249,12 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||
const auto HEADERSSTATUS = headersValid();
|
||||
|
||||
if (HEADERSSTATUS != HEADERS_OK) {
|
||||
std::cerr << "\n" << headerError(HEADERSSTATUS);
|
||||
std::println("\n{}", headerError(HEADERSSTATUS));
|
||||
return false;
|
||||
}
|
||||
|
||||
progress.m_iSteps = 3;
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " Hyprland headers OK");
|
||||
progress.printMessageAbove(successString("Hyprland headers OK"));
|
||||
progress.m_szCurrentMessage = "Building plugin(s)";
|
||||
progress.print();
|
||||
|
||||
@@ -257,35 +262,36 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||
std::string out;
|
||||
|
||||
if (p.since > HLVER.commits && HLVER.commits >= 1 /* for --depth 1 clones, we can't check this. */) {
|
||||
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Not building " + p.name + ": your Hyprland version is too old.\n");
|
||||
progress.printMessageAbove(failureString("Not building {}: your Hyprland version is too old.\n", p.name));
|
||||
p.failed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Building " + p.name);
|
||||
progress.printMessageAbove(infoString("Building {}", p.name));
|
||||
|
||||
for (auto const& bs : p.buildSteps) {
|
||||
std::string cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
|
||||
const std::string& cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
|
||||
out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n";
|
||||
}
|
||||
|
||||
if (m_bVerbose)
|
||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n";
|
||||
std::println("{}", verboseString("shell returned: {}", out));
|
||||
|
||||
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
|
||||
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Plugin " + p.name + " failed to build.\n" +
|
||||
" This likely means that the plugin is either outdated, not yet available for your version, or broken.\n If you are on -git, update "
|
||||
"first.\n Try re-running with -v to see "
|
||||
"more verbose output.\n");
|
||||
progress.printMessageAbove(failureString("Plugin {} failed to build.\n"
|
||||
" This likely means that the plugin is either outdated, not yet available for your version, or broken.\n"
|
||||
" If you are on -git, update first\n"
|
||||
" Try re-running with -v to see more verbose output.\n",
|
||||
p.name));
|
||||
|
||||
p.failed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " built " + p.name + " into " + p.output);
|
||||
progress.printMessageAbove(successString("built {} into {}", p.name, p.output));
|
||||
}
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " all plugins built");
|
||||
progress.printMessageAbove(successString("all plugins built"));
|
||||
progress.m_iSteps = 4;
|
||||
progress.m_szCurrentMessage = "Installing repository";
|
||||
progress.print();
|
||||
@@ -304,13 +310,13 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||
}
|
||||
DataState::addNewPluginRepo(repo);
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " installed repository");
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " you can now enable the plugin(s) with hyprpm enable");
|
||||
progress.printMessageAbove(successString("installed repository"));
|
||||
progress.printMessageAbove(successString("you can now enable the plugin(s) with hyprpm enable"));
|
||||
progress.m_iSteps = 5;
|
||||
progress.m_szCurrentMessage = "Done!";
|
||||
progress.print();
|
||||
|
||||
std::cout << "\n";
|
||||
std::print("\n");
|
||||
|
||||
// remove build files
|
||||
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
||||
@@ -320,7 +326,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||
|
||||
bool CPluginManager::removePluginRepo(const std::string& urlOrName) {
|
||||
if (!DataState::pluginRepoExists(urlOrName)) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not remove the repository. Repository is not installed.\n";
|
||||
std::println(stderr, "\n{}", failureString("Could not remove the repository. Repository is not installed."));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -331,7 +337,7 @@ bool CPluginManager::removePluginRepo(const std::string& urlOrName) {
|
||||
std::getline(std::cin, input);
|
||||
|
||||
if (input.size() > 0 && input[0] != 'Y' && input[0] != 'y') {
|
||||
std::cout << "Aborting.\n";
|
||||
std::println("Aborting.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -347,15 +353,15 @@ eHeadersErrors CPluginManager::headersValid() {
|
||||
return HEADERS_MISSING;
|
||||
|
||||
// find headers commit
|
||||
std::string cmd = std::format("PKG_CONFIG_PATH=\"{}/share/pkgconfig\" pkgconf --cflags --keep-system-cflags hyprland", DataState::getHeadersPath());
|
||||
auto headers = execAndGet(cmd.c_str());
|
||||
const std::string& cmd = std::format("PKG_CONFIG_PATH=\"{}/share/pkgconfig\" pkgconf --cflags --keep-system-cflags hyprland", DataState::getHeadersPath());
|
||||
auto headers = execAndGet(cmd.c_str());
|
||||
|
||||
if (!headers.contains("-I/"))
|
||||
return HEADERS_MISSING;
|
||||
|
||||
headers.pop_back(); // pop newline
|
||||
|
||||
std::string verHeader = "";
|
||||
std::string verHeader;
|
||||
|
||||
while (!headers.empty()) {
|
||||
const auto PATH = headers.substr(0, headers.find(" -I/", 3));
|
||||
@@ -406,7 +412,7 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||
const auto HLVER = getHyprlandVersion();
|
||||
|
||||
if (!hasDeps()) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not update. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio\n";
|
||||
std::println("\n{}", failureString("Could not update. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -416,7 +422,7 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||
}
|
||||
|
||||
if (!force && headersValid() == HEADERS_OK) {
|
||||
std::cout << "\n" << std::string{Colors::GREEN} + "✔" + Colors::RESET + " Headers up to date.\n";
|
||||
std::println("\n{}", successString("Headers up to date."));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -430,74 +436,73 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||
const auto WORKINGDIR = "/tmp/hyprpm/hyprland-" + USERNAME;
|
||||
|
||||
if (!createSafeDirectory(WORKINGDIR)) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not prepare working dir for hl\n";
|
||||
std::println("\n{}", failureString("Could not prepare working dir for hl"));
|
||||
return false;
|
||||
}
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::YELLOW} + "!" + Colors::RESET + " Cloning https://github.com/hyprwm/hyprland, this might take a moment.");
|
||||
progress.printMessageAbove(statusString("!", Colors::YELLOW, "Cloning https://github.com/hyprwm/Hyprland, this might take a moment."));
|
||||
|
||||
const bool bShallow = (HLVER.branch == "main" || HLVER.branch == "") && !m_bNoShallow;
|
||||
const bool bShallow = (HLVER.branch == "main") && !m_bNoShallow;
|
||||
|
||||
// let us give a bit of leg-room for shallowing
|
||||
// due to timezones, etc.
|
||||
const std::string SHALLOW_DATE =
|
||||
trim(HLVER.date).empty() ? "" : execAndGet("LC_TIME=\"en_US.UTF-8\" date --date='" + HLVER.date + " - 1 weeks' '+\%a \%b \%d \%H:\%M:\%S \%Y'");
|
||||
const std::string SHALLOW_DATE = trim(HLVER.date).empty() ? "" : execAndGet("LC_TIME=\"en_US.UTF-8\" date --date='" + HLVER.date + " - 1 weeks' '+%a %b %d %H:%M:%S %Y'");
|
||||
|
||||
if (m_bVerbose && bShallow)
|
||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "will shallow since: " + SHALLOW_DATE);
|
||||
progress.printMessageAbove(verboseString("will shallow since: {}", SHALLOW_DATE));
|
||||
|
||||
std::string ret =
|
||||
execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/hyprland hyprland-" + USERNAME + (bShallow ? " --shallow-since='" + SHALLOW_DATE + "'" : ""));
|
||||
execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/Hyprland hyprland-" + USERNAME + (bShallow ? " --shallow-since='" + SHALLOW_DATE + "'" : ""));
|
||||
|
||||
if (!std::filesystem::exists(WORKINGDIR)) {
|
||||
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Clone failed. Retrying without shallow.");
|
||||
progress.printMessageAbove(failureString("Clone failed. Retrying without shallow."));
|
||||
ret = execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/hyprland hyprland-" + USERNAME);
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(WORKINGDIR + "/.git")) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not clone the hyprland repository. shell returned:\n" << ret << "\n";
|
||||
std::println(stderr, "\n{}", failureString("Could not clone the Hyprland repository. shell returned:\n{}", ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " cloned");
|
||||
progress.printMessageAbove(successString("Hyprland cloned"));
|
||||
progress.m_iSteps = 2;
|
||||
progress.m_szCurrentMessage = "Checking out sources";
|
||||
progress.print();
|
||||
|
||||
if (m_bVerbose)
|
||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "will run: " + "cd " + WORKINGDIR + " && git checkout " + HLVER.hash + " 2>&1");
|
||||
progress.printMessageAbove(verboseString("will run: cd {} && git checkout {} 2>&1", WORKINGDIR, HLVER.hash));
|
||||
|
||||
ret = execAndGet("cd " + WORKINGDIR + " && git checkout " + HLVER.hash + " 2>&1");
|
||||
|
||||
if (ret.contains("fatal: unable to read tree")) {
|
||||
std::cerr << "\n"
|
||||
<< Colors::RED << "✖" << Colors::RESET
|
||||
<< " Could not checkout the running Hyprland commit. If you are on -git, try updating.\nYou can also try re-running hyprpm update with --no-shallow.\n";
|
||||
std::println(stderr, "\n{}",
|
||||
failureString("Could not checkout the running Hyprland commit. If you are on -git, try updating.\n"
|
||||
"You can also try re-running hyprpm update with --no-shallow."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_bVerbose)
|
||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "git returned (co): " + ret);
|
||||
progress.printMessageAbove(verboseString("git returned (co): {}", ret));
|
||||
|
||||
ret = execAndGet("cd " + WORKINGDIR + " ; git rm subprojects/tracy ; git submodule update --init 2>&1 ; git reset --hard --recurse-submodules " + HLVER.hash);
|
||||
|
||||
if (m_bVerbose)
|
||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "git returned (rs): " + ret);
|
||||
progress.printMessageAbove(verboseString("git returned (rs): {}", ret));
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " checked out to running ver");
|
||||
progress.printMessageAbove(successString("checked out to running ver"));
|
||||
progress.m_iSteps = 3;
|
||||
progress.m_szCurrentMessage = "Building Hyprland";
|
||||
progress.print();
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::YELLOW} + "!" + Colors::RESET + " configuring Hyprland");
|
||||
progress.printMessageAbove(statusString("!", Colors::YELLOW, "configuring Hyprland"));
|
||||
|
||||
if (m_bVerbose)
|
||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "setting PREFIX for cmake to " + DataState::getHeadersPath());
|
||||
progress.printMessageAbove(verboseString("setting PREFIX for cmake to {}", DataState::getHeadersPath()));
|
||||
|
||||
ret = execAndGet(std::format("cd {} && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=\"{}\" -S . -B ./build -G Ninja", WORKINGDIR,
|
||||
DataState::getHeadersPath()));
|
||||
if (m_bVerbose)
|
||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "cmake returned: " + ret);
|
||||
progress.printMessageAbove(verboseString("cmake returned: {}", ret));
|
||||
|
||||
if (ret.contains("CMake Error at")) {
|
||||
// missing deps, let the user know.
|
||||
@@ -506,48 +511,46 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||
missing = missing.substr(0, missing.find("-- Configuring incomplete"));
|
||||
missing = missing.substr(0, missing.find_last_of('\n'));
|
||||
|
||||
std::cerr << "\n"
|
||||
<< Colors::RED << "✖" << Colors::RESET << " Could not configure the hyprland source, cmake complained:\n"
|
||||
<< missing << "\n\nThis likely means that you are missing the above dependencies or they are out of date.\n";
|
||||
std::println(stderr, "\n{}",
|
||||
failureString("Could not configure the hyprland source, cmake complained:\n{}\n\n"
|
||||
"This likely means that you are missing the above dependencies or they are out of date.",
|
||||
missing));
|
||||
return false;
|
||||
}
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " configured Hyprland");
|
||||
progress.printMessageAbove(successString("configured Hyprland"));
|
||||
progress.m_iSteps = 4;
|
||||
progress.m_szCurrentMessage = "Installing sources";
|
||||
progress.print();
|
||||
|
||||
std::string cmd =
|
||||
const std::string& cmd =
|
||||
std::format("sed -i -e \"s#PREFIX = /usr/local#PREFIX = {}#\" {}/Makefile && cd {} && make installheaders", DataState::getHeadersPath(), WORKINGDIR, WORKINGDIR);
|
||||
if (m_bVerbose)
|
||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "installation will run: " + cmd);
|
||||
progress.printMessageAbove(verboseString("installation will run: {}", cmd));
|
||||
|
||||
ret = execAndGet(cmd);
|
||||
|
||||
if (m_bVerbose)
|
||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "installer returned: " << ret << "\n";
|
||||
std::println("{}", verboseString("installer returned: {}", ret));
|
||||
|
||||
// remove build files
|
||||
std::filesystem::remove_all(WORKINGDIR);
|
||||
|
||||
auto HEADERSVALID = headersValid();
|
||||
if (HEADERSVALID == HEADERS_OK) {
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " installed headers");
|
||||
progress.printMessageAbove(successString("installed headers"));
|
||||
progress.m_iSteps = 5;
|
||||
progress.m_szCurrentMessage = "Done!";
|
||||
progress.print();
|
||||
|
||||
std::cout << "\n";
|
||||
std::print("\n");
|
||||
} else {
|
||||
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " failed to install headers with error code " + std::to_string((int)HEADERSVALID) + " (" +
|
||||
headerErrorShort(HEADERSVALID) + ")");
|
||||
progress.printMessageAbove(failureString("failed to install headers with error code {} ({})", (int)HEADERSVALID, headerErrorShort(HEADERSVALID)));
|
||||
progress.m_iSteps = 5;
|
||||
progress.m_szCurrentMessage = "Failed";
|
||||
progress.print();
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
std::cerr << "\n" << headerError(HEADERSVALID);
|
||||
std::print(stderr, "\n\n{}", headerError(HEADERSVALID));
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -557,14 +560,14 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||
|
||||
bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||
if (headersValid() != HEADERS_OK) {
|
||||
std::cout << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " headers are not up-to-date, please run hyprpm update.\n";
|
||||
std::println("{}", failureString("headers are not up-to-date, please run hyprpm update."));
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto REPOS = DataState::getAllRepositories();
|
||||
|
||||
if (REPOS.size() < 1) {
|
||||
std::cout << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " No repos to update.\n";
|
||||
std::println("{}", failureString("No repos to update."));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -586,25 +589,26 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||
progress.m_szCurrentMessage = "Updating " + repo.name;
|
||||
progress.print();
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::RESET} + " → checking for updates for " + repo.name);
|
||||
progress.printMessageAbove(infoString("checking for updates for {}", repo.name));
|
||||
|
||||
createSafeDirectory(m_szWorkingPluginDirectory);
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Cloning " + repo.url);
|
||||
progress.printMessageAbove(infoString("Cloning {}", repo.url));
|
||||
|
||||
std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + repo.url + " " + USERNAME);
|
||||
|
||||
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
|
||||
std::cout << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " could not clone repo: shell returned:\n" + ret;
|
||||
std::println("{}", failureString("could not clone repo: shell returned: {}", ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!repo.rev.empty()) {
|
||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Plugin has revision set, resetting: " + repo.rev);
|
||||
progress.printMessageAbove(infoString("Plugin has revision set, resetting: {}", repo.rev));
|
||||
|
||||
std::string ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " reset --hard --recurse-submodules " + repo.rev);
|
||||
if (ret.compare(0, 6, "fatal:") == 0) {
|
||||
std::cout << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " could not check out revision " + repo.rev + ": shell returned:\n" + ret;
|
||||
std::println(stderr, "\n{}", failureString("could not check out revision {}: shell returned:\n{}", repo.rev, ret));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -620,7 +624,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||
|
||||
if (!update) {
|
||||
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " repository " + repo.name + " is up-to-date.");
|
||||
progress.printMessageAbove(successString("repository {} is up-to-date.", repo.name));
|
||||
progress.m_iSteps++;
|
||||
progress.print();
|
||||
continue;
|
||||
@@ -628,41 +632,41 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||
|
||||
// we need to update
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " repository " + repo.name + " has updates.");
|
||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Building " + repo.name);
|
||||
progress.printMessageAbove(successString("repository {} has updates.", repo.name));
|
||||
progress.printMessageAbove(infoString("Building {}", repo.name));
|
||||
progress.m_iSteps++;
|
||||
progress.print();
|
||||
|
||||
std::unique_ptr<CManifest> pManifest;
|
||||
|
||||
if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprpm manifest");
|
||||
progress.printMessageAbove(successString("found hyprpm manifest"));
|
||||
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, m_szWorkingPluginDirectory + "/hyprpm.toml");
|
||||
} else if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprload.toml")) {
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprload manifest");
|
||||
progress.printMessageAbove(successString("found hyprload manifest"));
|
||||
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
|
||||
}
|
||||
|
||||
if (!pManifest) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " The provided plugin repository does not have a valid manifest\n";
|
||||
std::println(stderr, "\n{}", failureString("The provided plugin repository does not have a valid manifest"));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!pManifest->m_bGood) {
|
||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " The provided plugin repository has a corrupted manifest\n";
|
||||
std::println(stderr, "\n{}", failureString("The provided plugin repository has a corrupted manifest"));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (repo.rev.empty() && !pManifest->m_sRepository.commitPins.empty()) {
|
||||
// check commit pins unless a revision is specified
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Manifest has " + std::to_string(pManifest->m_sRepository.commitPins.size()) + " pins, checking");
|
||||
progress.printMessageAbove(infoString("Manifest has {} pins, checking", pManifest->m_sRepository.commitPins.size()));
|
||||
|
||||
for (auto const& [hl, plugin] : pManifest->m_sRepository.commitPins) {
|
||||
if (hl != HLVER.hash)
|
||||
continue;
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " commit pin " + plugin + " matched hl, resetting");
|
||||
progress.printMessageAbove(successString("commit pin {} matched hl, resetting", plugin));
|
||||
|
||||
execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
|
||||
}
|
||||
@@ -672,32 +676,33 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||
std::string out;
|
||||
|
||||
if (p.since > HLVER.commits && HLVER.commits >= 1000 /* for shallow clones, we can't check this. 1000 is an arbitrary number I chose. */) {
|
||||
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Not building " + p.name + ": your Hyprland version is too old.\n");
|
||||
progress.printMessageAbove(failureString("Not building {}: your Hyprland version is too old.\n", p.name));
|
||||
p.failed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Building " + p.name);
|
||||
progress.printMessageAbove(infoString("Building {}", p.name));
|
||||
|
||||
for (auto const& bs : p.buildSteps) {
|
||||
std::string cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
|
||||
const std::string& cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
|
||||
out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n";
|
||||
}
|
||||
|
||||
if (m_bVerbose)
|
||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n";
|
||||
std::println("{}", verboseString("shell returned: {}", out));
|
||||
|
||||
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
|
||||
std::cerr << "\n"
|
||||
<< Colors::RED << "✖" << Colors::RESET << " Plugin " << p.name << " failed to build.\n"
|
||||
<< " This likely means that the plugin is either outdated, not yet available for your version, or broken.\n If you are on -git, update first.\n Try "
|
||||
"re-running with -v to see more verbose "
|
||||
"output.\n";
|
||||
std::println(stderr,
|
||||
"\n{}\n"
|
||||
" This likely means that the plugin is either outdated, not yet available for your version, or broken.\n"
|
||||
"If you are on -git, update first.\n"
|
||||
"Try re-running with -v to see more verbose output.",
|
||||
failureString("Plugin {} failed to build.", p.name));
|
||||
p.failed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " built " + p.name + " into " + p.output);
|
||||
progress.printMessageAbove(successString("built {} into {}", p.name, p.output));
|
||||
}
|
||||
|
||||
// add repo toml to DataState
|
||||
@@ -718,7 +723,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||
|
||||
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
||||
|
||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " updated " + repo.name);
|
||||
progress.printMessageAbove(successString("updated {}", repo.name));
|
||||
}
|
||||
|
||||
progress.m_iSteps++;
|
||||
@@ -733,7 +738,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||
progress.m_szCurrentMessage = "Done!";
|
||||
progress.print();
|
||||
|
||||
std::cout << "\n";
|
||||
std::print("\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -741,27 +746,27 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||
bool CPluginManager::enablePlugin(const std::string& name) {
|
||||
bool ret = DataState::setPluginEnabled(name, true);
|
||||
if (ret)
|
||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Enabled " << name << "\n";
|
||||
std::println("{}", successString("Enabled {}", name));
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CPluginManager::disablePlugin(const std::string& name) {
|
||||
bool ret = DataState::setPluginEnabled(name, false);
|
||||
if (ret)
|
||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Disabled " << name << "\n";
|
||||
std::println("{}", successString("Disabled {}", name));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||
if (headersValid() != HEADERS_OK) {
|
||||
std::cerr << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " headers are not up-to-date, please run hyprpm update.\n";
|
||||
std::println(stderr, "\n{}", failureString("headers are not up-to-date, please run hyprpm update."));
|
||||
return LOADSTATE_HEADERS_OUTDATED;
|
||||
}
|
||||
|
||||
const auto HOME = getenv("HOME");
|
||||
const auto HIS = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||
if (!HOME || !HIS) {
|
||||
std::cerr << "PluginManager: no $HOME or HIS\n";
|
||||
std::println(stderr, "PluginManager: no $HOME or HIS");
|
||||
return LOADSTATE_FAIL;
|
||||
}
|
||||
const auto HYPRPMPATH = DataState::getDataStatePath() + "/";
|
||||
@@ -770,14 +775,14 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||
|
||||
std::vector<std::string> loadedPlugins;
|
||||
|
||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Ensuring plugin load state\n";
|
||||
std::println("{}", successString("Ensuring plugin load state"));
|
||||
|
||||
// iterate line by line
|
||||
while (!pluginLines.empty()) {
|
||||
auto plLine = pluginLines.substr(0, pluginLines.find("\n"));
|
||||
auto plLine = pluginLines.substr(0, pluginLines.find('\n'));
|
||||
|
||||
if (pluginLines.find("\n") != std::string::npos)
|
||||
pluginLines = pluginLines.substr(pluginLines.find("\n") + 1);
|
||||
if (pluginLines.find('\n') != std::string::npos)
|
||||
pluginLines = pluginLines.substr(pluginLines.find('\n') + 1);
|
||||
else
|
||||
pluginLines = "";
|
||||
|
||||
@@ -820,7 +825,7 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||
if (!enabled(p)) {
|
||||
// unload
|
||||
loadUnloadPlugin(HYPRPMPATH + repoForName(p) + "/" + p + ".so", false);
|
||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Unloaded " << p << "\n";
|
||||
std::println("{}", successString("Unloaded {}", p));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -834,11 +839,11 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||
continue;
|
||||
|
||||
loadUnloadPlugin(HYPRPMPATH + repoForName(p.name) + "/" + p.filename, true);
|
||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Loaded " << p.name << "\n";
|
||||
std::println("{}", successString("Loaded {}", p.name));
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Plugin load state ensured\n";
|
||||
std::println("{}", successString("Plugin load state ensured"));
|
||||
|
||||
return LOADSTATE_OK;
|
||||
}
|
||||
@@ -856,16 +861,17 @@ void CPluginManager::listAllPlugins() {
|
||||
const auto REPOS = DataState::getAllRepositories();
|
||||
|
||||
for (auto const& r : REPOS) {
|
||||
std::cout << std::string{Colors::RESET} + " → Repository " + r.name + ":\n";
|
||||
std::println("{}", infoString("Repository {}:", r.name));
|
||||
|
||||
for (auto const& p : r.plugins) {
|
||||
|
||||
std::cout << std::string{Colors::RESET} + " │ Plugin " + p.name;
|
||||
std::println(" │ Plugin {}", p.name);
|
||||
|
||||
if (!p.failed)
|
||||
std::cout << "\n └─ enabled: " << (p.enabled ? Colors::GREEN : Colors::RED) << (p.enabled ? "true" : "false") << Colors::RESET << "\n";
|
||||
std::println(" └─ enabled: {}", (p.enabled ? std::string{Colors::GREEN} + "true" : std::string{Colors::RED} + "false"));
|
||||
else
|
||||
std::cout << "\n └─ enabled: " << Colors::RED << "Plugin failed to build" << Colors::RESET << "\n";
|
||||
std::println(" └─ enabled: {}Plugin failed to build", Colors::RED);
|
||||
|
||||
std::println("{}", Colors::RESET);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -876,19 +882,19 @@ void CPluginManager::notify(const eNotifyIcons icon, uint32_t color, int duratio
|
||||
|
||||
std::string CPluginManager::headerError(const eHeadersErrors err) {
|
||||
switch (err) {
|
||||
case HEADERS_CORRUPTED: return std::string{Colors::RED} + "✖" + Colors::RESET + " Headers corrupted. Please run hyprpm update to fix those.\n";
|
||||
case HEADERS_MISMATCHED: return std::string{Colors::RED} + "✖" + Colors::RESET + " Headers version mismatch. Please run hyprpm update to fix those.\n";
|
||||
case HEADERS_NOT_HYPRLAND: return std::string{Colors::RED} + "✖" + Colors::RESET + " It doesn't seem you are running on hyprland.\n";
|
||||
case HEADERS_MISSING: return std::string{Colors::RED} + "✖" + Colors::RESET + " Headers missing. Please run hyprpm update to fix those.\n";
|
||||
case HEADERS_CORRUPTED: return failureString("Headers corrupted. Please run hyprpm update to fix those.\n");
|
||||
case HEADERS_MISMATCHED: return failureString("Headers version mismatch. Please run hyprpm update to fix those.\n");
|
||||
case HEADERS_NOT_HYPRLAND: return failureString("It doesn't seem you are running on hyprland.\n");
|
||||
case HEADERS_MISSING: return failureString("Headers missing. Please run hyprpm update to fix those.\n");
|
||||
case HEADERS_DUPLICATED: {
|
||||
return std::string{Colors::RED} + "✖" + Colors::RESET + " Headers duplicated!!! This is a very bad sign.\n" +
|
||||
" This could be due to e.g. installing hyprland manually while a system package of hyprland is also installed.\n" +
|
||||
" If the above doesn't apply, check your /usr/include and /usr/local/include directories\n and remove all the hyprland headers.\n";
|
||||
return failureString("Headers duplicated!!! This is a very bad sign.\n"
|
||||
"This could be due to e.g. installing hyprland manually while a system package of hyprland is also installed.\n"
|
||||
"If the above doesn't apply, check your /usr/include and /usr/local/include directories\n and remove all the hyprland headers.\n");
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
return std::string{Colors::RED} + "✖" + Colors::RESET + " Unknown header error. Please run hyprpm update to fix those.\n";
|
||||
return failureString("Unknown header error. Please run hyprpm update to fix those.\n");
|
||||
}
|
||||
|
||||
std::string CPluginManager::headerErrorShort(const eHeadersErrors err) {
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
enum eHeadersErrors {
|
||||
HEADERS_OK = 0,
|
||||
@@ -68,7 +69,7 @@ class CPluginManager {
|
||||
std::string headerError(const eHeadersErrors err);
|
||||
std::string headerErrorShort(const eHeadersErrors err);
|
||||
|
||||
std::string m_szWorkingPluginDirectory = "";
|
||||
std::string m_szWorkingPluginDirectory;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CPluginManager> g_pPluginManager;
|
||||
|
32
hyprpm/src/helpers/StringUtils.hpp
Normal file
32
hyprpm/src/helpers/StringUtils.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <format>
|
||||
#include <string>
|
||||
#include "Colors.hpp"
|
||||
|
||||
template <typename... Args>
|
||||
std::string statusString(const std::string_view emoji, const std::string_view color, const std::string_view fmt, Args&&... args) {
|
||||
std::string ret = std::format("{}{}{} ", color, emoji, Colors::RESET);
|
||||
ret += std::vformat(fmt, std::make_format_args(args...));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::string successString(const std::string_view fmt, Args&&... args) {
|
||||
return statusString("✔", Colors::GREEN, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::string failureString(const std::string_view fmt, Args&&... args) {
|
||||
return statusString("✖", Colors::RED, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::string verboseString(const std::string_view fmt, Args&&... args) {
|
||||
return statusString("[v]", Colors::BLUE, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::string infoString(const std::string_view fmt, Args&&... args) {
|
||||
return statusString("→", Colors::RESET, fmt, args...);
|
||||
}
|
@@ -1,15 +1,16 @@
|
||||
#include "progress/CProgressBar.hpp"
|
||||
#include "helpers/Colors.hpp"
|
||||
#include "helpers/StringUtils.hpp"
|
||||
#include "core/PluginManager.hpp"
|
||||
#include "core/DataState.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <print>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
const std::string HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
||||
constexpr std::string_view HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
||||
┃
|
||||
┣ add [url] [git rev] → Install a new plugin repository from git. Git revision
|
||||
┃ is optional, when set, commit locks are ignored.
|
||||
@@ -22,7 +23,8 @@ const std::string HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
||||
┃
|
||||
┣ Flags:
|
||||
┃
|
||||
┣ --notify | -n → Send a hyprland notification for important events (e.g. load fail)
|
||||
┣ --notify | -n → Send a hyprland notification for important events (including both successes and fail events)
|
||||
┣ --notify-fail | -nn → Send a hyprland notification for fail events only
|
||||
┣ --help | -h → Show this menu
|
||||
┣ --verbose | -v → Enable too much logging
|
||||
┣ --force | -f → Force an operation ignoring checks (e.g. update -f)
|
||||
@@ -30,36 +32,38 @@ const std::string HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
||||
┗
|
||||
)#";
|
||||
|
||||
int main(int argc, char** argv, char** envp) {
|
||||
int main(int argc, char** argv, char** envp) {
|
||||
std::vector<std::string> ARGS{argc};
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
ARGS[i] = std::string{argv[i]};
|
||||
}
|
||||
|
||||
if (ARGS.size() < 2) {
|
||||
std::cout << HELP;
|
||||
std::println(stderr, "{}", HELP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<std::string> command;
|
||||
bool notify = false, verbose = false, force = false, noShallow = false;
|
||||
bool notify = false, notifyFail = false, verbose = false, force = false, noShallow = false;
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (ARGS[i].starts_with("-")) {
|
||||
if (ARGS[i] == "--help" || ARGS[i] == "-h") {
|
||||
std::cout << HELP;
|
||||
std::println("{}", HELP);
|
||||
return 0;
|
||||
} else if (ARGS[i] == "--notify" || ARGS[i] == "-n") {
|
||||
notify = true;
|
||||
} else if (ARGS[i] == "--notify-fail" || ARGS[i] == "-nn") {
|
||||
notifyFail = notify = true;
|
||||
} else if (ARGS[i] == "--verbose" || ARGS[i] == "-v") {
|
||||
verbose = true;
|
||||
} else if (ARGS[i] == "--no-shallow" || ARGS[i] == "-s") {
|
||||
noShallow = true;
|
||||
} else if (ARGS[i] == "--force" || ARGS[i] == "-f") {
|
||||
force = true;
|
||||
std::cout << Colors::RED << "!" << Colors::RESET << " Using --force, I hope you know what you are doing.\n";
|
||||
std::println("{}", statusString("!", Colors::RED, "Using --force, I hope you know what you are doing."));
|
||||
} else {
|
||||
std::cerr << "Unrecognized option " << ARGS[i] << "\n";
|
||||
std::println(stderr, "Unrecognized option {}", ARGS[i]);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
@@ -68,7 +72,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
}
|
||||
|
||||
if (command.empty()) {
|
||||
std::cout << HELP;
|
||||
std::println(stderr, "{}", HELP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -78,7 +82,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
|
||||
if (command[0] == "add") {
|
||||
if (command.size() < 2) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for add.\n";
|
||||
std::println(stderr, "{}", failureString("Not enough args for add."));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -90,7 +94,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
return g_pPluginManager->addNewPluginRepo(command[1], rev) ? 0 : 1;
|
||||
} else if (command[0] == "remove") {
|
||||
if (ARGS.size() < 2) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for remove.\n";
|
||||
std::println(stderr, "{}", failureString("Not enough args for remove."));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -116,12 +120,12 @@ int main(int argc, char** argv, char** envp) {
|
||||
g_pPluginManager->notify(ICON_ERROR, 0, 10000, "[hyprpm] Couldn't update headers");
|
||||
} else if (command[0] == "enable") {
|
||||
if (ARGS.size() < 2) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for enable.\n";
|
||||
std::println(stderr, "{}", failureString("Not enough args for enable."));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!g_pPluginManager->enablePlugin(command[1])) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Couldn't enable plugin (missing?)\n";
|
||||
std::println(stderr, "{}", failureString("Couldn't enable plugin (missing?)"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -130,12 +134,12 @@ int main(int argc, char** argv, char** envp) {
|
||||
return 1;
|
||||
} else if (command[0] == "disable") {
|
||||
if (command.size() < 2) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for disable.\n";
|
||||
std::println(stderr, "{}", failureString("Not enough args for disable."));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!g_pPluginManager->disablePlugin(command[1])) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Couldn't disable plugin (missing?)\n";
|
||||
std::println(stderr, "{}", failureString("Couldn't disable plugin (missing?)"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -154,15 +158,15 @@ int main(int argc, char** argv, char** envp) {
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
} else if (notify) {
|
||||
} else if (notify && !notifyFail) {
|
||||
g_pPluginManager->notify(ICON_OK, 0, 4000, "[hyprpm] Loaded plugins");
|
||||
}
|
||||
} else if (command[0] == "list") {
|
||||
g_pPluginManager->listAllPlugins();
|
||||
} else {
|
||||
std::cout << HELP;
|
||||
std::println(stderr, "{}", HELP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
#include "CProgressBar.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/ioctl.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <format>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <print>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -16,11 +16,12 @@ void CProgressBar::printMessageAbove(const std::string& msg) {
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
|
||||
std::string spaces;
|
||||
spaces.reserve(w.ws_col);
|
||||
for (size_t i = 0; i < w.ws_col; ++i) {
|
||||
spaces += ' ';
|
||||
}
|
||||
|
||||
std::cout << "\r" << spaces << "\r" << msg << "\n";
|
||||
std::println("\r{}\r{}", spaces, msg);
|
||||
print();
|
||||
}
|
||||
|
||||
@@ -29,15 +30,16 @@ void CProgressBar::print() {
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
|
||||
if (m_bFirstPrint)
|
||||
std::cout << "\n";
|
||||
std::print("\n");
|
||||
m_bFirstPrint = false;
|
||||
|
||||
std::string spaces;
|
||||
spaces.reserve(w.ws_col);
|
||||
for (size_t i = 0; i < w.ws_col; ++i) {
|
||||
spaces += ' ';
|
||||
}
|
||||
|
||||
std::cout << "\r" << spaces << "\r";
|
||||
std::print("\r{}\r", spaces);
|
||||
|
||||
std::string message = "";
|
||||
|
||||
@@ -74,7 +76,7 @@ void CProgressBar::print() {
|
||||
message += " " + std::format("{} / {}", m_iSteps, m_iMaxSteps) + " ";
|
||||
|
||||
// draw message
|
||||
std::cout << message + " " + m_szCurrentMessage;
|
||||
std::print("{} {}", message, m_szCurrentMessage);
|
||||
|
||||
std::fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
@@ -14,4 +14,4 @@ class CProgressBar {
|
||||
|
||||
private:
|
||||
bool m_bFirstPrint = true;
|
||||
};
|
||||
};
|
||||
|
@@ -21,6 +21,7 @@ add_project_arguments(
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wno-narrowing',
|
||||
'-Wno-pointer-arith', datarootdir,
|
||||
'-DHYPRLAND_VERSION="' + meson.project_version() + '"',
|
||||
],
|
||||
language: 'cpp',
|
||||
)
|
||||
@@ -30,7 +31,7 @@ if cpp_compiler.check_header('execinfo.h')
|
||||
add_project_arguments('-DHAS_EXECINFO', language: 'cpp')
|
||||
endif
|
||||
|
||||
aquamarine = dependency('aquamarine')
|
||||
aquamarine = dependency('aquamarine', version: '>=0.4.2')
|
||||
add_project_arguments(['-DAQUAMARINE_VERSION="@0@"'.format(aquamarine.version())], language: 'cpp')
|
||||
|
||||
xcb_dep = dependency('xcb', required: get_option('xwayland'))
|
||||
@@ -52,7 +53,9 @@ epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs
|
||||
|
||||
# Handle options
|
||||
if get_option('systemd').enabled()
|
||||
systemd = dependency('systemd')
|
||||
add_project_arguments('-DUSES_SYSTEMD', language: 'cpp')
|
||||
subdir('systemd')
|
||||
endif
|
||||
|
||||
if get_option('legacy_renderer').enabled()
|
||||
@@ -79,6 +82,8 @@ if get_option('tracy_enable') and get_option('buildtype') != 'debugoptimized'
|
||||
warning('Profiling builds should set -- buildtype = debugoptimized')
|
||||
endif
|
||||
|
||||
|
||||
|
||||
subdir('protocols')
|
||||
subdir('src')
|
||||
subdir('hyprctl')
|
||||
|
@@ -56,6 +56,7 @@
|
||||
|
||||
adapters = flatten [
|
||||
stdenvAdapters.useMoldLinker
|
||||
(lib.optional debug stdenvAdapters.keepDebugInfo)
|
||||
];
|
||||
|
||||
customStdenv = foldl' (acc: adapter: adapter acc) stdenv adapters;
|
||||
@@ -68,7 +69,7 @@ in
|
||||
inherit version;
|
||||
|
||||
src = cleanSourceWith {
|
||||
filter = name: type: let
|
||||
filter = name: _type: let
|
||||
baseName = baseNameOf (toString name);
|
||||
in
|
||||
! (hasSuffix ".nix" baseName);
|
||||
@@ -147,9 +148,6 @@ in
|
||||
then "debugoptimized"
|
||||
else "release";
|
||||
|
||||
# we want as much debug info as possible
|
||||
dontStrip = debug;
|
||||
|
||||
mesonFlags = flatten [
|
||||
(mapAttrsToList mesonEnable {
|
||||
"xwayland" = enableXWayland;
|
||||
|
64
nix/formatter.nix
Normal file
64
nix/formatter.nix
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
writeShellApplication,
|
||||
deadnix,
|
||||
statix,
|
||||
alejandra,
|
||||
llvmPackages_19,
|
||||
fd,
|
||||
}:
|
||||
writeShellApplication {
|
||||
name = "hyprland-treewide-formatter";
|
||||
runtimeInputs = [
|
||||
deadnix
|
||||
statix
|
||||
alejandra
|
||||
llvmPackages_19.clang-tools
|
||||
fd
|
||||
];
|
||||
text = ''
|
||||
# shellcheck disable=SC2148
|
||||
|
||||
# common excludes
|
||||
excludes="subprojects"
|
||||
|
||||
nix_format() {
|
||||
if [ "$*" = 0 ]; then
|
||||
fd '.*\.nix' . -E "$excludes" -x statix fix -- {} \;
|
||||
fd '.*\.nix' . -E "$excludes" -X deadnix -e -- {} \; -X alejandra {} \;
|
||||
elif [ -d "$1" ]; then
|
||||
fd '.*\.nix' "$1" -E "$excludes" -i -x statix fix -- {} \;
|
||||
fd '.*\.nix' "$1" -E "$excludes" -i -X deadnix -e -- {} \; -X alejandra {} \;
|
||||
else
|
||||
statix fix -- "$1"
|
||||
deadnix -e "$1"
|
||||
alejandra "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
cpp_format() {
|
||||
if [ "$*" = 0 ] || [ "$1" = "." ]; then
|
||||
fd '.*\.cpp' . -E "$excludes" | xargs clang-format --verbose -i
|
||||
elif [ -d "$1" ]; then
|
||||
fd '.*\.cpp' "$1" -E "$excludes" | xargs clang-format --verbose -i
|
||||
else
|
||||
clang-format --verbose -i "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
for i in "$@"; do
|
||||
case ''${i##*.} in
|
||||
"nix")
|
||||
nix_format "$i"
|
||||
;;
|
||||
"cpp")
|
||||
cpp_format "$i"
|
||||
;;
|
||||
*)
|
||||
nix_format "$i"
|
||||
cpp_format "$i"
|
||||
;;
|
||||
esac
|
||||
|
||||
done
|
||||
'';
|
||||
}
|
@@ -29,7 +29,7 @@ in {
|
||||
self.overlays.udis86
|
||||
|
||||
# Hyprland packages themselves
|
||||
(final: prev: let
|
||||
(final: _prev: let
|
||||
date = mkDate (self.lastModifiedDate or "19700101");
|
||||
in {
|
||||
hyprland = final.callPackage ./default.nix {
|
||||
@@ -40,7 +40,13 @@ in {
|
||||
inherit date;
|
||||
};
|
||||
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
|
||||
hyprland-debug = final.hyprland.override {debug = true;};
|
||||
|
||||
# Build major libs with debug to get as much info as possible in a stacktrace
|
||||
hyprland-debug = final.hyprland.override {
|
||||
aquamarine = final.aquamarine.override {debug = true;};
|
||||
hyprutils = final.hyprutils.override {debug = true;};
|
||||
debug = true;
|
||||
};
|
||||
hyprland-legacy-renderer = final.hyprland.override {legacyRenderer = true;};
|
||||
|
||||
# deprecated packages
|
||||
@@ -63,14 +69,14 @@ in {
|
||||
# Packages for extra software recommended for usage with Hyprland,
|
||||
# including forked or patched packages for compatibility.
|
||||
hyprland-extras = lib.composeManyExtensions [
|
||||
inputs.xdph.overlays.xdg-desktop-portal-hyprland
|
||||
inputs.xdph.overlays.default
|
||||
];
|
||||
|
||||
# udis86 from nixpkgs is too old, and also does not provide a .pc file
|
||||
# this version is the one used in the git submodule, and allows us to
|
||||
# fetch the source without '?submodules=1'
|
||||
udis86 = final: prev: {
|
||||
udis86-hyprland = prev.udis86.overrideAttrs (self: super: {
|
||||
udis86-hyprland = prev.udis86.overrideAttrs (_self: _super: {
|
||||
src = final.fetchFromGitHub {
|
||||
owner = "canihavesomecoffee";
|
||||
repo = "udis86";
|
||||
|
@@ -7,7 +7,7 @@ wayland_protos = dependency(
|
||||
|
||||
hyprland_protos = dependency(
|
||||
'hyprland-protocols',
|
||||
version: '>=0.2',
|
||||
version: '>=0.4',
|
||||
fallback: 'hyprland-protocols',
|
||||
)
|
||||
|
||||
@@ -36,6 +36,7 @@ protocols = [
|
||||
hyprland_protocol_dir / 'protocols/hyprland-global-shortcuts-v1.xml',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-toplevel-export-v1.xml',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-focus-grab-v1.xml',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-ctm-control-v1.xml',
|
||||
wayland_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
|
||||
wayland_protocol_dir / 'staging/fractional-scale/fractional-scale-v1.xml',
|
||||
wayland_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',
|
||||
@@ -64,6 +65,7 @@ protocols = [
|
||||
wayland_protocol_dir / 'staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml',
|
||||
wayland_protocol_dir / 'staging/xdg-dialog/xdg-dialog-v1.xml',
|
||||
wayland_protocol_dir / 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml',
|
||||
wayland_protocol_dir / 'staging/security-context/security-context-v1.xml',
|
||||
]
|
||||
|
||||
wl_protocols = []
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "Compositor.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "helpers/Splashes.hpp"
|
||||
#include "config/ConfigValue.hpp"
|
||||
#include "managers/CursorManager.hpp"
|
||||
@@ -8,7 +9,9 @@
|
||||
#include "managers/eventLoop/EventLoopManager.hpp"
|
||||
#include <aquamarine/output/Output.hpp>
|
||||
#include <bit>
|
||||
#include <ctime>
|
||||
#include <random>
|
||||
#include <print>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <unordered_set>
|
||||
@@ -24,12 +27,14 @@
|
||||
#include "protocols/LayerShell.hpp"
|
||||
#include "protocols/XDGShell.hpp"
|
||||
#include "protocols/XDGOutput.hpp"
|
||||
#include "protocols/SecurityContext.hpp"
|
||||
#include "protocols/core/Compositor.hpp"
|
||||
#include "protocols/core/Subcompositor.hpp"
|
||||
#include "desktop/LayerSurface.hpp"
|
||||
#include "render/Renderer.hpp"
|
||||
#include "xwayland/XWayland.hpp"
|
||||
#include "helpers/ByteOperations.hpp"
|
||||
#include "render/decorations/CHyprGroupBarDecoration.hpp"
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <aquamarine/input/Input.hpp>
|
||||
@@ -136,37 +141,37 @@ CCompositor::CCompositor() {
|
||||
m_szHyprTempDataRoot = std::string{getenv("XDG_RUNTIME_DIR")} + "/hypr";
|
||||
|
||||
if (m_szHyprTempDataRoot.starts_with("/hypr")) {
|
||||
std::cout << "Bailing out, XDG_RUNTIME_DIR is invalid\n";
|
||||
std::println("Bailing out, $XDG_RUNTIME_DIR is invalid");
|
||||
throw std::runtime_error("CCompositor() failed");
|
||||
}
|
||||
|
||||
if (!m_szHyprTempDataRoot.starts_with("/run/user"))
|
||||
std::cout << "[!!WARNING!!] XDG_RUNTIME_DIR looks non-standard. Proceeding anyways...\n";
|
||||
std::println("[!!WARNING!!] XDG_RUNTIME_DIR looks non-standard. Proceeding anyways...");
|
||||
|
||||
std::random_device dev;
|
||||
std::mt19937 engine(dev());
|
||||
std::uniform_int_distribution<> distribution(0, INT32_MAX);
|
||||
|
||||
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL)) + "_" + std::to_string(distribution(engine));
|
||||
m_szInstanceSignature = std::format("{}_{}_{}", GIT_COMMIT_HASH, std::time(NULL), distribution(engine));
|
||||
|
||||
setenv("HYPRLAND_INSTANCE_SIGNATURE", m_szInstanceSignature.c_str(), true);
|
||||
|
||||
if (!std::filesystem::exists(m_szHyprTempDataRoot))
|
||||
mkdir(m_szHyprTempDataRoot.c_str(), S_IRWXU);
|
||||
else if (!std::filesystem::is_directory(m_szHyprTempDataRoot)) {
|
||||
std::cout << "Bailing out, " << m_szHyprTempDataRoot << " is not a directory\n";
|
||||
std::println("Bailing out, {} is not a directory", m_szHyprTempDataRoot);
|
||||
throw std::runtime_error("CCompositor() failed");
|
||||
}
|
||||
|
||||
m_szInstancePath = m_szHyprTempDataRoot + "/" + m_szInstanceSignature;
|
||||
|
||||
if (std::filesystem::exists(m_szInstancePath)) {
|
||||
std::cout << "Bailing out, " << m_szInstancePath << " exists??\n";
|
||||
std::println("Bailing out, {} exists??", m_szInstancePath);
|
||||
throw std::runtime_error("CCompositor() failed");
|
||||
}
|
||||
|
||||
if (mkdir(m_szInstancePath.c_str(), S_IRWXU) < 0) {
|
||||
std::cout << "Bailing out, couldn't create " << m_szInstancePath << "\n";
|
||||
std::println("Bailing out, couldn't create {}", m_szInstancePath);
|
||||
throw std::runtime_error("CCompositor() failed");
|
||||
}
|
||||
|
||||
@@ -210,11 +215,22 @@ void CCompositor::setRandomSplash() {
|
||||
|
||||
static std::vector<SP<Aquamarine::IOutput>> pendingOutputs;
|
||||
|
||||
//
|
||||
|
||||
static bool filterGlobals(const wl_client* client, const wl_global* global, void* data) {
|
||||
if (!PROTO::securityContext->isClientSandboxed(client))
|
||||
return true;
|
||||
|
||||
return !g_pProtocolManager || !g_pProtocolManager->isGlobalPrivileged(global);
|
||||
}
|
||||
|
||||
//
|
||||
void CCompositor::initServer(std::string socketName, int socketFd) {
|
||||
|
||||
m_sWLDisplay = wl_display_create();
|
||||
|
||||
wl_display_set_global_filter(m_sWLDisplay, ::filterGlobals, nullptr);
|
||||
|
||||
m_sWLEventLoop = wl_display_get_event_loop(m_sWLDisplay);
|
||||
|
||||
// register crit signal handler
|
||||
@@ -397,8 +413,8 @@ void CCompositor::initAllSignals() {
|
||||
m_bSessionActive = true;
|
||||
|
||||
for (auto const& m : m_vMonitors) {
|
||||
scheduleFrameForMonitor(m.get());
|
||||
g_pHyprRenderer->applyMonitorRule(m.get(), &m->activeMonitorRule, true);
|
||||
scheduleFrameForMonitor(m);
|
||||
g_pHyprRenderer->applyMonitorRule(m, &m->activeMonitorRule, true);
|
||||
}
|
||||
|
||||
g_pConfigManager->m_bWantsMonitorReload = true;
|
||||
@@ -483,7 +499,7 @@ void CCompositor::cleanup() {
|
||||
m_vWindows.clear();
|
||||
|
||||
for (auto const& m : m_vMonitors) {
|
||||
g_pHyprOpenGL->destroyMonitorResources(m.get());
|
||||
g_pHyprOpenGL->destroyMonitorResources(m);
|
||||
|
||||
m->output->state->setEnabled(false);
|
||||
m->state.commit();
|
||||
@@ -702,39 +718,39 @@ void CCompositor::startCompositor() {
|
||||
g_pEventLoopManager->enterLoop();
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorFromID(const MONITORID& id) {
|
||||
PHLMONITOR CCompositor::getMonitorFromID(const MONITORID& id) {
|
||||
for (auto const& m : m_vMonitors) {
|
||||
if (m->ID == id) {
|
||||
return m.get();
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorFromName(const std::string& name) {
|
||||
PHLMONITOR CCompositor::getMonitorFromName(const std::string& name) {
|
||||
for (auto const& m : m_vMonitors) {
|
||||
if (m->szName == name) {
|
||||
return m.get();
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorFromDesc(const std::string& desc) {
|
||||
PHLMONITOR CCompositor::getMonitorFromDesc(const std::string& desc) {
|
||||
for (auto const& m : m_vMonitors) {
|
||||
if (m->szDescription.starts_with(desc))
|
||||
return m.get();
|
||||
return m;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorFromCursor() {
|
||||
PHLMONITOR CCompositor::getMonitorFromCursor() {
|
||||
return getMonitorFromVector(g_pPointerManager->position());
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
|
||||
SP<CMonitor> mon;
|
||||
PHLMONITOR CCompositor::getMonitorFromVector(const Vector2D& point) {
|
||||
PHLMONITOR mon;
|
||||
for (auto const& m : m_vMonitors) {
|
||||
if (CBox{m->vecPosition, m->vecSize}.containsPoint(point)) {
|
||||
mon = m;
|
||||
@@ -743,8 +759,8 @@ CMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
|
||||
}
|
||||
|
||||
if (!mon) {
|
||||
float bestDistance = 0.f;
|
||||
SP<CMonitor> pBestMon;
|
||||
float bestDistance = 0.f;
|
||||
PHLMONITOR pBestMon;
|
||||
|
||||
for (auto const& m : m_vMonitors) {
|
||||
float dist = vecToRectDistanceSquared(point, m->vecPosition, m->vecPosition + m->vecSize);
|
||||
@@ -757,13 +773,13 @@ CMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
|
||||
|
||||
if (!pBestMon) { // ?????
|
||||
Debug::log(WARN, "getMonitorFromVector no close mon???");
|
||||
return m_vMonitors.front().get();
|
||||
return m_vMonitors.front();
|
||||
}
|
||||
|
||||
return pBestMon.get();
|
||||
return pBestMon;
|
||||
}
|
||||
|
||||
return mon.get();
|
||||
return mon;
|
||||
}
|
||||
|
||||
void CCompositor::removeWindowFromVectorSafe(PHLWINDOW pWindow) {
|
||||
@@ -775,9 +791,9 @@ void CCompositor::removeWindowFromVectorSafe(PHLWINDOW pWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CCompositor::monitorExists(CMonitor* pMonitor) {
|
||||
bool CCompositor::monitorExists(PHLMONITOR pMonitor) {
|
||||
for (auto const& m : m_vRealMonitors) {
|
||||
if (m.get() == pMonitor)
|
||||
if (m == pMonitor)
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -795,10 +811,10 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
||||
// pinned windows on top of floating regardless
|
||||
if (properties & ALLOW_FLOATING) {
|
||||
for (auto const& w : m_vWindows | std::views::reverse) {
|
||||
const auto BB = w->getWindowBoxUnified(properties);
|
||||
CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0);
|
||||
if (w->m_bIsFloating && w->m_bIsMapped && !w->isHidden() && !w->m_bX11ShouldntFocus && w->m_bPinned && !w->m_sWindowData.noFocus.valueOrDefault() &&
|
||||
w != pIgnoreWindow) {
|
||||
const auto BB = w->getWindowBoxUnified(properties);
|
||||
CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0);
|
||||
if (box.containsPoint(g_pPointerManager->position()))
|
||||
return w;
|
||||
|
||||
@@ -817,22 +833,25 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
||||
if (special && !w->onSpecialWorkspace()) // because special floating may creep up into regular
|
||||
continue;
|
||||
|
||||
const auto BB = w->getWindowBoxUnified(properties);
|
||||
const auto PWINDOWMONITOR = getMonitorFromID(w->m_iMonitorID);
|
||||
const auto PWINDOWMONITOR = w->m_pMonitor.lock();
|
||||
|
||||
// to avoid focusing windows behind special workspaces from other monitors
|
||||
if (!*PSPECIALFALLTHRU && PWINDOWMONITOR && PWINDOWMONITOR->activeSpecialWorkspace && w->m_pWorkspace != PWINDOWMONITOR->activeSpecialWorkspace &&
|
||||
BB.x >= PWINDOWMONITOR->vecPosition.x && BB.y >= PWINDOWMONITOR->vecPosition.y &&
|
||||
BB.x + BB.width <= PWINDOWMONITOR->vecPosition.x + PWINDOWMONITOR->vecSize.x && BB.y + BB.height <= PWINDOWMONITOR->vecPosition.y + PWINDOWMONITOR->vecSize.y)
|
||||
continue;
|
||||
if (!*PSPECIALFALLTHRU && PWINDOWMONITOR && PWINDOWMONITOR->activeSpecialWorkspace && w->m_pWorkspace != PWINDOWMONITOR->activeSpecialWorkspace) {
|
||||
const auto BB = w->getWindowBoxUnified(properties);
|
||||
if (BB.x >= PWINDOWMONITOR->vecPosition.x && BB.y >= PWINDOWMONITOR->vecPosition.y &&
|
||||
BB.x + BB.width <= PWINDOWMONITOR->vecPosition.x + PWINDOWMONITOR->vecSize.x &&
|
||||
BB.y + BB.height <= PWINDOWMONITOR->vecPosition.y + PWINDOWMONITOR->vecSize.y)
|
||||
continue;
|
||||
}
|
||||
|
||||
CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0);
|
||||
if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_pWorkspace) && !w->isHidden() && !w->m_bPinned && !w->m_sWindowData.noFocus.valueOrDefault() &&
|
||||
w != pIgnoreWindow && (!aboveFullscreen || w->m_bCreatedOverFullscreen)) {
|
||||
// OR windows should add focus to parent
|
||||
if (w->m_bX11ShouldntFocus && !w->isX11OverrideRedirect())
|
||||
continue;
|
||||
|
||||
const auto BB = w->getWindowBoxUnified(properties);
|
||||
CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0);
|
||||
if (box.containsPoint(g_pPointerManager->position())) {
|
||||
|
||||
if (w->m_bIsX11 && w->isX11OverrideRedirect() && !w->m_pXWaylandSurface->wantsFocus()) {
|
||||
@@ -890,10 +909,12 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
||||
if (special != w->onSpecialWorkspace())
|
||||
continue;
|
||||
|
||||
CBox box = (properties & USE_PROP_TILED) ? w->getWindowBoxUnified(properties) : CBox{w->m_vPosition, w->m_vSize};
|
||||
if (!w->m_bIsFloating && w->m_bIsMapped && box.containsPoint(pos) && w->workspaceID() == WSPID && !w->isHidden() && !w->m_bX11ShouldntFocus &&
|
||||
!w->m_sWindowData.noFocus.valueOrDefault() && w != pIgnoreWindow)
|
||||
return w;
|
||||
if (!w->m_bIsFloating && w->m_bIsMapped && w->workspaceID() == WSPID && !w->isHidden() && !w->m_bX11ShouldntFocus && !w->m_sWindowData.noFocus.valueOrDefault() &&
|
||||
w != pIgnoreWindow) {
|
||||
CBox box = (properties & USE_PROP_TILED) ? w->getWindowBoxUnified(properties) : CBox{w->m_vPosition, w->m_vSize};
|
||||
if (box.containsPoint(pos))
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -967,20 +988,20 @@ Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindo
|
||||
return vec - pWindow->m_vRealPosition.goal() - std::get<1>(iterData) + Vector2D{geom.x, geom.y};
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorFromOutput(SP<Aquamarine::IOutput> out) {
|
||||
PHLMONITOR CCompositor::getMonitorFromOutput(SP<Aquamarine::IOutput> out) {
|
||||
for (auto const& m : m_vMonitors) {
|
||||
if (m->output == out) {
|
||||
return m.get();
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getRealMonitorFromOutput(SP<Aquamarine::IOutput> out) {
|
||||
PHLMONITOR CCompositor::getRealMonitorFromOutput(SP<Aquamarine::IOutput> out) {
|
||||
for (auto const& m : m_vRealMonitors) {
|
||||
if (m->output == out) {
|
||||
return m.get();
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1041,13 +1062,13 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pLastWindow.lock() == pWindow && g_pSeatManager->state.keyboardFocus == pSurface)
|
||||
if (m_pLastWindow.lock() == pWindow && g_pSeatManager->state.keyboardFocus == pSurface && g_pSeatManager->state.keyboardFocus)
|
||||
return;
|
||||
|
||||
if (pWindow->m_bPinned)
|
||||
pWindow->m_pWorkspace = m_pLastMonitor->activeWorkspace;
|
||||
|
||||
const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
if (!isWorkspaceVisible(pWindow->m_pWorkspace)) {
|
||||
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
||||
@@ -1056,7 +1077,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
||||
PWORKSPACE->rememberPrevWorkspace(m_pLastMonitor->activeWorkspace);
|
||||
if (PWORKSPACE->m_bIsSpecialWorkspace)
|
||||
m_pLastMonitor->changeWorkspace(PWORKSPACE, false, true); // if special ws, open on current monitor
|
||||
else
|
||||
else if (PMONITOR)
|
||||
PMONITOR->changeWorkspace(PWORKSPACE, false, true);
|
||||
// changeworkspace already calls focusWindow
|
||||
return;
|
||||
@@ -1067,7 +1088,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
||||
|
||||
/* If special fallthrough is enabled, this behavior will be disabled, as I have no better idea of nicely tracking which
|
||||
window focuses are "via keybinds" and which ones aren't. */
|
||||
if (PMONITOR->activeSpecialWorkspace && PMONITOR->activeSpecialWorkspace != pWindow->m_pWorkspace && !pWindow->m_bPinned && !*PSPECIALFALLTHROUGH)
|
||||
if (PMONITOR && PMONITOR->activeSpecialWorkspace && PMONITOR->activeSpecialWorkspace != pWindow->m_pWorkspace && !pWindow->m_bPinned && !*PSPECIALFALLTHROUGH)
|
||||
PMONITOR->setSpecialWorkspace(nullptr);
|
||||
|
||||
// we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window
|
||||
@@ -1168,7 +1189,7 @@ void CCompositor::focusSurface(SP<CWLSurfaceResource> pSurface, PHLWINDOW pWindo
|
||||
SURF->constraint()->activate();
|
||||
}
|
||||
|
||||
SP<CWLSurfaceResource> CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonitor* monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
|
||||
SP<CWLSurfaceResource> CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, PHLMONITOR monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
|
||||
for (auto const& lsl : monitor->m_aLayerSurfaceLayers | std::views::reverse) {
|
||||
for (auto const& ls : lsl | std::views::reverse) {
|
||||
if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->mapped) || ls->alpha.value() == 0.f)
|
||||
@@ -1243,7 +1264,7 @@ bool CCompositor::isWorkspaceVisibleNotCovered(PHLWORKSPACE w) {
|
||||
if (!valid(w))
|
||||
return false;
|
||||
|
||||
const auto PMONITOR = getMonitorFromID(w->m_iMonitorID);
|
||||
const auto PMONITOR = w->m_pMonitor.lock();
|
||||
if (PMONITOR->activeSpecialWorkspace)
|
||||
return PMONITOR->activeSpecialWorkspace->m_iID == w->m_iID;
|
||||
|
||||
@@ -1338,7 +1359,7 @@ PHLWINDOW CCompositor::getTopLeftWindowOnWorkspace(const WORKSPACEID& id) {
|
||||
if (!PWORKSPACE)
|
||||
return nullptr;
|
||||
|
||||
const auto PMONITOR = getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
const auto PMONITOR = PWORKSPACE->m_pMonitor.lock();
|
||||
|
||||
for (auto const& w : m_vWindows) {
|
||||
if (w->workspaceID() != id || !w->m_bIsMapped || w->isHidden())
|
||||
@@ -1368,6 +1389,12 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) {
|
||||
if (!validMapped(pWindow))
|
||||
return;
|
||||
|
||||
if (top)
|
||||
pWindow->m_bCreatedOverFullscreen = true;
|
||||
|
||||
if (pWindow == (top ? m_vWindows.back() : m_vWindows.front()))
|
||||
return;
|
||||
|
||||
auto moveToZ = [&](PHLWINDOW pw, bool top) -> void {
|
||||
if (top) {
|
||||
for (auto it = m_vWindows.begin(); it != m_vWindows.end(); ++it) {
|
||||
@@ -1386,12 +1413,9 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) {
|
||||
}
|
||||
|
||||
if (pw->m_bIsMapped)
|
||||
g_pHyprRenderer->damageMonitor(getMonitorFromID(pw->m_iMonitorID));
|
||||
g_pHyprRenderer->damageMonitor(pw->m_pMonitor.lock());
|
||||
};
|
||||
|
||||
if (top)
|
||||
pWindow->m_bCreatedOverFullscreen = true;
|
||||
|
||||
if (!pWindow->m_bIsX11)
|
||||
moveToZ(pWindow, top);
|
||||
else {
|
||||
@@ -1425,7 +1449,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) {
|
||||
|
||||
auto w = ww.lock();
|
||||
|
||||
if (w->m_iMonitorID != monid)
|
||||
if (w->monitorID() != monid && w->m_pMonitor)
|
||||
continue;
|
||||
|
||||
if (!w->m_bFadingOut || w->m_fAlpha.value() == 0.f) {
|
||||
@@ -1455,7 +1479,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ls->monitorID != monid)
|
||||
if (ls->monitorID() != monid && ls->monitor)
|
||||
continue;
|
||||
|
||||
// mark blur for recalc
|
||||
@@ -1518,7 +1542,7 @@ PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) {
|
||||
static auto PMETHOD = CConfigValue<Hyprlang::INT>("binds:focus_preferred_method");
|
||||
static auto PMONITORFALLBACK = CConfigValue<Hyprlang::INT>("binds:window_direction_monitor_fallback");
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return nullptr; // ??
|
||||
@@ -1539,13 +1563,13 @@ PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) {
|
||||
if (w == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->isFullscreen() && w->m_bIsFloating) || !isWorkspaceVisible(w->m_pWorkspace))
|
||||
continue;
|
||||
|
||||
if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_pWorkspace != w->m_pWorkspace)
|
||||
if (pWindow->m_pMonitor == w->m_pMonitor && pWindow->m_pWorkspace != w->m_pWorkspace)
|
||||
continue;
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen)
|
||||
continue;
|
||||
|
||||
if (!*PMONITORFALLBACK && pWindow->m_iMonitorID != w->m_iMonitorID)
|
||||
if (!*PMONITORFALLBACK && pWindow->m_pMonitor != w->m_pMonitor)
|
||||
continue;
|
||||
|
||||
const auto BWINDOWIDEALBB = w->getWindowIdealBoundingBoxIgnoreReserved();
|
||||
@@ -1631,13 +1655,13 @@ PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) {
|
||||
if (w == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->isFullscreen() && !w->m_bIsFloating) || !isWorkspaceVisible(w->m_pWorkspace))
|
||||
continue;
|
||||
|
||||
if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_pWorkspace != w->m_pWorkspace)
|
||||
if (pWindow->m_pMonitor == w->m_pMonitor && pWindow->m_pWorkspace != w->m_pWorkspace)
|
||||
continue;
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen)
|
||||
continue;
|
||||
|
||||
if (!*PMONITORFALLBACK && pWindow->m_iMonitorID != w->m_iMonitorID)
|
||||
if (!*PMONITORFALLBACK && pWindow->m_pMonitor != w->m_pMonitor)
|
||||
continue;
|
||||
|
||||
const auto DIST = w->middle().distance(pWindow->middle());
|
||||
@@ -1761,7 +1785,7 @@ bool CCompositor::isPointOnAnyMonitor(const Vector2D& point) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCompositor::isPointOnReservedArea(const Vector2D& point, const CMonitor* pMonitor) {
|
||||
bool CCompositor::isPointOnReservedArea(const Vector2D& point, const PHLMONITOR pMonitor) {
|
||||
const auto PMONITOR = pMonitor ? pMonitor : getMonitorFromVector(point);
|
||||
|
||||
const auto XY1 = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
||||
@@ -1770,11 +1794,11 @@ bool CCompositor::isPointOnReservedArea(const Vector2D& point, const CMonitor* p
|
||||
return !VECINRECT(point, XY1.x, XY1.y, XY2.x, XY2.y);
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
||||
return this->getMonitorInDirection(m_pLastMonitor.get(), dir);
|
||||
PHLMONITOR CCompositor::getMonitorInDirection(const char& dir) {
|
||||
return getMonitorInDirection(m_pLastMonitor.lock(), dir);
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorInDirection(CMonitor* pSourceMonitor, const char& dir) {
|
||||
PHLMONITOR CCompositor::getMonitorInDirection(PHLMONITOR pSourceMonitor, const char& dir) {
|
||||
if (!pSourceMonitor)
|
||||
return nullptr;
|
||||
|
||||
@@ -1782,7 +1806,7 @@ CMonitor* CCompositor::getMonitorInDirection(CMonitor* pSourceMonitor, const cha
|
||||
const auto SIZEA = pSourceMonitor->vecSize;
|
||||
|
||||
auto longestIntersect = -1;
|
||||
CMonitor* longestIntersectMonitor = nullptr;
|
||||
PHLMONITOR longestIntersectMonitor = nullptr;
|
||||
|
||||
for (auto const& m : m_vMonitors) {
|
||||
if (m == m_pLastMonitor)
|
||||
@@ -1796,7 +1820,7 @@ CMonitor* CCompositor::getMonitorInDirection(CMonitor* pSourceMonitor, const cha
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = m.get();
|
||||
longestIntersectMonitor = m;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1805,7 +1829,7 @@ CMonitor* CCompositor::getMonitorInDirection(CMonitor* pSourceMonitor, const cha
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = m.get();
|
||||
longestIntersectMonitor = m;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1815,7 +1839,7 @@ CMonitor* CCompositor::getMonitorInDirection(CMonitor* pSourceMonitor, const cha
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = m.get();
|
||||
longestIntersectMonitor = m;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1825,7 +1849,7 @@ CMonitor* CCompositor::getMonitorInDirection(CMonitor* pSourceMonitor, const cha
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = m.get();
|
||||
longestIntersectMonitor = m;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1869,8 +1893,8 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) {
|
||||
static auto PINACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:inactive_opacity");
|
||||
static auto PACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:active_opacity");
|
||||
static auto PFULLSCREENALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:fullscreen_opacity");
|
||||
static auto PSHADOWCOL = CConfigValue<Hyprlang::INT>("decoration:col.shadow");
|
||||
static auto PSHADOWCOLINACTIVE = CConfigValue<Hyprlang::INT>("decoration:col.shadow_inactive");
|
||||
static auto PSHADOWCOL = CConfigValue<Hyprlang::INT>("decoration:shadow:color");
|
||||
static auto PSHADOWCOLINACTIVE = CConfigValue<Hyprlang::INT>("decoration:shadow:color_inactive");
|
||||
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
|
||||
static auto PDIMENABLED = CConfigValue<Hyprlang::INT>("decoration:dim_inactive");
|
||||
|
||||
@@ -1941,11 +1965,10 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) {
|
||||
|
||||
// shadow
|
||||
if (!pWindow->isX11OverrideRedirect() && !pWindow->m_bX11DoesntWantBorders) {
|
||||
if (pWindow == m_pLastWindow) {
|
||||
if (pWindow == m_pLastWindow)
|
||||
pWindow->m_cRealShadowColor = CColor(*PSHADOWCOL);
|
||||
} else {
|
||||
pWindow->m_cRealShadowColor = CColor(*PSHADOWCOLINACTIVE != INT_MAX ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
|
||||
}
|
||||
else
|
||||
pWindow->m_cRealShadowColor = CColor(*PSHADOWCOLINACTIVE != INT64_MAX ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
|
||||
} else {
|
||||
pWindow->m_cRealShadowColor.setValueAndWarp(CColor(0, 0, 0, 0)); // no shadow
|
||||
}
|
||||
@@ -1972,12 +1995,12 @@ MONITORID CCompositor::getNextAvailableMonitorID(std::string const& name) {
|
||||
return nextID;
|
||||
}
|
||||
|
||||
void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) {
|
||||
void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitorB) {
|
||||
|
||||
const auto PWORKSPACEA = pMonitorA->activeWorkspace;
|
||||
const auto PWORKSPACEB = pMonitorB->activeWorkspace;
|
||||
|
||||
PWORKSPACEA->m_iMonitorID = pMonitorB->ID;
|
||||
PWORKSPACEA->m_pMonitor = pMonitorB;
|
||||
PWORKSPACEA->moveToMonitor(pMonitorB->ID);
|
||||
|
||||
for (auto const& w : m_vWindows) {
|
||||
@@ -1987,7 +2010,7 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
|
||||
continue;
|
||||
}
|
||||
|
||||
w->m_iMonitorID = pMonitorB->ID;
|
||||
w->m_pMonitor = pMonitorB;
|
||||
|
||||
// additionally, move floating and fs windows manually
|
||||
if (w->m_bIsFloating)
|
||||
@@ -2002,7 +2025,7 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
|
||||
}
|
||||
}
|
||||
|
||||
PWORKSPACEB->m_iMonitorID = pMonitorA->ID;
|
||||
PWORKSPACEB->m_pMonitor = pMonitorA;
|
||||
PWORKSPACEB->moveToMonitor(pMonitorA->ID);
|
||||
|
||||
for (auto const& w : m_vWindows) {
|
||||
@@ -2012,7 +2035,7 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
|
||||
continue;
|
||||
}
|
||||
|
||||
w->m_iMonitorID = pMonitorA->ID;
|
||||
w->m_pMonitor = pMonitorA;
|
||||
|
||||
// additionally, move floating and fs windows manually
|
||||
if (w->m_bIsFloating)
|
||||
@@ -2059,16 +2082,16 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
|
||||
EMIT_HOOK_EVENT("moveWorkspace", (std::vector<std::any>{PWORKSPACEB, pMonitorA}));
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
|
||||
PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
|
||||
if (name == "current")
|
||||
return g_pCompositor->m_pLastMonitor.get();
|
||||
return g_pCompositor->m_pLastMonitor.lock();
|
||||
else if (isDirection(name))
|
||||
return getMonitorInDirection(name[0]);
|
||||
else if (name[0] == '+' || name[0] == '-') {
|
||||
// relative
|
||||
|
||||
if (m_vMonitors.size() == 1)
|
||||
return m_vMonitors.begin()->get();
|
||||
return *m_vMonitors.begin();
|
||||
|
||||
const auto OFFSET = name[0] == '-' ? name : name.substr(1);
|
||||
|
||||
@@ -2101,7 +2124,7 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
|
||||
currentPlace = std::clamp(currentPlace, 0, (int)m_vMonitors.size() - 1);
|
||||
}
|
||||
|
||||
return m_vMonitors[currentPlace].get();
|
||||
return m_vMonitors[currentPlace];
|
||||
} else if (isNumber(name)) {
|
||||
// change by ID
|
||||
MONITORID monID = MONITOR_INVALID;
|
||||
@@ -2125,7 +2148,7 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
|
||||
continue;
|
||||
|
||||
if (m->matchesStaticSelector(name)) {
|
||||
return m.get();
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2133,16 +2156,16 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMonitor, bool noWarpCursor) {
|
||||
void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMonitor, bool noWarpCursor) {
|
||||
|
||||
// We trust the monitor to be correct.
|
||||
|
||||
if (pWorkspace->m_iMonitorID == pMonitor->ID)
|
||||
if (pWorkspace->m_pMonitor == pMonitor)
|
||||
return;
|
||||
|
||||
Debug::log(LOG, "moveWorkspaceToMonitor: Moving {} to monitor {}", pWorkspace->m_iID, pMonitor->ID);
|
||||
|
||||
const auto POLDMON = getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
const auto POLDMON = pWorkspace->m_pMonitor.lock();
|
||||
|
||||
const bool SWITCHINGISACTIVE = POLDMON ? POLDMON->activeWorkspace == pWorkspace : false;
|
||||
|
||||
@@ -2152,7 +2175,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMon
|
||||
nextWorkspaceOnMonitorID = pWorkspace->m_iID;
|
||||
else {
|
||||
for (auto const& w : m_vWorkspaces) {
|
||||
if (w->m_iMonitorID == POLDMON->ID && w->m_iID != pWorkspace->m_iID && !w->m_bIsSpecialWorkspace) {
|
||||
if (w->m_pMonitor == POLDMON && w->m_iID != pWorkspace->m_iID && !w->m_bIsSpecialWorkspace) {
|
||||
nextWorkspaceOnMonitorID = w->m_iID;
|
||||
break;
|
||||
}
|
||||
@@ -2177,7 +2200,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMon
|
||||
}
|
||||
|
||||
// move the workspace
|
||||
pWorkspace->m_iMonitorID = pMonitor->ID;
|
||||
pWorkspace->m_pMonitor = pMonitor;
|
||||
pWorkspace->moveToMonitor(pMonitor->ID);
|
||||
|
||||
for (auto const& w : m_vWindows) {
|
||||
@@ -2187,7 +2210,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMon
|
||||
continue;
|
||||
}
|
||||
|
||||
w->m_iMonitorID = pMonitor->ID;
|
||||
w->m_pMonitor = pMonitor;
|
||||
|
||||
// additionally, move floating and fs windows manually
|
||||
if (w->m_bIsMapped && !w->isHidden()) {
|
||||
@@ -2208,7 +2231,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMon
|
||||
}
|
||||
}
|
||||
|
||||
if (SWITCHINGISACTIVE && POLDMON == g_pCompositor->m_pLastMonitor.get()) { // if it was active, preserve its' status. If it wasn't, don't.
|
||||
if (SWITCHINGISACTIVE && POLDMON == g_pCompositor->m_pLastMonitor) { // if it was active, preserve its' status. If it wasn't, don't.
|
||||
Debug::log(LOG, "moveWorkspaceToMonitor: SWITCHINGISACTIVE, active {} -> {}", pMonitor->activeWorkspaceID(), pWorkspace->m_iID);
|
||||
|
||||
if (valid(pMonitor->activeWorkspace)) {
|
||||
@@ -2280,7 +2303,7 @@ void CCompositor::updateFullscreenFadeOnWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
}
|
||||
}
|
||||
|
||||
const auto PMONITOR = getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
const auto PMONITOR = pWorkspace->m_pMonitor.lock();
|
||||
|
||||
if (pWorkspace->m_iID == PMONITOR->activeWorkspaceID() || pWorkspace->m_iID == PMONITOR->activeSpecialWorkspaceID()) {
|
||||
for (auto const& ls : PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
@@ -2323,7 +2346,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, sFullscreenS
|
||||
state.internal = std::clamp(state.internal, (eFullscreenMode)0, FSMODE_MAX);
|
||||
state.client = std::clamp(state.client, (eFullscreenMode)0, FSMODE_MAX);
|
||||
|
||||
const auto PMONITOR = getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
const auto PWORKSPACE = PWINDOW->m_pWorkspace;
|
||||
|
||||
const eFullscreenMode CURRENT_EFFECTIVE_MODE = (eFullscreenMode)std::bit_floor((uint8_t)PWINDOW->m_sFullscreenState.internal);
|
||||
@@ -2341,7 +2364,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, sFullscreenS
|
||||
if (!CHANGEINTERNAL) {
|
||||
PWINDOW->updateDynamicRules();
|
||||
updateWindowAnimatedDecorationValues(PWINDOW);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2356,7 +2379,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, sFullscreenS
|
||||
|
||||
PWINDOW->updateDynamicRules();
|
||||
updateWindowAnimatedDecorationValues(PWINDOW);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID());
|
||||
|
||||
// make all windows on the same workspace under the fullscreen window
|
||||
for (auto const& w : m_vWindows) {
|
||||
@@ -2420,7 +2443,7 @@ void CCompositor::updateWorkspaceWindowData(const WORKSPACEID& id) {
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::scheduleFrameForMonitor(CMonitor* pMonitor, IOutput::scheduleFrameReason reason) {
|
||||
void CCompositor::scheduleFrameForMonitor(PHLMONITOR pMonitor, IOutput::scheduleFrameReason reason) {
|
||||
if ((m_pAqBackend->hasSession() && !m_pAqBackend->session->active) || !m_bSessionActive)
|
||||
return;
|
||||
|
||||
@@ -2433,13 +2456,31 @@ void CCompositor::scheduleFrameForMonitor(CMonitor* pMonitor, IOutput::scheduleF
|
||||
pMonitor->output->scheduleFrame(reason);
|
||||
}
|
||||
|
||||
PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp) {
|
||||
PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp_) {
|
||||
auto regexp = trim(regexp_);
|
||||
|
||||
if (regexp.starts_with("active"))
|
||||
return m_pLastWindow.lock();
|
||||
else if (regexp.starts_with("floating") || regexp.starts_with("tiled")) {
|
||||
// first floating on the current ws
|
||||
if (!valid(m_pLastWindow))
|
||||
return nullptr;
|
||||
|
||||
const bool FLOAT = regexp.starts_with("floating");
|
||||
|
||||
for (auto const& w : m_vWindows) {
|
||||
if (!w->m_bIsMapped || w->m_bIsFloating != FLOAT || w->m_pWorkspace != m_pLastWindow->m_pWorkspace || w->isHidden())
|
||||
continue;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
eFocusWindowMode mode = MODE_CLASS_REGEX;
|
||||
|
||||
std::regex regexCheck(regexp);
|
||||
std::regex regexCheck(regexp_);
|
||||
std::string matchCheck;
|
||||
if (regexp.starts_with("class:")) {
|
||||
regexCheck = std::regex(regexp.substr(6));
|
||||
@@ -2458,21 +2499,6 @@ PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp) {
|
||||
} else if (regexp.starts_with("pid:")) {
|
||||
mode = MODE_PID;
|
||||
matchCheck = regexp.substr(4);
|
||||
} else if (regexp.starts_with("floating") || regexp.starts_with("tiled")) {
|
||||
// first floating on the current ws
|
||||
if (!valid(m_pLastWindow))
|
||||
return nullptr;
|
||||
|
||||
const bool FLOAT = regexp.starts_with("floating");
|
||||
|
||||
for (auto const& w : m_vWindows) {
|
||||
if (!w->m_bIsMapped || w->m_bIsFloating != FLOAT || w->m_pWorkspace != m_pLastWindow->m_pWorkspace || w->isHidden())
|
||||
continue;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||
@@ -2534,7 +2560,7 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
|
||||
|
||||
if (*PNOWARPS && !force) {
|
||||
const auto PMONITORNEW = getMonitorFromVector(pos);
|
||||
if (PMONITORNEW != m_pLastMonitor.get())
|
||||
if (PMONITORNEW != m_pLastMonitor)
|
||||
setActiveMonitor(PMONITORNEW);
|
||||
return;
|
||||
}
|
||||
@@ -2542,7 +2568,7 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
|
||||
g_pPointerManager->warpTo(pos);
|
||||
|
||||
const auto PMONITORNEW = getMonitorFromVector(pos);
|
||||
if (PMONITORNEW != m_pLastMonitor.get())
|
||||
if (PMONITORNEW != m_pLastMonitor)
|
||||
setActiveMonitor(PMONITORNEW);
|
||||
}
|
||||
|
||||
@@ -2641,13 +2667,12 @@ PHLWORKSPACE CCompositor::createNewWorkspace(const WORKSPACEID& id, const MONITO
|
||||
auto monID = monid;
|
||||
|
||||
// check if bound
|
||||
if (const auto PMONITOR = g_pConfigManager->getBoundMonitorForWS(NAME); PMONITOR) {
|
||||
if (const auto PMONITOR = g_pConfigManager->getBoundMonitorForWS(NAME); PMONITOR)
|
||||
monID = PMONITOR->ID;
|
||||
}
|
||||
|
||||
const bool SPECIAL = id >= SPECIAL_WORKSPACE_START && id <= -2;
|
||||
|
||||
const auto PWORKSPACE = m_vWorkspaces.emplace_back(CWorkspace::create(id, monID, NAME, SPECIAL, isEmpty));
|
||||
const auto PWORKSPACE = m_vWorkspaces.emplace_back(CWorkspace::create(id, getMonitorFromID(monID), NAME, SPECIAL, isEmpty));
|
||||
|
||||
PWORKSPACE->m_fAlpha.setValueAndWarp(0);
|
||||
|
||||
@@ -2669,8 +2694,8 @@ void CCompositor::renameWorkspace(const WORKSPACEID& id, const std::string& name
|
||||
g_pEventManager->postEvent({"renameworkspace", std::to_string(PWORKSPACE->m_iID) + "," + PWORKSPACE->m_szName});
|
||||
}
|
||||
|
||||
void CCompositor::setActiveMonitor(CMonitor* pMonitor) {
|
||||
if (m_pLastMonitor.get() == pMonitor)
|
||||
void CCompositor::setActiveMonitor(PHLMONITOR pMonitor) {
|
||||
if (m_pLastMonitor == pMonitor)
|
||||
return;
|
||||
|
||||
if (!pMonitor) {
|
||||
@@ -2712,6 +2737,12 @@ void CCompositor::performUserChecks() {
|
||||
CColor{}, 15000, ICON_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_pHyprOpenGL->failedAssetsNo > 0) {
|
||||
g_pHyprNotificationOverlay->addNotification(std::format("Hyprland failed to load {} essential asset{}, blame your distro's packager for doing a bad job at packaging!",
|
||||
g_pHyprOpenGL->failedAssetsNo, g_pHyprOpenGL->failedAssetsNo > 1 ? "s" : ""),
|
||||
CColor{1.0, 0.1, 0.1, 1.0}, 15000, ICON_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace) {
|
||||
@@ -2727,31 +2758,57 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor
|
||||
if (FULLSCREEN)
|
||||
setWindowFullscreenInternal(pWindow, FSMODE_NONE);
|
||||
|
||||
if (!pWindow->m_bIsFloating) {
|
||||
const PHLWINDOW pFirstWindowOnWorkspace = g_pCompositor->getFirstWindowOnWorkspace(pWorkspace->m_iID);
|
||||
const int visibleWindowsOnWorkspace = g_pCompositor->getWindowsOnWorkspace(pWorkspace->m_iID, std::nullopt, true);
|
||||
const auto PWINDOWMONITOR = pWindow->m_pMonitor.lock();
|
||||
const auto POSTOMON = pWindow->m_vRealPosition.goal() - PWINDOWMONITOR->vecPosition;
|
||||
const auto PWORKSPACEMONITOR = pWorkspace->m_pMonitor.lock();
|
||||
|
||||
if (!pWindow->m_bIsFloating)
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowRemovedTiling(pWindow);
|
||||
pWindow->moveToWorkspace(pWorkspace);
|
||||
pWindow->m_iMonitorID = pWorkspace->m_iMonitorID;
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow);
|
||||
|
||||
pWindow->moveToWorkspace(pWorkspace);
|
||||
pWindow->m_pMonitor = pWorkspace->m_pMonitor;
|
||||
|
||||
static auto PGROUPONMOVETOWORKSPACE = CConfigValue<Hyprlang::INT>("group:group_on_movetoworkspace");
|
||||
if (*PGROUPONMOVETOWORKSPACE && visibleWindowsOnWorkspace == 1 && pFirstWindowOnWorkspace && pFirstWindowOnWorkspace != pWindow &&
|
||||
pFirstWindowOnWorkspace->m_sGroupData.pNextWindow.lock() && pWindow->canBeGroupedInto(pFirstWindowOnWorkspace)) {
|
||||
|
||||
pWindow->m_bIsFloating = pFirstWindowOnWorkspace->m_bIsFloating; // match the floating state. Needed to group tiled into floated and vice versa.
|
||||
if (!pWindow->m_sGroupData.pNextWindow.expired()) {
|
||||
PHLWINDOW next = pWindow->m_sGroupData.pNextWindow.lock();
|
||||
while (next != pWindow) {
|
||||
next->m_bIsFloating = pFirstWindowOnWorkspace->m_bIsFloating; // match the floating state of group members
|
||||
next = next->m_sGroupData.pNextWindow.lock();
|
||||
}
|
||||
}
|
||||
|
||||
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
|
||||
(*USECURRPOS ? pFirstWindowOnWorkspace : pFirstWindowOnWorkspace->getGroupTail())->insertWindowToGroup(pWindow);
|
||||
|
||||
pFirstWindowOnWorkspace->setGroupCurrent(pWindow);
|
||||
pWindow->updateWindowDecos();
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
|
||||
|
||||
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||
|
||||
} else {
|
||||
const auto PWINDOWMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto POSTOMON = pWindow->m_vRealPosition.goal() - PWINDOWMONITOR->vecPosition;
|
||||
if (!pWindow->m_bIsFloating)
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow);
|
||||
|
||||
const auto PWORKSPACEMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
|
||||
pWindow->moveToWorkspace(pWorkspace);
|
||||
pWindow->m_iMonitorID = pWorkspace->m_iMonitorID;
|
||||
|
||||
pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition;
|
||||
if (pWindow->m_bIsFloating)
|
||||
pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition;
|
||||
}
|
||||
|
||||
pWindow->updateToplevel();
|
||||
pWindow->updateDynamicRules();
|
||||
pWindow->uncacheWindowDecos();
|
||||
pWindow->updateGroupOutputs();
|
||||
|
||||
if (!pWindow->m_sGroupData.pNextWindow.expired()) {
|
||||
PHLWINDOW next = pWindow->m_sGroupData.pNextWindow.lock();
|
||||
while (next != pWindow) {
|
||||
next->moveToWorkspace(pWorkspace);
|
||||
next->updateToplevel();
|
||||
next = next->m_sGroupData.pNextWindow.lock();
|
||||
}
|
||||
@@ -2780,13 +2837,13 @@ PHLWINDOW CCompositor::getForceFocus() {
|
||||
}
|
||||
|
||||
void CCompositor::arrangeMonitors() {
|
||||
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling");
|
||||
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling");
|
||||
|
||||
std::vector<CMonitor*> toArrange;
|
||||
std::vector<CMonitor*> arranged;
|
||||
std::vector<PHLMONITOR> toArrange;
|
||||
std::vector<PHLMONITOR> arranged;
|
||||
|
||||
for (auto const& m : m_vMonitors)
|
||||
toArrange.push_back(m.get());
|
||||
toArrange.push_back(m);
|
||||
|
||||
Debug::log(LOG, "arrangeMonitors: {} to arrange", toArrange.size());
|
||||
|
||||
@@ -2885,7 +2942,7 @@ void CCompositor::enterUnsafeState() {
|
||||
|
||||
m_bUnsafeState = true;
|
||||
|
||||
setActiveMonitor(m_pUnsafeOutput);
|
||||
setActiveMonitor(m_pUnsafeOutput.lock());
|
||||
}
|
||||
|
||||
void CCompositor::leaveUnsafeState() {
|
||||
@@ -2896,10 +2953,10 @@ void CCompositor::leaveUnsafeState() {
|
||||
|
||||
m_bUnsafeState = false;
|
||||
|
||||
CMonitor* pNewMonitor = nullptr;
|
||||
PHLMONITOR pNewMonitor = nullptr;
|
||||
for (auto const& pMonitor : m_vMonitors) {
|
||||
if (pMonitor->output != m_pUnsafeOutput->output) {
|
||||
pNewMonitor = pMonitor.get();
|
||||
pNewMonitor = pMonitor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2910,7 +2967,7 @@ void CCompositor::leaveUnsafeState() {
|
||||
m_pUnsafeOutput->onDisconnect();
|
||||
|
||||
for (auto const& m : m_vMonitors) {
|
||||
scheduleFrameForMonitor(m.get());
|
||||
scheduleFrameForMonitor(m);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2960,7 +3017,7 @@ PHLWINDOW CCompositor::windowForCPointer(CWindow* pWindow) {
|
||||
return {};
|
||||
}
|
||||
|
||||
static void checkDefaultCursorWarp(SP<CMonitor> monitor) {
|
||||
static void checkDefaultCursorWarp(PHLMONITOR monitor) {
|
||||
static auto PCURSORMONITOR = CConfigValue<std::string>("cursor:default_monitor");
|
||||
static bool cursorDefaultDone = false;
|
||||
static bool firstLaunch = true;
|
||||
@@ -2986,7 +3043,7 @@ static void checkDefaultCursorWarp(SP<CMonitor> monitor) {
|
||||
}
|
||||
|
||||
// modechange happend check if cursor is on that monitor and warp it to middle to not place it out of bounds if resolution changed.
|
||||
if (g_pCompositor->getMonitorFromCursor() == monitor.get()) {
|
||||
if (g_pCompositor->getMonitorFromCursor() == monitor) {
|
||||
g_pCompositor->warpCursorTo(POS, true);
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
@@ -2996,7 +3053,7 @@ void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
|
||||
// add it to real
|
||||
auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>(output));
|
||||
if (std::string("HEADLESS-1") == output->name) {
|
||||
g_pCompositor->m_pUnsafeOutput = PNEWMONITOR.get();
|
||||
g_pCompositor->m_pUnsafeOutput = PNEWMONITOR;
|
||||
output->name = "FALLBACK"; // we are allowed to do this :)
|
||||
}
|
||||
|
||||
@@ -3019,22 +3076,22 @@ void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
|
||||
// ready to process if we have a real monitor
|
||||
|
||||
if ((!g_pHyprRenderer->m_pMostHzMonitor || PNEWMONITOR->refreshRate > g_pHyprRenderer->m_pMostHzMonitor->refreshRate) && PNEWMONITOR->m_bEnabled)
|
||||
g_pHyprRenderer->m_pMostHzMonitor = PNEWMONITOR.get();
|
||||
g_pHyprRenderer->m_pMostHzMonitor = PNEWMONITOR;
|
||||
|
||||
g_pCompositor->m_bReadyToProcess = true;
|
||||
|
||||
g_pConfigManager->m_bWantsMonitorReload = true;
|
||||
g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR.get(), IOutput::AQ_SCHEDULE_NEW_MONITOR);
|
||||
g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR, IOutput::AQ_SCHEDULE_NEW_MONITOR);
|
||||
|
||||
checkDefaultCursorWarp(PNEWMONITOR);
|
||||
|
||||
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iMonitorID == PNEWMONITOR->ID) {
|
||||
if (w->m_pMonitor == PNEWMONITOR) {
|
||||
w->m_iLastSurfaceMonitorID = MONITOR_INVALID;
|
||||
w->updateSurfaceScaleTransformDetails();
|
||||
}
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageMonitor(PNEWMONITOR.get());
|
||||
Events::listener_monitorFrame(PNEWMONITOR.get(), nullptr);
|
||||
g_pHyprRenderer->damageMonitor(PNEWMONITOR);
|
||||
PNEWMONITOR->onMonitorFrame();
|
||||
}
|
||||
|
@@ -59,8 +59,8 @@ class CCompositor {
|
||||
std::string m_szInstancePath = "";
|
||||
std::string m_szCurrentSplash = "error";
|
||||
|
||||
std::vector<SP<CMonitor>> m_vMonitors;
|
||||
std::vector<SP<CMonitor>> m_vRealMonitors; // for all monitors, even those turned off
|
||||
std::vector<PHLMONITOR> m_vMonitors;
|
||||
std::vector<PHLMONITOR> m_vRealMonitors; // for all monitors, even those turned off
|
||||
std::vector<PHLWINDOW> m_vWindows;
|
||||
std::vector<PHLLS> m_vLayers;
|
||||
std::vector<PHLWORKSPACE> m_vWorkspaces;
|
||||
@@ -80,7 +80,7 @@ class CCompositor {
|
||||
|
||||
WP<CWLSurfaceResource> m_pLastFocus;
|
||||
PHLWINDOWREF m_pLastWindow;
|
||||
WP<CMonitor> m_pLastMonitor;
|
||||
PHLMONITORREF m_pLastMonitor;
|
||||
|
||||
std::vector<PHLWINDOWREF> m_vWindowFocusHistory; // first element is the most recently focused.
|
||||
|
||||
@@ -89,7 +89,7 @@ class CCompositor {
|
||||
bool m_bDPMSStateON = true;
|
||||
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
|
||||
bool m_bNextIsUnsafe = false;
|
||||
CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state
|
||||
PHLMONITORREF m_pUnsafeOutput; // fallback output for the unsafe state
|
||||
bool m_bIsShuttingDown = false;
|
||||
bool m_bFinalRequests = false;
|
||||
bool m_bDesktopEnvSet = false;
|
||||
@@ -97,22 +97,22 @@ class CCompositor {
|
||||
|
||||
// ------------------------------------------------- //
|
||||
|
||||
CMonitor* getMonitorFromID(const MONITORID&);
|
||||
CMonitor* getMonitorFromName(const std::string&);
|
||||
CMonitor* getMonitorFromDesc(const std::string&);
|
||||
CMonitor* getMonitorFromCursor();
|
||||
CMonitor* getMonitorFromVector(const Vector2D&);
|
||||
PHLMONITOR getMonitorFromID(const MONITORID&);
|
||||
PHLMONITOR getMonitorFromName(const std::string&);
|
||||
PHLMONITOR getMonitorFromDesc(const std::string&);
|
||||
PHLMONITOR getMonitorFromCursor();
|
||||
PHLMONITOR getMonitorFromVector(const Vector2D&);
|
||||
void removeWindowFromVectorSafe(PHLWINDOW);
|
||||
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr);
|
||||
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
|
||||
bool monitorExists(CMonitor*);
|
||||
bool monitorExists(PHLMONITOR);
|
||||
PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
|
||||
SP<CWLSurfaceResource> vectorToLayerSurface(const Vector2D&, std::vector<PHLLSREF>*, Vector2D*, PHLLS*);
|
||||
SP<CWLSurfaceResource> vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, PHLLS*);
|
||||
SP<CWLSurfaceResource> vectorToLayerPopupSurface(const Vector2D&, PHLMONITOR monitor, Vector2D*, PHLLS*);
|
||||
SP<CWLSurfaceResource> vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl);
|
||||
Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, SP<CWLSurfaceResource>);
|
||||
CMonitor* getMonitorFromOutput(SP<Aquamarine::IOutput>);
|
||||
CMonitor* getRealMonitorFromOutput(SP<Aquamarine::IOutput>);
|
||||
PHLMONITOR getMonitorFromOutput(SP<Aquamarine::IOutput>);
|
||||
PHLMONITOR getRealMonitorFromOutput(SP<Aquamarine::IOutput>);
|
||||
PHLWINDOW getWindowFromSurface(SP<CWLSurfaceResource>);
|
||||
PHLWINDOW getWindowFromHandle(uint32_t);
|
||||
bool isWorkspaceVisible(PHLWORKSPACE);
|
||||
@@ -138,16 +138,16 @@ class CCompositor {
|
||||
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
||||
WORKSPACEID getNextAvailableNamedWorkspace();
|
||||
bool isPointOnAnyMonitor(const Vector2D&);
|
||||
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
|
||||
CMonitor* getMonitorInDirection(const char&);
|
||||
CMonitor* getMonitorInDirection(CMonitor*, const char&);
|
||||
bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr);
|
||||
PHLMONITOR getMonitorInDirection(const char&);
|
||||
PHLMONITOR getMonitorInDirection(PHLMONITOR, const char&);
|
||||
void updateAllWindowsAnimatedDecorationValues();
|
||||
void updateWorkspaceWindows(const WORKSPACEID& id);
|
||||
void updateWindowAnimatedDecorationValues(PHLWINDOW);
|
||||
MONITORID getNextAvailableMonitorID(std::string const& name);
|
||||
void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
|
||||
void swapActiveWorkspaces(CMonitor*, CMonitor*);
|
||||
CMonitor* getMonitorFromString(const std::string&);
|
||||
void moveWorkspaceToMonitor(PHLWORKSPACE, PHLMONITOR, bool noWarpCursor = false);
|
||||
void swapActiveWorkspaces(PHLMONITOR, PHLMONITOR);
|
||||
PHLMONITOR getMonitorFromString(const std::string&);
|
||||
bool workspaceIDOutOfBounds(const WORKSPACEID&);
|
||||
void setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||
void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||
@@ -156,7 +156,7 @@ class CCompositor {
|
||||
void changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON);
|
||||
void updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
|
||||
PHLWINDOW getX11Parent(PHLWINDOW);
|
||||
void scheduleFrameForMonitor(CMonitor*, Aquamarine::IOutput::scheduleFrameReason reason = Aquamarine::IOutput::AQ_SCHEDULE_CLIENT_UNKNOWN);
|
||||
void scheduleFrameForMonitor(PHLMONITOR, Aquamarine::IOutput::scheduleFrameReason reason = Aquamarine::IOutput::AQ_SCHEDULE_CLIENT_UNKNOWN);
|
||||
void addToFadingOutSafe(PHLLS);
|
||||
void removeFromFadingOutSafe(PHLLS);
|
||||
void addToFadingOutSafe(PHLWINDOW);
|
||||
@@ -169,7 +169,7 @@ class CCompositor {
|
||||
PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "",
|
||||
bool isEmpty = true); // will be deleted next frame if left empty and unfocused!
|
||||
void renameWorkspace(const WORKSPACEID&, const std::string& name = "");
|
||||
void setActiveMonitor(CMonitor*);
|
||||
void setActiveMonitor(PHLMONITOR);
|
||||
bool isWorkspaceSpecial(const WORKSPACEID&);
|
||||
WORKSPACEID getNewSpecialID();
|
||||
void performUserChecks();
|
||||
|
@@ -104,6 +104,30 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{0, 0, 4},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "general:snap:enabled",
|
||||
.description = "enable snapping for floating windows",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "general:snap:window_gap",
|
||||
.description = "minimum gap in pixels between windows before snapping",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{10, 0, 100},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "general:snap:monitor_gap",
|
||||
.description = "minimum gap in pixels between window and monitor edges before snapping",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{10, 0, 100},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "general:snap:border_overlap",
|
||||
.description = "if true, windows snap such that only one border's worth of space is between them",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
|
||||
/*
|
||||
* decoration:
|
||||
@@ -134,49 +158,55 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:drop_shadow",
|
||||
.value = "decoration:shadow:enabled",
|
||||
.description = "enable drop shadows on windows",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow_range",
|
||||
.value = "decoration:shadow:range",
|
||||
.description = "Shadow range (size) in layout px",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{4, 0, 100},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow_render_power",
|
||||
.value = "decoration:shadow:render_power",
|
||||
.description = "in what power to render the falloff (more power, the faster the falloff) [1 - 4]",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{3, 1, 4},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow_ignore_window",
|
||||
.value = "decoration:shadow:sharp",
|
||||
.description = "whether the shadow should be sharp or not. Akin to an infinitely high render power.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow:ignore_window",
|
||||
.description = "if true, the shadow will not be rendered behind the window itself, only around it.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:col.shadow",
|
||||
.value = "decoration:shadow:color",
|
||||
.description = "shadow's color. Alpha dictates shadow's opacity.",
|
||||
.type = CONFIG_OPTION_COLOR,
|
||||
.data = SConfigOptionDescription::SColorData{0xee1a1a1a},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:col.shadow_inactive",
|
||||
.value = "decoration:shadow:color_inactive",
|
||||
.description = "inactive shadow color. (if not set, will fall back to col.shadow)",
|
||||
.type = CONFIG_OPTION_COLOR,
|
||||
.data = SConfigOptionDescription::SColorData{}, //##TODO UNSET?
|
||||
.data = SConfigOptionDescription::SColorData{}, //TODO: UNSET?
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow_offset",
|
||||
.value = "decoration:shadow:offset",
|
||||
.description = "shadow's rendering offset.",
|
||||
.type = CONFIG_OPTION_VECTOR,
|
||||
.data = SConfigOptionDescription::SVectorData{{}, {-250, -250}, {250, 250}},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow_scale",
|
||||
.value = "decoration:shadow:scale",
|
||||
.description = "shadow's scale. [0.0 - 1.0]",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
||||
@@ -748,6 +778,12 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "group:merge_groups_on_groupbar",
|
||||
.description = "whether one group will be merged with another when dragged into its groupbar",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "general:col.border_active",
|
||||
.description = "border color for inactive windows",
|
||||
@@ -778,6 +814,24 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "group:drag_into_group",
|
||||
.description = "whether dragging a window into a unlocked group will merge them. Options: 0 (disabled), 1 (enabled), 2 (only when dragging into the groupbar)",
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{0, "disabled,enabled,only when dragging into the groupbar"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "group:merge_floated_into_tiled_on_groupbar",
|
||||
.description = "whether dragging a floating window into a tiled window groupbar will merge them",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "group:group_on_movetoworkspace",
|
||||
.description = "whether using movetoworkspace[silent] will merge the window into the workspace's solitary unlocked group",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
|
||||
/*
|
||||
* group:groupbar:
|
||||
@@ -1208,8 +1262,8 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
SConfigOptionDescription{
|
||||
.value = "cursor:no_hardware_cursors",
|
||||
.description = "disables hardware cursors",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{0, "Disabled,Enabled,Auto"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "cursor:no_break_fs_vrr",
|
||||
@@ -1434,12 +1488,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{1, 0.1, 3},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:no_gaps_when_only",
|
||||
.description = "whether to apply gaps when there is only one window on a workspace, aka. smart gaps. (default: disabled - 0) no border - 1, with border - 2 [0/1/2]",
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{0, "disabled,no border,with border"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:use_active_for_splits",
|
||||
.description = "whether to prefer the active window or the mouse position for splits",
|
||||
@@ -1500,12 +1548,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_STRING_SHORT,
|
||||
.data = SConfigOptionDescription::SStringData{"none"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:no_gaps_when_only",
|
||||
.description = "whether to apply gaps when there is only one window on a workspace, aka. smart gaps. (default: disabled - 0) no border - 1, with border - 2 [0/1/2]",
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{0, "disabled,no border,with border"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:orientation",
|
||||
.description = "default placement of the master area, can be left, right, top, bottom or center",
|
||||
|
@@ -341,6 +341,10 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("general:layout", {"dwindle"});
|
||||
m_pConfig->addConfigValue("general:allow_tearing", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("general:resize_corner", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("general:snap:enabled", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("general:snap:window_gap", Hyprlang::INT{10});
|
||||
m_pConfig->addConfigValue("general:snap:monitor_gap", Hyprlang::INT{10});
|
||||
m_pConfig->addConfigValue("general:snap:border_overlap", Hyprlang::INT{0});
|
||||
|
||||
m_pConfig->addConfigValue("misc:disable_hyprland_logo", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("misc:disable_splash_rendering", Hyprlang::INT{0});
|
||||
@@ -377,7 +381,11 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("group:insert_after_current", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("group:merge_groups_on_drag", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("group:merge_groups_on_groupbar", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("group:merge_floated_into_tiled_on_groupbar", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("group:auto_group", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("group:drag_into_group", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("group:group_on_movetoworkspace", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("group:groupbar:enabled", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("group:groupbar:font_family", {STRVAL_EMPTY});
|
||||
m_pConfig->addConfigValue("group:groupbar:font_size", Hyprlang::INT{8});
|
||||
@@ -424,14 +432,15 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("decoration:inactive_opacity", {1.F});
|
||||
m_pConfig->addConfigValue("decoration:fullscreen_opacity", {1.F});
|
||||
m_pConfig->addConfigValue("decoration:no_blur_on_oversized", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("decoration:drop_shadow", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("decoration:shadow_range", Hyprlang::INT{4});
|
||||
m_pConfig->addConfigValue("decoration:shadow_render_power", Hyprlang::INT{3});
|
||||
m_pConfig->addConfigValue("decoration:shadow_ignore_window", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("decoration:shadow_offset", Hyprlang::VEC2{0, 0});
|
||||
m_pConfig->addConfigValue("decoration:shadow_scale", {1.f});
|
||||
m_pConfig->addConfigValue("decoration:col.shadow", Hyprlang::INT{0xee1a1a1a});
|
||||
m_pConfig->addConfigValue("decoration:col.shadow_inactive", {(Hyprlang::INT)INT_MAX});
|
||||
m_pConfig->addConfigValue("decoration:shadow:enabled", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("decoration:shadow:range", Hyprlang::INT{4});
|
||||
m_pConfig->addConfigValue("decoration:shadow:render_power", Hyprlang::INT{3});
|
||||
m_pConfig->addConfigValue("decoration:shadow:ignore_window", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("decoration:shadow:offset", Hyprlang::VEC2{0, 0});
|
||||
m_pConfig->addConfigValue("decoration:shadow:scale", {1.f});
|
||||
m_pConfig->addConfigValue("decoration:shadow:sharp", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("decoration:shadow:color", Hyprlang::INT{0xee1a1a1a});
|
||||
m_pConfig->addConfigValue("decoration:shadow:color_inactive", {(Hyprlang::INT)INT64_MAX});
|
||||
m_pConfig->addConfigValue("decoration:dim_inactive", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("decoration:dim_strength", {0.5f});
|
||||
m_pConfig->addConfigValue("decoration:dim_special", {0.2f});
|
||||
@@ -444,7 +453,6 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("dwindle:preserve_split", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("dwindle:special_scale_factor", {1.f});
|
||||
m_pConfig->addConfigValue("dwindle:split_width_multiplier", {1.0f});
|
||||
m_pConfig->addConfigValue("dwindle:no_gaps_when_only", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("dwindle:use_active_for_splits", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("dwindle:default_split_ratio", {1.f});
|
||||
m_pConfig->addConfigValue("dwindle:split_bias", Hyprlang::INT{0});
|
||||
@@ -457,7 +465,6 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("master:always_center_master", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("master:new_on_active", {"none"});
|
||||
m_pConfig->addConfigValue("master:new_on_top", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("master:no_gaps_when_only", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("master:orientation", {"left"});
|
||||
m_pConfig->addConfigValue("master:inherit_fullscreen", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("master:allow_small_split", Hyprlang::INT{0});
|
||||
@@ -548,7 +555,7 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("opengl:force_introspection", Hyprlang::INT{2});
|
||||
|
||||
m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{2});
|
||||
m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24});
|
||||
m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0});
|
||||
@@ -585,6 +592,7 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("render:explicit_sync", Hyprlang::INT{2});
|
||||
m_pConfig->addConfigValue("render:explicit_sync_kms", Hyprlang::INT{2});
|
||||
m_pConfig->addConfigValue("render:direct_scanout", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("render:expand_undersized_textures", Hyprlang::INT{1});
|
||||
|
||||
// devices
|
||||
m_pConfig->addSpecialCategory("device", {"name"});
|
||||
@@ -688,14 +696,13 @@ std::string CConfigManager::getMainConfigPath() {
|
||||
|
||||
if (const auto CFG_ENV = getenv("HYPRLAND_CONFIG"); CFG_ENV)
|
||||
return CFG_ENV;
|
||||
Debug::log(TRACE, "Seems as if HYPRLAND_CONFIG isn't set, let's see what we can do with HOME.");
|
||||
|
||||
static const auto paths = Hyprutils::Path::findConfig(ISDEBUG ? "hyprlandd" : "hyprland");
|
||||
if (paths.first.has_value()) {
|
||||
return paths.first.value();
|
||||
} else if (paths.second.has_value()) {
|
||||
auto configPath = Hyprutils::Path::fullConfigPath(paths.second.value(), ISDEBUG ? "hyprlandd" : "hyprland");
|
||||
return generateConfig(configPath).value();
|
||||
const auto PATHS = Hyprutils::Path::findConfig(ISDEBUG ? "hyprlandd" : "hyprland");
|
||||
if (PATHS.first.has_value()) {
|
||||
return PATHS.first.value();
|
||||
} else if (PATHS.second.has_value()) {
|
||||
const auto CONFIGPATH = Hyprutils::Path::fullConfigPath(PATHS.second.value(), ISDEBUG ? "hyprlandd" : "hyprland");
|
||||
return generateConfig(CONFIGPATH).value();
|
||||
} else
|
||||
throw std::runtime_error("Neither HOME nor XDG_CONFIG_HOME are set in the environment. Could not find config in XDG_CONFIG_DIRS or /etc/xdg.");
|
||||
}
|
||||
@@ -867,8 +874,10 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||
if (result.error && !std::any_cast<Hyprlang::INT>(m_pConfig->getConfigValue("debug:suppress_errors")))
|
||||
g_pHyprError->queueCreate(result.getError(), CColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0));
|
||||
else if (std::any_cast<Hyprlang::INT>(m_pConfig->getConfigValue("autogenerated")) == 1)
|
||||
g_pHyprError->queueCreate("Warning: You're using an autogenerated config! (config file: " + getMainConfigPath() + " )\nSUPER+Q -> kitty\nSUPER+M -> exit Hyprland",
|
||||
CColor(1.0, 1.0, 70.0 / 255.0, 1.0));
|
||||
g_pHyprError->queueCreate(
|
||||
"Warning: You're using an autogenerated config! (config file: " + getMainConfigPath() +
|
||||
" )\nSUPER+Q -> kitty (if it doesn't launch, make sure it's installed or choose a different terminal in the config)\nSUPER+M -> exit Hyprland",
|
||||
CColor(1.0, 1.0, 70.0 / 255.0, 1.0));
|
||||
else if (*PENABLEEXPLICIT != prevEnabledExplicit)
|
||||
g_pHyprError->queueCreate("Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland.", CColor(0.9, 0.76, 0.221, 1.0));
|
||||
else
|
||||
@@ -942,9 +951,9 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
// mark blur dirty
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(m.get());
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(m);
|
||||
|
||||
g_pCompositor->scheduleFrameForMonitor(m.get());
|
||||
g_pCompositor->scheduleFrameForMonitor(m);
|
||||
|
||||
// Force the compositor to fully re-render all monitors
|
||||
m->forceFullFrames = 2;
|
||||
@@ -1082,7 +1091,7 @@ std::string CConfigManager::getDeviceString(const std::string& dev, const std::s
|
||||
return VAL;
|
||||
}
|
||||
|
||||
SMonitorRule CConfigManager::getMonitorRuleFor(const SP<CMonitor> PMONITOR) {
|
||||
SMonitorRule CConfigManager::getMonitorRuleFor(const PHLMONITOR PMONITOR) {
|
||||
auto applyWlrOutputConfig = [PMONITOR](SMonitorRule rule) -> SMonitorRule {
|
||||
const auto CONFIG = PROTO::outputManagement->getOutputStateFor(PMONITOR);
|
||||
|
||||
@@ -1505,7 +1514,7 @@ void CConfigManager::performMonitorReload() {
|
||||
|
||||
auto rule = getMonitorRuleFor(m);
|
||||
|
||||
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule)) {
|
||||
if (!g_pHyprRenderer->applyMonitorRule(m, &rule)) {
|
||||
overAgain = true;
|
||||
break;
|
||||
}
|
||||
@@ -1563,14 +1572,14 @@ void CConfigManager::ensureMonitorStatus() {
|
||||
auto rule = getMonitorRuleFor(rm);
|
||||
|
||||
if (rule.disabled == rm->m_bEnabled)
|
||||
g_pHyprRenderer->applyMonitorRule(rm.get(), &rule);
|
||||
g_pHyprRenderer->applyMonitorRule(rm, &rule);
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||
void CConfigManager::ensureVRR(PHLMONITOR pMonitor) {
|
||||
static auto PVRR = reinterpret_cast<Hyprlang::INT* const*>(getConfigValuePtr("misc:vrr"));
|
||||
|
||||
static auto ensureVRRForDisplay = [&](CMonitor* m) -> void {
|
||||
static auto ensureVRRForDisplay = [&](PHLMONITOR m) -> void {
|
||||
if (!m->output || m->createdByUser)
|
||||
return;
|
||||
|
||||
@@ -1602,9 +1611,6 @@ void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||
m->vrrActive = true;
|
||||
return;
|
||||
} else if (USEVRR == 2) {
|
||||
/* fullscreen */
|
||||
m->vrrActive = true;
|
||||
|
||||
const auto PWORKSPACE = m->activeWorkspace;
|
||||
|
||||
if (!PWORKSPACE)
|
||||
@@ -1613,6 +1619,9 @@ void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||
const auto WORKSPACEFULL = PWORKSPACE->m_bHasFullscreenWindow && (PWORKSPACE->m_efFullscreenMode & FSMODE_FULLSCREEN);
|
||||
|
||||
if (WORKSPACEFULL) {
|
||||
/* fullscreen */
|
||||
m->vrrActive = true;
|
||||
|
||||
m->output->state->resetExplicitFences();
|
||||
m->output->state->setAdaptiveSync(true);
|
||||
|
||||
@@ -1625,6 +1634,8 @@ void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||
Debug::log(ERR, "Couldn't commit output {} in ensureVRR -> true", m->output->name);
|
||||
|
||||
} else if (!WORKSPACEFULL) {
|
||||
m->vrrActive = false;
|
||||
|
||||
m->output->state->resetExplicitFences();
|
||||
m->output->state->setAdaptiveSync(false);
|
||||
|
||||
@@ -1640,7 +1651,7 @@ void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||
}
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
ensureVRRForDisplay(m.get());
|
||||
ensureVRRForDisplay(m);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1652,7 +1663,7 @@ void CConfigManager::addParseError(const std::string& err) {
|
||||
g_pHyprError->queueCreate(err + "\nHyprland may not work correctly.", CColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0));
|
||||
}
|
||||
|
||||
CMonitor* CConfigManager::getBoundMonitorForWS(const std::string& wsname) {
|
||||
PHLMONITOR CConfigManager::getBoundMonitorForWS(const std::string& wsname) {
|
||||
auto monitor = getBoundMonitorStringForWS(wsname);
|
||||
if (monitor.substr(0, 5) == "desc:")
|
||||
return g_pCompositor->getMonitorFromDesc(monitor.substr(5));
|
||||
@@ -2773,6 +2784,18 @@ const std::vector<SConfigOptionDescription>& CConfigManager::getAllDescriptions(
|
||||
return CONFIG_OPTIONS;
|
||||
}
|
||||
|
||||
bool CConfigManager::shouldUseSoftwareCursors() {
|
||||
static auto PNOHW = CConfigValue<Hyprlang::INT>("cursor:no_hardware_cursors");
|
||||
|
||||
switch (*PNOHW) {
|
||||
case 0: return false;
|
||||
case 1: return true;
|
||||
default: return g_pHyprRenderer->isNvidia();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string SConfigOptionDescription::jsonify() const {
|
||||
auto parseData = [this]() -> std::string {
|
||||
return std::visit(
|
||||
|
@@ -169,11 +169,11 @@ class CConfigManager {
|
||||
static std::string getMainConfigPath();
|
||||
const std::string getConfigString();
|
||||
|
||||
SMonitorRule getMonitorRuleFor(const SP<CMonitor>);
|
||||
SMonitorRule getMonitorRuleFor(const PHLMONITOR);
|
||||
SWorkspaceRule getWorkspaceRuleFor(PHLWORKSPACE workspace);
|
||||
std::string getDefaultWorkspaceFor(const std::string&);
|
||||
|
||||
CMonitor* getBoundMonitorForWS(const std::string&);
|
||||
PHLMONITOR getBoundMonitorForWS(const std::string&);
|
||||
std::string getBoundMonitorStringForWS(const std::string&);
|
||||
const std::deque<SWorkspaceRule>& getAllWorkspaceRules();
|
||||
|
||||
@@ -198,7 +198,9 @@ class CConfigManager {
|
||||
void appendMonitorRule(const SMonitorRule&);
|
||||
bool replaceMonitorRule(const SMonitorRule&);
|
||||
void ensureMonitorStatus();
|
||||
void ensureVRR(CMonitor* pMonitor = nullptr);
|
||||
void ensureVRR(PHLMONITOR pMonitor = nullptr);
|
||||
|
||||
bool shouldUseSoftwareCursors();
|
||||
|
||||
std::string parseKeyword(const std::string&, const std::string&);
|
||||
|
||||
|
@@ -13,7 +13,7 @@ autogenerated = 1 # remove this line to remove the warning
|
||||
|
||||
# This is an example Hyprland config file.
|
||||
# Refer to the wiki for more information.
|
||||
# https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
||||
# https://wiki.hyprland.org/Configuring/
|
||||
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki
|
||||
@@ -99,10 +99,12 @@ decoration {
|
||||
active_opacity = 1.0
|
||||
inactive_opacity = 1.0
|
||||
|
||||
drop_shadow = true
|
||||
shadow_range = 4
|
||||
shadow_render_power = 3
|
||||
col.shadow = rgba(1a1a1aee)
|
||||
shadow {
|
||||
enabled = true
|
||||
range = 4
|
||||
render_power = 3
|
||||
color = rgba(1a1a1aee)
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#blur
|
||||
blur {
|
||||
@@ -116,20 +118,44 @@ decoration {
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
||||
animations {
|
||||
enabled = true
|
||||
enabled = yes, please :)
|
||||
|
||||
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||
|
||||
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
|
||||
bezier = easeOutQuint,0.23,1,0.32,1
|
||||
bezier = easeInOutCubic,0.65,0.05,0.36,1
|
||||
bezier = linear,0,0,1,1
|
||||
bezier = almostLinear,0.5,0.5,0.75,1.0
|
||||
bezier = quick,0.15,0,0.1,1
|
||||
|
||||
animation = windows, 1, 7, myBezier
|
||||
animation = windowsOut, 1, 7, default, popin 80%
|
||||
animation = border, 1, 10, default
|
||||
animation = borderangle, 1, 8, default
|
||||
animation = fade, 1, 7, default
|
||||
animation = workspaces, 1, 6, default
|
||||
animation = global, 1, 10, default
|
||||
animation = border, 1, 5.39, easeOutQuint
|
||||
animation = windows, 1, 4.79, easeOutQuint
|
||||
animation = windowsIn, 1, 4.1, easeOutQuint, popin 87%
|
||||
animation = windowsOut, 1, 1.49, linear, popin 87%
|
||||
animation = fadeIn, 1, 1.73, almostLinear
|
||||
animation = fadeOut, 1, 1.46, almostLinear
|
||||
animation = fade, 1, 3.03, quick
|
||||
animation = layers, 1, 3.81, easeOutQuint
|
||||
animation = layersIn, 1, 4, easeOutQuint, fade
|
||||
animation = layersOut, 1, 1.5, linear, fade
|
||||
animation = fadeLayersIn, 1, 1.79, almostLinear
|
||||
animation = fadeLayersOut, 1, 1.39, almostLinear
|
||||
animation = workspaces, 1, 1.94, almostLinear, fade
|
||||
animation = workspacesIn, 1, 1.21, almostLinear, fade
|
||||
animation = workspacesOut, 1, 1.94, almostLinear, fade
|
||||
}
|
||||
|
||||
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
|
||||
# "Smart gaps" / "No gaps when only"
|
||||
# uncomment all if you wish to use that.
|
||||
# workspace = w[tv1], gapsout:0, gapsin:0
|
||||
# workspace = f[1], gapsout:0, gapsin:0
|
||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[tv1]
|
||||
# windowrulev2 = rounding 0, floating:0, onworkspace:w[tv1]
|
||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:f[1]
|
||||
# windowrulev2 = rounding 0, floating:0, onworkspace:f[1]
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||
dwindle {
|
||||
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||
@@ -268,5 +294,9 @@ bindl = , XF86AudioPrev, exec, playerctl previous
|
||||
# Example windowrule v2
|
||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||
|
||||
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
|
||||
# Ignore maximize requests from apps. You'll probably like this.
|
||||
windowrulev2 = suppressevent maximize, class:.*
|
||||
|
||||
# Fix some dragging issues with XWayland
|
||||
windowrulev2 = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
|
||||
)#";
|
||||
|
@@ -159,7 +159,7 @@ void CrashReporter::createAndSaveCrash(int sig) {
|
||||
|
||||
finalCrashReport += "GPU:\n\t";
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
finalCrashReport.writeCmdOutput("pciconf -lv | fgrep -A4 vga");
|
||||
finalCrashReport.writeCmdOutput("pciconf -lv | grep -F -A4 vga");
|
||||
#else
|
||||
finalCrashReport.writeCmdOutput("lspci -vnn | grep VGA");
|
||||
#endif
|
||||
|
@@ -54,7 +54,7 @@ static std::string formatToString(uint32_t drmFormat) {
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
static std::string availableModesForOutput(CMonitor* pMonitor, eHyprCtlOutputFormat format) {
|
||||
static std::string availableModesForOutput(PHLMONITOR pMonitor, eHyprCtlOutputFormat format) {
|
||||
std::string result;
|
||||
|
||||
for (auto const& m : pMonitor->output->modes) {
|
||||
@@ -107,6 +107,7 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor>
|
||||
"activelyTearing": {},
|
||||
"disabled": {},
|
||||
"currentFormat": "{}",
|
||||
"mirrorOf": "{}",
|
||||
"availableModes": [{}]
|
||||
}},)#",
|
||||
|
||||
@@ -117,18 +118,19 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor>
|
||||
(int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m == g_pCompositor->m_pLastMonitor ? "true" : "false"),
|
||||
(m->dpmsStatus ? "true" : "false"), (m->output->state->state().adaptiveSync ? "true" : "false"), (uint64_t)m->solitaryClient.get(),
|
||||
(m->tearingState.activelyTearing ? "true" : "false"), (m->m_bEnabled ? "false" : "true"), formatToString(m->output->state->state().drmFormat),
|
||||
availableModesForOutput(m.get(), format));
|
||||
m->pMirrorOf ? std::format("{}", m->pMirrorOf->ID) : "none", availableModesForOutput(m, format));
|
||||
|
||||
} else {
|
||||
result += std::format("Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\t"
|
||||
"special workspace: {} ({})\n\treserved: {} {} {} {}\n\tscale: {:.2f}\n\ttransform: {}\n\tfocused: {}\n\t"
|
||||
"dpmsStatus: {}\n\tvrr: {}\n\tsolitary: {:x}\n\tactivelyTearing: {}\n\tdisabled: {}\n\tcurrentFormat: {}\n\tavailableModes: {}\n\n",
|
||||
"dpmsStatus: {}\n\tvrr: {}\n\tsolitary: {:x}\n\tactivelyTearing: {}\n\tdisabled: {}\n\tcurrentFormat: {}\n\tmirrorOf: {}\n\tavailableModes: {}\n\n",
|
||||
m->szName, m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->szShortDescription,
|
||||
m->output->make, m->output->model, m->output->serial, m->activeWorkspaceID(), (!m->activeWorkspace ? "" : m->activeWorkspace->m_szName),
|
||||
m->activeSpecialWorkspaceID(), (m->activeSpecialWorkspace ? m->activeSpecialWorkspace->m_szName : ""), (int)m->vecReservedTopLeft.x,
|
||||
(int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform,
|
||||
(m == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus, m->output->state->state().adaptiveSync, (uint64_t)m->solitaryClient.get(),
|
||||
m->tearingState.activelyTearing, !m->m_bEnabled, formatToString(m->output->state->state().drmFormat), availableModesForOutput(m.get(), format));
|
||||
m->tearingState.activelyTearing, !m->m_bEnabled, formatToString(m->output->state->state().drmFormat),
|
||||
m->pMirrorOf ? std::format("{}", m->pMirrorOf->ID) : "none", availableModesForOutput(m, format));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -242,7 +244,7 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) {
|
||||
(uintptr_t)w.get(), (w->m_bIsMapped ? "true" : "false"), (w->isHidden() ? "true" : "false"), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y,
|
||||
(int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID,
|
||||
escapeJSONStrings(!w->m_pWorkspace ? "" : w->m_pWorkspace->m_szName), ((int)w->m_bIsFloating == 1 ? "true" : "false"), (w->m_bIsPseudotiled ? "true" : "false"),
|
||||
(int64_t)w->m_iMonitorID, escapeJSONStrings(w->m_szClass), escapeJSONStrings(w->m_szTitle), escapeJSONStrings(w->m_szInitialClass),
|
||||
(int64_t)w->monitorID(), escapeJSONStrings(w->m_szClass), escapeJSONStrings(w->m_szTitle), escapeJSONStrings(w->m_szInitialClass),
|
||||
escapeJSONStrings(w->m_szInitialTitle), w->getPID(), ((int)w->m_bIsX11 == 1 ? "true" : "false"), (w->m_bPinned ? "true" : "false"),
|
||||
(uint8_t)w->m_sFullscreenState.internal, (uint8_t)w->m_sFullscreenState.client, getGroupedData(w, format), getTagsData(w, format),
|
||||
(uintptr_t)w->m_pSwallowed.lock().get(), getFocusHistoryID(w));
|
||||
@@ -254,7 +256,7 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) {
|
||||
"{}\n\tfullscreen: {}\n\tfullscreenClient: {}\n\tgrouped: {}\n\ttags: {}\n\tswallowing: {:x}\n\tfocusHistoryID: {}\n\n",
|
||||
(uintptr_t)w.get(), w->m_szTitle, (int)w->m_bIsMapped, (int)w->isHidden(), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y,
|
||||
(int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID, (!w->m_pWorkspace ? "" : w->m_pWorkspace->m_szName),
|
||||
(int)w->m_bIsFloating, (int)w->m_bIsPseudotiled, (int64_t)w->m_iMonitorID, w->m_szClass, w->m_szTitle, w->m_szInitialClass, w->m_szInitialTitle, w->getPID(),
|
||||
(int)w->m_bIsFloating, (int)w->m_bIsPseudotiled, (int64_t)w->monitorID(), w->m_szClass, w->m_szTitle, w->m_szInitialClass, w->m_szInitialTitle, w->getPID(),
|
||||
(int)w->m_bIsX11, (int)w->m_bPinned, (uint8_t)w->m_sFullscreenState.internal, (uint8_t)w->m_sFullscreenState.client, getGroupedData(w, format), getTagsData(w, format),
|
||||
(uintptr_t)w->m_pSwallowed.lock().get(), getFocusHistoryID(w));
|
||||
}
|
||||
@@ -288,7 +290,7 @@ std::string clientsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
|
||||
std::string CHyprCtl::getWorkspaceData(PHLWORKSPACE w, eHyprCtlOutputFormat format) {
|
||||
const auto PLASTW = w->getLastFocusedWindow();
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(w->m_iMonitorID);
|
||||
const auto PMONITOR = w->m_pMonitor.lock();
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
return std::format(R"#({{
|
||||
"id": {},
|
||||
@@ -549,6 +551,15 @@ std::string configErrorsRequest(eHyprCtlOutputFormat format, std::string request
|
||||
std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string result = "";
|
||||
|
||||
auto getModState = [](SP<IKeyboard> keyboard, const char* xkbModName) -> bool {
|
||||
auto IDX = xkb_keymap_mod_get_index(keyboard->xkbKeymap, xkbModName);
|
||||
|
||||
if (IDX == XKB_MOD_INVALID)
|
||||
return false;
|
||||
|
||||
return (keyboard->modifiersState.locked & (1 << IDX)) > 0;
|
||||
};
|
||||
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
result += "{\n";
|
||||
result += "\"mice\": [\n";
|
||||
@@ -580,11 +591,13 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
"variant": "{}",
|
||||
"options": "{}",
|
||||
"active_keymap": "{}",
|
||||
"capsLock": {},
|
||||
"numLock": {},
|
||||
"main": {}
|
||||
}},)#",
|
||||
(uintptr_t)k.get(), escapeJSONStrings(k->hlName), escapeJSONStrings(k->currentRules.rules), escapeJSONStrings(k->currentRules.model),
|
||||
escapeJSONStrings(k->currentRules.layout), escapeJSONStrings(k->currentRules.variant), escapeJSONStrings(k->currentRules.options), escapeJSONStrings(KM),
|
||||
(k->active ? "true" : "false"));
|
||||
(getModState(k, XKB_MOD_NAME_CAPS) ? "true" : "false"), (getModState(k, XKB_MOD_NAME_NUM) ? "true" : "false"), (k->active ? "true" : "false"));
|
||||
}
|
||||
|
||||
trimTrailingComma(result);
|
||||
@@ -668,9 +681,11 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
|
||||
for (auto const& k : g_pInputManager->m_vKeyboards) {
|
||||
const auto KM = k->getActiveLayout();
|
||||
result += std::format("\tKeyboard at {:x}:\n\t\t{}\n\t\t\trules: r \"{}\", m \"{}\", l \"{}\", v \"{}\", o \"{}\"\n\t\t\tactive keymap: {}\n\t\t\tmain: {}\n",
|
||||
(uintptr_t)k.get(), k->hlName, k->currentRules.rules, k->currentRules.model, k->currentRules.layout, k->currentRules.variant,
|
||||
k->currentRules.options, KM, (k->active ? "yes" : "no"));
|
||||
result +=
|
||||
std::format("\tKeyboard at {:x}:\n\t\t{}\n\t\t\trules: r \"{}\", m \"{}\", l \"{}\", v \"{}\", o \"{}\"\n\t\t\tactive keymap: {}\n\t\t\tcapsLock: "
|
||||
"{}\n\t\t\tnumLock: {}\n\t\t\tmain: {}\n",
|
||||
(uintptr_t)k.get(), k->hlName, k->currentRules.rules, k->currentRules.model, k->currentRules.layout, k->currentRules.variant, k->currentRules.options,
|
||||
KM, (getModState(k, XKB_MOD_NAME_CAPS) ? "yes" : "no"), (getModState(k, XKB_MOD_NAME_NUM) ? "yes" : "no"), (k->active ? "yes" : "no"));
|
||||
}
|
||||
|
||||
result += "\n\nTablets:\n";
|
||||
@@ -853,26 +868,33 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::replace(commitMsg.begin(), commitMsg.end(), '#', ' ');
|
||||
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||
std::string result = "Hyprland, built from branch " + std::string(GIT_BRANCH) + " at commit " + GIT_COMMIT_HASH + " " + GIT_DIRTY + " (" + commitMsg +
|
||||
").\nDate: " + GIT_COMMIT_DATE + "\nTag: " + GIT_TAG + ", commits: " + GIT_COMMITS + std::string{"\nbuilt against aquamarine "} + AQUAMARINE_VERSION + "\n" +
|
||||
"\n\nflags: (if any)\n";
|
||||
std::string result = std::format("Hyprland {} built from branch {} at commit {} {} ({}).\n"
|
||||
"Date: {}\n"
|
||||
"Tag: {}, commits: {}\n"
|
||||
"built against aquamarine {}\n\n\n",
|
||||
HYPRLAND_VERSION, GIT_BRANCH, GIT_COMMIT_HASH, GIT_DIRTY, commitMsg, GIT_COMMIT_DATE, GIT_TAG, GIT_COMMITS, AQUAMARINE_VERSION);
|
||||
|
||||
#if (!defined(LEGACY_RENDERER) && !defined(ISDEBUG) && !defined(NO_XWAYLAND))
|
||||
result += "no flags were set\n";
|
||||
#else
|
||||
result += "flags set:\n";
|
||||
#ifdef LEGACY_RENDERER
|
||||
result += "legacyrenderer\n";
|
||||
#endif
|
||||
#ifndef ISDEBUG
|
||||
#ifdef ISDEBUG
|
||||
result += "debug\n";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
result += "no xwayland\n";
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return result;
|
||||
} else {
|
||||
std::string result = std::format(
|
||||
R"#({{
|
||||
"branch": "{}",
|
||||
"commit": "{}",
|
||||
"version": "{}",
|
||||
"dirty": {},
|
||||
"commit_message": "{}",
|
||||
"commit_date": "{}",
|
||||
@@ -880,13 +902,13 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
"commits": "{}",
|
||||
"buildAquamarine": "{}",
|
||||
"flags": [)#",
|
||||
GIT_BRANCH, GIT_COMMIT_HASH, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), escapeJSONStrings(commitMsg), GIT_COMMIT_DATE, GIT_TAG, GIT_COMMITS,
|
||||
AQUAMARINE_VERSION);
|
||||
GIT_BRANCH, GIT_COMMIT_HASH, HYPRLAND_VERSION, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), escapeJSONStrings(commitMsg), GIT_COMMIT_DATE, GIT_TAG,
|
||||
GIT_COMMITS, AQUAMARINE_VERSION);
|
||||
|
||||
#ifdef LEGACY_RENDERER
|
||||
result += "\"legacyrenderer\",";
|
||||
#endif
|
||||
#ifndef ISDEBUG
|
||||
#ifdef ISDEBUG
|
||||
result += "\"debug\",";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
@@ -920,7 +942,7 @@ std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request)
|
||||
result += "\n\n";
|
||||
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
const std::string GPUINFO = execAndGet("pciconf -lv | fgrep -A4 vga");
|
||||
const std::string GPUINFO = execAndGet("pciconf -lv | grep -F -A4 vga");
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
const std::string GPUINFO = execAndGet("cat /proc/device-tree/soc*/gpu*/compatible");
|
||||
#else
|
||||
@@ -1021,9 +1043,10 @@ std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) {
|
||||
}
|
||||
|
||||
// decorations will probably need a repaint
|
||||
if (COMMAND.contains("decoration:") || COMMAND.contains("border") || COMMAND == "workspace" || COMMAND.contains("zoom_factor") || COMMAND == "source") {
|
||||
if (COMMAND.contains("decoration:") || COMMAND.contains("border") || COMMAND == "workspace" || COMMAND.contains("zoom_factor") || COMMAND == "source" ||
|
||||
COMMAND.starts_with("windowrule")) {
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
g_pHyprRenderer->damageMonitor(m.get());
|
||||
g_pHyprRenderer->damageMonitor(m);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||
}
|
||||
}
|
||||
@@ -1242,101 +1265,8 @@ std::string dispatchSeterror(eHyprCtlOutputFormat format, std::string request) {
|
||||
}
|
||||
|
||||
std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
|
||||
if (vars.size() < 4)
|
||||
return "not enough args";
|
||||
|
||||
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock();
|
||||
const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[1]);
|
||||
|
||||
if (!PWINDOW)
|
||||
return "window not found";
|
||||
|
||||
const auto PROP = vars[2];
|
||||
const auto VAL = vars[3];
|
||||
|
||||
bool noFocus = PWINDOW->m_sWindowData.noFocus.valueOrDefault();
|
||||
|
||||
try {
|
||||
if (PROP == "animationstyle") {
|
||||
PWINDOW->m_sWindowData.animationStyle = CWindowOverridableVar(VAL, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "maxsize") {
|
||||
PWINDOW->m_sWindowData.maxSize = CWindowOverridableVar(configStringToVector2D(VAL + " " + vars[4]), PRIORITY_SET_PROP);
|
||||
PWINDOW->m_vRealSize = Vector2D(std::min((double)PWINDOW->m_sWindowData.maxSize.value().x, PWINDOW->m_vRealSize.goal().x),
|
||||
std::min((double)PWINDOW->m_sWindowData.maxSize.value().y, PWINDOW->m_vRealSize.goal().y));
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
|
||||
PWINDOW->setHidden(false);
|
||||
} else if (PROP == "minsize") {
|
||||
PWINDOW->m_sWindowData.minSize = CWindowOverridableVar(configStringToVector2D(VAL + " " + vars[4]), PRIORITY_SET_PROP);
|
||||
PWINDOW->m_vRealSize = Vector2D(std::max((double)PWINDOW->m_sWindowData.minSize.value().x, PWINDOW->m_vRealSize.goal().x),
|
||||
std::max((double)PWINDOW->m_sWindowData.minSize.value().y, PWINDOW->m_vRealSize.goal().y));
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
|
||||
PWINDOW->setHidden(false);
|
||||
} else if (PROP == "alpha") {
|
||||
PWINDOW->m_sWindowData.alpha = CWindowOverridableVar(SAlphaValue{std::stof(VAL), PWINDOW->m_sWindowData.alpha.valueOrDefault().m_bOverride}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "alphainactive") {
|
||||
PWINDOW->m_sWindowData.alphaInactive =
|
||||
CWindowOverridableVar(SAlphaValue{std::stof(VAL), PWINDOW->m_sWindowData.alphaInactive.valueOrDefault().m_bOverride}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "alphafullscreen") {
|
||||
PWINDOW->m_sWindowData.alphaFullscreen =
|
||||
CWindowOverridableVar(SAlphaValue{std::stof(VAL), PWINDOW->m_sWindowData.alphaFullscreen.valueOrDefault().m_bOverride}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "alphaoverride") {
|
||||
PWINDOW->m_sWindowData.alpha =
|
||||
CWindowOverridableVar(SAlphaValue{PWINDOW->m_sWindowData.alpha.valueOrDefault().m_fAlpha, (bool)configStringToInt(VAL)}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "alphainactiveoverride") {
|
||||
PWINDOW->m_sWindowData.alphaInactive =
|
||||
CWindowOverridableVar(SAlphaValue{PWINDOW->m_sWindowData.alphaInactive.valueOrDefault().m_fAlpha, (bool)configStringToInt(VAL)}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "alphafullscreenoverride") {
|
||||
PWINDOW->m_sWindowData.alphaFullscreen =
|
||||
CWindowOverridableVar(SAlphaValue{PWINDOW->m_sWindowData.alphaFullscreen.valueOrDefault().m_fAlpha, (bool)configStringToInt(VAL)}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "activebordercolor" || PROP == "inactivebordercolor") {
|
||||
CGradientValueData colorData = {};
|
||||
if (vars.size() > 4) {
|
||||
for (int i = 3; i < static_cast<int>(vars.size()); ++i) {
|
||||
const auto TOKEN = vars[i];
|
||||
if (TOKEN.ends_with("deg"))
|
||||
colorData.m_fAngle = std::stoi(TOKEN.substr(0, TOKEN.size() - 3)) * (PI / 180.0);
|
||||
else
|
||||
colorData.m_vColors.push_back(configStringToInt(TOKEN));
|
||||
}
|
||||
} else if (VAL != "-1")
|
||||
colorData.m_vColors.push_back(configStringToInt(VAL));
|
||||
|
||||
if (PROP == "activebordercolor")
|
||||
PWINDOW->m_sWindowData.activeBorderColor = CWindowOverridableVar(colorData, PRIORITY_SET_PROP);
|
||||
else
|
||||
PWINDOW->m_sWindowData.inactiveBorderColor = CWindowOverridableVar(colorData, PRIORITY_SET_PROP);
|
||||
} else if (auto search = g_pConfigManager->mbWindowProperties.find(PROP); search != g_pConfigManager->mbWindowProperties.end()) {
|
||||
auto pWindowDataElement = search->second(PWINDOW);
|
||||
if (VAL == "toggle")
|
||||
*pWindowDataElement = CWindowOverridableVar(!pWindowDataElement->valueOrDefault(), PRIORITY_SET_PROP);
|
||||
else if (VAL == "unset")
|
||||
pWindowDataElement->unset(PRIORITY_SET_PROP);
|
||||
else
|
||||
*pWindowDataElement = CWindowOverridableVar((bool)configStringToInt(VAL), PRIORITY_SET_PROP);
|
||||
} else if (auto search = g_pConfigManager->miWindowProperties.find(PROP); search != g_pConfigManager->miWindowProperties.end()) {
|
||||
if (VAL == "unset")
|
||||
search->second(PWINDOW)->unset(PRIORITY_SET_PROP);
|
||||
else
|
||||
*(search->second(PWINDOW)) = CWindowOverridableVar((int)configStringToInt(VAL), PRIORITY_SET_PROP);
|
||||
} else {
|
||||
return "prop not found";
|
||||
}
|
||||
} catch (std::exception& e) { return "error in parsing prop value: " + std::string(e.what()); }
|
||||
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
if (!(PWINDOW->m_sWindowData.noFocus.valueOrDefault() == noFocus)) {
|
||||
g_pCompositor->focusWindow(nullptr);
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
g_pCompositor->focusWindow(PLASTWINDOW);
|
||||
}
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors)
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||
|
||||
return "ok";
|
||||
auto result = g_pKeybindManager->m_mDispatchers["setprop"](request.substr(request.find_first_of(' ') + 1, -1));
|
||||
return "DEPRECATED: use hyprctl dispatch setprop instead" + (result.success ? "" : "\n" + result.error);
|
||||
}
|
||||
|
||||
std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string request) {
|
||||
@@ -1771,8 +1701,16 @@ std::string CHyprCtl::getReply(std::string request) {
|
||||
rd.blurFBDirty = true;
|
||||
}
|
||||
|
||||
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||
if (!w->m_bIsMapped || !g_pCompositor->isWorkspaceVisible(w->m_pWorkspace))
|
||||
continue;
|
||||
|
||||
w->updateDynamicRules();
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(w);
|
||||
}
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
g_pHyprRenderer->damageMonitor(m.get());
|
||||
g_pHyprRenderer->damageMonitor(m);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||
}
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
// exposed for main.cpp
|
||||
std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request);
|
||||
std::string versionRequest(eHyprCtlOutputFormat format, std::string request);
|
||||
|
||||
class CHyprCtl {
|
||||
public:
|
||||
|
@@ -7,7 +7,7 @@ CHyprDebugOverlay::CHyprDebugOverlay() {
|
||||
m_pTexture = makeShared<CTexture>();
|
||||
}
|
||||
|
||||
void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) {
|
||||
void CHyprMonitorDebugOverlay::renderData(PHLMONITOR pMonitor, float durationUs) {
|
||||
m_dLastRenderTimes.push_back(durationUs / 1000.f);
|
||||
|
||||
if (m_dLastRenderTimes.size() > (long unsigned int)pMonitor->refreshRate)
|
||||
@@ -17,7 +17,7 @@ void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float durationUs)
|
||||
m_pMonitor = pMonitor;
|
||||
}
|
||||
|
||||
void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) {
|
||||
void CHyprMonitorDebugOverlay::renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs) {
|
||||
m_dLastRenderTimesNoOverlay.push_back(durationUs / 1000.f);
|
||||
|
||||
if (m_dLastRenderTimesNoOverlay.size() > (long unsigned int)pMonitor->refreshRate)
|
||||
@@ -27,7 +27,7 @@ void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float dur
|
||||
m_pMonitor = pMonitor;
|
||||
}
|
||||
|
||||
void CHyprMonitorDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||
void CHyprMonitorDebugOverlay::frameData(PHLMONITOR pMonitor) {
|
||||
m_dLastFrametimes.push_back(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - m_tpLastFrame).count() / 1000.f);
|
||||
|
||||
if (m_dLastFrametimes.size() > (long unsigned int)pMonitor->refreshRate)
|
||||
@@ -39,7 +39,7 @@ void CHyprMonitorDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||
m_pMonitor = pMonitor;
|
||||
|
||||
// anim data too
|
||||
const auto PMONITORFORTICKS = g_pHyprRenderer->m_pMostHzMonitor ? g_pHyprRenderer->m_pMostHzMonitor : g_pCompositor->m_pLastMonitor.get();
|
||||
const auto PMONITORFORTICKS = g_pHyprRenderer->m_pMostHzMonitor ? g_pHyprRenderer->m_pMostHzMonitor.lock() : g_pCompositor->m_pLastMonitor.lock();
|
||||
if (PMONITORFORTICKS) {
|
||||
if (m_dLastAnimationTicks.size() > (long unsigned int)PMONITORFORTICKS->refreshRate)
|
||||
m_dLastAnimationTicks.pop_front();
|
||||
@@ -188,21 +188,21 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||
return posY - offset;
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) {
|
||||
void CHyprDebugOverlay::renderData(PHLMONITOR pMonitor, float durationUs) {
|
||||
m_mMonitorOverlays[pMonitor].renderData(pMonitor, durationUs);
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) {
|
||||
void CHyprDebugOverlay::renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs) {
|
||||
m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, durationUs);
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||
void CHyprDebugOverlay::frameData(PHLMONITOR pMonitor) {
|
||||
m_mMonitorOverlays[pMonitor].frameData(pMonitor);
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::draw() {
|
||||
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front();
|
||||
|
||||
if (!m_pCairoSurface || !m_pCairo) {
|
||||
m_pCairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
@@ -218,7 +218,7 @@ void CHyprDebugOverlay::draw() {
|
||||
// draw the things
|
||||
int offsetY = 0;
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
offsetY += m_mMonitorOverlays[m.get()].draw(offsetY);
|
||||
offsetY += m_mMonitorOverlays[m].draw(offsetY);
|
||||
offsetY += 5; // for padding between mons
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include "../render/Texture.hpp"
|
||||
#include <deque>
|
||||
#include <cairo/cairo.h>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
class CHyprRenderer;
|
||||
|
||||
@@ -13,9 +13,9 @@ class CHyprMonitorDebugOverlay {
|
||||
public:
|
||||
int draw(int offset);
|
||||
|
||||
void renderData(CMonitor* pMonitor, float durationUs);
|
||||
void renderDataNoOverlay(CMonitor* pMonitor, float durationUs);
|
||||
void frameData(CMonitor* pMonitor);
|
||||
void renderData(PHLMONITOR pMonitor, float durationUs);
|
||||
void renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs);
|
||||
void frameData(PHLMONITOR pMonitor);
|
||||
|
||||
private:
|
||||
std::deque<float> m_dLastFrametimes;
|
||||
@@ -23,7 +23,7 @@ class CHyprMonitorDebugOverlay {
|
||||
std::deque<float> m_dLastRenderTimesNoOverlay;
|
||||
std::deque<float> m_dLastAnimationTicks;
|
||||
std::chrono::high_resolution_clock::time_point m_tpLastFrame;
|
||||
CMonitor* m_pMonitor = nullptr;
|
||||
PHLMONITORREF m_pMonitor;
|
||||
CBox m_wbLastDrawnBox;
|
||||
|
||||
friend class CHyprRenderer;
|
||||
@@ -33,17 +33,17 @@ class CHyprDebugOverlay {
|
||||
public:
|
||||
CHyprDebugOverlay();
|
||||
void draw();
|
||||
void renderData(CMonitor*, float durationUs);
|
||||
void renderDataNoOverlay(CMonitor*, float durationUs);
|
||||
void frameData(CMonitor*);
|
||||
void renderData(PHLMONITOR, float durationUs);
|
||||
void renderDataNoOverlay(PHLMONITOR, float durationUs);
|
||||
void frameData(PHLMONITOR);
|
||||
|
||||
private:
|
||||
std::unordered_map<CMonitor*, CHyprMonitorDebugOverlay> m_mMonitorOverlays;
|
||||
std::map<PHLMONITORREF, CHyprMonitorDebugOverlay> m_mMonitorOverlays;
|
||||
|
||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||
cairo_t* m_pCairo = nullptr;
|
||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||
cairo_t* m_pCairo = nullptr;
|
||||
|
||||
SP<CTexture> m_pTexture;
|
||||
SP<CTexture> m_pTexture;
|
||||
|
||||
friend class CHyprMonitorDebugOverlay;
|
||||
friend class CHyprRenderer;
|
||||
|
@@ -37,7 +37,7 @@ CHyprNotificationOverlay::~CHyprNotificationOverlay() {
|
||||
void CHyprNotificationOverlay::addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon, const float fontSize) {
|
||||
const auto PNOTIF = m_dNotifications.emplace_back(std::make_unique<SNotification>()).get();
|
||||
|
||||
PNOTIF->text = text;
|
||||
PNOTIF->text = icon != eIcons::ICON_NONE ? " " + text /* tiny bit of padding otherwise icon touches text */ : text;
|
||||
PNOTIF->color = color == CColor(0) ? ICONS_COLORS[icon] : color;
|
||||
PNOTIF->started.reset();
|
||||
PNOTIF->timeMs = timeMs;
|
||||
@@ -45,7 +45,7 @@ void CHyprNotificationOverlay::addNotification(const std::string& text, const CC
|
||||
PNOTIF->fontSize = fontSize;
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
g_pCompositor->scheduleFrameForMonitor(m.get());
|
||||
g_pCompositor->scheduleFrameForMonitor(m);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ void CHyprNotificationOverlay::dismissNotifications(const int amount) {
|
||||
}
|
||||
}
|
||||
|
||||
CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
|
||||
CBox CHyprNotificationOverlay::drawNotifications(PHLMONITOR pMonitor) {
|
||||
static constexpr auto ANIM_DURATION_MS = 600.0;
|
||||
static constexpr auto ANIM_LAG_MS = 100.0;
|
||||
static constexpr auto NOTIF_LEFTBAR_SIZE = 5.0;
|
||||
@@ -187,7 +187,7 @@ CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
|
||||
return CBox{(int)(pMonitor->vecPosition.x + pMonitor->vecSize.x - maxWidth - 20), (int)pMonitor->vecPosition.y, (int)maxWidth + 20, (int)offsetY + 10};
|
||||
}
|
||||
|
||||
void CHyprNotificationOverlay::draw(CMonitor* pMonitor) {
|
||||
void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) {
|
||||
|
||||
const auto MONSIZE = pMonitor->vecTransformedSize;
|
||||
|
||||
|
@@ -41,13 +41,13 @@ class CHyprNotificationOverlay {
|
||||
CHyprNotificationOverlay();
|
||||
~CHyprNotificationOverlay();
|
||||
|
||||
void draw(CMonitor* pMonitor);
|
||||
void draw(PHLMONITOR pMonitor);
|
||||
void addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon = ICON_NONE, const float fontSize = 13.f);
|
||||
void dismissNotifications(const int amount);
|
||||
bool hasAny();
|
||||
|
||||
private:
|
||||
CBox drawNotifications(CMonitor* pMonitor);
|
||||
CBox drawNotifications(PHLMONITOR pMonitor);
|
||||
CBox m_bLastDamage;
|
||||
|
||||
std::deque<std::unique_ptr<SNotification>> m_dNotifications;
|
||||
@@ -55,8 +55,8 @@ class CHyprNotificationOverlay {
|
||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||
cairo_t* m_pCairo = nullptr;
|
||||
|
||||
CMonitor* m_pLastMonitor = nullptr;
|
||||
Vector2D m_vecLastSize = Vector2D(-1, -1);
|
||||
PHLMONITORREF m_pLastMonitor;
|
||||
Vector2D m_vecLastSize = Vector2D(-1, -1);
|
||||
|
||||
SP<CTexture> m_pTexture;
|
||||
};
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "RollingLogFollow.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <print>
|
||||
#include <fcntl.h>
|
||||
|
||||
void Debug::init(const std::string& IS) {
|
||||
@@ -69,5 +69,5 @@ void Debug::log(LogLevel level, std::string str) {
|
||||
|
||||
// log it to the stdout too.
|
||||
if (!disableStdout)
|
||||
std::cout << ((coloredLogs && !**coloredLogs) ? str : coloredStr) << "\n";
|
||||
std::println("{}", ((coloredLogs && !**coloredLogs) ? str : coloredStr));
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@
|
||||
class CWorkspace;
|
||||
class CWindow;
|
||||
class CLayerSurface;
|
||||
class CMonitor;
|
||||
|
||||
/* Shared pointer to a workspace */
|
||||
typedef SP<CWorkspace> PHLWORKSPACE;
|
||||
@@ -18,3 +19,8 @@ typedef WP<CWindow> PHLWINDOWREF;
|
||||
typedef SP<CLayerSurface> PHLLS;
|
||||
/* Weak pointer to a layer surface */
|
||||
typedef WP<CLayerSurface> PHLLSREF;
|
||||
|
||||
/* Shared pointer to a monitor */
|
||||
typedef SP<CMonitor> PHLMONITOR;
|
||||
/* Weak pointer to a monitor */
|
||||
typedef WP<CMonitor> PHLMONITORREF;
|
||||
|
@@ -6,9 +6,9 @@
|
||||
#include "../managers/SeatManager.hpp"
|
||||
|
||||
PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
|
||||
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
|
||||
|
||||
CMonitor* pMonitor = resource->monitor.empty() ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->getMonitorFromName(resource->monitor);
|
||||
auto pMonitor = resource->monitor.empty() ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->getMonitorFromName(resource->monitor);
|
||||
|
||||
pLS->surface->assign(resource->surface.lock(), pLS);
|
||||
|
||||
@@ -18,7 +18,7 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
}
|
||||
|
||||
if (pMonitor->pMirrorOf)
|
||||
pMonitor = g_pCompositor->m_vMonitors.front().get();
|
||||
pMonitor = g_pCompositor->m_vMonitors.front();
|
||||
|
||||
pLS->self = pLS;
|
||||
|
||||
@@ -26,7 +26,7 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
|
||||
pLS->layer = resource->current.layer;
|
||||
pLS->popupHead = std::make_unique<CPopup>(pLS);
|
||||
pLS->monitorID = pMonitor->ID;
|
||||
pLS->monitor = pMonitor;
|
||||
pMonitor->m_aLayerSurfaceLayers[resource->current.layer].emplace_back(pLS);
|
||||
|
||||
pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace);
|
||||
@@ -50,7 +50,7 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
void CLayerSurface::registerCallbacks() {
|
||||
alpha.setUpdateCallback([this](void*) {
|
||||
if (dimAround)
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(monitorID));
|
||||
g_pHyprRenderer->damageMonitor(monitor.lock());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -82,9 +82,9 @@ CLayerSurface::~CLayerSurface() {
|
||||
void CLayerSurface::onDestroy() {
|
||||
Debug::log(LOG, "LayerSurface {:x} destroyed", (uintptr_t)layerSurface.get());
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||
const auto PMONITOR = monitor.lock();
|
||||
|
||||
if (!g_pCompositor->getMonitorFromID(monitorID))
|
||||
if (!PMONITOR)
|
||||
Debug::log(WARN, "Layersurface destroyed on an invalid monitor (removed?)");
|
||||
|
||||
if (!fadingOut) {
|
||||
@@ -137,7 +137,7 @@ void CLayerSurface::onMap() {
|
||||
g_pCompositor->removeFromFadingOutSafe(self.lock());
|
||||
|
||||
// fix if it changed its mon
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||
const auto PMONITOR = monitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
@@ -175,8 +175,7 @@ void CLayerSurface::onMap() {
|
||||
|
||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
const auto WORKSPACE = PMONITOR->activeWorkspace;
|
||||
const bool FULLSCREEN = WORKSPACE->m_bHasFullscreenWindow && WORKSPACE->m_efFullscreenMode == FSMODE_FULLSCREEN;
|
||||
const bool FULLSCREEN = PMONITOR->activeWorkspace && PMONITOR->activeWorkspace->m_bHasFullscreenWindow && PMONITOR->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN;
|
||||
|
||||
startAnimation(!(layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS));
|
||||
readyToDelete = false;
|
||||
@@ -197,7 +196,7 @@ void CLayerSurface::onUnmap() {
|
||||
|
||||
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
|
||||
|
||||
if (!g_pCompositor->getMonitorFromID(monitorID) || g_pCompositor->m_bUnsafeState) {
|
||||
if (!monitor || g_pCompositor->m_bUnsafeState) {
|
||||
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
|
||||
|
||||
g_pCompositor->addToFadingOutSafe(self.lock());
|
||||
@@ -221,9 +220,9 @@ void CLayerSurface::onUnmap() {
|
||||
|
||||
g_pCompositor->addToFadingOutSafe(self.lock());
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||
const auto PMONITOR = monitor.lock();
|
||||
|
||||
const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource();
|
||||
const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == surface->resource() || g_pSeatManager->state.pointerFocus == surface->resource();
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
@@ -232,7 +231,7 @@ void CLayerSurface::onUnmap() {
|
||||
// vvvvvvvvvvvvv if there is a last focus and the last focus is not keyboard focusable, fallback to window
|
||||
if (WASLASTFOCUS || (g_pCompositor->m_pLastFocus && g_pCompositor->m_pLastFocus->hlSurface && !g_pCompositor->m_pLastFocus->hlSurface->keyboardFocusable()))
|
||||
g_pInputManager->refocusLastWindow(PMONITOR);
|
||||
else if (g_pCompositor->m_pLastFocus)
|
||||
else if (g_pCompositor->m_pLastFocus && g_pCompositor->m_pLastFocus != surface->resource())
|
||||
g_pSeatManager->setKeyboardFocus(g_pCompositor->m_pLastFocus.lock());
|
||||
|
||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
||||
@@ -256,13 +255,13 @@ void CLayerSurface::onCommit() {
|
||||
if (layerSurface->surface && !layerSurface->surface->current.texture) {
|
||||
fadingOut = false;
|
||||
geometry = {};
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(monitorID);
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(monitorID());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||
const auto PMONITOR = monitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
@@ -321,8 +320,18 @@ void CLayerSurface::onCommit() {
|
||||
realSize.setValueAndWarp(geometry.size());
|
||||
}
|
||||
|
||||
if (mapped) {
|
||||
const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource();
|
||||
if (mapped && (layerSurface->current.committed & CLayerShellResource::eCommittedState::STATE_INTERACTIVITY)) {
|
||||
bool WASLASTFOCUS = false;
|
||||
layerSurface->surface->breadthfirst(
|
||||
[&WASLASTFOCUS](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) { WASLASTFOCUS = WASLASTFOCUS || g_pSeatManager->state.keyboardFocus == surf; },
|
||||
nullptr);
|
||||
if (!WASLASTFOCUS && popupHead) {
|
||||
popupHead->breadthfirst(
|
||||
[&WASLASTFOCUS](CPopup* popup, void* data) {
|
||||
WASLASTFOCUS = WASLASTFOCUS || (popup->m_pWLSurface && g_pSeatManager->state.keyboardFocus == popup->m_pWLSurface->resource());
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
const bool WASEXCLUSIVE = interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
|
||||
const bool ISEXCLUSIVE = layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
|
||||
|
||||
@@ -332,11 +341,13 @@ void CLayerSurface::onCommit() {
|
||||
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
|
||||
|
||||
// if the surface was focused and interactive but now isn't, refocus
|
||||
if (WASLASTFOCUS && !layerSurface->current.interactivity) {
|
||||
if (WASLASTFOCUS && layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
|
||||
// moveMouseUnified won't focus non interactive layers but it won't unfocus them either,
|
||||
// so unfocus the surface here.
|
||||
g_pCompositor->focusSurface(nullptr);
|
||||
g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID));
|
||||
g_pInputManager->refocusLastWindow(monitor.lock());
|
||||
} else if (WASLASTFOCUS && WASEXCLUSIVE && layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
} else if (!WASEXCLUSIVE && ISEXCLUSIVE) {
|
||||
// if now exclusive and not previously
|
||||
g_pSeatManager->setGrab(nullptr);
|
||||
@@ -545,3 +556,7 @@ int CLayerSurface::popupsCount() {
|
||||
popupHead->breadthfirst([](CPopup* p, void* data) { *(int*)data += 1; }, &no);
|
||||
return no;
|
||||
}
|
||||
|
||||
MONITORID CLayerSurface::monitorID() {
|
||||
return monitor ? monitor->ID : MONITOR_INVALID;
|
||||
}
|
||||
|
@@ -42,7 +42,7 @@ class CLayerSurface {
|
||||
bool mapped = false;
|
||||
uint32_t layer = 0;
|
||||
|
||||
MONITORID monitorID = -1;
|
||||
PHLMONITORREF monitor;
|
||||
|
||||
bool fadingOut = false;
|
||||
bool readyToDelete = false;
|
||||
@@ -70,6 +70,7 @@ class CLayerSurface {
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit();
|
||||
MONITORID monitorID();
|
||||
|
||||
private:
|
||||
struct {
|
||||
@@ -83,6 +84,6 @@ class CLayerSurface {
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CLayerSurface& rhs) const {
|
||||
return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID;
|
||||
return layerSurface == rhs.layerSurface && monitor == rhs.monitor;
|
||||
}
|
||||
};
|
||||
|
@@ -4,6 +4,8 @@
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "../managers/eventLoop/EventLoopManager.hpp"
|
||||
#include <ranges>
|
||||
|
||||
CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) {
|
||||
@@ -106,6 +108,8 @@ void CPopup::onUnmap() {
|
||||
return;
|
||||
}
|
||||
|
||||
m_bMapped = false;
|
||||
|
||||
m_vLastSize = m_pResource->surface->surface->current.size;
|
||||
|
||||
const auto COORDS = coordsGlobal();
|
||||
@@ -116,8 +120,6 @@ void CPopup::onUnmap() {
|
||||
|
||||
m_pSubsurfaceHead.reset();
|
||||
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
|
||||
if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
|
||||
|
||||
@@ -131,6 +133,11 @@ void CPopup::onUnmap() {
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
},
|
||||
nullptr);
|
||||
|
||||
const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == m_pWLSurface->resource() || g_pSeatManager->state.pointerFocus == m_pWLSurface->resource();
|
||||
|
||||
if (WASLASTFOCUS)
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
}
|
||||
|
||||
void CPopup::onCommit(bool ignoreSiblings) {
|
||||
@@ -288,12 +295,13 @@ bool CPopup::visible() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPopup::bfHelper(std::vector<CPopup*> nodes, std::function<void(CPopup*, void*)> fn, void* data) {
|
||||
void CPopup::bfHelper(std::vector<CPopup*> const& nodes, std::function<void(CPopup*, void*)> fn, void* data) {
|
||||
for (auto const& n : nodes) {
|
||||
fn(n, data);
|
||||
}
|
||||
|
||||
std::vector<CPopup*> nodes2;
|
||||
nodes2.reserve(nodes.size() * 2);
|
||||
|
||||
for (auto const& n : nodes) {
|
||||
for (auto const& c : n->m_vChildren) {
|
||||
@@ -316,7 +324,7 @@ CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||
breadthfirst([](CPopup* popup, void* data) { ((std::vector<CPopup*>*)data)->push_back(popup); }, &popups);
|
||||
|
||||
for (auto const& p : popups | std::views::reverse) {
|
||||
if (!p->m_pResource)
|
||||
if (!p->m_pResource || !p->m_bMapped)
|
||||
continue;
|
||||
|
||||
if (!allowsInput) {
|
||||
|
@@ -41,6 +41,7 @@ class CPopup {
|
||||
|
||||
//
|
||||
SP<CWLSurface> m_pWLSurface;
|
||||
bool m_bMapped = false;
|
||||
|
||||
private:
|
||||
// T1 owners, each popup has to have one of these
|
||||
@@ -57,8 +58,7 @@ class CPopup {
|
||||
|
||||
bool m_bRequestedReposition = false;
|
||||
|
||||
bool m_bInert = false;
|
||||
bool m_bMapped = false;
|
||||
bool m_bInert = false;
|
||||
|
||||
//
|
||||
std::vector<SP<CPopup>> m_vChildren;
|
||||
@@ -81,5 +81,5 @@ class CPopup {
|
||||
|
||||
Vector2D localToGlobal(const Vector2D& rel);
|
||||
Vector2D t1ParentCoords();
|
||||
static void bfHelper(std::vector<CPopup*> nodes, std::function<void(CPopup*, void*)> fn, void* data);
|
||||
static void bfHelper(std::vector<CPopup*> const& nodes, std::function<void(CPopup*, void*)> fn, void* data);
|
||||
};
|
||||
|
@@ -113,7 +113,7 @@ SBoxExtents CWindow::getFullWindowExtents() {
|
||||
const int BORDERSIZE = getRealBorderSize();
|
||||
|
||||
if (m_sWindowData.dimAround.valueOrDefault()) {
|
||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); PMONITOR)
|
||||
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR)
|
||||
return {{m_vRealPosition.value().x - PMONITOR->vecPosition.x, m_vRealPosition.value().y - PMONITOR->vecPosition.y},
|
||||
{PMONITOR->vecSize.x - (m_vRealPosition.value().x - PMONITOR->vecPosition.x), PMONITOR->vecSize.y - (m_vRealPosition.value().y - PMONITOR->vecPosition.y)}};
|
||||
}
|
||||
@@ -173,7 +173,7 @@ SBoxExtents CWindow::getFullWindowExtents() {
|
||||
|
||||
CBox CWindow::getFullWindowBoundingBox() {
|
||||
if (m_sWindowData.dimAround.valueOrDefault()) {
|
||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); PMONITOR)
|
||||
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR)
|
||||
return {PMONITOR->vecPosition.x, PMONITOR->vecPosition.y, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ CBox CWindow::getFullWindowBoundingBox() {
|
||||
}
|
||||
|
||||
CBox CWindow::getWindowIdealBoundingBoxIgnoreReserved() {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return {m_vPosition, m_vSize};
|
||||
@@ -221,7 +221,7 @@ CBox CWindow::getWindowIdealBoundingBoxIgnoreReserved() {
|
||||
|
||||
CBox CWindow::getWindowBoxUnified(uint64_t properties) {
|
||||
if (m_sWindowData.dimAround.valueOrDefault()) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
if (PMONITOR)
|
||||
return {PMONITOR->vecPosition.x, PMONITOR->vecPosition.y, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
|
||||
}
|
||||
@@ -240,10 +240,6 @@ CBox CWindow::getWindowBoxUnified(uint64_t properties) {
|
||||
return box;
|
||||
}
|
||||
|
||||
CBox CWindow::getWindowMainSurfaceBox() {
|
||||
return {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y};
|
||||
}
|
||||
|
||||
SBoxExtents CWindow::getFullWindowReservedArea() {
|
||||
return g_pDecorationPositioner->getWindowDecorationReserved(m_pSelf.lock());
|
||||
}
|
||||
@@ -356,9 +352,9 @@ void CWindow::updateSurfaceScaleTransformDetails(bool force) {
|
||||
|
||||
const auto PLASTMONITOR = g_pCompositor->getMonitorFromID(m_iLastSurfaceMonitorID);
|
||||
|
||||
m_iLastSurfaceMonitorID = m_iMonitorID;
|
||||
m_iLastSurfaceMonitorID = monitorID();
|
||||
|
||||
const auto PNEWMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
const auto PNEWMONITOR = m_pMonitor.lock();
|
||||
|
||||
if (!PNEWMONITOR)
|
||||
return;
|
||||
@@ -370,10 +366,10 @@ void CWindow::updateSurfaceScaleTransformDetails(bool force) {
|
||||
m_pWLSurface->resource()->breadthfirst([PNEWMONITOR](SP<CWLSurfaceResource> s, const Vector2D& offset, void* d) { s->enter(PNEWMONITOR->self.lock()); }, nullptr);
|
||||
}
|
||||
|
||||
m_pWLSurface->resource()->breadthfirst(
|
||||
[this](SP<CWLSurfaceResource> s, const Vector2D& offset, void* d) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
|
||||
m_pWLSurface->resource()->breadthfirst(
|
||||
[PMONITOR](SP<CWLSurfaceResource> s, const Vector2D& offset, void* d) {
|
||||
const auto PSURFACE = CWLSurface::fromResource(s);
|
||||
if (PSURFACE && PSURFACE->m_fLastScale == PMONITOR->scale)
|
||||
return;
|
||||
@@ -408,7 +404,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
|
||||
const auto OLDWORKSPACE = m_pWorkspace;
|
||||
|
||||
m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->m_iMonitorID : -1;
|
||||
m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->monitorID() : -1;
|
||||
m_fMovingToWorkspaceAlpha.setValueAndWarp(1.F);
|
||||
m_fMovingToWorkspaceAlpha = 0.F;
|
||||
m_fMovingToWorkspaceAlpha.setCallbackOnEnd([this](void* thisptr) { m_iMonitorMovedFrom = -1; });
|
||||
@@ -419,11 +415,11 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
|
||||
g_pCompositor->updateWorkspaceWindows(OLDWORKSPACE->m_iID);
|
||||
g_pCompositor->updateWorkspaceWindowData(OLDWORKSPACE->m_iID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(OLDWORKSPACE->m_iMonitorID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(OLDWORKSPACE->monitorID());
|
||||
|
||||
g_pCompositor->updateWorkspaceWindows(workspaceID());
|
||||
g_pCompositor->updateWorkspaceWindowData(workspaceID());
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(monitorID());
|
||||
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
@@ -435,14 +431,14 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
|
||||
if (const auto SWALLOWED = m_pSwallowed.lock()) {
|
||||
SWALLOWED->moveToWorkspace(pWorkspace);
|
||||
SWALLOWED->m_iMonitorID = m_iMonitorID;
|
||||
SWALLOWED->m_pMonitor = m_pMonitor;
|
||||
}
|
||||
|
||||
// update xwayland coords
|
||||
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.value());
|
||||
|
||||
if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_iID) && g_pCompositor->getWindowsOnWorkspace(OLDWORKSPACE->m_iID) == 0 && *PCLOSEONLASTSPECIAL) {
|
||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(OLDWORKSPACE->m_iMonitorID); PMONITOR)
|
||||
if (const auto PMONITOR = OLDWORKSPACE->m_pMonitor.lock(); PMONITOR)
|
||||
PMONITOR->setSpecialWorkspace(nullptr);
|
||||
}
|
||||
}
|
||||
@@ -451,15 +447,21 @@ PHLWINDOW CWindow::X11TransientFor() {
|
||||
if (!m_pXWaylandSurface || !m_pXWaylandSurface->parent)
|
||||
return nullptr;
|
||||
|
||||
auto s = m_pXWaylandSurface->parent;
|
||||
auto oldParent = s;
|
||||
auto s = m_pXWaylandSurface->parent;
|
||||
std::vector<SP<CXWaylandSurface>> visited;
|
||||
while (s) {
|
||||
// break cyclic loop of m_pXWaylandSurface being parent of itself, #TODO reject this from even being created?
|
||||
if (!s->parent || s->parent == oldParent)
|
||||
// break loops. Some X apps make them, and it seems like it's valid behavior?!?!?!
|
||||
// TODO: we should reject loops being created in the first place.
|
||||
if (std::find(visited.begin(), visited.end(), s) != visited.end())
|
||||
break;
|
||||
|
||||
visited.emplace_back(s.lock());
|
||||
s = s->parent;
|
||||
}
|
||||
|
||||
if (s == m_pXWaylandSurface)
|
||||
return nullptr; // dead-ass circle
|
||||
|
||||
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_pXWaylandSurface != s)
|
||||
continue;
|
||||
@@ -515,19 +517,19 @@ void CWindow::onUnmap() {
|
||||
std::erase_if(g_pCompositor->m_vWindowFocusHistory, [&](const auto& other) { return other.expired() || other.lock().get() == this; });
|
||||
|
||||
if (*PCLOSEONLASTSPECIAL && g_pCompositor->getWindowsOnWorkspace(workspaceID()) == 0 && onSpecialWorkspace()) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
if (PMONITOR && PMONITOR->activeSpecialWorkspace && PMONITOR->activeSpecialWorkspace == m_pWorkspace)
|
||||
PMONITOR->setSpecialWorkspace(nullptr);
|
||||
}
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
|
||||
if (PMONITOR && PMONITOR->solitaryClient.lock().get() == this)
|
||||
PMONITOR->solitaryClient.reset();
|
||||
|
||||
g_pCompositor->updateWorkspaceWindows(workspaceID());
|
||||
g_pCompositor->updateWorkspaceWindowData(workspaceID());
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(monitorID());
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
m_pWorkspace.reset();
|
||||
@@ -736,9 +738,8 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
|
||||
}
|
||||
|
||||
m_sWindowData.maxSize = CWindowOverridableVar(VEC, priority);
|
||||
m_vRealSize =
|
||||
Vector2D(std::min((double)m_sWindowData.maxSize.value().x, m_vRealSize.goal().x), std::min((double)m_sWindowData.maxSize.value().y, m_vRealSize.goal().y));
|
||||
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal());
|
||||
clampWindowSize(std::nullopt, m_sWindowData.maxSize.value());
|
||||
|
||||
} catch (std::exception& e) { Debug::log(ERR, "maxsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
|
||||
} else if (r.szRule.starts_with("minsize")) {
|
||||
try {
|
||||
@@ -751,9 +752,8 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
|
||||
}
|
||||
|
||||
m_sWindowData.minSize = CWindowOverridableVar(VEC, priority);
|
||||
m_vRealSize =
|
||||
Vector2D(std::max((double)m_sWindowData.minSize.value().x, m_vRealSize.goal().x), std::max((double)m_sWindowData.minSize.value().y, m_vRealSize.goal().y));
|
||||
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal());
|
||||
clampWindowSize(m_sWindowData.minSize.value(), std::nullopt);
|
||||
|
||||
if (m_sGroupData.pNextWindow.expired())
|
||||
setHidden(false);
|
||||
} catch (std::exception& e) { Debug::log(ERR, "minsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
|
||||
@@ -790,7 +790,7 @@ void CWindow::updateDynamicRules() {
|
||||
|
||||
EMIT_HOOK_EVENT("windowUpdateRules", m_pSelf.lock());
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(monitorID());
|
||||
}
|
||||
|
||||
// check if the point is "hidden" under a rounded corner of the window
|
||||
@@ -857,7 +857,7 @@ void CWindow::createGroup() {
|
||||
|
||||
g_pCompositor->updateWorkspaceWindows(workspaceID());
|
||||
g_pCompositor->updateWorkspaceWindowData(workspaceID());
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(monitorID());
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"togglegroup", std::format("1,{:x}", (uintptr_t)this)});
|
||||
@@ -875,7 +875,7 @@ void CWindow::destroyGroup() {
|
||||
updateWindowDecos();
|
||||
g_pCompositor->updateWorkspaceWindows(workspaceID());
|
||||
g_pCompositor->updateWorkspaceWindowData(workspaceID());
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(monitorID());
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"togglegroup", std::format("0,{:x}", (uintptr_t)this)});
|
||||
@@ -911,7 +911,7 @@ void CWindow::destroyGroup() {
|
||||
|
||||
g_pCompositor->updateWorkspaceWindows(workspaceID());
|
||||
g_pCompositor->updateWorkspaceWindowData(workspaceID());
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(monitorID());
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
if (!addresses.empty())
|
||||
@@ -1087,7 +1087,7 @@ void CWindow::updateGroupOutputs() {
|
||||
const auto WS = m_pWorkspace;
|
||||
|
||||
while (curr.get() != this) {
|
||||
curr->m_iMonitorID = m_iMonitorID;
|
||||
curr->m_pMonitor = m_pMonitor;
|
||||
curr->moveToWorkspace(WS);
|
||||
|
||||
curr->m_vRealPosition = m_vRealPosition.goal();
|
||||
@@ -1184,7 +1184,7 @@ void CWindow::setSuspended(bool suspend) {
|
||||
m_bSuspended = suspend;
|
||||
}
|
||||
|
||||
bool CWindow::visibleOnMonitor(CMonitor* pMonitor) {
|
||||
bool CWindow::visibleOnMonitor(PHLMONITOR pMonitor) {
|
||||
CBox wbox = {m_vRealPosition.value(), m_vRealSize.value()};
|
||||
|
||||
return !wbox.intersection({pMonitor->vecPosition, pMonitor->vecSize}).empty();
|
||||
@@ -1209,7 +1209,7 @@ void CWindow::onWorkspaceAnimUpdate() {
|
||||
if (!PWORKSPACE)
|
||||
return;
|
||||
|
||||
const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
const auto PWSMON = m_pMonitor.lock();
|
||||
if (!PWSMON)
|
||||
return;
|
||||
|
||||
@@ -1253,6 +1253,16 @@ int CWindow::surfacesCount() {
|
||||
return no;
|
||||
}
|
||||
|
||||
void CWindow::clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize) {
|
||||
const Vector2D REALSIZE = m_vRealSize.goal();
|
||||
const Vector2D NEWSIZE = REALSIZE.clamp(minSize.value_or(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), maxSize.value_or(Vector2D{INFINITY, INFINITY}));
|
||||
const Vector2D DELTA = REALSIZE - NEWSIZE;
|
||||
|
||||
m_vRealPosition = m_vRealPosition.goal() + DELTA / 2.0;
|
||||
m_vRealSize = NEWSIZE;
|
||||
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), NEWSIZE);
|
||||
}
|
||||
|
||||
bool CWindow::isFullscreen() {
|
||||
return m_sFullscreenState.internal != FSMODE_NONE;
|
||||
}
|
||||
@@ -1265,6 +1275,10 @@ WORKSPACEID CWindow::workspaceID() {
|
||||
return m_pWorkspace ? m_pWorkspace->m_iID : m_iLastWorkspace;
|
||||
}
|
||||
|
||||
MONITORID CWindow::monitorID() {
|
||||
return m_pMonitor ? m_pMonitor->ID : MONITOR_INVALID;
|
||||
}
|
||||
|
||||
bool CWindow::onSpecialWorkspace() {
|
||||
return m_pWorkspace ? m_pWorkspace->m_bIsSpecialWorkspace : g_pCompositor->isWorkspaceSpecial(m_iLastWorkspace);
|
||||
}
|
||||
@@ -1451,7 +1465,7 @@ void CWindow::onX11Configure(CBox box) {
|
||||
m_pXWaylandSurface->configure(box);
|
||||
m_vPendingReportedSize = box.size();
|
||||
m_vReportedSize = box.size();
|
||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); PMONITOR)
|
||||
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR)
|
||||
m_fX11SurfaceScaledBy = PMONITOR->scale;
|
||||
return;
|
||||
}
|
||||
@@ -1477,7 +1491,7 @@ void CWindow::onX11Configure(CBox box) {
|
||||
|
||||
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
|
||||
if (*PXWLFORCESCALEZERO) {
|
||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); PMONITOR) {
|
||||
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR) {
|
||||
m_vRealSize.setValueAndWarp(m_vRealSize.goal() / PMONITOR->scale);
|
||||
m_fX11SurfaceScaledBy = PMONITOR->scale;
|
||||
}
|
||||
@@ -1521,7 +1535,7 @@ PHLWINDOW CWindow::getSwallower() {
|
||||
static auto PSWALLOWEXREGEX = CConfigValue<std::string>("misc:swallow_exception_regex");
|
||||
static auto PSWALLOW = CConfigValue<Hyprlang::INT>("misc:enable_swallow");
|
||||
|
||||
if (!*PSWALLOW || (*PSWALLOWREGEX).empty())
|
||||
if (!*PSWALLOW || std::string{*PSWALLOWREGEX} == STRVAL_EMPTY || (*PSWALLOWREGEX).empty())
|
||||
return nullptr;
|
||||
|
||||
// check parent
|
||||
@@ -1587,3 +1601,29 @@ bool CWindow::isX11OverrideRedirect() {
|
||||
bool CWindow::isModal() {
|
||||
return (m_pXWaylandSurface && m_pXWaylandSurface->modal);
|
||||
}
|
||||
|
||||
Vector2D CWindow::requestedMinSize() {
|
||||
if ((m_bIsX11 && !m_pXWaylandSurface->sizeHints) || (!m_bIsX11 && !m_pXDGSurface->toplevel))
|
||||
return Vector2D(1, 1);
|
||||
|
||||
Vector2D minSize = m_bIsX11 ? Vector2D(m_pXWaylandSurface->sizeHints->min_width, m_pXWaylandSurface->sizeHints->min_height) : m_pXDGSurface->toplevel->layoutMinSize();
|
||||
|
||||
minSize = minSize.clamp({1, 1});
|
||||
|
||||
return minSize;
|
||||
}
|
||||
|
||||
Vector2D CWindow::requestedMaxSize() {
|
||||
constexpr int NO_MAX_SIZE_LIMIT = 99999;
|
||||
if (((m_bIsX11 && !m_pXWaylandSurface->sizeHints) || (!m_bIsX11 && !m_pXDGSurface->toplevel) || m_sWindowData.noMaxSize.valueOrDefault()))
|
||||
return Vector2D(NO_MAX_SIZE_LIMIT, NO_MAX_SIZE_LIMIT);
|
||||
|
||||
Vector2D maxSize = m_bIsX11 ? Vector2D(m_pXWaylandSurface->sizeHints->max_width, m_pXWaylandSurface->sizeHints->max_height) : m_pXDGSurface->toplevel->layoutMaxSize();
|
||||
|
||||
if (maxSize.x < 5)
|
||||
maxSize.x = NO_MAX_SIZE_LIMIT;
|
||||
if (maxSize.y < 5)
|
||||
maxSize.y = NO_MAX_SIZE_LIMIT;
|
||||
|
||||
return maxSize;
|
||||
}
|
||||
|
@@ -144,6 +144,13 @@ class CWindowOverridableVar {
|
||||
unset(priority);
|
||||
}
|
||||
|
||||
operator std::optional<T>() {
|
||||
if (hasValue())
|
||||
return value();
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<eOverridePriority, T> values;
|
||||
T defaultValue; // used for toggling, so required for bool
|
||||
@@ -272,12 +279,12 @@ class CWindow {
|
||||
bool m_bDraggingTiled = false; // for dragging around tiled windows
|
||||
bool m_bWasMaximized = false;
|
||||
sFullscreenState m_sFullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE};
|
||||
MONITORID m_iMonitorID = -1;
|
||||
std::string m_szTitle = "";
|
||||
std::string m_szClass = "";
|
||||
std::string m_szInitialTitle = "";
|
||||
std::string m_szInitialClass = "";
|
||||
PHLWORKSPACE m_pWorkspace;
|
||||
PHLMONITORREF m_pMonitor;
|
||||
|
||||
bool m_bIsMapped = false;
|
||||
|
||||
@@ -357,6 +364,7 @@ class CWindow {
|
||||
|
||||
// swallowing
|
||||
PHLWINDOWREF m_pSwallowed;
|
||||
bool m_bGroupSwallowed = false;
|
||||
|
||||
// focus stuff
|
||||
bool m_bStayFocused = false;
|
||||
@@ -398,7 +406,6 @@ class CWindow {
|
||||
CBox getFullWindowBoundingBox();
|
||||
SBoxExtents getFullWindowExtents();
|
||||
CBox getWindowBoxUnified(uint64_t props);
|
||||
CBox getWindowMainSurfaceBox();
|
||||
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
||||
void addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco);
|
||||
void updateWindowDecos();
|
||||
@@ -424,24 +431,22 @@ class CWindow {
|
||||
float rounding();
|
||||
bool canBeTorn();
|
||||
void setSuspended(bool suspend);
|
||||
bool visibleOnMonitor(CMonitor* pMonitor);
|
||||
bool visibleOnMonitor(PHLMONITOR pMonitor);
|
||||
WORKSPACEID workspaceID();
|
||||
MONITORID monitorID();
|
||||
bool onSpecialWorkspace();
|
||||
void activate(bool force = false);
|
||||
int surfacesCount();
|
||||
|
||||
void clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize);
|
||||
bool isFullscreen();
|
||||
bool isEffectiveInternalFSMode(const eFullscreenMode);
|
||||
|
||||
int getRealBorderSize();
|
||||
void updateWindowData();
|
||||
void updateWindowData(const struct SWorkspaceRule&);
|
||||
|
||||
void onBorderAngleAnimEnd(void* ptr);
|
||||
bool isInCurvedCorner(double x, double y);
|
||||
bool hasPopupAt(const Vector2D& pos);
|
||||
int popupsCount();
|
||||
|
||||
void applyGroupRules();
|
||||
void createGroup();
|
||||
void destroyGroup();
|
||||
@@ -469,6 +474,12 @@ class CWindow {
|
||||
void unsetWindowData(eOverridePriority priority);
|
||||
bool isX11OverrideRedirect();
|
||||
bool isModal();
|
||||
Vector2D requestedMinSize();
|
||||
Vector2D requestedMaxSize();
|
||||
|
||||
inline CBox getWindowMainSurfaceBox() const {
|
||||
return {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y};
|
||||
}
|
||||
|
||||
// listeners
|
||||
void onAck(uint32_t serial);
|
||||
@@ -555,7 +566,7 @@ struct std::formatter<PHLWINDOW, CharT> : std::formatter<CharT> {
|
||||
if (formatWorkspace)
|
||||
std::format_to(out, ", workspace: {}", w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID);
|
||||
if (formatMonitor)
|
||||
std::format_to(out, ", monitor: {}", w->m_iMonitorID);
|
||||
std::format_to(out, ", monitor: {}", w->monitorID());
|
||||
if (formatClass)
|
||||
std::format_to(out, ", class: {}", w->m_szClass);
|
||||
return std::format_to(out, "]");
|
||||
|
@@ -5,14 +5,14 @@
|
||||
#include <hyprutils/string/String.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
|
||||
PHLWORKSPACE CWorkspace::create(WORKSPACEID id, MONITORID monitorID, std::string name, bool special, bool isEmpty) {
|
||||
PHLWORKSPACE workspace = makeShared<CWorkspace>(id, monitorID, name, special, isEmpty);
|
||||
PHLWORKSPACE CWorkspace::create(WORKSPACEID id, PHLMONITOR monitor, std::string name, bool special, bool isEmpty) {
|
||||
PHLWORKSPACE workspace = makeShared<CWorkspace>(id, monitor, name, special, isEmpty);
|
||||
workspace->init(workspace);
|
||||
return workspace;
|
||||
}
|
||||
|
||||
CWorkspace::CWorkspace(WORKSPACEID id, MONITORID monitorID, std::string name, bool special, bool isEmpty) {
|
||||
m_iMonitorID = monitorID;
|
||||
CWorkspace::CWorkspace(WORKSPACEID id, PHLMONITOR monitor, std::string name, bool special, bool isEmpty) {
|
||||
m_pMonitor = monitor;
|
||||
m_iID = id;
|
||||
m_szName = name;
|
||||
m_bIsSpecialWorkspace = special;
|
||||
@@ -103,7 +103,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
});
|
||||
|
||||
if (ANIMSTYLE.starts_with("slidefade")) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
float movePerc = 100.f;
|
||||
|
||||
if (ANIMSTYLE.find("%") != std::string::npos) {
|
||||
@@ -151,7 +151,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
}
|
||||
} else if (ANIMSTYLE == "slidevert") {
|
||||
// fallback is slide
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
const auto YDISTANCE = PMONITOR->vecSize.y + *PWORKSPACEGAP;
|
||||
|
||||
m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
|
||||
@@ -164,7 +164,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
}
|
||||
} else {
|
||||
// fallback is slide
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
const auto XDISTANCE = PMONITOR->vecSize.x + *PWORKSPACEGAP;
|
||||
|
||||
m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
|
||||
@@ -224,7 +224,7 @@ void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) {
|
||||
m_sPrevWorkspace.id = prev->m_iID;
|
||||
m_sPrevWorkspace.name = prev->m_szName;
|
||||
|
||||
if (prev->m_iMonitorID == m_iMonitorID) {
|
||||
if (prev->m_pMonitor == m_pMonitor) {
|
||||
m_sPrevWorkspacePerMonitor.id = prev->m_iID;
|
||||
m_sPrevWorkspacePerMonitor.name = prev->m_szName;
|
||||
}
|
||||
@@ -347,7 +347,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) {
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromString(prop);
|
||||
|
||||
if (!(PMONITOR ? PMONITOR->ID == m_iMonitorID : false))
|
||||
if (!(PMONITOR ? PMONITOR == m_pMonitor : false))
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
@@ -512,12 +512,16 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) {
|
||||
}
|
||||
|
||||
void CWorkspace::markInert() {
|
||||
m_bInert = true;
|
||||
m_iID = WORKSPACE_INVALID;
|
||||
m_iMonitorID = MONITOR_INVALID;
|
||||
m_bVisible = false;
|
||||
m_bInert = true;
|
||||
m_iID = WORKSPACE_INVALID;
|
||||
m_bVisible = false;
|
||||
m_pMonitor.reset();
|
||||
}
|
||||
|
||||
bool CWorkspace::inert() {
|
||||
return m_bInert;
|
||||
}
|
||||
|
||||
MONITORID CWorkspace::monitorID() {
|
||||
return m_pMonitor ? m_pMonitor->ID : MONITOR_INVALID;
|
||||
}
|
||||
|
@@ -17,16 +17,16 @@ class CWindow;
|
||||
|
||||
class CWorkspace {
|
||||
public:
|
||||
static PHLWORKSPACE create(WORKSPACEID id, MONITORID monitorID, std::string name, bool special = false, bool isEmpty = true);
|
||||
static PHLWORKSPACE create(WORKSPACEID id, PHLMONITOR monitor, std::string name, bool special = false, bool isEmpty = true);
|
||||
// use create() don't use this
|
||||
CWorkspace(WORKSPACEID id, MONITORID monitorID, std::string name, bool special = false, bool isEmpty = true);
|
||||
CWorkspace(WORKSPACEID id, PHLMONITOR monitor, std::string name, bool special = false, bool isEmpty = true);
|
||||
~CWorkspace();
|
||||
|
||||
// Workspaces ID-based have IDs > 0
|
||||
// and workspaces name-based have IDs starting with -1337
|
||||
WORKSPACEID m_iID = WORKSPACE_INVALID;
|
||||
std::string m_szName = "";
|
||||
MONITORID m_iMonitorID = MONITOR_INVALID;
|
||||
WORKSPACEID m_iID = WORKSPACE_INVALID;
|
||||
std::string m_szName = "";
|
||||
PHLMONITORREF m_pMonitor;
|
||||
// Previous workspace ID and name is stored during a workspace change, allowing travel
|
||||
// to the previous workspace.
|
||||
SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor;
|
||||
@@ -68,6 +68,7 @@ class CWorkspace {
|
||||
void setActive(bool on);
|
||||
|
||||
void moveToMonitor(const MONITORID&);
|
||||
MONITORID monitorID();
|
||||
|
||||
PHLWINDOW getLastFocusedWindow();
|
||||
void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace);
|
||||
|
@@ -36,5 +36,5 @@ class IHID {
|
||||
CSignal destroy;
|
||||
} events;
|
||||
|
||||
std::string deviceName;
|
||||
std::string deviceName, hlName;
|
||||
};
|
@@ -178,13 +178,18 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
||||
if (xkbState)
|
||||
xkb_state_unref(xkbState);
|
||||
|
||||
if (xkbSymState)
|
||||
xkb_state_unref(xkbSymState);
|
||||
|
||||
xkbState = nullptr;
|
||||
xkbStaticState = nullptr;
|
||||
xkbSymState = nullptr;
|
||||
|
||||
if (keymap) {
|
||||
Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
|
||||
xkbStaticState = xkb_state_new(keymap);
|
||||
xkbState = xkb_state_new(keymap);
|
||||
xkbSymState = xkb_state_new(keymap);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -230,6 +235,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
||||
|
||||
xkbState = xkb_state_new(KEYMAP);
|
||||
xkbStaticState = xkb_state_new(KEYMAP);
|
||||
xkbSymState = xkb_state_new(KEYMAP);
|
||||
|
||||
xkb_keymap_unref(KEYMAP);
|
||||
xkb_context_unref(PCONTEXT);
|
||||
@@ -252,6 +258,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
||||
|
||||
xkbState = xkb_state_new(NEWKEYMAP);
|
||||
xkbStaticState = xkb_state_new(NEWKEYMAP);
|
||||
xkbSymState = xkb_state_new(NEWKEYMAP);
|
||||
|
||||
xkb_keymap_unref(NEWKEYMAP);
|
||||
xkb_context_unref(PCONTEXT);
|
||||
@@ -332,6 +339,9 @@ void IKeyboard::updateModifiers(uint32_t depressed, uint32_t latched, uint32_t l
|
||||
|
||||
xkb_state_update_mask(xkbState, depressed, latched, locked, 0, 0, group);
|
||||
|
||||
if (xkbSymState)
|
||||
xkb_state_update_mask(xkbSymState, 0, 0, 0, 0, 0, group);
|
||||
|
||||
if (!updateModifiersState())
|
||||
return;
|
||||
|
||||
@@ -382,6 +392,9 @@ void IKeyboard::updateXkbStateWithKey(uint32_t xkbKey, bool pressed) {
|
||||
xkb_state_update_key(xkbState, xkbKey, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
|
||||
|
||||
if (updateModifiersState()) {
|
||||
if (xkbSymState)
|
||||
xkb_state_update_mask(xkbSymState, 0, 0, 0, 0, 0, modifiersState.group);
|
||||
|
||||
keyboardEvents.modifiers.emit(SModifiersEvent{
|
||||
.depressed = modifiersState.depressed,
|
||||
.latched = modifiersState.latched,
|
||||
|
@@ -82,8 +82,9 @@ class IKeyboard : public IHID {
|
||||
bool keymapOverridden = false;
|
||||
|
||||
xkb_layout_index_t activeLayout = 0;
|
||||
xkb_state * xkbState = nullptr, *xkbStaticState /* Static state: never gets modifiers or layout changes sent, used for keybinds. */ = nullptr;
|
||||
xkb_keymap* xkbKeymap = nullptr;
|
||||
xkb_state * xkbState = nullptr, *xkbStaticState /* Static state: never gets modifiers or layout changes sent, used for keybinds. */ = nullptr,
|
||||
*xkbSymState = nullptr /* Same as static but gets layouts */;
|
||||
xkb_keymap* xkbKeymap = nullptr;
|
||||
|
||||
struct {
|
||||
uint32_t depressed = 0, latched = 0, locked = 0, group = 0;
|
||||
@@ -93,7 +94,6 @@ class IKeyboard : public IHID {
|
||||
std::array<xkb_mod_index_t, 8> modIndexes = {XKB_MOD_INVALID};
|
||||
uint32_t leds = 0;
|
||||
|
||||
std::string hlName = "";
|
||||
std::string xkbFilePath = "";
|
||||
std::string xkbKeymapString = "";
|
||||
int xkbKeymapFD = -1;
|
||||
|
@@ -104,7 +104,6 @@ class IPointer : public IHID {
|
||||
CSignal holdEnd;
|
||||
} pointerEvents;
|
||||
|
||||
std::string hlName;
|
||||
bool connected = false; // means connected to the cursor
|
||||
std::string boundOutput = "";
|
||||
|
||||
|
@@ -44,7 +44,6 @@ class ITouch : public IHID {
|
||||
CSignal frame;
|
||||
} touchEvents;
|
||||
|
||||
std::string hlName = "";
|
||||
std::string boundOutput = "";
|
||||
|
||||
WP<ITouch> self;
|
||||
|
@@ -197,7 +197,7 @@ CTabletPad::CTabletPad(SP<Aquamarine::ITabletPad> pad_) : pad(pad_) {
|
||||
});
|
||||
});
|
||||
|
||||
listeners.attach = pad->events.attach.registerListener([this](std::any d) {
|
||||
listeners.attach = pad->events.attach.registerListener([](std::any d) {
|
||||
; // TODO: this doesn't do anything in aq atm
|
||||
});
|
||||
|
||||
|
@@ -92,7 +92,6 @@ class CTablet : public IHID {
|
||||
WP<CTablet> self;
|
||||
|
||||
bool relativeInput = false;
|
||||
std::string hlName = "";
|
||||
std::string boundOutput = "";
|
||||
CBox activeArea;
|
||||
CBox boundBox; // output-local
|
||||
@@ -154,8 +153,6 @@ class CTabletPad : public IHID {
|
||||
WP<CTabletPad> self;
|
||||
WP<CTabletTool> parent;
|
||||
|
||||
std::string hlName;
|
||||
|
||||
private:
|
||||
CTabletPad(SP<Aquamarine::ITabletPad> pad);
|
||||
|
||||
@@ -210,8 +207,6 @@ class CTabletTool : public IHID {
|
||||
std::vector<uint32_t> buttonsDown;
|
||||
Vector2D absolutePos; // last known absolute position.
|
||||
|
||||
std::string hlName;
|
||||
|
||||
private:
|
||||
CTabletTool(SP<Aquamarine::ITabletTool> tool);
|
||||
|
||||
|
@@ -24,12 +24,4 @@ namespace Events {
|
||||
DYNLISTENFUNC(requestMaximize);
|
||||
DYNLISTENFUNC(setOverrideRedirect);
|
||||
DYNLISTENFUNC(ackConfigure);
|
||||
|
||||
// Monitor part 2 the sequel
|
||||
DYNLISTENFUNC(monitorFrame);
|
||||
DYNLISTENFUNC(monitorStateRequest);
|
||||
DYNLISTENFUNC(monitorDamage);
|
||||
DYNLISTENFUNC(monitorNeedsFrame);
|
||||
DYNLISTENFUNC(monitorCommit);
|
||||
DYNLISTENFUNC(monitorBind);
|
||||
};
|
||||
|
@@ -1,105 +0,0 @@
|
||||
#include "../Compositor.hpp"
|
||||
#include "../helpers/WLClasses.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "Events.hpp"
|
||||
#include "../debug/HyprCtl.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../protocols/Screencopy.hpp"
|
||||
#include "../protocols/ToplevelExport.hpp"
|
||||
#include <aquamarine/output/Output.hpp>
|
||||
|
||||
// --------------------------------------------------------- //
|
||||
// __ __ ____ _ _ _____ _______ ____ _____ _____ //
|
||||
// | \/ |/ __ \| \ | |_ _|__ __/ __ \| __ \ / ____| //
|
||||
// | \ / | | | | \| | | | | | | | | | |__) | (___ //
|
||||
// | |\/| | | | | . ` | | | | | | | | | _ / \___ \ //
|
||||
// | | | | |__| | |\ |_| |_ | | | |__| | | \ \ ____) | //
|
||||
// |_| |_|\____/|_| \_|_____| |_| \____/|_| \_\_____/ //
|
||||
// //
|
||||
// --------------------------------------------------------- //
|
||||
|
||||
void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
CMonitor* const PMONITOR = (CMonitor*)owner;
|
||||
|
||||
if ((g_pCompositor->m_pAqBackend->hasSession() && !g_pCompositor->m_pAqBackend->session->active) || !g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
|
||||
Debug::log(WARN, "Attempted to render frame on inactive session!");
|
||||
|
||||
if (g_pCompositor->m_bUnsafeState && std::ranges::any_of(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& m) {
|
||||
return m->output != g_pCompositor->m_pUnsafeOutput->output;
|
||||
})) {
|
||||
// restore from unsafe state
|
||||
g_pCompositor->leaveUnsafeState();
|
||||
}
|
||||
|
||||
return; // cannot draw on session inactive (different tty)
|
||||
}
|
||||
|
||||
if (!PMONITOR->m_bEnabled)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->recheckSolitaryForMonitor(PMONITOR);
|
||||
|
||||
PMONITOR->tearingState.busy = false;
|
||||
|
||||
if (PMONITOR->tearingState.activelyTearing && PMONITOR->solitaryClient.lock() /* can be invalidated by a recheck */) {
|
||||
|
||||
if (!PMONITOR->tearingState.frameScheduledWhileBusy)
|
||||
return; // we did not schedule a frame yet to be displayed, but we are tearing. Why render?
|
||||
|
||||
PMONITOR->tearingState.nextRenderTorn = true;
|
||||
PMONITOR->tearingState.frameScheduledWhileBusy = false;
|
||||
}
|
||||
|
||||
static auto PENABLERAT = CConfigValue<Hyprlang::INT>("misc:render_ahead_of_time");
|
||||
static auto PRATSAFE = CConfigValue<Hyprlang::INT>("misc:render_ahead_safezone");
|
||||
|
||||
PMONITOR->lastPresentationTimer.reset();
|
||||
|
||||
if (*PENABLERAT && !PMONITOR->tearingState.nextRenderTorn) {
|
||||
if (!PMONITOR->RATScheduled) {
|
||||
// render
|
||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
||||
}
|
||||
|
||||
PMONITOR->RATScheduled = false;
|
||||
|
||||
const auto& [avg, max, min] = g_pHyprRenderer->getRenderTimes(PMONITOR);
|
||||
|
||||
if (max + *PRATSAFE > 1000.0 / PMONITOR->refreshRate)
|
||||
return;
|
||||
|
||||
const auto MSLEFT = 1000.0 / PMONITOR->refreshRate - PMONITOR->lastPresentationTimer.getMillis();
|
||||
|
||||
PMONITOR->RATScheduled = true;
|
||||
|
||||
const auto ESTRENDERTIME = std::ceil(avg + *PRATSAFE);
|
||||
const auto TIMETOSLEEP = std::floor(MSLEFT - ESTRENDERTIME);
|
||||
|
||||
if (MSLEFT < 1 || MSLEFT < ESTRENDERTIME || TIMETOSLEEP < 1)
|
||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
||||
else
|
||||
wl_event_source_timer_update(PMONITOR->renderTimer, TIMETOSLEEP);
|
||||
} else {
|
||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
||||
}
|
||||
}
|
||||
|
||||
void Events::listener_monitorNeedsFrame(void* owner, void* data) {
|
||||
const auto PMONITOR = (CMonitor*)owner;
|
||||
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME);
|
||||
}
|
||||
|
||||
void Events::listener_monitorCommit(void* owner, void* data) {
|
||||
const auto PMONITOR = (CMonitor*)owner;
|
||||
|
||||
if (true) { // FIXME: E->state->committed & WLR_OUTPUT_STATE_BUFFER
|
||||
PROTO::screencopy->onOutputCommit(PMONITOR);
|
||||
PROTO::toplevelExport->onOutputCommit(PMONITOR);
|
||||
}
|
||||
}
|
||||
|
||||
void Events::listener_monitorBind(void* owner, void* data) {
|
||||
;
|
||||
}
|
@@ -12,6 +12,7 @@
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../protocols/ToplevelExport.hpp"
|
||||
#include "../xwayland/XSurface.hpp"
|
||||
#include "managers/PointerManager.hpp"
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
@@ -43,18 +44,16 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
static auto PINACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:inactive_opacity");
|
||||
static auto PACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:active_opacity");
|
||||
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
|
||||
static auto PSWALLOW = CConfigValue<Hyprlang::INT>("misc:enable_swallow");
|
||||
static auto PSWALLOWREGEX = CConfigValue<std::string>("misc:swallow_regex");
|
||||
static auto PNEWTAKESOVERFS = CConfigValue<Hyprlang::INT>("misc:new_window_takes_over_fullscreen");
|
||||
static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
|
||||
|
||||
auto PMONITOR = g_pCompositor->m_pLastMonitor.get();
|
||||
auto PMONITOR = g_pCompositor->m_pLastMonitor.lock();
|
||||
if (!g_pCompositor->m_pLastMonitor) {
|
||||
g_pCompositor->setActiveMonitor(g_pCompositor->getMonitorFromVector({}));
|
||||
PMONITOR = g_pCompositor->m_pLastMonitor.get();
|
||||
PMONITOR = g_pCompositor->m_pLastMonitor.lock();
|
||||
}
|
||||
auto PWORKSPACE = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace;
|
||||
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
PWINDOW->m_pMonitor = PMONITOR;
|
||||
PWINDOW->m_pWorkspace = PWORKSPACE;
|
||||
PWINDOW->m_bIsMapped = true;
|
||||
PWINDOW->m_bReadyToDelete = false;
|
||||
@@ -145,18 +144,18 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
const auto MONITORSTR = trim(r.szRule.substr(r.szRule.find(' ')));
|
||||
|
||||
if (MONITORSTR == "unset") {
|
||||
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
PWINDOW->m_pMonitor = PMONITOR;
|
||||
} else {
|
||||
if (isNumber(MONITORSTR)) {
|
||||
const MONITORID MONITOR = std::stoi(MONITORSTR);
|
||||
if (!g_pCompositor->getMonitorFromID(MONITOR))
|
||||
PWINDOW->m_iMonitorID = 0;
|
||||
if (const auto PM = g_pCompositor->getMonitorFromID(MONITOR); PM)
|
||||
PWINDOW->m_pMonitor = PM;
|
||||
else
|
||||
PWINDOW->m_iMonitorID = MONITOR;
|
||||
PWINDOW->m_pMonitor = g_pCompositor->m_vMonitors.at(0);
|
||||
} else {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromName(MONITORSTR);
|
||||
if (PMONITOR)
|
||||
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
PWINDOW->m_pMonitor = PMONITOR;
|
||||
else {
|
||||
Debug::log(ERR, "No monitor in monitor {} rule", MONITORSTR);
|
||||
continue;
|
||||
@@ -164,10 +163,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
}
|
||||
}
|
||||
|
||||
const auto PMONITORFROMID = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
const auto PMONITORFROMID = PWINDOW->m_pMonitor.lock();
|
||||
|
||||
if (PWINDOW->m_iMonitorID != PMONITOR->ID) {
|
||||
g_pKeybindManager->m_mDispatchers["focusmonitor"](std::to_string(PWINDOW->m_iMonitorID));
|
||||
if (PWINDOW->m_pMonitor != PMONITOR) {
|
||||
g_pKeybindManager->m_mDispatchers["focusmonitor"](std::to_string(PWINDOW->monitorID()));
|
||||
PMONITOR = PMONITORFROMID;
|
||||
}
|
||||
PWINDOW->m_pWorkspace = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace;
|
||||
@@ -297,23 +296,23 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
auto pWorkspace = g_pCompositor->getWorkspaceByID(REQUESTEDWORKSPACEID);
|
||||
|
||||
if (!pWorkspace)
|
||||
pWorkspace = g_pCompositor->createNewWorkspace(REQUESTEDWORKSPACEID, PWINDOW->m_iMonitorID, requestedWorkspaceName);
|
||||
pWorkspace = g_pCompositor->createNewWorkspace(REQUESTEDWORKSPACEID, PWINDOW->monitorID(), requestedWorkspaceName, false);
|
||||
|
||||
PWORKSPACE = pWorkspace;
|
||||
|
||||
PWINDOW->m_pWorkspace = pWorkspace;
|
||||
PWINDOW->m_iMonitorID = pWorkspace->m_iMonitorID;
|
||||
PWINDOW->m_pMonitor = pWorkspace->m_pMonitor;
|
||||
|
||||
if (g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeSpecialWorkspace && !pWorkspace->m_bIsSpecialWorkspace)
|
||||
if (PWINDOW->m_pMonitor.lock()->activeSpecialWorkspace && !pWorkspace->m_bIsSpecialWorkspace)
|
||||
workspaceSilent = true;
|
||||
|
||||
if (!workspaceSilent) {
|
||||
if (pWorkspace->m_bIsSpecialWorkspace)
|
||||
g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID)->setSpecialWorkspace(pWorkspace);
|
||||
pWorkspace->m_pMonitor->setSpecialWorkspace(pWorkspace);
|
||||
else if (PMONITOR->activeWorkspaceID() != REQUESTEDWORKSPACEID)
|
||||
g_pKeybindManager->m_mDispatchers["workspace"](requestedWorkspaceName);
|
||||
|
||||
PMONITOR = g_pCompositor->m_pLastMonitor.get();
|
||||
PMONITOR = g_pCompositor->m_pLastMonitor.lock();
|
||||
}
|
||||
} else
|
||||
workspaceSilent = false;
|
||||
@@ -321,6 +320,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
PWINDOW->updateWindowData();
|
||||
|
||||
// Verify window swallowing. Get the swallower before calling onWindowCreated(PWINDOW) because getSwallower() wouldn't get it after if PWINDOW gets auto grouped.
|
||||
const auto SWALLOWER = PWINDOW->getSwallower();
|
||||
PWINDOW->m_pSwallowed = SWALLOWER;
|
||||
|
||||
if (PWINDOW->m_bIsFloating) {
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
|
||||
PWINDOW->m_bCreatedOverFullscreen = true;
|
||||
@@ -329,24 +332,31 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
for (auto const& r : PWINDOW->m_vMatchedRules) {
|
||||
if (r.szRule.starts_with("size")) {
|
||||
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 MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW);
|
||||
auto stringToFloatClamp = [](const std::string& VALUE, const float CURR, const float REL) {
|
||||
if (VALUE.starts_with('<'))
|
||||
return std::min(CURR, stringToPercentage(VALUE.substr(1, VALUE.length() - 1), REL));
|
||||
else if (VALUE.starts_with('>'))
|
||||
return std::max(CURR, stringToPercentage(VALUE.substr(1, VALUE.length() - 1), REL));
|
||||
|
||||
const auto SIZEX = SIZEXSTR == "max" ?
|
||||
std::clamp(MAXSIZE.x, 20.0, PMONITOR->vecSize.x) :
|
||||
(!SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stof(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.x);
|
||||
const auto SIZEY = SIZEYSTR == "max" ?
|
||||
std::clamp(MAXSIZE.y, 20.0, PMONITOR->vecSize.y) :
|
||||
(!SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stof(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y);
|
||||
return stringToPercentage(VALUE, REL);
|
||||
};
|
||||
|
||||
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 MAXSIZE = PWINDOW->requestedMaxSize();
|
||||
|
||||
const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, PMONITOR->vecSize.x) :
|
||||
stringToFloatClamp(SIZEXSTR, PWINDOW->m_vRealSize.goal().x, PMONITOR->vecSize.x);
|
||||
|
||||
const float SIZEY = SIZEYSTR == "max" ? std::clamp(MAXSIZE.y, MIN_WINDOW_SIZE, PMONITOR->vecSize.y) :
|
||||
stringToFloatClamp(SIZEYSTR, PWINDOW->m_vRealSize.goal().y, PMONITOR->vecSize.y);
|
||||
|
||||
Debug::log(LOG, "Rule size, applying to {}", PWINDOW);
|
||||
|
||||
PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY);
|
||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal();
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
|
||||
PWINDOW->clampWindowSize(Vector2D{SIZEXSTR.starts_with("<") ? 0 : SIZEX, SIZEYSTR.starts_with("<") ? 0 : SIZEY}, Vector2D{SIZEX, SIZEY});
|
||||
|
||||
PWINDOW->setHidden(false);
|
||||
} catch (...) { Debug::log(LOG, "Rule size failed, rule: {} -> {}", r.szRule, r.szValue); }
|
||||
@@ -455,18 +465,15 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
for (auto const& r : PWINDOW->m_vMatchedRules) {
|
||||
if (r.szRule.starts_with("size")) {
|
||||
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 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 MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW);
|
||||
const auto MAXSIZE = PWINDOW->requestedMaxSize();
|
||||
|
||||
const auto SIZEX = SIZEXSTR == "max" ?
|
||||
std::clamp(MAXSIZE.x, 20.0, PMONITOR->vecSize.x) :
|
||||
(!SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stof(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.x);
|
||||
const auto SIZEY = SIZEYSTR == "max" ?
|
||||
std::clamp(MAXSIZE.y, 20.0, PMONITOR->vecSize.y) :
|
||||
(!SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stof(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y);
|
||||
const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, PMONITOR->vecSize.x) : stringToPercentage(SIZEXSTR, PMONITOR->vecSize.x);
|
||||
|
||||
const float SIZEY = SIZEYSTR == "max" ? std::clamp(MAXSIZE.y, MIN_WINDOW_SIZE, PMONITOR->vecSize.y) : stringToPercentage(SIZEYSTR, PMONITOR->vecSize.y);
|
||||
|
||||
Debug::log(LOG, "Rule size (tiled), applying to {}", PWINDOW);
|
||||
|
||||
@@ -552,20 +559,12 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
g_pCompositor->focusWindow(nullptr);
|
||||
}
|
||||
|
||||
// verify swallowing
|
||||
if (*PSWALLOW && std::string{*PSWALLOWREGEX} != STRVAL_EMPTY) {
|
||||
const auto SWALLOWER = PWINDOW->getSwallower();
|
||||
|
||||
if (SWALLOWER) {
|
||||
// swallow
|
||||
PWINDOW->m_pSwallowed = SWALLOWER;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(SWALLOWER);
|
||||
|
||||
SWALLOWER->setHidden(true);
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
|
||||
}
|
||||
// swallow
|
||||
if (SWALLOWER) {
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(SWALLOWER);
|
||||
g_pHyprRenderer->damageWindow(SWALLOWER);
|
||||
SWALLOWER->setHidden(true);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID());
|
||||
}
|
||||
|
||||
PWINDOW->m_bFirstMap = false;
|
||||
@@ -626,7 +625,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
if (PMONITOR) {
|
||||
PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.value() - PMONITOR->vecPosition;
|
||||
PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.value();
|
||||
@@ -647,7 +646,13 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
// swallowing
|
||||
if (valid(PWINDOW->m_pSwallowed)) {
|
||||
PWINDOW->m_pSwallowed->setHidden(false);
|
||||
|
||||
if (PWINDOW->m_sGroupData.pNextWindow.lock())
|
||||
PWINDOW->m_pSwallowed->m_bGroupSwallowed = true; // flag for the swallowed window to be created into the group where it belongs when auto_group = false.
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW->m_pSwallowed.lock());
|
||||
|
||||
PWINDOW->m_pSwallowed->m_bGroupSwallowed = false;
|
||||
PWINDOW->m_pSwallowed.reset();
|
||||
}
|
||||
|
||||
@@ -672,6 +677,8 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
|
||||
// do this after onWindowRemoved because otherwise it'll think the window is invalid
|
||||
PWINDOW->m_bIsMapped = false;
|
||||
|
||||
@@ -711,8 +718,6 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
|
||||
g_pCompositor->addToFadingOutSafe(PWINDOW);
|
||||
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID));
|
||||
|
||||
if (!PWINDOW->m_bX11DoesntWantBorders) // don't animate out if they weren't animated in.
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.value() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it
|
||||
|
||||
@@ -748,36 +753,33 @@ void Events::listener_commitWindow(void* owner, void* data) {
|
||||
PWINDOW->m_vReportedSize = PWINDOW->m_vPendingReportedSize; // apply pending size. We pinged, the window ponged.
|
||||
|
||||
if (!PWINDOW->m_bIsX11 && !PWINDOW->isFullscreen() && PWINDOW->m_bIsFloating) {
|
||||
const auto MINSIZE = PWINDOW->m_pXDGSurface->toplevel->current.minSize;
|
||||
const auto MAXSIZE = PWINDOW->m_pXDGSurface->toplevel->current.maxSize;
|
||||
const auto MINSIZE = PWINDOW->m_pXDGSurface->toplevel->layoutMinSize();
|
||||
const auto MAXSIZE = PWINDOW->m_pXDGSurface->toplevel->layoutMaxSize();
|
||||
|
||||
if (MAXSIZE > Vector2D{1, 1}) {
|
||||
const auto REALSIZE = PWINDOW->m_vRealSize.goal();
|
||||
Vector2D newSize = REALSIZE;
|
||||
|
||||
if (MAXSIZE.x < newSize.x)
|
||||
newSize.x = MAXSIZE.x;
|
||||
if (MAXSIZE.y < newSize.y)
|
||||
newSize.y = MAXSIZE.y;
|
||||
if (MINSIZE.x > newSize.x)
|
||||
newSize.x = MINSIZE.x;
|
||||
if (MINSIZE.y > newSize.y)
|
||||
newSize.y = MINSIZE.y;
|
||||
|
||||
const Vector2D DELTA = REALSIZE - newSize;
|
||||
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + DELTA / 2.0;
|
||||
PWINDOW->m_vRealSize = newSize;
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, newSize);
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
PWINDOW->clampWindowSize(MINSIZE, MAXSIZE > Vector2D{1, 1} ? std::optional<Vector2D>{MAXSIZE} : std::nullopt);
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
|
||||
if (!PWINDOW->m_pWorkspace->m_bVisible)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface->resource(), PWINDOW->m_vRealPosition.goal().x, PWINDOW->m_vRealPosition.goal().y,
|
||||
PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0);
|
||||
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
|
||||
if (PMONITOR)
|
||||
PMONITOR->debugLastPresentation(g_pSeatManager->isPointerFrameCommit ? "listener_commitWindow skip" : "listener_commitWindow");
|
||||
|
||||
if (g_pSeatManager->isPointerFrameCommit) {
|
||||
g_pSeatManager->isPointerFrameSkipped = false;
|
||||
g_pSeatManager->isPointerFrameCommit = false;
|
||||
} else
|
||||
g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface->resource(), PWINDOW->m_vRealPosition.goal().x, PWINDOW->m_vRealPosition.goal().y,
|
||||
PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0);
|
||||
|
||||
if (g_pSeatManager->isPointerFrameSkipped) {
|
||||
g_pPointerManager->sendStoredMovement();
|
||||
g_pSeatManager->sendPointerFrame();
|
||||
g_pSeatManager->isPointerFrameCommit = true;
|
||||
}
|
||||
|
||||
if (!PWINDOW->m_bIsX11) {
|
||||
PWINDOW->m_pSubsurfaceHead->recheckDamageForSubsurfaces();
|
||||
@@ -785,7 +787,6 @@ void Events::listener_commitWindow(void* owner, void* data) {
|
||||
}
|
||||
|
||||
// tearing: if solitary, redraw it. This still might be a single surface window
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
if (PMONITOR && PMONITOR->solitaryClient.lock() == PWINDOW && PWINDOW->canBeTorn() && PMONITOR->tearingState.canTear && PWINDOW->m_pWLSurface->resource()->current.texture) {
|
||||
CRegion damageBox{PWINDOW->m_pWLSurface->resource()->accumulateCurrentBufferDamage()};
|
||||
|
||||
@@ -900,7 +901,7 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_pXWaylandSurface->geometry.size());
|
||||
|
||||
if (*PXWLFORCESCALEZERO) {
|
||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR) {
|
||||
if (const auto PMONITOR = PWINDOW->m_pMonitor.lock(); PMONITOR) {
|
||||
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goal() / PMONITOR->scale);
|
||||
}
|
||||
}
|
||||
|
@@ -302,7 +302,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||
|
||||
// Collect all the workspaces we can't jump to.
|
||||
for (auto const& ws : g_pCompositor->m_vWorkspaces) {
|
||||
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)) {
|
||||
if (ws->m_bIsSpecialWorkspace || (ws->m_pMonitor != g_pCompositor->m_pLastMonitor)) {
|
||||
// Can't jump to this workspace
|
||||
invalidWSes.insert(ws->m_iID);
|
||||
}
|
||||
@@ -320,7 +320,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||
// Prepare all named workspaces in case when we need them
|
||||
std::vector<WORKSPACEID> namedWSes;
|
||||
for (auto const& ws : g_pCompositor->m_vWorkspaces) {
|
||||
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID) || ws->m_iID >= 0)
|
||||
if (ws->m_bIsSpecialWorkspace || (ws->m_pMonitor != g_pCompositor->m_pLastMonitor) || ws->m_iID >= 0)
|
||||
continue;
|
||||
|
||||
namedWSes.push_back(ws->m_iID);
|
||||
@@ -464,7 +464,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||
|
||||
std::vector<WORKSPACEID> validWSes;
|
||||
for (auto const& ws : g_pCompositor->m_vWorkspaces) {
|
||||
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID && !onAllMonitors))
|
||||
if (ws->m_bIsSpecialWorkspace || (ws->m_pMonitor != g_pCompositor->m_pLastMonitor && !onAllMonitors))
|
||||
continue;
|
||||
|
||||
validWSes.push_back(ws->m_iID);
|
||||
@@ -610,7 +610,7 @@ void logSystemInfo() {
|
||||
Debug::log(NONE, "\n");
|
||||
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
const std::string GPUINFO = execAndGet("pciconf -lv | fgrep -A4 vga");
|
||||
const std::string GPUINFO = execAndGet("pciconf -lv | grep -F -A4 vga");
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
const std::string GPUINFO = execAndGet("cat /proc/device-tree/soc*/gpu*/compatible");
|
||||
#else
|
||||
@@ -863,3 +863,10 @@ bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr) {
|
||||
*ro_fd_ptr = ro_fd;
|
||||
return true;
|
||||
}
|
||||
|
||||
float stringToPercentage(const std::string& VALUE, const float REL) {
|
||||
if (VALUE.ends_with('%'))
|
||||
return (std::stof(VALUE.substr(0, VALUE.length() - 1)) * REL) / 100.f;
|
||||
else
|
||||
return std::stof(VALUE);
|
||||
};
|
||||
|
@@ -40,6 +40,7 @@ void throwError(const std::string& err);
|
||||
bool envEnabled(const std::string& env);
|
||||
int allocateSHMFile(size_t len);
|
||||
bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr);
|
||||
float stringToPercentage(const std::string& VALUE, const float REL);
|
||||
|
||||
template <typename... Args>
|
||||
[[deprecated("use std::format instead")]] std::string getFormat(std::format_string<Args...> fmt, Args&&... args) {
|
||||
|
@@ -11,18 +11,21 @@
|
||||
#include "../protocols/DRMLease.hpp"
|
||||
#include "../protocols/DRMSyncobj.hpp"
|
||||
#include "../protocols/core/Output.hpp"
|
||||
#include "../protocols/Screencopy.hpp"
|
||||
#include "../protocols/ToplevelExport.hpp"
|
||||
#include "../managers/PointerManager.hpp"
|
||||
#include "../managers/eventLoop/EventLoopManager.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "sync/SyncTimeline.hpp"
|
||||
#include <aquamarine/output/Output.hpp>
|
||||
#include "debug/Log.hpp"
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <hyprutils/utils/ScopeGuard.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
using namespace Hyprutils::Utils;
|
||||
|
||||
int ratHandler(void* data) {
|
||||
g_pHyprRenderer->renderMonitor((CMonitor*)data);
|
||||
g_pHyprRenderer->renderMonitor(((CMonitor*)data)->self.lock());
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -43,10 +46,15 @@ void CMonitor::onConnect(bool noRule) {
|
||||
outTimeline = CSyncTimeline::create(output->getBackend()->drmFD());
|
||||
}
|
||||
|
||||
listeners.frame = output->events.frame.registerListener([this](std::any d) { Events::listener_monitorFrame(this, nullptr); });
|
||||
listeners.commit = output->events.commit.registerListener([this](std::any d) { Events::listener_monitorCommit(this, nullptr); });
|
||||
listeners.frame = output->events.frame.registerListener([this](std::any d) { onMonitorFrame(); });
|
||||
listeners.commit = output->events.commit.registerListener([this](std::any d) {
|
||||
if (true) { // FIXME: E->state->committed & WLR_OUTPUT_STATE_BUFFER
|
||||
PROTO::screencopy->onOutputCommit(self.lock());
|
||||
PROTO::toplevelExport->onOutputCommit(self.lock());
|
||||
}
|
||||
});
|
||||
listeners.needsFrame =
|
||||
output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); });
|
||||
output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); });
|
||||
|
||||
listeners.presented = output->events.present.registerListener([this](std::any d) {
|
||||
auto E = std::any_cast<Aquamarine::IOutput::SPresentEvent>(d);
|
||||
@@ -63,7 +71,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
|
||||
Debug::log(LOG, "Removing monitor {} from realMonitors", szName);
|
||||
|
||||
std::erase_if(g_pCompositor->m_vRealMonitors, [&](SP<CMonitor>& el) { return el.get() == this; });
|
||||
std::erase_if(g_pCompositor->m_vRealMonitors, [&](PHLMONITOR& el) { return el.get() == this; });
|
||||
});
|
||||
|
||||
listeners.state = output->events.state.registerListener([this](std::any d) {
|
||||
@@ -76,7 +84,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
return;
|
||||
|
||||
Debug::log(LOG, "Reapplying monitor rule for {} from a state request", szName);
|
||||
g_pHyprRenderer->applyMonitorRule(this, &activeMonitorRule, true);
|
||||
g_pHyprRenderer->applyMonitorRule(self.lock(), &activeMonitorRule, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -90,7 +98,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
SMonitorRule rule = activeMonitorRule;
|
||||
rule.resolution = SIZE;
|
||||
|
||||
g_pHyprRenderer->applyMonitorRule(this, &rule);
|
||||
g_pHyprRenderer->applyMonitorRule(self.lock(), &rule);
|
||||
});
|
||||
|
||||
tearingState.canTear = output->getBackend()->type() == Aquamarine::AQ_BACKEND_DRM;
|
||||
@@ -141,7 +149,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
return;
|
||||
}
|
||||
|
||||
SP<CMonitor>* thisWrapper = nullptr;
|
||||
PHLMONITOR* thisWrapper = nullptr;
|
||||
|
||||
// find the wrap
|
||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||
@@ -163,7 +171,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
|
||||
// set mode, also applies
|
||||
if (!noRule)
|
||||
g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true);
|
||||
g_pHyprRenderer->applyMonitorRule(self.lock(), &monitorRule, true);
|
||||
|
||||
if (!state.commit())
|
||||
Debug::log(WARN, "state.commit() failed in CMonitor::onCommit");
|
||||
@@ -179,7 +187,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
continue;
|
||||
|
||||
if (ws->m_szLastMonitor == szName || g_pCompositor->m_vMonitors.size() == 1 /* avoid lost workspaces on recover */) {
|
||||
g_pCompositor->moveWorkspaceToMonitor(ws, this);
|
||||
g_pCompositor->moveWorkspaceToMonitor(ws, self.lock());
|
||||
ws->startAnim(true, true, true);
|
||||
ws->m_szLastMonitor = "";
|
||||
}
|
||||
@@ -196,13 +204,13 @@ void CMonitor::onConnect(bool noRule) {
|
||||
setMirror(activeMonitorRule.mirrorOf);
|
||||
|
||||
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
|
||||
g_pCompositor->setActiveMonitor(this);
|
||||
g_pCompositor->setActiveMonitor(self.lock());
|
||||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(ID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
|
||||
|
||||
// ensure VRR (will enable if necessary)
|
||||
g_pConfigManager->ensureVRR(this);
|
||||
g_pConfigManager->ensureVRR(self.lock());
|
||||
|
||||
// verify last mon valid
|
||||
bool found = false;
|
||||
@@ -214,19 +222,19 @@ void CMonitor::onConnect(bool noRule) {
|
||||
}
|
||||
|
||||
if (!found)
|
||||
g_pCompositor->setActiveMonitor(this);
|
||||
g_pCompositor->setActiveMonitor(self.lock());
|
||||
|
||||
renderTimer = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, ratHandler, this);
|
||||
|
||||
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_NEW_MONITOR);
|
||||
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEW_MONITOR);
|
||||
|
||||
PROTO::gamma->applyGammaToState(this);
|
||||
PROTO::gamma->applyGammaToState(self.lock());
|
||||
|
||||
events.connect.emit();
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", szName});
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitoraddedv2", std::format("{},{},{}", ID, szName, szShortDescription)});
|
||||
EMIT_HOOK_EVENT("monitorAdded", this);
|
||||
EMIT_HOOK_EVENT("monitorAdded", self.lock());
|
||||
}
|
||||
|
||||
void CMonitor::onDisconnect(bool destroy) {
|
||||
@@ -234,7 +242,7 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||
if (g_pCompositor->m_bIsShuttingDown)
|
||||
return;
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitorremoved", szName});
|
||||
EMIT_HOOK_EVENT("monitorRemoved", this);
|
||||
EMIT_HOOK_EVENT("monitorRemoved", self.lock());
|
||||
g_pCompositor->arrangeMonitors();
|
||||
}};
|
||||
|
||||
@@ -251,21 +259,21 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||
events.disconnect.emit();
|
||||
|
||||
// Cleanup everything. Move windows back, snap cursor, shit.
|
||||
CMonitor* BACKUPMON = nullptr;
|
||||
PHLMONITOR BACKUPMON = nullptr;
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
if (m.get() != this) {
|
||||
BACKUPMON = m.get();
|
||||
BACKUPMON = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// remove mirror
|
||||
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 == self; }));
|
||||
|
||||
// unlock software for mirrored monitor
|
||||
g_pPointerManager->unlockSoftwareForMonitor(pMirrorOf);
|
||||
pMirrorOf = nullptr;
|
||||
g_pPointerManager->unlockSoftwareForMonitor(pMirrorOf.lock());
|
||||
pMirrorOf.reset();
|
||||
}
|
||||
|
||||
if (!mirrors.empty()) {
|
||||
@@ -306,9 +314,8 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||
// move workspaces
|
||||
std::deque<PHLWORKSPACE> wspToMove;
|
||||
for (auto const& w : g_pCompositor->m_vWorkspaces) {
|
||||
if (w->m_iMonitorID == ID || !g_pCompositor->getMonitorFromID(w->m_iMonitorID)) {
|
||||
if (w->m_pMonitor == self || !w->m_pMonitor)
|
||||
wspToMove.push_back(w);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& w : wspToMove) {
|
||||
@@ -327,37 +334,38 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||
activeWorkspace.reset();
|
||||
|
||||
output->state->resetExplicitFences();
|
||||
output->state->setAdaptiveSync(false);
|
||||
output->state->setEnabled(false);
|
||||
|
||||
if (!state.commit())
|
||||
Debug::log(WARN, "state.commit() failed in CMonitor::onDisconnect");
|
||||
|
||||
if (g_pCompositor->m_pLastMonitor.get() == this)
|
||||
g_pCompositor->setActiveMonitor(BACKUPMON ? BACKUPMON : g_pCompositor->m_pUnsafeOutput);
|
||||
if (g_pCompositor->m_pLastMonitor == self)
|
||||
g_pCompositor->setActiveMonitor(BACKUPMON ? BACKUPMON : g_pCompositor->m_pUnsafeOutput.lock());
|
||||
|
||||
if (g_pHyprRenderer->m_pMostHzMonitor == this) {
|
||||
int mostHz = 0;
|
||||
CMonitor* pMonitorMostHz = nullptr;
|
||||
if (g_pHyprRenderer->m_pMostHzMonitor == self) {
|
||||
int mostHz = 0;
|
||||
PHLMONITOR pMonitorMostHz = nullptr;
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->refreshRate > mostHz && m.get() != this) {
|
||||
pMonitorMostHz = m.get();
|
||||
if (m->refreshRate > mostHz && m != self) {
|
||||
pMonitorMostHz = m;
|
||||
mostHz = m->refreshRate;
|
||||
}
|
||||
}
|
||||
|
||||
g_pHyprRenderer->m_pMostHzMonitor = pMonitorMostHz;
|
||||
}
|
||||
std::erase_if(g_pCompositor->m_vMonitors, [&](SP<CMonitor>& el) { return el.get() == this; });
|
||||
std::erase_if(g_pCompositor->m_vMonitors, [&](PHLMONITOR& el) { return el.get() == this; });
|
||||
}
|
||||
|
||||
void CMonitor::addDamage(const pixman_region32_t* rg) {
|
||||
static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
|
||||
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
|
||||
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == self) {
|
||||
damage.damageEntire();
|
||||
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
} else if (damage.damage(rg))
|
||||
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
}
|
||||
|
||||
void CMonitor::addDamage(const CRegion* rg) {
|
||||
@@ -366,13 +374,13 @@ void CMonitor::addDamage(const CRegion* rg) {
|
||||
|
||||
void CMonitor::addDamage(const CBox* box) {
|
||||
static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
|
||||
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
|
||||
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == self) {
|
||||
damage.damageEntire();
|
||||
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
}
|
||||
|
||||
if (damage.damage(*box))
|
||||
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
}
|
||||
|
||||
bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
|
||||
@@ -384,7 +392,7 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
|
||||
*PNOBREAK && output->state->state().adaptiveSync && activeWorkspace && activeWorkspace->m_bHasFullscreenWindow && activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN;
|
||||
|
||||
// keep requested minimum refresh rate
|
||||
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000 / *PMINRR) {
|
||||
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) {
|
||||
// damage whole screen because some previous cursor box damages were skipped
|
||||
damage.damageEntire();
|
||||
return false;
|
||||
@@ -448,7 +456,7 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
|
||||
|
||||
if (PNEWWORKSPACE) {
|
||||
// workspace exists, move it to the newly connected monitor
|
||||
g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, this);
|
||||
g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, self.lock());
|
||||
activeWorkspace = PNEWWORKSPACE;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
|
||||
PNEWWORKSPACE->startAnim(true, true, true);
|
||||
@@ -456,7 +464,7 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
|
||||
if (newDefaultWorkspaceName == "")
|
||||
newDefaultWorkspaceName = std::to_string(wsID);
|
||||
|
||||
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(CWorkspace::create(wsID, ID, newDefaultWorkspaceName));
|
||||
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(CWorkspace::create(wsID, self.lock(), newDefaultWorkspaceName));
|
||||
}
|
||||
|
||||
activeWorkspace = PNEWWORKSPACE;
|
||||
@@ -477,7 +485,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PMIRRORMON == this) {
|
||||
if (PMIRRORMON == self) {
|
||||
Debug::log(ERR, "Cannot mirror self!");
|
||||
return;
|
||||
}
|
||||
@@ -486,13 +494,13 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||
// disable mirroring
|
||||
|
||||
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 == self; }));
|
||||
|
||||
// unlock software for mirrored monitor
|
||||
g_pPointerManager->unlockSoftwareForMonitor(pMirrorOf);
|
||||
g_pPointerManager->unlockSoftwareForMonitor(pMirrorOf.lock());
|
||||
}
|
||||
|
||||
pMirrorOf = nullptr;
|
||||
pMirrorOf.reset();
|
||||
|
||||
// set rule
|
||||
const auto RULE = g_pConfigManager->getMonitorRuleFor(self.lock());
|
||||
@@ -501,7 +509,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||
|
||||
// push to mvmonitors
|
||||
|
||||
SP<CMonitor>* thisWrapper = nullptr;
|
||||
PHLMONITOR* thisWrapper = nullptr;
|
||||
|
||||
// find the wrap
|
||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||
@@ -520,12 +528,12 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||
|
||||
setupDefaultWS(RULE);
|
||||
|
||||
g_pHyprRenderer->applyMonitorRule(this, (SMonitorRule*)&RULE, true); // will apply the offset and stuff
|
||||
g_pHyprRenderer->applyMonitorRule(self.lock(), (SMonitorRule*)&RULE, true); // will apply the offset and stuff
|
||||
} else {
|
||||
CMonitor* BACKUPMON = nullptr;
|
||||
PHLMONITOR BACKUPMON = nullptr;
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
if (m.get() != this) {
|
||||
BACKUPMON = m.get();
|
||||
BACKUPMON = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -533,9 +541,8 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||
// move all the WS
|
||||
std::deque<PHLWORKSPACE> wspToMove;
|
||||
for (auto const& w : g_pCompositor->m_vWorkspaces) {
|
||||
if (w->m_iMonitorID == ID) {
|
||||
if (w->m_pMonitor == self || !w->m_pMonitor)
|
||||
wspToMove.push_back(w);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& w : wspToMove) {
|
||||
@@ -549,14 +556,14 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||
|
||||
pMirrorOf = PMIRRORMON;
|
||||
|
||||
pMirrorOf->mirrors.push_back(this);
|
||||
pMirrorOf->mirrors.push_back(self);
|
||||
|
||||
// remove from mvmonitors
|
||||
std::erase_if(g_pCompositor->m_vMonitors, [&](const auto& other) { return other.get() == this; });
|
||||
std::erase_if(g_pCompositor->m_vMonitors, [&](const auto& other) { return other == self; });
|
||||
|
||||
g_pCompositor->arrangeMonitors();
|
||||
|
||||
g_pCompositor->setActiveMonitor(g_pCompositor->m_vMonitors.front().get());
|
||||
g_pCompositor->setActiveMonitor(g_pCompositor->m_vMonitors.front());
|
||||
|
||||
g_pCompositor->sanityCheckWorkspaces();
|
||||
|
||||
@@ -618,7 +625,7 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
|
||||
}
|
||||
|
||||
if (!noFocus && !g_pCompositor->m_pLastMonitor->activeSpecialWorkspace &&
|
||||
!(g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bPinned && g_pCompositor->m_pLastWindow->m_iMonitorID == ID)) {
|
||||
!(g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bPinned && g_pCompositor->m_pLastWindow->m_pMonitor == self)) {
|
||||
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
||||
auto pWindow = pWorkspace->getLastFocusedWindow();
|
||||
|
||||
@@ -646,11 +653,11 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
|
||||
EMIT_HOOK_EVENT("workspace", pWorkspace);
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageMonitor(this);
|
||||
g_pHyprRenderer->damageMonitor(self.lock());
|
||||
|
||||
g_pCompositor->updateFullscreenFadeOnWorkspace(pWorkspace);
|
||||
|
||||
g_pConfigManager->ensureVRR(this);
|
||||
g_pConfigManager->ensureVRR(self.lock());
|
||||
|
||||
g_pCompositor->updateSuspendedStates();
|
||||
|
||||
@@ -666,7 +673,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
if (activeSpecialWorkspace == pWorkspace)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageMonitor(this);
|
||||
g_pHyprRenderer->damageMonitor(self.lock());
|
||||
|
||||
if (!pWorkspace) {
|
||||
// remove special if exists
|
||||
@@ -679,7 +686,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
|
||||
|
||||
if (!(g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bPinned && g_pCompositor->m_pLastWindow->m_iMonitorID == ID)) {
|
||||
if (!(g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bPinned && g_pCompositor->m_pLastWindow->m_pMonitor == self)) {
|
||||
if (const auto PLAST = activeWorkspace->getLastFocusedWindow(); PLAST)
|
||||
g_pCompositor->focusWindow(PLAST);
|
||||
else
|
||||
@@ -688,7 +695,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
|
||||
g_pCompositor->updateFullscreenFadeOnWorkspace(activeWorkspace);
|
||||
|
||||
g_pConfigManager->ensureVRR(this);
|
||||
g_pConfigManager->ensureVRR(self.lock());
|
||||
|
||||
g_pCompositor->updateSuspendedStates();
|
||||
|
||||
@@ -702,7 +709,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
|
||||
bool animate = true;
|
||||
//close if open elsewhere
|
||||
const auto PMONITORWORKSPACEOWNER = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
const auto PMONITORWORKSPACEOWNER = pWorkspace->m_pMonitor.lock();
|
||||
if (PMONITORWORKSPACEOWNER->activeSpecialWorkspace == pWorkspace) {
|
||||
PMONITORWORKSPACEOWNER->activeSpecialWorkspace.reset();
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITORWORKSPACEOWNER->ID);
|
||||
@@ -715,7 +722,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
}
|
||||
|
||||
// open special
|
||||
pWorkspace->m_iMonitorID = ID;
|
||||
pWorkspace->m_pMonitor = self;
|
||||
activeSpecialWorkspace = pWorkspace;
|
||||
activeSpecialWorkspace->m_bVisible = true;
|
||||
if (animate)
|
||||
@@ -723,7 +730,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
|
||||
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_pWorkspace == pWorkspace) {
|
||||
w->m_iMonitorID = ID;
|
||||
w->m_pMonitor = self;
|
||||
w->updateSurfaceScaleTransformDetails();
|
||||
w->setAnimationsToMove();
|
||||
|
||||
@@ -747,7 +754,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
|
||||
|
||||
if (!(g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bPinned && g_pCompositor->m_pLastWindow->m_iMonitorID == ID)) {
|
||||
if (!(g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bPinned && g_pCompositor->m_pLastWindow->m_pMonitor == self)) {
|
||||
if (const auto PLAST = pWorkspace->getLastFocusedWindow(); PLAST)
|
||||
g_pCompositor->focusWindow(PLAST);
|
||||
else
|
||||
@@ -756,11 +763,11 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activespecial", pWorkspace->m_szName + "," + szName});
|
||||
|
||||
g_pHyprRenderer->damageMonitor(this);
|
||||
g_pHyprRenderer->damageMonitor(self.lock());
|
||||
|
||||
g_pCompositor->updateFullscreenFadeOnWorkspace(pWorkspace);
|
||||
|
||||
g_pConfigManager->ensureVRR(this);
|
||||
g_pConfigManager->ensureVRR(self.lock());
|
||||
|
||||
g_pCompositor->updateSuspendedStates();
|
||||
}
|
||||
@@ -813,6 +820,12 @@ void CMonitor::scheduleDone() {
|
||||
});
|
||||
}
|
||||
|
||||
void CMonitor::setCTM(const Mat3x3& ctm_) {
|
||||
ctm = ctm_;
|
||||
ctmUpdated = true;
|
||||
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::scheduleFrameReason::AQ_SCHEDULE_NEEDS_FRAME);
|
||||
}
|
||||
|
||||
bool CMonitor::attemptDirectScanout() {
|
||||
if (!mirrors.empty() || isMirror() || g_pHyprRenderer->m_bDirectScanoutBlocked)
|
||||
return false; // do not DS if this monitor is being mirrored. Will break the functionality.
|
||||
@@ -831,7 +844,7 @@ bool CMonitor::attemptDirectScanout() {
|
||||
return false;
|
||||
|
||||
// we can't scanout shm buffers.
|
||||
if (!PSURFACE->current.buffer || !PSURFACE->current.texture || !PSURFACE->current.texture->m_pEglImage /* dmabuf */)
|
||||
if (!PSURFACE->current.buffer || !PSURFACE->current.buffer->buffer || !PSURFACE->current.texture || !PSURFACE->current.texture->m_pEglImage /* dmabuf */)
|
||||
return false;
|
||||
|
||||
Debug::log(TRACE, "attemptDirectScanout: surface {:x} passed, will attempt", (uintptr_t)PSURFACE.get());
|
||||
@@ -927,6 +940,74 @@ bool CMonitor::attemptDirectScanout() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMonitor::debugLastPresentation(const std::string& message) {
|
||||
Debug::log(TRACE, "{} (last presentation {} - {} fps)", message, lastPresentationTimer.getMillis(),
|
||||
lastPresentationTimer.getMillis() > 0 ? 1000.0f / lastPresentationTimer.getMillis() : 0.0f);
|
||||
}
|
||||
|
||||
void CMonitor::onMonitorFrame() {
|
||||
if ((g_pCompositor->m_pAqBackend->hasSession() && !g_pCompositor->m_pAqBackend->session->active) || !g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
|
||||
Debug::log(WARN, "Attempted to render frame on inactive session!");
|
||||
|
||||
if (g_pCompositor->m_bUnsafeState && std::ranges::any_of(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& m) {
|
||||
return m->output != g_pCompositor->m_pUnsafeOutput->output;
|
||||
})) {
|
||||
// restore from unsafe state
|
||||
g_pCompositor->leaveUnsafeState();
|
||||
}
|
||||
|
||||
return; // cannot draw on session inactive (different tty)
|
||||
}
|
||||
|
||||
if (!m_bEnabled)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->recheckSolitaryForMonitor(self.lock());
|
||||
|
||||
tearingState.busy = false;
|
||||
|
||||
if (tearingState.activelyTearing && solitaryClient.lock() /* can be invalidated by a recheck */) {
|
||||
|
||||
if (!tearingState.frameScheduledWhileBusy)
|
||||
return; // we did not schedule a frame yet to be displayed, but we are tearing. Why render?
|
||||
|
||||
tearingState.nextRenderTorn = true;
|
||||
tearingState.frameScheduledWhileBusy = false;
|
||||
}
|
||||
|
||||
static auto PENABLERAT = CConfigValue<Hyprlang::INT>("misc:render_ahead_of_time");
|
||||
static auto PRATSAFE = CConfigValue<Hyprlang::INT>("misc:render_ahead_safezone");
|
||||
|
||||
lastPresentationTimer.reset();
|
||||
|
||||
if (*PENABLERAT && !tearingState.nextRenderTorn) {
|
||||
if (!RATScheduled) {
|
||||
// render
|
||||
g_pHyprRenderer->renderMonitor(self.lock());
|
||||
}
|
||||
|
||||
RATScheduled = false;
|
||||
|
||||
const auto& [avg, max, min] = g_pHyprRenderer->getRenderTimes(self.lock());
|
||||
|
||||
if (max + *PRATSAFE > 1000.0 / refreshRate)
|
||||
return;
|
||||
|
||||
const auto MSLEFT = 1000.0 / refreshRate - lastPresentationTimer.getMillis();
|
||||
|
||||
RATScheduled = true;
|
||||
|
||||
const auto ESTRENDERTIME = std::ceil(avg + *PRATSAFE);
|
||||
const auto TIMETOSLEEP = std::floor(MSLEFT - ESTRENDERTIME);
|
||||
|
||||
if (MSLEFT < 1 || MSLEFT < ESTRENDERTIME || TIMETOSLEEP < 1)
|
||||
g_pHyprRenderer->renderMonitor(self.lock());
|
||||
else
|
||||
wl_event_source_timer_update(renderTimer, TIMETOSLEEP);
|
||||
} else
|
||||
g_pHyprRenderer->renderMonitor(self.lock());
|
||||
}
|
||||
|
||||
CMonitorState::CMonitorState(CMonitor* owner) {
|
||||
m_pOwner = owner;
|
||||
}
|
||||
@@ -958,7 +1039,7 @@ bool CMonitorState::commit() {
|
||||
if (!updateSwapchain())
|
||||
return false;
|
||||
|
||||
EMIT_HOOK_EVENT("preMonitorCommit", m_pOwner);
|
||||
EMIT_HOOK_EVENT("preMonitorCommit", m_pOwner->self.lock());
|
||||
|
||||
ensureBufferPresent();
|
||||
|
||||
|
@@ -54,7 +54,7 @@ class CMonitorState {
|
||||
private:
|
||||
void ensureBufferPresent();
|
||||
|
||||
CMonitor* m_pOwner;
|
||||
CMonitor* m_pOwner = nullptr;
|
||||
};
|
||||
|
||||
class CMonitor {
|
||||
@@ -125,11 +125,15 @@ class CMonitor {
|
||||
SP<CSyncTimeline> outTimeline;
|
||||
uint64_t commitSeq = 0;
|
||||
|
||||
WP<CMonitor> self;
|
||||
PHLMONITORREF self;
|
||||
|
||||
// mirroring
|
||||
CMonitor* pMirrorOf = nullptr;
|
||||
std::vector<CMonitor*> mirrors;
|
||||
PHLMONITORREF pMirrorOf;
|
||||
std::vector<PHLMONITORREF> mirrors;
|
||||
|
||||
// ctm
|
||||
Mat3x3 ctm = Mat3x3::identity();
|
||||
bool ctmUpdated = false;
|
||||
|
||||
// for tearing
|
||||
PHLWINDOWREF solitaryClient;
|
||||
@@ -179,6 +183,10 @@ class CMonitor {
|
||||
CBox logicalBox();
|
||||
void scheduleDone();
|
||||
bool attemptDirectScanout();
|
||||
void setCTM(const Mat3x3& ctm);
|
||||
|
||||
void debugLastPresentation(const std::string& message);
|
||||
void onMonitorFrame();
|
||||
|
||||
bool m_bEnabled = false;
|
||||
bool m_bRenderingInitPassed = false;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "Timer.hpp"
|
||||
#include <chrono>
|
||||
|
||||
void CTimer::reset() {
|
||||
m_tpLastReset = std::chrono::steady_clock::now();
|
||||
@@ -8,8 +9,8 @@ std::chrono::steady_clock::duration CTimer::getDuration() {
|
||||
return std::chrono::steady_clock::now() - m_tpLastReset;
|
||||
}
|
||||
|
||||
long CTimer::getMillis() {
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(getDuration()).count();
|
||||
float CTimer::getMillis() {
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(getDuration()).count() / 1000.f;
|
||||
}
|
||||
|
||||
float CTimer::getSeconds() {
|
||||
|
@@ -6,7 +6,7 @@ class CTimer {
|
||||
public:
|
||||
void reset();
|
||||
float getSeconds();
|
||||
long getMillis();
|
||||
float getMillis();
|
||||
const std::chrono::steady_clock::time_point& chrono() const;
|
||||
|
||||
private:
|
||||
|
@@ -18,9 +18,9 @@ class CWLSurfaceResource;
|
||||
AQUAMARINE_FORWARD(ISwitch);
|
||||
|
||||
struct SRenderData {
|
||||
CMonitor* pMonitor;
|
||||
timespec* when;
|
||||
double x, y;
|
||||
PHLMONITORREF pMonitor;
|
||||
timespec* when;
|
||||
double x, y;
|
||||
|
||||
// for iters
|
||||
void* data = nullptr;
|
||||
@@ -59,16 +59,16 @@ struct SRenderData {
|
||||
};
|
||||
|
||||
struct SSwipeGesture {
|
||||
PHLWORKSPACE pWorkspaceBegin = nullptr;
|
||||
PHLWORKSPACE pWorkspaceBegin = nullptr;
|
||||
|
||||
double delta = 0;
|
||||
double delta = 0;
|
||||
|
||||
int initialDirection = 0;
|
||||
float avgSpeed = 0;
|
||||
int speedPoints = 0;
|
||||
int touch_id = 0;
|
||||
int initialDirection = 0;
|
||||
float avgSpeed = 0;
|
||||
int speedPoints = 0;
|
||||
int touch_id = 0;
|
||||
|
||||
CMonitor* pMonitor = nullptr;
|
||||
PHLMONITORREF pMonitor;
|
||||
};
|
||||
|
||||
struct SSwitchDevice {
|
||||
|
@@ -3,6 +3,9 @@
|
||||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
|
||||
#include <hyprutils/utils/ScopeGuard.hpp>
|
||||
using namespace Hyprutils::Utils;
|
||||
|
||||
CHyprError::CHyprError() {
|
||||
m_fFadeOpacity.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), AVARDAMAGE_NONE);
|
||||
m_fFadeOpacity.registerVar();
|
||||
@@ -11,7 +14,7 @@ CHyprError::CHyprError() {
|
||||
if (!m_bIsCreated)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->m_pLastMonitor.get());
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->m_pLastMonitor.lock());
|
||||
m_bMonitorChanged = true;
|
||||
});
|
||||
|
||||
@@ -44,7 +47,7 @@ void CHyprError::createQueued() {
|
||||
m_fFadeOpacity.setValueAndWarp(0.f);
|
||||
m_fFadeOpacity = 1.f;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front();
|
||||
|
||||
const auto SCALE = PMONITOR->scale;
|
||||
|
||||
@@ -130,6 +133,8 @@ void CHyprError::createQueued() {
|
||||
}
|
||||
m_szQueued = "";
|
||||
|
||||
m_fLastHeight = yoffset + PAD + 1 - (TOPBAR ? 0 : Y - PAD);
|
||||
|
||||
pango_font_description_free(pangoFD);
|
||||
g_object_unref(layoutText);
|
||||
|
||||
@@ -158,6 +163,8 @@ void CHyprError::createQueued() {
|
||||
m_cQueued = CColor();
|
||||
|
||||
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||
}
|
||||
|
||||
void CHyprError::draw() {
|
||||
@@ -174,6 +181,11 @@ void CHyprError::draw() {
|
||||
m_pTexture->destroyTexture();
|
||||
m_bIsCreated = false;
|
||||
m_szQueued = "";
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(m->ID);
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
m_fFadeOpacity.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut"));
|
||||
@@ -203,3 +215,11 @@ void CHyprError::destroy() {
|
||||
else
|
||||
m_szQueued = "";
|
||||
}
|
||||
|
||||
bool CHyprError::active() {
|
||||
return m_bIsCreated;
|
||||
}
|
||||
|
||||
float CHyprError::height() {
|
||||
return m_fLastHeight;
|
||||
}
|
||||
|
@@ -11,9 +11,12 @@ class CHyprError {
|
||||
CHyprError();
|
||||
~CHyprError();
|
||||
|
||||
void queueCreate(std::string message, const CColor& color);
|
||||
void draw();
|
||||
void destroy();
|
||||
void queueCreate(std::string message, const CColor& color);
|
||||
void draw();
|
||||
void destroy();
|
||||
|
||||
bool active();
|
||||
float height(); // logical
|
||||
|
||||
private:
|
||||
void createQueued();
|
||||
@@ -23,7 +26,8 @@ class CHyprError {
|
||||
bool m_bIsCreated = false;
|
||||
SP<CTexture> m_pTexture;
|
||||
CAnimatedVariable<float> m_fFadeOpacity;
|
||||
CBox m_bDamageBox = {0, 0, 0, 0};
|
||||
CBox m_bDamageBox = {0, 0, 0, 0};
|
||||
float m_fLastHeight = 0.F;
|
||||
|
||||
bool m_bMonitorChanged = false;
|
||||
};
|
||||
|
@@ -101,18 +101,17 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
if (pNode->isNode)
|
||||
return;
|
||||
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
PHLMONITOR PMONITOR = nullptr;
|
||||
|
||||
if (g_pCompositor->isWorkspaceSpecial(pNode->workspaceID)) {
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->activeSpecialWorkspaceID() == pNode->workspaceID) {
|
||||
PMONITOR = m.get();
|
||||
PMONITOR = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_iMonitorID);
|
||||
}
|
||||
} else
|
||||
PMONITOR = g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR) {
|
||||
Debug::log(ERR, "Orphaned Node {}!!", pNode);
|
||||
@@ -142,11 +141,10 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
PWINDOW->unsetWindowData(PRIORITY_LAYOUT);
|
||||
PWINDOW->updateWindowData();
|
||||
|
||||
static auto PNOGAPSWHENONLY = CConfigValue<Hyprlang::INT>("dwindle:no_gaps_when_only");
|
||||
static auto PGAPSINDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_in");
|
||||
static auto PGAPSOUTDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_out");
|
||||
auto* const PGAPSIN = (CCssGapData*)(PGAPSINDATA.ptr())->getData();
|
||||
auto* const PGAPSOUT = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData();
|
||||
static auto PGAPSINDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_in");
|
||||
static auto PGAPSOUTDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_out");
|
||||
auto* const PGAPSIN = (CCssGapData*)(PGAPSINDATA.ptr())->getData();
|
||||
auto* const PGAPSOUT = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData();
|
||||
|
||||
auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN);
|
||||
auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT);
|
||||
@@ -156,27 +154,6 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
PWINDOW->m_vSize = nodeBox.size();
|
||||
PWINDOW->m_vPosition = nodeBox.pos();
|
||||
|
||||
const auto NODESONWORKSPACE = getNodesOnWorkspace(PWINDOW->workspaceID());
|
||||
|
||||
if (*PNOGAPSWHENONLY && !PWINDOW->onSpecialWorkspace() && (NODESONWORKSPACE == 1 || PWINDOW->isEffectiveInternalFSMode(FSMODE_MAXIMIZED))) {
|
||||
|
||||
PWINDOW->m_sWindowData.decorate = CWindowOverridableVar(true, PRIORITY_LAYOUT);
|
||||
PWINDOW->m_sWindowData.noBorder = CWindowOverridableVar(*PNOGAPSWHENONLY != 2, PRIORITY_LAYOUT);
|
||||
PWINDOW->m_sWindowData.noRounding = CWindowOverridableVar(true, PRIORITY_LAYOUT);
|
||||
PWINDOW->m_sWindowData.noShadow = CWindowOverridableVar(true, PRIORITY_LAYOUT);
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
|
||||
const auto RESERVED = PWINDOW->getFullWindowReservedArea();
|
||||
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vPosition + RESERVED.topLeft;
|
||||
PWINDOW->m_vRealSize = PWINDOW->m_vSize - (RESERVED.topLeft + RESERVED.bottomRight);
|
||||
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
|
||||
auto calcPos = PWINDOW->m_vPosition;
|
||||
@@ -257,7 +234,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
|
||||
m_lDwindleNodesData.push_back(SDwindleNodeData());
|
||||
const auto PNODE = &m_lDwindleNodesData.back();
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
static auto PUSEACTIVE = CConfigValue<Hyprlang::INT>("dwindle:use_active_for_splits");
|
||||
static auto PDEFAULTSPLIT = CConfigValue<Hyprlang::FLOAT>("dwindle:default_split_ratio");
|
||||
@@ -306,7 +283,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
|
||||
|
||||
// first, check if OPENINGON isn't too big.
|
||||
const auto PREDSIZEMAX = OPENINGON ? Vector2D(OPENINGON->box.w, OPENINGON->box.h) : PMONITOR->vecSize;
|
||||
if (const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow); MAXSIZE.x < PREDSIZEMAX.x || MAXSIZE.y < PREDSIZEMAX.y) {
|
||||
if (const auto MAXSIZE = pWindow->requestedMaxSize(); MAXSIZE.x < PREDSIZEMAX.x || MAXSIZE.y < PREDSIZEMAX.y) {
|
||||
// we can't continue. make it floating.
|
||||
pWindow->m_bIsFloating = true;
|
||||
m_lDwindleNodesData.remove(*PNODE);
|
||||
@@ -330,16 +307,9 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
|
||||
|
||||
applyNodeDataToWindow(PNODE);
|
||||
|
||||
pWindow->applyGroupRules();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_vOverrideFocalPoint && g_pInputManager->m_bWasDraggingWindow) {
|
||||
if (OPENINGON->pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, pWindow))
|
||||
return;
|
||||
}
|
||||
|
||||
// get the node under our cursor
|
||||
|
||||
m_lDwindleNodesData.push_back(SDwindleNodeData());
|
||||
@@ -471,9 +441,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
|
||||
|
||||
NEWPARENT->recalcSizePosRecursive(false, horizontalOverride, verticalOverride);
|
||||
|
||||
recalculateMonitor(pWindow->m_iMonitorID);
|
||||
|
||||
pWindow->applyGroupRules();
|
||||
recalculateMonitor(pWindow->monitorID());
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::onWindowRemovedTiling(PHLWINDOW pWindow) {
|
||||
@@ -539,7 +507,7 @@ void CHyprDwindleLayout::recalculateMonitor(const MONITORID& monid) {
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::calculateWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
const auto PMONITOR = pWorkspace->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
@@ -595,7 +563,9 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
|
||||
if (!PNODE) {
|
||||
PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goal() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goal() + pixResize).y, 20.0));
|
||||
PWINDOW->m_vRealSize =
|
||||
(PWINDOW->m_vRealSize.goal() + pixResize)
|
||||
.clamp(PWINDOW->m_sWindowData.minSize.valueOr(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), PWINDOW->m_sWindowData.maxSize.valueOr(Vector2D{INFINITY, INFINITY}));
|
||||
PWINDOW->updateWindowDecos();
|
||||
return;
|
||||
}
|
||||
@@ -604,7 +574,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
|
||||
static auto PSMARTRESIZING = CConfigValue<Hyprlang::INT>("dwindle:smart_resizing");
|
||||
|
||||
// get some data about our window
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
const bool DISPLAYLEFT = STICKS(PWINDOW->m_vPosition.x, PMONITOR->vecPosition.x + PMONITOR->vecReservedTopLeft.x);
|
||||
const bool DISPLAYRIGHT = STICKS(PWINDOW->m_vPosition.x + PWINDOW->m_vSize.x, PMONITOR->vecPosition.x + PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x);
|
||||
const bool DISPLAYTOP = STICKS(PWINDOW->m_vPosition.y, PMONITOR->vecPosition.y + PMONITOR->vecReservedTopLeft.y);
|
||||
@@ -777,7 +747,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFullscreenMode CURRENT_EFFECTIVE_MODE, const eFullscreenMode EFFECTIVE_MODE) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
||||
|
||||
// save position and size if floating
|
||||
@@ -887,9 +857,9 @@ void CHyprDwindleLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
|
||||
|
||||
const auto PMONITORFOCAL = g_pCompositor->getMonitorFromVector(focalPoint);
|
||||
|
||||
if (PMONITORFOCAL->ID != pWindow->m_iMonitorID) {
|
||||
if (PMONITORFOCAL != pWindow->m_pMonitor) {
|
||||
pWindow->moveToWorkspace(PMONITORFOCAL->activeWorkspace);
|
||||
pWindow->m_iMonitorID = PMONITORFOCAL->ID;
|
||||
pWindow->m_pMonitor = PMONITORFOCAL;
|
||||
}
|
||||
|
||||
onWindowCreatedTiling(pWindow);
|
||||
@@ -927,7 +897,7 @@ void CHyprDwindleLayout::switchWindows(PHLWINDOW pWindow, PHLWINDOW pWindow2) {
|
||||
PNODE->pWindow = pWindow2;
|
||||
|
||||
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
|
||||
std::swap(pWindow2->m_pMonitor, pWindow->m_pMonitor);
|
||||
std::swap(pWindow2->m_pWorkspace, pWindow->m_pWorkspace);
|
||||
}
|
||||
|
||||
|
@@ -13,13 +13,16 @@ void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) {
|
||||
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
|
||||
|
||||
if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
pWindow->m_vLastFloatingSize = PMONITOR->vecSize / 2.f;
|
||||
} else
|
||||
pWindow->m_vLastFloatingSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
|
||||
|
||||
pWindow->m_vPseudoSize = pWindow->m_vLastFloatingSize;
|
||||
|
||||
if (!g_pXWaylandManager->shouldBeFloated(pWindow)) // do not apply group rules to child windows
|
||||
pWindow->applyGroupRules();
|
||||
|
||||
bool autoGrouped = IHyprLayout::onWindowCreatedAutoGroup(pWindow);
|
||||
if (autoGrouped)
|
||||
return;
|
||||
@@ -85,7 +88,7 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
|
||||
|
||||
CBox desiredGeometry = {0};
|
||||
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
if (pWindow->m_bIsX11) {
|
||||
Vector2D xy = {desiredGeometry.x, desiredGeometry.y};
|
||||
@@ -181,34 +184,27 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
|
||||
}
|
||||
|
||||
bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) {
|
||||
static auto AUTOGROUP = CConfigValue<Hyprlang::INT>("group:auto_group");
|
||||
if ((*AUTOGROUP || g_pInputManager->m_bWasDraggingWindow) // check if auto_group is enabled, or, if the user is manually dragging the window into the group.
|
||||
&& g_pCompositor->m_pLastWindow.lock() // check if a focused window exists.
|
||||
&& g_pCompositor->m_pLastWindow != pWindow // fixes a freeze when activating togglefloat to transform a floating group into a tiled group.
|
||||
&& g_pCompositor->m_pLastWindow->m_pWorkspace ==
|
||||
pWindow
|
||||
->m_pWorkspace // fix for multimonitor: when there is a focused group in monitor 1 and monitor 2 is empty, this enables adding the first window of monitor 2 when using the mouse to focus it.
|
||||
&& g_pCompositor->m_pLastWindow->m_sGroupData.pNextWindow.lock() // check if the focused window is a group
|
||||
&& pWindow->canBeGroupedInto(g_pCompositor->m_pLastWindow.lock()) // check if the new window can be grouped into the focused group
|
||||
&& !g_pXWaylandManager->shouldBeFloated(pWindow)) { // don't group XWayland windows that should be floated.
|
||||
static auto PAUTOGROUP = CConfigValue<Hyprlang::INT>("group:auto_group");
|
||||
const PHLWINDOW OPENINGON = g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_pWorkspace == pWindow->m_pWorkspace ?
|
||||
g_pCompositor->m_pLastWindow.lock() :
|
||||
g_pCompositor->getFirstWindowOnWorkspace(pWindow->workspaceID());
|
||||
const bool FLOATEDINTOTILED = pWindow->m_bIsFloating && !OPENINGON->m_bIsFloating;
|
||||
const bool SWALLOWING = pWindow->m_pSwallowed || pWindow->m_bGroupSwallowed;
|
||||
|
||||
switch (pWindow->m_bIsFloating) {
|
||||
case false:
|
||||
if (g_pCompositor->m_pLastWindow->m_bIsFloating)
|
||||
pWindow->m_bIsFloating = true;
|
||||
break;
|
||||
if ((*PAUTOGROUP || SWALLOWING) // continue if auto_group is enabled or if dealing with window swallowing.
|
||||
&& OPENINGON // this shouldn't be 0, but honestly, better safe than sorry.
|
||||
&& OPENINGON != pWindow // prevent freeze when the "group set" window rule makes the new window to be already a group.
|
||||
&& OPENINGON->m_sGroupData.pNextWindow.lock() // check if OPENINGON is a group.
|
||||
&& pWindow->canBeGroupedInto(OPENINGON) // check if the new window can be grouped into OPENINGON.
|
||||
&& !g_pXWaylandManager->shouldBeFloated(pWindow) // don't group child windows. Fix for floated groups. Tiled groups don't need this because we check if !FLOATEDINTOTILED.
|
||||
&& !FLOATEDINTOTILED) { // don't group a new floated window into a tiled group (for convenience).
|
||||
|
||||
case true:
|
||||
if (!g_pCompositor->m_pLastWindow->m_bIsFloating)
|
||||
pWindow->m_bIsFloating = false;
|
||||
break;
|
||||
}
|
||||
pWindow->m_bIsFloating = OPENINGON->m_bIsFloating; // match the floating state. Needed to autogroup a new tiled window into a floated group.
|
||||
|
||||
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
|
||||
(*USECURRPOS ? g_pCompositor->m_pLastWindow : g_pCompositor->m_pLastWindow->getGroupTail())->insertWindowToGroup(pWindow);
|
||||
(*USECURRPOS ? OPENINGON : OPENINGON->getGroupTail())->insertWindowToGroup(pWindow);
|
||||
|
||||
g_pCompositor->m_pLastWindow->setGroupCurrent(pWindow);
|
||||
pWindow->applyGroupRules();
|
||||
OPENINGON->setGroupCurrent(pWindow);
|
||||
pWindow->updateWindowDecos();
|
||||
recalculateWindow(pWindow);
|
||||
|
||||
@@ -334,21 +330,37 @@ void IHyprLayout::onEndDragWindow() {
|
||||
g_pInputManager->currentlyDraggedWindow.reset();
|
||||
g_pInputManager->m_bWasDraggingWindow = true;
|
||||
|
||||
if (DRAGGINGWINDOW->m_bDraggingTiled) {
|
||||
DRAGGINGWINDOW->m_bIsFloating = false;
|
||||
g_pInputManager->refocus();
|
||||
changeWindowFloatingMode(DRAGGINGWINDOW);
|
||||
DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize;
|
||||
} else if (g_pInputManager->dragMode == MBIND_MOVE) {
|
||||
if (g_pInputManager->dragMode == MBIND_MOVE) {
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
|
||||
PHLWINDOW pWindow = g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING | FLOATING_ONLY, DRAGGINGWINDOW);
|
||||
PHLWINDOW pWindow = g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING, DRAGGINGWINDOW);
|
||||
|
||||
if (pWindow) {
|
||||
if (pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, DRAGGINGWINDOW))
|
||||
return;
|
||||
|
||||
if (pWindow->m_sGroupData.pNextWindow.lock() && DRAGGINGWINDOW->canBeGroupedInto(pWindow)) {
|
||||
const bool FLOATEDINTOTILED = !pWindow->m_bIsFloating && !DRAGGINGWINDOW->m_bDraggingTiled;
|
||||
static auto PDRAGINTOGROUP = CConfigValue<Hyprlang::INT>("group:drag_into_group");
|
||||
|
||||
if (pWindow->m_sGroupData.pNextWindow.lock() && DRAGGINGWINDOW->canBeGroupedInto(pWindow) && *PDRAGINTOGROUP == 1 && !FLOATEDINTOTILED) {
|
||||
|
||||
if (DRAGGINGWINDOW->m_sGroupData.pNextWindow) {
|
||||
PHLWINDOW next = DRAGGINGWINDOW->m_sGroupData.pNextWindow.lock();
|
||||
while (next != DRAGGINGWINDOW) {
|
||||
next->m_bIsFloating = pWindow->m_bIsFloating; // match the floating state of group members
|
||||
next->m_vRealSize = pWindow->m_vRealSize.goal(); // match the size of group members
|
||||
next->m_vRealPosition = pWindow->m_vRealPosition.goal(); // match the position of group members
|
||||
next = next->m_sGroupData.pNextWindow.lock();
|
||||
}
|
||||
}
|
||||
|
||||
DRAGGINGWINDOW->m_bIsFloating = pWindow->m_bIsFloating; // match the floating state of the window
|
||||
DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize;
|
||||
DRAGGINGWINDOW->m_bDraggingTiled = false;
|
||||
|
||||
if (pWindow->m_bIsFloating)
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, pWindow->m_vRealSize.goal()); // match the size of the window
|
||||
|
||||
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
|
||||
(*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW);
|
||||
pWindow->setGroupCurrent(DRAGGINGWINDOW);
|
||||
@@ -360,12 +372,159 @@ void IHyprLayout::onEndDragWindow() {
|
||||
}
|
||||
}
|
||||
|
||||
if (DRAGGINGWINDOW->m_bDraggingTiled) {
|
||||
DRAGGINGWINDOW->m_bIsFloating = false;
|
||||
g_pInputManager->refocus();
|
||||
changeWindowFloatingMode(DRAGGINGWINDOW);
|
||||
DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize;
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
g_pCompositor->focusWindow(DRAGGINGWINDOW);
|
||||
|
||||
g_pInputManager->m_bWasDraggingWindow = false;
|
||||
}
|
||||
|
||||
static inline bool canSnap(const double SIDEA, const double SIDEB, const double GAP) {
|
||||
return std::abs(SIDEA - SIDEB) < GAP;
|
||||
}
|
||||
|
||||
static void snapMove(double& start, double& end, const double P) {
|
||||
end = P + (end - start);
|
||||
start = P;
|
||||
}
|
||||
|
||||
static void snapResize(double& start, double& end, const double P) {
|
||||
start = P;
|
||||
}
|
||||
|
||||
typedef std::function<void(double&, double&, const double)> SnapFn;
|
||||
|
||||
static void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRAGGINGWINDOW, const eMouseBindMode MODE, const int CORNER, const Vector2D& BEGINSIZE) {
|
||||
static auto SNAPWINDOWGAP = CConfigValue<Hyprlang::INT>("general:snap:window_gap");
|
||||
static auto SNAPMONITORGAP = CConfigValue<Hyprlang::INT>("general:snap:monitor_gap");
|
||||
static auto SNAPBORDEROVERLAP = CConfigValue<Hyprlang::INT>("general:snap:border_overlap");
|
||||
|
||||
const SnapFn SNAP = (MODE == MBIND_MOVE) ? snapMove : snapResize;
|
||||
int snaps = 0;
|
||||
|
||||
const bool OVERLAP = *SNAPBORDEROVERLAP;
|
||||
const int DRAGGINGBORDERSIZE = DRAGGINGWINDOW->getRealBorderSize();
|
||||
|
||||
struct SRange {
|
||||
double start = 0;
|
||||
double end = 0;
|
||||
};
|
||||
SRange sourceX = {sourcePos.x, sourcePos.x + sourceSize.x};
|
||||
SRange sourceY = {sourcePos.y, sourcePos.y + sourceSize.y};
|
||||
|
||||
if (*SNAPWINDOWGAP) {
|
||||
const double GAPSIZE = *SNAPWINDOWGAP;
|
||||
const auto WSID = DRAGGINGWINDOW->workspaceID();
|
||||
|
||||
for (auto& other : g_pCompositor->m_vWindows) {
|
||||
if (other == DRAGGINGWINDOW || other->workspaceID() != WSID || !other->m_bIsMapped || other->m_bFadingOut || other->isX11OverrideRedirect())
|
||||
continue;
|
||||
|
||||
const int OTHERBORDERSIZE = other->getRealBorderSize();
|
||||
const double BORDERSIZE = OVERLAP ? std::max(DRAGGINGBORDERSIZE, OTHERBORDERSIZE) : (DRAGGINGBORDERSIZE + OTHERBORDERSIZE);
|
||||
|
||||
const CBox SURF = other->getWindowMainSurfaceBox();
|
||||
const SRange SURFBX = {SURF.x - BORDERSIZE, SURF.x + SURF.w + BORDERSIZE};
|
||||
const SRange SURFBY = {SURF.y - BORDERSIZE, SURF.y + SURF.h + BORDERSIZE};
|
||||
|
||||
// only snap windows if their ranges overlap in the opposite axis
|
||||
if (sourceY.start <= SURFBY.end && SURFBY.start <= sourceY.end) {
|
||||
if (CORNER & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && canSnap(sourceX.start, SURFBX.end, GAPSIZE)) {
|
||||
SNAP(sourceX.start, sourceX.end, SURFBX.end);
|
||||
snaps |= SNAP_LEFT;
|
||||
} else if (CORNER & (CORNER_TOPRIGHT | CORNER_BOTTOMRIGHT) && canSnap(sourceX.end, SURFBX.start, GAPSIZE)) {
|
||||
SNAP(sourceX.end, sourceX.start, SURFBX.start);
|
||||
snaps |= SNAP_RIGHT;
|
||||
}
|
||||
}
|
||||
if (sourceX.start <= SURFBX.end && SURFBX.start <= sourceX.end) {
|
||||
if (CORNER & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && canSnap(sourceY.start, SURFBY.end, GAPSIZE)) {
|
||||
SNAP(sourceY.start, sourceY.end, SURFBY.end);
|
||||
snaps |= SNAP_UP;
|
||||
} else if (CORNER & (CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) && canSnap(sourceY.end, SURFBY.start, GAPSIZE)) {
|
||||
SNAP(sourceY.end, sourceY.start, SURFBY.start);
|
||||
snaps |= SNAP_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// corner snapping
|
||||
const double BORDERDIFF = OTHERBORDERSIZE - DRAGGINGBORDERSIZE;
|
||||
if (sourceX.start == SURFBX.end || SURFBX.start == sourceX.end) {
|
||||
const SRange SURFY = {SURF.y - BORDERDIFF, SURF.y + SURF.h + BORDERDIFF};
|
||||
if (CORNER & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && canSnap(sourceY.start, SURFY.start, GAPSIZE)) {
|
||||
SNAP(sourceY.start, sourceY.end, SURFY.start);
|
||||
snaps |= SNAP_UP;
|
||||
} else if (CORNER & (CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) && canSnap(sourceY.end, SURFY.end, GAPSIZE)) {
|
||||
SNAP(sourceY.end, sourceY.start, SURFY.end);
|
||||
snaps |= SNAP_DOWN;
|
||||
}
|
||||
}
|
||||
if (sourceY.start == SURFBY.end || SURFBY.start == sourceY.end) {
|
||||
const SRange SURFX = {SURF.x - BORDERDIFF, SURF.x + SURF.w + BORDERDIFF};
|
||||
if (CORNER & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && canSnap(sourceX.start, SURFX.start, GAPSIZE)) {
|
||||
SNAP(sourceX.start, sourceX.end, SURFX.start);
|
||||
snaps |= SNAP_LEFT;
|
||||
} else if (CORNER & (CORNER_TOPRIGHT | CORNER_BOTTOMRIGHT) && canSnap(sourceX.end, SURFX.end, GAPSIZE)) {
|
||||
SNAP(sourceX.end, sourceX.start, SURFX.end);
|
||||
snaps |= SNAP_RIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*SNAPMONITORGAP) {
|
||||
const double GAPSIZE = *SNAPMONITORGAP;
|
||||
const double BORDERSIZE = OVERLAP ? 0 : DRAGGINGBORDERSIZE;
|
||||
const double BORDERDIFF = DRAGGINGBORDERSIZE - BORDERSIZE;
|
||||
const auto MON = DRAGGINGWINDOW->m_pMonitor.lock();
|
||||
|
||||
SRange monX = {MON->vecPosition.x + BORDERSIZE, MON->vecSize.x - BORDERSIZE};
|
||||
SRange monY = {MON->vecPosition.y + BORDERSIZE, MON->vecSize.y - BORDERSIZE};
|
||||
|
||||
if (canSnap(sourceX.start, monX.start, GAPSIZE) || canSnap(sourceX.start, (monX.start += MON->vecReservedTopLeft.x + BORDERDIFF), GAPSIZE)) {
|
||||
SNAP(sourceX.start, sourceX.end, monX.start);
|
||||
snaps |= SNAP_LEFT;
|
||||
}
|
||||
if (canSnap(sourceX.end, monX.end, GAPSIZE) || canSnap(sourceX.end, (monX.end -= MON->vecReservedBottomRight.x + BORDERDIFF), GAPSIZE)) {
|
||||
SNAP(sourceX.end, sourceX.start, monX.end);
|
||||
snaps |= SNAP_RIGHT;
|
||||
}
|
||||
if (canSnap(sourceY.start, monY.start, GAPSIZE) || canSnap(sourceY.start, (monY.start += MON->vecReservedTopLeft.y + BORDERDIFF), GAPSIZE)) {
|
||||
SNAP(sourceY.start, sourceY.end, monY.start);
|
||||
snaps |= SNAP_UP;
|
||||
}
|
||||
if (canSnap(sourceY.end, monY.end, GAPSIZE) || canSnap(sourceY.end, (monY.end -= MON->vecReservedBottomRight.y + BORDERDIFF), GAPSIZE)) {
|
||||
SNAP(sourceY.end, sourceY.start, monY.end);
|
||||
snaps |= SNAP_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
if (MODE == MBIND_RESIZE_FORCE_RATIO) {
|
||||
if ((CORNER & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && snaps & SNAP_LEFT) || (CORNER & (CORNER_TOPRIGHT | CORNER_BOTTOMRIGHT) && snaps & SNAP_RIGHT)) {
|
||||
const double SIZEY = (sourceX.end - sourceX.start) * (BEGINSIZE.y / BEGINSIZE.x);
|
||||
if (CORNER & (CORNER_TOPLEFT | CORNER_TOPRIGHT))
|
||||
sourceY.start = sourceY.end - SIZEY;
|
||||
else
|
||||
sourceY.end = sourceY.start + SIZEY;
|
||||
} else if ((CORNER & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && snaps & SNAP_UP) || (CORNER & (CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) && snaps & SNAP_DOWN)) {
|
||||
const double SIZEX = (sourceY.end - sourceY.start) * (BEGINSIZE.x / BEGINSIZE.y);
|
||||
if (CORNER & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT))
|
||||
sourceX.start = sourceX.end - SIZEX;
|
||||
else
|
||||
sourceX.end = sourceX.start + SIZEX;
|
||||
}
|
||||
}
|
||||
|
||||
sourcePos = {sourceX.start, sourceY.start};
|
||||
sourceSize = {sourceX.end - sourceX.start, sourceY.end - sourceY.start};
|
||||
}
|
||||
|
||||
void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
if (g_pInputManager->currentlyDraggedWindow.expired())
|
||||
return;
|
||||
@@ -388,6 +547,8 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
static auto PANIMATEMOUSE = CConfigValue<Hyprlang::INT>("misc:animate_mouse_windowdragging");
|
||||
static auto PANIMATE = CConfigValue<Hyprlang::INT>("misc:animate_manual_resizes");
|
||||
|
||||
static auto SNAPENABLED = CConfigValue<Hyprlang::INT>("general:snap:enabled");
|
||||
|
||||
const auto TIMERDELTA = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - TIMER).count();
|
||||
const auto MSDELTA = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - MSTIMER).count();
|
||||
const auto MSMONITOR = 1000.0 / g_pHyprRenderer->m_pMostHzMonitor->refreshRate;
|
||||
@@ -418,7 +579,13 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
|
||||
if (g_pInputManager->dragMode == MBIND_MOVE) {
|
||||
|
||||
CBox wb = {m_vBeginDragPositionXY + DELTA, DRAGGINGWINDOW->m_vRealSize.goal()};
|
||||
Vector2D newPos = m_vBeginDragPositionXY + DELTA;
|
||||
Vector2D newSize = DRAGGINGWINDOW->m_vRealSize.goal();
|
||||
|
||||
if (*SNAPENABLED && !DRAGGINGWINDOW->m_bDraggingTiled)
|
||||
performSnap(newPos, newSize, DRAGGINGWINDOW, MBIND_MOVE, -1, m_vBeginDragSizeXY);
|
||||
|
||||
CBox wb = {newPos, newSize};
|
||||
wb.round();
|
||||
|
||||
if (*PANIMATEMOUSE)
|
||||
@@ -430,12 +597,12 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
} else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) {
|
||||
if (DRAGGINGWINDOW->m_bIsFloating) {
|
||||
|
||||
Vector2D MINSIZE = g_pXWaylandManager->getMinSizeForWindow(DRAGGINGWINDOW).clamp(DRAGGINGWINDOW->m_sWindowData.minSize.valueOr(Vector2D(20, 20)));
|
||||
Vector2D MINSIZE = DRAGGINGWINDOW->requestedMinSize().clamp(DRAGGINGWINDOW->m_sWindowData.minSize.valueOr(Vector2D(20, 20)));
|
||||
Vector2D MAXSIZE;
|
||||
if (DRAGGINGWINDOW->m_sWindowData.maxSize.hasValue())
|
||||
MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW).clamp({}, DRAGGINGWINDOW->m_sWindowData.maxSize.value());
|
||||
MAXSIZE = DRAGGINGWINDOW->requestedMaxSize().clamp({}, DRAGGINGWINDOW->m_sWindowData.maxSize.value());
|
||||
else
|
||||
MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW).clamp({}, Vector2D(std::numeric_limits<double>::max(), std::numeric_limits<double>::max()));
|
||||
MAXSIZE = DRAGGINGWINDOW->requestedMaxSize().clamp({}, Vector2D(std::numeric_limits<double>::max(), std::numeric_limits<double>::max()));
|
||||
|
||||
Vector2D newSize = m_vBeginDragSizeXY;
|
||||
Vector2D newPos = m_vBeginDragPositionXY;
|
||||
@@ -449,9 +616,11 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
else if (m_eGrabbedCorner == CORNER_BOTTOMLEFT)
|
||||
newSize = newSize + Vector2D(-DELTA.x, DELTA.y);
|
||||
|
||||
if ((m_vBeginDragSizeXY.x >= 1 && m_vBeginDragSizeXY.y >= 1) &&
|
||||
(g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO ||
|
||||
(!(g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) && DRAGGINGWINDOW->m_sWindowData.keepAspectRatio.valueOrDefault()))) {
|
||||
eMouseBindMode mode = g_pInputManager->dragMode;
|
||||
if (DRAGGINGWINDOW->m_sWindowData.keepAspectRatio.valueOrDefault() && mode != MBIND_RESIZE_BLOCK_RATIO)
|
||||
mode = MBIND_RESIZE_FORCE_RATIO;
|
||||
|
||||
if (m_vBeginDragSizeXY.x >= 1 && m_vBeginDragSizeXY.y >= 1 && mode == MBIND_RESIZE_FORCE_RATIO) {
|
||||
|
||||
const float RATIO = m_vBeginDragSizeXY.y / m_vBeginDragSizeXY.x;
|
||||
|
||||
@@ -480,6 +649,11 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
else if (m_eGrabbedCorner == CORNER_BOTTOMLEFT)
|
||||
newPos = newPos + Vector2D((m_vBeginDragSizeXY - newSize).x, 0.0);
|
||||
|
||||
if (*SNAPENABLED) {
|
||||
performSnap(newPos, newSize, DRAGGINGWINDOW, mode, m_eGrabbedCorner, m_vBeginDragSizeXY);
|
||||
newSize = newSize.clamp(MINSIZE, MAXSIZE);
|
||||
}
|
||||
|
||||
CBox wb = {newPos, newSize};
|
||||
wb.round();
|
||||
|
||||
@@ -504,7 +678,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle);
|
||||
|
||||
if (PMONITOR && !SPECIAL) {
|
||||
DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
DRAGGINGWINDOW->m_pMonitor = PMONITOR;
|
||||
DRAGGINGWINDOW->moveToWorkspace(PMONITOR->activeWorkspace);
|
||||
DRAGGINGWINDOW->updateGroupOutputs();
|
||||
|
||||
@@ -532,8 +706,8 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
|
||||
EMIT_HOOK_EVENT("changeFloatingMode", pWindow);
|
||||
|
||||
if (!TILED) {
|
||||
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.value() + pWindow->m_vRealSize.value() / 2.f);
|
||||
pWindow->m_iMonitorID = PNEWMON->ID;
|
||||
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.value() + pWindow->m_vRealSize.value() / 2.f);
|
||||
pWindow->m_pMonitor = PNEWMON;
|
||||
pWindow->moveToWorkspace(PNEWMON->activeSpecialWorkspace ? PNEWMON->activeSpecialWorkspace : PNEWMON->activeWorkspace);
|
||||
pWindow->updateGroupOutputs();
|
||||
|
||||
@@ -552,16 +726,16 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
|
||||
|
||||
pWindow->m_vLastFloatingSize = PSAVEDSIZE;
|
||||
|
||||
// move to narnia because we don't wanna find our own node. onWindowCreated should apply the coords back.
|
||||
// move to narnia because we don't wanna find our own node. onWindowCreatedTiling should apply the coords back.
|
||||
pWindow->m_vPosition = Vector2D(-999999, -999999);
|
||||
|
||||
onWindowCreated(pWindow);
|
||||
onWindowCreatedTiling(pWindow);
|
||||
|
||||
pWindow->m_vRealPosition.setValue(PSAVEDPOS);
|
||||
pWindow->m_vRealSize.setValue(PSAVEDSIZE);
|
||||
|
||||
// fix pseudo leaving artifacts
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||
g_pHyprRenderer->damageMonitor(pWindow->m_pMonitor.lock());
|
||||
|
||||
if (pWindow == g_pCompositor->m_pLastWindow)
|
||||
m_pLastTiledWindow = pWindow;
|
||||
@@ -584,7 +758,7 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
|
||||
pWindow->m_vSize = wb.pos();
|
||||
pWindow->m_vPosition = wb.size();
|
||||
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||
g_pHyprRenderer->damageMonitor(pWindow->m_pMonitor.lock());
|
||||
|
||||
pWindow->unsetWindowData(PRIORITY_LAYOUT);
|
||||
pWindow->updateWindowData();
|
||||
@@ -674,7 +848,7 @@ PHLWINDOW IHyprLayout::getNextWindowCandidate(PHLWINDOW pWindow) {
|
||||
pWindowCandidate = g_pCompositor->getFirstWindowOnWorkspace(pWindow->workspaceID());
|
||||
|
||||
if (!pWindowCandidate || pWindow == pWindowCandidate || !pWindowCandidate->m_bIsMapped || pWindowCandidate->isHidden() || pWindowCandidate->m_bX11ShouldntFocus ||
|
||||
pWindowCandidate->isX11OverrideRedirect() || pWindowCandidate->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)
|
||||
pWindowCandidate->isX11OverrideRedirect() || pWindowCandidate->m_pMonitor != g_pCompositor->m_pLastMonitor)
|
||||
return nullptr;
|
||||
|
||||
return pWindowCandidate;
|
||||
@@ -706,18 +880,17 @@ Vector2D IHyprLayout::predictSizeForNewWindowFloating(PHLWINDOW pWindow) { // ge
|
||||
for (auto const& r : g_pConfigManager->getMatchingRules(pWindow, true, true)) {
|
||||
if (r.szRule.starts_with("size")) {
|
||||
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 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 MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow);
|
||||
const auto MAXSIZE = pWindow->requestedMaxSize();
|
||||
|
||||
const auto SIZEX = SIZEXSTR == "max" ?
|
||||
std::clamp(MAXSIZE.x, 20.0, g_pCompositor->m_pLastMonitor->vecSize.x) :
|
||||
(!SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stof(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01 * g_pCompositor->m_pLastMonitor->vecSize.x);
|
||||
const auto SIZEY = SIZEYSTR == "max" ?
|
||||
std::clamp(MAXSIZE.y, 20.0, g_pCompositor->m_pLastMonitor->vecSize.y) :
|
||||
(!SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stof(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01 * g_pCompositor->m_pLastMonitor->vecSize.y);
|
||||
const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, g_pCompositor->m_pLastMonitor->vecSize.x) :
|
||||
stringToPercentage(SIZEXSTR, g_pCompositor->m_pLastMonitor->vecSize.x);
|
||||
|
||||
const float SIZEY = SIZEYSTR == "max" ? std::clamp(MAXSIZE.y, MIN_WINDOW_SIZE, g_pCompositor->m_pLastMonitor->vecSize.y) :
|
||||
stringToPercentage(SIZEYSTR, g_pCompositor->m_pLastMonitor->vecSize.y);
|
||||
|
||||
sizeOverride = {SIZEX, SIZEY};
|
||||
|
||||
|
@@ -18,11 +18,19 @@ struct SLayoutMessageHeader {
|
||||
enum eFullscreenMode : int8_t;
|
||||
|
||||
enum eRectCorner {
|
||||
CORNER_NONE = 0,
|
||||
CORNER_TOPLEFT,
|
||||
CORNER_TOPRIGHT,
|
||||
CORNER_BOTTOMRIGHT,
|
||||
CORNER_BOTTOMLEFT
|
||||
CORNER_NONE = 0,
|
||||
CORNER_TOPLEFT = (1 << 0),
|
||||
CORNER_TOPRIGHT = (1 << 1),
|
||||
CORNER_BOTTOMRIGHT = (1 << 2),
|
||||
CORNER_BOTTOMLEFT = (1 << 3),
|
||||
};
|
||||
|
||||
enum eSnapEdge {
|
||||
SNAP_INVALID = 0,
|
||||
SNAP_UP = (1 << 0),
|
||||
SNAP_DOWN = (1 << 1),
|
||||
SNAP_LEFT = (1 << 2),
|
||||
SNAP_RIGHT = (1 << 3),
|
||||
};
|
||||
|
||||
enum eDirection {
|
||||
|
@@ -80,7 +80,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
|
||||
static auto PNEWONTOP = CConfigValue<Hyprlang::INT>("master:new_on_top");
|
||||
static auto PNEWSTATUS = CConfigValue<std::string>("master:new_status");
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
const bool BNEWBEFOREACTIVE = *PNEWONACTIVE == "before";
|
||||
const bool BNEWISMASTER = *PNEWSTATUS == "master";
|
||||
@@ -101,23 +101,15 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
|
||||
PNODE->workspaceID = pWindow->workspaceID();
|
||||
PNODE->pWindow = pWindow;
|
||||
|
||||
const auto WINDOWSONWORKSPACE = getNodesOnWorkspace(PNODE->workspaceID);
|
||||
static auto PMFACT = CConfigValue<Hyprlang::FLOAT>("master:mfact");
|
||||
float lastSplitPercent = *PMFACT;
|
||||
const auto WINDOWSONWORKSPACE = getNodesOnWorkspace(PNODE->workspaceID);
|
||||
static auto PMFACT = CConfigValue<Hyprlang::FLOAT>("master:mfact");
|
||||
float lastSplitPercent = *PMFACT;
|
||||
|
||||
auto OPENINGON = isWindowTiled(g_pCompositor->m_pLastWindow.lock()) && g_pCompositor->m_pLastWindow->m_pWorkspace == pWindow->m_pWorkspace ?
|
||||
getNodeFromWindow(g_pCompositor->m_pLastWindow.lock()) :
|
||||
getMasterNodeOnWorkspace(pWindow->workspaceID());
|
||||
|
||||
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
|
||||
|
||||
if (g_pInputManager->m_bWasDraggingWindow && OPENINGON) {
|
||||
if (OPENINGON->pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, pWindow))
|
||||
return;
|
||||
}
|
||||
|
||||
pWindow->applyGroupRules();
|
||||
auto OPENINGON = isWindowTiled(g_pCompositor->m_pLastWindow.lock()) && g_pCompositor->m_pLastWindow->m_pWorkspace == pWindow->m_pWorkspace ?
|
||||
getNodeFromWindow(g_pCompositor->m_pLastWindow.lock()) :
|
||||
getMasterNodeOnWorkspace(pWindow->workspaceID());
|
||||
|
||||
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
|
||||
static auto PDROPATCURSOR = CConfigValue<Hyprlang::INT>("master:drop_at_cursor");
|
||||
eOrientation orientation = getDynamicOrientation(pWindow->m_pWorkspace);
|
||||
const auto NODEIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *PNODE);
|
||||
@@ -208,7 +200,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
|
||||
PNODE->percMaster = lastSplitPercent;
|
||||
|
||||
// first, check if it isn't too big.
|
||||
if (const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow); MAXSIZE.x < PMONITOR->vecSize.x * lastSplitPercent || MAXSIZE.y < PMONITOR->vecSize.y) {
|
||||
if (const auto MAXSIZE = pWindow->requestedMaxSize(); MAXSIZE.x < PMONITOR->vecSize.x * lastSplitPercent || MAXSIZE.y < PMONITOR->vecSize.y) {
|
||||
// we can't continue. make it floating.
|
||||
pWindow->m_bIsFloating = true;
|
||||
m_lMasterNodesData.remove(*PNODE);
|
||||
@@ -220,7 +212,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
|
||||
PNODE->percMaster = lastSplitPercent;
|
||||
|
||||
// first, check if it isn't too big.
|
||||
if (const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow);
|
||||
if (const auto MAXSIZE = pWindow->requestedMaxSize();
|
||||
MAXSIZE.x < PMONITOR->vecSize.x * (1 - lastSplitPercent) || MAXSIZE.y < PMONITOR->vecSize.y * (1.f / (WINDOWSONWORKSPACE - 1))) {
|
||||
// we can't continue. make it floating.
|
||||
pWindow->m_bIsFloating = true;
|
||||
@@ -231,7 +223,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
|
||||
}
|
||||
|
||||
// recalc
|
||||
recalculateMonitor(pWindow->m_iMonitorID);
|
||||
recalculateMonitor(pWindow->monitorID());
|
||||
}
|
||||
|
||||
void CHyprMasterLayout::onWindowRemovedTiling(PHLWINDOW pWindow) {
|
||||
@@ -281,7 +273,7 @@ void CHyprMasterLayout::onWindowRemovedTiling(PHLWINDOW pWindow) {
|
||||
}
|
||||
}
|
||||
}
|
||||
recalculateMonitor(pWindow->m_iMonitorID);
|
||||
recalculateMonitor(pWindow->monitorID());
|
||||
}
|
||||
|
||||
void CHyprMasterLayout::recalculateMonitor(const MONITORID& monid) {
|
||||
@@ -299,7 +291,7 @@ void CHyprMasterLayout::recalculateMonitor(const MONITORID& monid) {
|
||||
}
|
||||
|
||||
void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
const auto PMONITOR = pWorkspace->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
@@ -596,18 +588,17 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
}
|
||||
|
||||
void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
PHLMONITOR PMONITOR = nullptr;
|
||||
|
||||
if (g_pCompositor->isWorkspaceSpecial(pNode->workspaceID)) {
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->activeSpecialWorkspaceID() == pNode->workspaceID) {
|
||||
PMONITOR = m.get();
|
||||
PMONITOR = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_iMonitorID);
|
||||
}
|
||||
} else
|
||||
PMONITOR = g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR) {
|
||||
Debug::log(ERR, "Orphaned Node {}!!", pNode);
|
||||
@@ -631,12 +622,11 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
PWINDOW->unsetWindowData(PRIORITY_LAYOUT);
|
||||
PWINDOW->updateWindowData();
|
||||
|
||||
static auto PNOGAPSWHENONLY = CConfigValue<Hyprlang::INT>("master:no_gaps_when_only");
|
||||
static auto PANIMATE = CConfigValue<Hyprlang::INT>("misc:animate_manual_resizes");
|
||||
static auto PGAPSINDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_in");
|
||||
static auto PGAPSOUTDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_out");
|
||||
auto* PGAPSIN = (CCssGapData*)(PGAPSINDATA.ptr())->getData();
|
||||
auto* PGAPSOUT = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData();
|
||||
static auto PANIMATE = CConfigValue<Hyprlang::INT>("misc:animate_manual_resizes");
|
||||
static auto PGAPSINDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_in");
|
||||
static auto PGAPSOUTDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_out");
|
||||
auto* PGAPSIN = (CCssGapData*)(PGAPSINDATA.ptr())->getData();
|
||||
auto* PGAPSOUT = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData();
|
||||
|
||||
auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN);
|
||||
auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT);
|
||||
@@ -649,25 +639,6 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
PWINDOW->m_vSize = pNode->size;
|
||||
PWINDOW->m_vPosition = pNode->position;
|
||||
|
||||
if (*PNOGAPSWHENONLY && !PWINDOW->onSpecialWorkspace() && (getNodesOnWorkspace(PWINDOW->workspaceID()) == 1 || PWINDOW->isEffectiveInternalFSMode(FSMODE_MAXIMIZED))) {
|
||||
|
||||
PWINDOW->m_sWindowData.decorate = CWindowOverridableVar(true, PRIORITY_LAYOUT);
|
||||
PWINDOW->m_sWindowData.noBorder = CWindowOverridableVar(*PNOGAPSWHENONLY != 2, PRIORITY_LAYOUT);
|
||||
PWINDOW->m_sWindowData.noRounding = CWindowOverridableVar(true, PRIORITY_LAYOUT);
|
||||
PWINDOW->m_sWindowData.noShadow = CWindowOverridableVar(true, PRIORITY_LAYOUT);
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
|
||||
const auto RESERVED = PWINDOW->getFullWindowReservedArea();
|
||||
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vPosition + RESERVED.topLeft;
|
||||
PWINDOW->m_vRealSize = PWINDOW->m_vSize - (RESERVED.topLeft + RESERVED.bottomRight);
|
||||
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
|
||||
auto calcPos = PWINDOW->m_vPosition;
|
||||
@@ -729,12 +700,14 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
|
||||
if (!PNODE) {
|
||||
PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goal() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goal() + pixResize).y, 20.0));
|
||||
PWINDOW->m_vRealSize =
|
||||
(PWINDOW->m_vRealSize.goal() + pixResize)
|
||||
.clamp(PWINDOW->m_sWindowData.minSize.valueOr(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), PWINDOW->m_sWindowData.maxSize.valueOr(Vector2D{INFINITY, INFINITY}));
|
||||
PWINDOW->updateWindowDecos();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
static auto ALWAYSCENTER = CConfigValue<Hyprlang::INT>("master:always_center_master");
|
||||
static auto PSMARTRESIZING = CConfigValue<Hyprlang::INT>("master:smart_resizing");
|
||||
|
||||
@@ -863,7 +836,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
|
||||
}
|
||||
|
||||
void CHyprMasterLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFullscreenMode CURRENT_EFFECTIVE_MODE, const eFullscreenMode EFFECTIVE_MODE) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
||||
|
||||
// save position and size if floating
|
||||
@@ -919,7 +892,7 @@ void CHyprMasterLayout::recalculateWindow(PHLWINDOW pWindow) {
|
||||
if (!PNODE)
|
||||
return;
|
||||
|
||||
recalculateMonitor(pWindow->m_iMonitorID);
|
||||
recalculateMonitor(pWindow->monitorID());
|
||||
}
|
||||
|
||||
SWindowRenderLayoutHints CHyprMasterLayout::requestRenderHints(PHLWINDOW pWindow) {
|
||||
@@ -945,9 +918,9 @@ void CHyprMasterLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
|
||||
// if different monitors, send to monitor
|
||||
onWindowRemovedTiling(pWindow);
|
||||
pWindow->moveToWorkspace(PWINDOW2->m_pWorkspace);
|
||||
pWindow->m_iMonitorID = PWINDOW2->m_iMonitorID;
|
||||
pWindow->m_pMonitor = PWINDOW2->m_pMonitor;
|
||||
if (!silent) {
|
||||
const auto pMonitor = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto pMonitor = pWindow->m_pMonitor.lock();
|
||||
g_pCompositor->setActiveMonitor(pMonitor);
|
||||
}
|
||||
onWindowCreatedTiling(pWindow);
|
||||
@@ -969,7 +942,7 @@ void CHyprMasterLayout::switchWindows(PHLWINDOW pWindow, PHLWINDOW pWindow2) {
|
||||
return;
|
||||
|
||||
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
|
||||
std::swap(pWindow2->m_pMonitor, pWindow->m_pMonitor);
|
||||
std::swap(pWindow2->m_pWorkspace, pWindow->m_pWorkspace);
|
||||
}
|
||||
|
||||
@@ -980,9 +953,9 @@ void CHyprMasterLayout::switchWindows(PHLWINDOW pWindow, PHLWINDOW pWindow2) {
|
||||
pWindow->setAnimationsToMove();
|
||||
pWindow2->setAnimationsToMove();
|
||||
|
||||
recalculateMonitor(pWindow->m_iMonitorID);
|
||||
recalculateMonitor(pWindow->monitorID());
|
||||
if (PNODE2->workspaceID != PNODE->workspaceID)
|
||||
recalculateMonitor(pWindow2->m_iMonitorID);
|
||||
recalculateMonitor(pWindow2->monitorID());
|
||||
|
||||
g_pHyprRenderer->damageWindow(pWindow);
|
||||
g_pHyprRenderer->damageWindow(pWindow2);
|
||||
@@ -1001,7 +974,7 @@ void CHyprMasterLayout::alterSplitRatio(PHLWINDOW pWindow, float ratio, bool exa
|
||||
float newRatio = exact ? ratio : PMASTER->percMaster + ratio;
|
||||
PMASTER->percMaster = std::clamp(newRatio, 0.05f, 0.95f);
|
||||
|
||||
recalculateMonitor(pWindow->m_iMonitorID);
|
||||
recalculateMonitor(pWindow->monitorID());
|
||||
}
|
||||
|
||||
PHLWINDOW CHyprMasterLayout::getNextWindow(PHLWINDOW pWindow, bool next) {
|
||||
@@ -1208,7 +1181,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
PNODE->isMaster = true;
|
||||
}
|
||||
|
||||
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||
recalculateMonitor(header.pWindow->monitorID());
|
||||
|
||||
} else if (command == "removemaster") {
|
||||
|
||||
@@ -1240,7 +1213,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
PNODE->isMaster = false;
|
||||
}
|
||||
|
||||
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||
recalculateMonitor(header.pWindow->monitorID());
|
||||
} else if (command == "orientationleft" || command == "orientationright" || command == "orientationtop" || command == "orientationbottom" || command == "orientationcenter") {
|
||||
const auto PWINDOW = header.pWindow;
|
||||
|
||||
@@ -1262,7 +1235,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
else if (command == "orientationcenter")
|
||||
PWORKSPACEDATA->orientation = ORIENTATION_CENTER;
|
||||
|
||||
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||
recalculateMonitor(header.pWindow->monitorID());
|
||||
|
||||
} else if (command == "orientationnext") {
|
||||
runOrientationCycle(header, nullptr, 1);
|
||||
@@ -1297,7 +1270,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
}
|
||||
}
|
||||
|
||||
recalculateMonitor(PWINDOW->m_iMonitorID);
|
||||
recalculateMonitor(PWINDOW->monitorID());
|
||||
} else if (command == "rollprev") {
|
||||
const auto PWINDOW = header.pWindow;
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
@@ -1323,7 +1296,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
}
|
||||
}
|
||||
|
||||
recalculateMonitor(PWINDOW->m_iMonitorID);
|
||||
recalculateMonitor(PWINDOW->monitorID());
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1361,7 +1334,7 @@ void CHyprMasterLayout::runOrientationCycle(SLayoutMessageHeader& header, CVarLi
|
||||
nextOrPrev = cycle.size() + (nextOrPrev % (int)cycle.size());
|
||||
|
||||
PWORKSPACEDATA->orientation = cycle.at(nextOrPrev);
|
||||
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||
recalculateMonitor(header.pWindow->monitorID());
|
||||
}
|
||||
|
||||
void CHyprMasterLayout::buildOrientationCycleVectorFromEOperation(std::vector<eOrientation>& cycle) {
|
||||
|
@@ -29,6 +29,8 @@
|
||||
|
||||
#define MONITOR_INVALID -1L
|
||||
|
||||
#define MIN_WINDOW_SIZE 20.0
|
||||
|
||||
#define LISTENER(name) \
|
||||
void listener_##name(wl_listener*, void*); \
|
||||
inline wl_listener listen_##name = {.notify = listener_##name}
|
||||
|
72
src/main.cpp
72
src/main.cpp
@@ -5,7 +5,9 @@
|
||||
#include "init/initHelpers.hpp"
|
||||
#include "debug/HyprCtl.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <print>
|
||||
using namespace Hyprutils::String;
|
||||
|
||||
#include <fcntl.h>
|
||||
@@ -17,14 +19,15 @@ using namespace Hyprutils::String;
|
||||
#include <filesystem>
|
||||
|
||||
void help() {
|
||||
std::cout << "usage: Hyprland [arg [...]].\n";
|
||||
std::cout << "\nArguments:\n";
|
||||
std::cout << " --help -h - Show this message again\n";
|
||||
std::cout << " --config FILE -c FILE - Specify config file to use\n";
|
||||
std::cout << " --socket NAME - Sets the Wayland socket name (for Wayland socket handover)\n";
|
||||
std::cout << " --wayland-fd FD - Sets the Wayland socket fd (for Wayland socket handover)\n";
|
||||
std::cout << " --i-am-really-stupid - Omits root user privileges check (why would you do that?)\n";
|
||||
std::cout << " --version -v - Print this binary's version\n";
|
||||
std::println("usage: Hyprland [arg [...]].\n");
|
||||
std::println(R"(Arguments:
|
||||
--help -h - Show this message again
|
||||
--config FILE -c FILE - Specify config file to use
|
||||
--socket NAME - Sets the Wayland socket name (for Wayland socket handover)
|
||||
--wayland-fd FD - Sets the Wayland socket fd (for Wayland socket handover)
|
||||
--systeminfo - Prints system infos
|
||||
--i-am-really-stupid - Omits root user privileges check (why would you do that?)
|
||||
--version -v - Print this binary's version)");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
@@ -33,9 +36,9 @@ int main(int argc, char** argv) {
|
||||
throwError("XDG_RUNTIME_DIR is not set!");
|
||||
|
||||
// export HYPRLAND_CMD
|
||||
std::string cmd = "";
|
||||
for (auto i = 0; i < argc; ++i)
|
||||
cmd += std::string(i == 0 ? "" : " ") + argv[i];
|
||||
std::string cmd = argv[0];
|
||||
for (int i = 1; i < argc; ++i)
|
||||
cmd += std::string(" ") + argv[i];
|
||||
|
||||
setenv("HYPRLAND_CMD", cmd.c_str(), 1);
|
||||
setenv("XDG_BACKEND", "wayland", 1);
|
||||
@@ -52,7 +55,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
for (auto it = args.begin(); it != args.end(); it++) {
|
||||
if (it->compare("--i-am-really-stupid") == 0 && !ignoreSudo) {
|
||||
std::cout << "[ WARNING ] Running Hyprland with superuser privileges might damage your system\n";
|
||||
std::println("[ WARNING ] Running Hyprland with superuser privileges might damage your system");
|
||||
|
||||
ignoreSudo = true;
|
||||
} else if (it->compare("--socket") == 0) {
|
||||
@@ -78,7 +81,7 @@ int main(int argc, char** argv) {
|
||||
if (fcntl(socketFd, F_GETFD) == -1)
|
||||
throw std::exception();
|
||||
} catch (...) {
|
||||
std::cerr << "[ ERROR ] Invalid Wayland FD!\n";
|
||||
std::println(stderr, "[ ERROR ] Invalid Wayland FD!");
|
||||
help();
|
||||
|
||||
return 1;
|
||||
@@ -100,7 +103,7 @@ int main(int argc, char** argv) {
|
||||
throw std::exception();
|
||||
}
|
||||
} catch (...) {
|
||||
std::cerr << "[ ERROR ] Config file '" << configPath << "' doesn't exist!\n";
|
||||
std::println(stderr, "[ ERROR ] Config file '{}' doesn't exist!", configPath);
|
||||
help();
|
||||
|
||||
return 1;
|
||||
@@ -116,30 +119,13 @@ int main(int argc, char** argv) {
|
||||
|
||||
return 0;
|
||||
} else if (it->compare("-v") == 0 || it->compare("--version") == 0) {
|
||||
auto commitMsg = trim(GIT_COMMIT_MESSAGE);
|
||||
std::replace(commitMsg.begin(), commitMsg.end(), '#', ' ');
|
||||
std::string result = "Hyprland, built from branch " + std::string(GIT_BRANCH) + " at commit " + GIT_COMMIT_HASH + " " + GIT_DIRTY + " (" + commitMsg +
|
||||
").\nDate: " + GIT_COMMIT_DATE + "\nTag: " + GIT_TAG + ", commits: " + GIT_COMMITS + std::string{"\nbuilt against aquamarine "} + AQUAMARINE_VERSION + "\n" +
|
||||
"\n\nflags: (if any)\n";
|
||||
|
||||
#ifdef LEGACY_RENDERER
|
||||
result += "legacyrenderer\n";
|
||||
#endif
|
||||
#ifndef ISDEBUG
|
||||
result += "debug\n";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
result += "no xwayland\n";
|
||||
#endif
|
||||
|
||||
std::cout << result;
|
||||
std::println("{}", versionRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, ""));
|
||||
return 0;
|
||||
} else if (it->compare("--systeminfo") == 0) {
|
||||
const auto SYSINFO = systemInfoRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, "");
|
||||
std::cout << SYSINFO << "\n";
|
||||
std::println("{}", systemInfoRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, ""));
|
||||
return 0;
|
||||
} else {
|
||||
std::cerr << "[ ERROR ] Unknown option '" << it->c_str() << "'!\n";
|
||||
std::println(stderr, "[ ERROR ] Unknown option '{}' !", it->c_str());
|
||||
help();
|
||||
|
||||
return 1;
|
||||
@@ -147,30 +133,32 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
if (!ignoreSudo && Init::isSudo()) {
|
||||
std::cerr << "[ ERROR ] Hyprland was launched with superuser privileges, but the privileges check is not omitted.\n";
|
||||
std::cerr << " Hint: Use the --i-am-really-stupid flag to omit that check.\n";
|
||||
std::println(stderr,
|
||||
"[ ERROR ] Hyprland was launched with superuser privileges, but the privileges check is not omitted.\n"
|
||||
" Hint: Use the --i-am-really-stupid flag to omit that check.");
|
||||
|
||||
return 1;
|
||||
} else if (ignoreSudo && Init::isSudo()) {
|
||||
std::cout << "Superuser privileges check is omitted. I hope you know what you're doing.\n";
|
||||
std::println("Superuser privileges check is omitted. I hope you know what you're doing.");
|
||||
}
|
||||
|
||||
if (socketName.empty() ^ (socketFd == -1)) {
|
||||
std::cerr << "[ ERROR ] Hyprland was launched with only one of --socket and --wayland-fd.\n";
|
||||
std::cerr << " Hint: Pass both --socket and --wayland-fd to perform Wayland socket handover.\n";
|
||||
std::println(stderr,
|
||||
"[ ERROR ] Hyprland was launched with only one of --socket and --wayland-fd.\n"
|
||||
" Hint: Pass both --socket and --wayland-fd to perform Wayland socket handover.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Welcome to Hyprland!\n";
|
||||
std::println("Welcome to Hyprland!");
|
||||
|
||||
// let's init the compositor.
|
||||
// it initializes basic Wayland stuff in the constructor.
|
||||
try {
|
||||
g_pCompositor = std::make_unique<CCompositor>();
|
||||
g_pCompositor->explicitConfigPath = configPath;
|
||||
} catch (std::exception& e) {
|
||||
std::cout << "Hyprland threw in ctor: " << e.what() << "\nCannot continue.\n";
|
||||
} catch (const std::exception& e) {
|
||||
std::println(stderr, "Hyprland threw in ctor: {}\nCannot continue.", e.what());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@@ -64,7 +64,7 @@ void CAnimationManager::tick() {
|
||||
if (!*PANIMENABLED)
|
||||
animGlobalDisabled = true;
|
||||
|
||||
static auto* const PSHADOWSENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:drop_shadow");
|
||||
static auto* const PSHADOWSENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:shadow:enabled");
|
||||
|
||||
const auto DEFAULTBEZIER = m_mBezierCurves.find("default");
|
||||
|
||||
@@ -85,7 +85,7 @@ void CAnimationManager::tick() {
|
||||
PHLWINDOW PWINDOW = av->m_pWindow.lock();
|
||||
PHLWORKSPACE PWORKSPACE = av->m_pWorkspace.lock();
|
||||
PHLLS PLAYER = av->m_pLayer.lock();
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
PHLMONITOR PMONITOR = nullptr;
|
||||
bool animationsDisabled = animGlobalDisabled;
|
||||
|
||||
if (PWINDOW) {
|
||||
@@ -99,12 +99,12 @@ void CAnimationManager::tick() {
|
||||
PDECO->damageEntire();
|
||||
}
|
||||
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
if (!PMONITOR)
|
||||
continue;
|
||||
animationsDisabled = PWINDOW->m_sWindowData.noAnim.valueOr(animationsDisabled);
|
||||
} else if (PWORKSPACE) {
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
PMONITOR = PWORKSPACE->m_pMonitor.lock();
|
||||
if (!PMONITOR)
|
||||
continue;
|
||||
|
||||
@@ -259,7 +259,7 @@ void CAnimationManager::tick() {
|
||||
|
||||
// manually schedule a frame
|
||||
if (PMONITOR)
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_ANIMATION);
|
||||
}
|
||||
|
||||
// do it here, because if this alters the animation vars deque we would be in trouble above.
|
||||
@@ -325,7 +325,7 @@ void CAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, boo
|
||||
const auto GOALPOS = pWindow->m_vRealPosition.goal();
|
||||
const auto GOALSIZE = pWindow->m_vRealSize.goal();
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return; // unsafe state most likely
|
||||
|
@@ -309,7 +309,7 @@ void CCursorManager::updateTheme() {
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
m->forceFullFrames = 5;
|
||||
g_pCompositor->scheduleFrameForMonitor(m.get(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
|
||||
g_pCompositor->scheduleFrameForMonitor(m, Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -126,6 +126,7 @@ CKeybindManager::CKeybindManager() {
|
||||
m_mDispatchers["denywindowfromgroup"] = denyWindowFromGroup;
|
||||
m_mDispatchers["event"] = event;
|
||||
m_mDispatchers["global"] = global;
|
||||
m_mDispatchers["setprop"] = setProp;
|
||||
|
||||
m_tScrollTimer.reset();
|
||||
|
||||
@@ -271,11 +272,11 @@ void updateRelativeCursorCoords() {
|
||||
g_pCompositor->m_pLastWindow->m_vRelativeCursorCoordsOnLastWarp = g_pInputManager->getMouseCoordsInternal() - g_pCompositor->m_pLastWindow->m_vPosition;
|
||||
}
|
||||
|
||||
bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) {
|
||||
bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
|
||||
if (!monitor)
|
||||
return false;
|
||||
|
||||
const auto LASTMONITOR = g_pCompositor->m_pLastMonitor.get();
|
||||
const auto LASTMONITOR = g_pCompositor->m_pLastMonitor.lock();
|
||||
if (!LASTMONITOR)
|
||||
return false;
|
||||
if (LASTMONITOR == monitor) {
|
||||
@@ -349,9 +350,9 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
|
||||
g_pInputManager->m_pForcedFocus.reset();
|
||||
}
|
||||
|
||||
if (PLASTWINDOW && PLASTWINDOW->m_iMonitorID != PWINDOWTOCHANGETO->m_iMonitorID) {
|
||||
if (PLASTWINDOW && PLASTWINDOW->m_pMonitor != PWINDOWTOCHANGETO->m_pMonitor) {
|
||||
// event
|
||||
const auto PNEWMON = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID);
|
||||
const auto PNEWMON = PWINDOWTOCHANGETO->m_pMonitor.lock();
|
||||
|
||||
g_pCompositor->setActiveMonitor(PNEWMON);
|
||||
}
|
||||
@@ -376,7 +377,7 @@ bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) {
|
||||
|
||||
const auto KEYCODE = e.keycode + 8; // Because to xkbcommon it's +8 from libinput
|
||||
|
||||
const xkb_keysym_t keysym = xkb_state_key_get_one_sym(pKeyboard->resolveBindsBySym ? pKeyboard->xkbState : m_pXKBTranslationState, KEYCODE);
|
||||
const xkb_keysym_t keysym = xkb_state_key_get_one_sym(pKeyboard->resolveBindsBySym ? pKeyboard->xkbSymState : m_pXKBTranslationState, KEYCODE);
|
||||
const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(pKeyboard->xkbState, KEYCODE);
|
||||
|
||||
if (handleInternalKeybinds(internalKeysym))
|
||||
@@ -1011,7 +1012,7 @@ static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional<
|
||||
}
|
||||
g_pCompositor->updateWorkspaceWindows(PWINDOW->workspaceID());
|
||||
g_pCompositor->updateWorkspaceWindowData(PWINDOW->workspaceID());
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID());
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
return {};
|
||||
@@ -1035,7 +1036,7 @@ SDispatchResult CKeybindManager::centerWindow(std::string args) {
|
||||
if (!PWINDOW || !PWINDOW->m_bIsFloating || PWINDOW->isFullscreen())
|
||||
return {.success = false, .error = "No floating window found"};
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
|
||||
auto RESERVEDOFFSET = Vector2D();
|
||||
if (args == "1")
|
||||
@@ -1081,7 +1082,7 @@ SWorkspaceIDName getWorkspaceToChangeFromArgs(std::string args, PHLWORKSPACE PCU
|
||||
|
||||
const auto ID = PCURRENTWORKSPACE->m_iID;
|
||||
if (const auto PWORKSPACETOCHANGETO = g_pCompositor->getWorkspaceByID(PPREVWS.id); PWORKSPACETOCHANGETO) {
|
||||
if (PER_MON && PCURRENTWORKSPACE->m_iMonitorID != PWORKSPACETOCHANGETO->m_iMonitorID)
|
||||
if (PER_MON && PCURRENTWORKSPACE->m_pMonitor != PWORKSPACETOCHANGETO->m_pMonitor)
|
||||
return {WORKSPACE_NOT_CHANGED, ""};
|
||||
return {ID, PWORKSPACETOCHANGETO->m_szName};
|
||||
}
|
||||
@@ -1096,7 +1097,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
|
||||
static auto PALLOWWORKSPACECYCLES = CConfigValue<Hyprlang::INT>("binds:allow_workspace_cycles");
|
||||
static auto PWORKSPACECENTERON = CConfigValue<Hyprlang::INT>("binds:workspace_center_on");
|
||||
|
||||
const auto PMONITOR = g_pCompositor->m_pLastMonitor.get();
|
||||
const auto PMONITOR = g_pCompositor->m_pLastMonitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return {.success = false, .error = "Last monitor not found"};
|
||||
@@ -1135,7 +1136,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
|
||||
|
||||
g_pInputManager->releaseAllMouseButtons();
|
||||
|
||||
const auto PMONITORWORKSPACEOWNER = PMONITOR->ID == pWorkspaceToChangeTo->m_iMonitorID ? PMONITOR : g_pCompositor->getMonitorFromID(pWorkspaceToChangeTo->m_iMonitorID);
|
||||
const auto PMONITORWORKSPACEOWNER = PMONITOR == pWorkspaceToChangeTo->m_pMonitor ? PMONITOR : pWorkspaceToChangeTo->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITORWORKSPACEOWNER)
|
||||
return {.success = false, .error = "Workspace to switch to has no monitor"};
|
||||
@@ -1260,7 +1261,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
}
|
||||
|
||||
auto pWorkspace = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||
CMonitor* pMonitor = nullptr;
|
||||
PHLMONITOR pMonitor = nullptr;
|
||||
const auto POLDWS = PWINDOW->m_pWorkspace;
|
||||
static auto PALLOWWORKSPACECYCLES = CConfigValue<Hyprlang::INT>("binds:allow_workspace_cycles");
|
||||
|
||||
@@ -1270,11 +1271,11 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
|
||||
if (pWorkspace) {
|
||||
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
|
||||
pMonitor = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
pMonitor = pWorkspace->m_pMonitor.lock();
|
||||
g_pCompositor->setActiveMonitor(pMonitor);
|
||||
} else {
|
||||
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->m_iMonitorID, workspaceName, false);
|
||||
pMonitor = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->monitorID(), workspaceName, false);
|
||||
pMonitor = pWorkspace->m_pMonitor.lock();
|
||||
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
|
||||
}
|
||||
|
||||
@@ -1283,7 +1284,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
if (pWorkspace->m_bIsSpecialWorkspace)
|
||||
pMonitor->setSpecialWorkspace(pWorkspace);
|
||||
else if (POLDWS->m_bIsSpecialWorkspace)
|
||||
g_pCompositor->getMonitorFromID(POLDWS->m_iMonitorID)->setSpecialWorkspace(nullptr);
|
||||
POLDWS->m_pMonitor.lock()->setSpecialWorkspace(nullptr);
|
||||
|
||||
if (*PALLOWWORKSPACECYCLES)
|
||||
pWorkspace->rememberPrevWorkspace(POLDWS);
|
||||
@@ -1328,7 +1329,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||
if (pWorkspace) {
|
||||
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
|
||||
} else {
|
||||
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->m_iMonitorID, workspaceName, false);
|
||||
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->monitorID(), workspaceName, false);
|
||||
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
|
||||
}
|
||||
|
||||
@@ -1475,7 +1476,7 @@ SDispatchResult CKeybindManager::moveActiveTo(std::string args) {
|
||||
|
||||
if (PLASTWINDOW->m_bIsFloating) {
|
||||
std::optional<float> vPosx, vPosy;
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PLASTWINDOW->m_iMonitorID);
|
||||
const auto PMONITOR = PLASTWINDOW->m_pMonitor.lock();
|
||||
const auto BORDERSIZE = PLASTWINDOW->getRealBorderSize();
|
||||
|
||||
switch (arg) {
|
||||
@@ -1795,7 +1796,7 @@ SDispatchResult CKeybindManager::exitHyprland(std::string argz) {
|
||||
}
|
||||
|
||||
SDispatchResult CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
||||
CMonitor* PMONITOR = g_pCompositor->getMonitorFromString(args);
|
||||
PHLMONITOR PMONITOR = g_pCompositor->getMonitorFromString(args);
|
||||
|
||||
if (!PMONITOR) {
|
||||
Debug::log(ERR, "Ignoring moveCurrentWorkspaceToMonitor: monitor doesnt exist");
|
||||
@@ -1848,13 +1849,13 @@ SDispatchResult CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
||||
}
|
||||
|
||||
SDispatchResult CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) {
|
||||
auto workspaceID = getWorkspaceIDNameFromString(args).id;
|
||||
auto [workspaceID, workspaceName] = getWorkspaceIDNameFromString(args);
|
||||
if (workspaceID == WORKSPACE_INVALID) {
|
||||
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor invalid workspace!");
|
||||
return {.success = false, .error = "focusWorkspaceOnCurrentMonitor invalid workspace!"};
|
||||
}
|
||||
|
||||
const auto PCURRMONITOR = g_pCompositor->m_pLastMonitor.get();
|
||||
const auto PCURRMONITOR = g_pCompositor->m_pLastMonitor.lock();
|
||||
|
||||
if (!PCURRMONITOR) {
|
||||
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor monitor doesn't exist!");
|
||||
@@ -1864,7 +1865,7 @@ SDispatchResult CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args
|
||||
auto pWorkspace = g_pCompositor->getWorkspaceByID(workspaceID);
|
||||
|
||||
if (!pWorkspace) {
|
||||
pWorkspace = g_pCompositor->createNewWorkspace(workspaceID, PCURRMONITOR->ID);
|
||||
pWorkspace = g_pCompositor->createNewWorkspace(workspaceID, PCURRMONITOR->ID, workspaceName);
|
||||
// we can skip the moving, since it's already on the current monitor
|
||||
changeworkspace(pWorkspace->getConfigName());
|
||||
return {};
|
||||
@@ -1882,8 +1883,8 @@ SDispatchResult CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args
|
||||
workspaceID = pWorkspace->m_iID;
|
||||
}
|
||||
|
||||
if (pWorkspace->m_iMonitorID != PCURRMONITOR->ID) {
|
||||
const auto POLDMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
if (pWorkspace->m_pMonitor != PCURRMONITOR) {
|
||||
const auto POLDMONITOR = pWorkspace->m_pMonitor.lock();
|
||||
if (!POLDMONITOR) { // wat
|
||||
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor old monitor doesn't exist!");
|
||||
return {.success = false, .error = "focusWorkspaceOnCurrentMonitor old monitor doesn't exist!"};
|
||||
@@ -1944,7 +1945,7 @@ SDispatchResult CKeybindManager::forceRendererReload(std::string args) {
|
||||
continue;
|
||||
|
||||
auto rule = g_pConfigManager->getMonitorRuleFor(m);
|
||||
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule, true)) {
|
||||
if (!g_pHyprRenderer->applyMonitorRule(m, &rule, true)) {
|
||||
overAgain = true;
|
||||
break;
|
||||
}
|
||||
@@ -2427,7 +2428,7 @@ SDispatchResult CKeybindManager::dpms(std::string arg) {
|
||||
}
|
||||
|
||||
if (enable)
|
||||
g_pHyprRenderer->damageMonitor(m.get());
|
||||
g_pHyprRenderer->damageMonitor(m);
|
||||
|
||||
m->events.dpmsChanged.emit();
|
||||
}
|
||||
@@ -2509,7 +2510,7 @@ SDispatchResult CKeybindManager::pinActive(std::string args) {
|
||||
|
||||
PWINDOW->m_bPinned = !PWINDOW->m_bPinned;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR) {
|
||||
Debug::log(ERR, "pin: monitor not found");
|
||||
@@ -2658,15 +2659,14 @@ void CKeybindManager::moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowIn
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); // This removes groupped property!
|
||||
|
||||
if (pWindow->m_iMonitorID != pWindowInDirection->m_iMonitorID) {
|
||||
if (pWindow->m_pMonitor != pWindowInDirection->m_pMonitor) {
|
||||
pWindow->moveToWorkspace(pWindowInDirection->m_pWorkspace);
|
||||
pWindow->m_iMonitorID = pWindowInDirection->m_iMonitorID;
|
||||
pWindow->m_pMonitor = pWindowInDirection->m_pMonitor;
|
||||
}
|
||||
|
||||
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
|
||||
pWindowInDirection = *USECURRPOS ? pWindowInDirection : pWindowInDirection->getGroupTail();
|
||||
(*USECURRPOS ? pWindowInDirection : pWindowInDirection->getGroupTail())->insertWindowToGroup(pWindow);
|
||||
|
||||
pWindowInDirection->insertWindowToGroup(pWindow);
|
||||
pWindowInDirection->setGroupCurrent(pWindow);
|
||||
pWindow->updateWindowDecos();
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
|
||||
@@ -2891,3 +2891,97 @@ SDispatchResult CKeybindManager::event(std::string args) {
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"custom", args});
|
||||
return {};
|
||||
}
|
||||
|
||||
SDispatchResult CKeybindManager::setProp(std::string args) {
|
||||
CVarList vars(args, 3, ' ');
|
||||
|
||||
if (vars.size() < 3)
|
||||
return {.success = false, .error = "Not enough args"};
|
||||
|
||||
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock();
|
||||
const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[0]);
|
||||
|
||||
if (!PWINDOW)
|
||||
return {.success = false, .error = "Window not found"};
|
||||
|
||||
const auto PROP = vars[1];
|
||||
const auto VAL = vars[2];
|
||||
|
||||
bool noFocus = PWINDOW->m_sWindowData.noFocus.valueOrDefault();
|
||||
|
||||
try {
|
||||
if (PROP == "animationstyle") {
|
||||
PWINDOW->m_sWindowData.animationStyle = CWindowOverridableVar(VAL, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "maxsize") {
|
||||
PWINDOW->m_sWindowData.maxSize = CWindowOverridableVar(configStringToVector2D(VAL), PRIORITY_SET_PROP);
|
||||
PWINDOW->clampWindowSize(std::nullopt, PWINDOW->m_sWindowData.maxSize.value());
|
||||
PWINDOW->setHidden(false);
|
||||
} else if (PROP == "minsize") {
|
||||
PWINDOW->m_sWindowData.minSize = CWindowOverridableVar(configStringToVector2D(VAL), PRIORITY_SET_PROP);
|
||||
PWINDOW->clampWindowSize(PWINDOW->m_sWindowData.minSize.value(), std::nullopt);
|
||||
PWINDOW->setHidden(false);
|
||||
} else if (PROP == "alpha") {
|
||||
PWINDOW->m_sWindowData.alpha = CWindowOverridableVar(SAlphaValue{std::stof(VAL), PWINDOW->m_sWindowData.alpha.valueOrDefault().m_bOverride}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "alphainactive") {
|
||||
PWINDOW->m_sWindowData.alphaInactive =
|
||||
CWindowOverridableVar(SAlphaValue{std::stof(VAL), PWINDOW->m_sWindowData.alphaInactive.valueOrDefault().m_bOverride}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "alphafullscreen") {
|
||||
PWINDOW->m_sWindowData.alphaFullscreen =
|
||||
CWindowOverridableVar(SAlphaValue{std::stof(VAL), PWINDOW->m_sWindowData.alphaFullscreen.valueOrDefault().m_bOverride}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "alphaoverride") {
|
||||
PWINDOW->m_sWindowData.alpha =
|
||||
CWindowOverridableVar(SAlphaValue{PWINDOW->m_sWindowData.alpha.valueOrDefault().m_fAlpha, (bool)configStringToInt(VAL)}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "alphainactiveoverride") {
|
||||
PWINDOW->m_sWindowData.alphaInactive =
|
||||
CWindowOverridableVar(SAlphaValue{PWINDOW->m_sWindowData.alphaInactive.valueOrDefault().m_fAlpha, (bool)configStringToInt(VAL)}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "alphafullscreenoverride") {
|
||||
PWINDOW->m_sWindowData.alphaFullscreen =
|
||||
CWindowOverridableVar(SAlphaValue{PWINDOW->m_sWindowData.alphaFullscreen.valueOrDefault().m_fAlpha, (bool)configStringToInt(VAL)}, PRIORITY_SET_PROP);
|
||||
} else if (PROP == "activebordercolor" || PROP == "inactivebordercolor") {
|
||||
CGradientValueData colorData = {};
|
||||
if (vars.size() > 4) {
|
||||
for (int i = 3; i < static_cast<int>(vars.size()); ++i) {
|
||||
const auto TOKEN = vars[i];
|
||||
if (TOKEN.ends_with("deg"))
|
||||
colorData.m_fAngle = std::stoi(TOKEN.substr(0, TOKEN.size() - 3)) * (PI / 180.0);
|
||||
else
|
||||
colorData.m_vColors.push_back(configStringToInt(TOKEN));
|
||||
}
|
||||
} else if (VAL != "-1")
|
||||
colorData.m_vColors.push_back(configStringToInt(VAL));
|
||||
|
||||
if (PROP == "activebordercolor")
|
||||
PWINDOW->m_sWindowData.activeBorderColor = CWindowOverridableVar(colorData, PRIORITY_SET_PROP);
|
||||
else
|
||||
PWINDOW->m_sWindowData.inactiveBorderColor = CWindowOverridableVar(colorData, PRIORITY_SET_PROP);
|
||||
} else if (auto search = g_pConfigManager->mbWindowProperties.find(PROP); search != g_pConfigManager->mbWindowProperties.end()) {
|
||||
auto pWindowDataElement = search->second(PWINDOW);
|
||||
if (VAL == "toggle")
|
||||
*pWindowDataElement = CWindowOverridableVar(!pWindowDataElement->valueOrDefault(), PRIORITY_SET_PROP);
|
||||
else if (VAL == "unset")
|
||||
pWindowDataElement->unset(PRIORITY_SET_PROP);
|
||||
else
|
||||
*pWindowDataElement = CWindowOverridableVar((bool)configStringToInt(VAL), PRIORITY_SET_PROP);
|
||||
} else if (auto search = g_pConfigManager->miWindowProperties.find(PROP); search != g_pConfigManager->miWindowProperties.end()) {
|
||||
if (VAL == "unset")
|
||||
search->second(PWINDOW)->unset(PRIORITY_SET_PROP);
|
||||
else
|
||||
*(search->second(PWINDOW)) = CWindowOverridableVar((int)configStringToInt(VAL), PRIORITY_SET_PROP);
|
||||
} else {
|
||||
return {.success = false, .error = "Prop not found"};
|
||||
}
|
||||
} catch (std::exception& e) { return {.success = false, .error = std::format("Error parsing prop value: {}", std::string(e.what()))}; }
|
||||
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
if (!(PWINDOW->m_sWindowData.noFocus.valueOrDefault() == noFocus)) {
|
||||
g_pCompositor->focusWindow(nullptr);
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
g_pCompositor->focusWindow(PLASTWINDOW);
|
||||
}
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors)
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@@ -146,7 +146,7 @@ class CKeybindManager {
|
||||
void updateXKBTranslationState();
|
||||
bool ensureMouseBindState();
|
||||
|
||||
static bool tryMoveFocusToMonitor(CMonitor* monitor);
|
||||
static bool tryMoveFocusToMonitor(PHLMONITOR monitor);
|
||||
static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = "");
|
||||
static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection);
|
||||
static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO);
|
||||
@@ -217,6 +217,7 @@ class CKeybindManager {
|
||||
static SDispatchResult denyWindowFromGroup(std::string);
|
||||
static SDispatchResult global(std::string);
|
||||
static SDispatchResult event(std::string);
|
||||
static SDispatchResult setProp(std::string);
|
||||
|
||||
friend class CCompositor;
|
||||
friend class CInputManager;
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../protocols/PointerGestures.hpp"
|
||||
#include "../protocols/RelativePointer.hpp"
|
||||
#include "../protocols/FractionalScale.hpp"
|
||||
#include "../protocols/IdleNotify.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
@@ -13,7 +14,7 @@
|
||||
|
||||
CPointerManager::CPointerManager() {
|
||||
hooks.monitorAdded = g_pHookSystem->hookDynamic("monitorAdded", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
auto PMONITOR = std::any_cast<CMonitor*>(data)->self.lock();
|
||||
auto PMONITOR = std::any_cast<PHLMONITOR>(data);
|
||||
|
||||
onMonitorLayoutChange();
|
||||
|
||||
@@ -28,7 +29,7 @@ CPointerManager::CPointerManager() {
|
||||
});
|
||||
|
||||
hooks.monitorPreRender = g_pHookSystem->hookDynamic("preMonitorCommit", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
auto state = stateFor(std::any_cast<CMonitor*>(data)->self.lock());
|
||||
auto state = stateFor(std::any_cast<PHLMONITOR>(data));
|
||||
if (!state)
|
||||
return;
|
||||
|
||||
@@ -50,34 +51,16 @@ void CPointerManager::unlockSoftwareAll() {
|
||||
updateCursorBackend();
|
||||
}
|
||||
|
||||
void CPointerManager::lockSoftwareForMonitor(CMonitor* Monitor) {
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->ID == Monitor->ID) {
|
||||
lockSoftwareForMonitor(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPointerManager::lockSoftwareForMonitor(SP<CMonitor> mon) {
|
||||
auto state = stateFor(mon);
|
||||
void CPointerManager::lockSoftwareForMonitor(PHLMONITOR mon) {
|
||||
auto const state = stateFor(mon);
|
||||
state->softwareLocks++;
|
||||
|
||||
if (state->softwareLocks == 1)
|
||||
updateCursorBackend();
|
||||
}
|
||||
|
||||
void CPointerManager::unlockSoftwareForMonitor(CMonitor* Monitor) {
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->ID == Monitor->ID) {
|
||||
unlockSoftwareForMonitor(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPointerManager::unlockSoftwareForMonitor(SP<CMonitor> mon) {
|
||||
auto state = stateFor(mon);
|
||||
void CPointerManager::unlockSoftwareForMonitor(PHLMONITOR mon) {
|
||||
auto const state = stateFor(mon);
|
||||
state->softwareLocks--;
|
||||
if (state->softwareLocks < 0)
|
||||
state->softwareLocks = 0;
|
||||
@@ -86,8 +69,8 @@ void CPointerManager::unlockSoftwareForMonitor(SP<CMonitor> mon) {
|
||||
updateCursorBackend();
|
||||
}
|
||||
|
||||
bool CPointerManager::softwareLockedFor(SP<CMonitor> mon) {
|
||||
auto state = stateFor(mon);
|
||||
bool CPointerManager::softwareLockedFor(PHLMONITOR mon) {
|
||||
auto const state = stateFor(mon);
|
||||
return state->softwareLocks > 0 || state->hardwareFailed;
|
||||
}
|
||||
|
||||
@@ -99,7 +82,7 @@ bool CPointerManager::hasCursor() {
|
||||
return currentCursorImage.pBuffer || currentCursorImage.surface;
|
||||
}
|
||||
|
||||
SP<CPointerManager::SMonitorPointerState> CPointerManager::stateFor(SP<CMonitor> mon) {
|
||||
SP<CPointerManager::SMonitorPointerState> CPointerManager::stateFor(PHLMONITOR mon) {
|
||||
auto it = std::find_if(monitorStates.begin(), monitorStates.end(), [mon](const auto& other) { return other->monitor == mon; });
|
||||
if (it == monitorStates.end())
|
||||
return monitorStates.emplace_back(makeShared<CPointerManager::SMonitorPointerState>(mon));
|
||||
@@ -264,19 +247,16 @@ void CPointerManager::resetCursorImage(bool apply) {
|
||||
}
|
||||
|
||||
void CPointerManager::updateCursorBackend() {
|
||||
static auto PNOHW = CConfigValue<Hyprlang::INT>("cursor:no_hardware_cursors");
|
||||
|
||||
const auto CURSORBOX = getCursorBoxGlobal();
|
||||
const auto CURSORBOX = getCursorBoxGlobal();
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
auto state = stateFor(m);
|
||||
|
||||
if (!m->m_bEnabled || !m->dpmsStatus) {
|
||||
Debug::log(TRACE, "Not updating hw cursors: disabled / dpms off display");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto CROSSES = !m->logicalBox().intersection(CURSORBOX).empty();
|
||||
auto state = stateFor(m);
|
||||
|
||||
if (!CROSSES) {
|
||||
if (state->cursorFrontBuffer)
|
||||
@@ -285,7 +265,7 @@ void CPointerManager::updateCursorBackend() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state->softwareLocks > 0 || *PNOHW || !attemptHardwareCursor(state)) {
|
||||
if (state->softwareLocks > 0 || g_pConfigManager->shouldUseSoftwareCursors() || !attemptHardwareCursor(state)) {
|
||||
Debug::log(TRACE, "Output {} rejected hardware cursors, falling back to sw", m->szName);
|
||||
state->box = getCursorBoxLogicalForMonitor(state->monitor.lock());
|
||||
state->hardwareFailed = true;
|
||||
@@ -328,7 +308,7 @@ void CPointerManager::onCursorMoved() {
|
||||
continue;
|
||||
|
||||
const auto CURSORPOS = getCursorPosForMonitor(m);
|
||||
m->output->moveCursor(CURSORPOS);
|
||||
m->output->moveCursor(CURSORPOS, m->shouldSkipScheduleFrameOnMouseEvent());
|
||||
}
|
||||
|
||||
if (recalc)
|
||||
@@ -342,7 +322,7 @@ bool CPointerManager::attemptHardwareCursor(SP<CPointerManager::SMonitorPointerS
|
||||
return false;
|
||||
|
||||
const auto CURSORPOS = getCursorPosForMonitor(state->monitor.lock());
|
||||
state->monitor->output->moveCursor(CURSORPOS);
|
||||
state->monitor->output->moveCursor(CURSORPOS, state->monitor->shouldSkipScheduleFrameOnMouseEvent());
|
||||
|
||||
auto texture = getCurrentCursorTexture();
|
||||
|
||||
@@ -385,16 +365,15 @@ bool CPointerManager::setHWCursorBuffer(SP<SMonitorPointerState> state, SP<Aquam
|
||||
|
||||
state->cursorFrontBuffer = buf;
|
||||
|
||||
g_pCompositor->scheduleFrameForMonitor(state->monitor.get(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
|
||||
if (!state->monitor->shouldSkipScheduleFrameOnMouseEvent())
|
||||
g_pCompositor->scheduleFrameForMonitor(state->monitor.lock(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager::SMonitorPointerState> state, SP<CTexture> texture) {
|
||||
auto output = state->monitor->output;
|
||||
|
||||
auto maxSize = output->cursorPlaneSize();
|
||||
auto cursorSize = currentCursorImage.size;
|
||||
auto maxSize = state->monitor->output->cursorPlaneSize();
|
||||
auto const& cursorSize = currentCursorImage.size;
|
||||
|
||||
if (maxSize == Vector2D{})
|
||||
return nullptr;
|
||||
@@ -441,10 +420,8 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CRegion damage = {0, 0, INT16_MAX, INT16_MAX};
|
||||
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
g_pHyprOpenGL->m_RenderData.pMonitor = state->monitor.get();
|
||||
g_pHyprOpenGL->m_RenderData.pMonitor = state->monitor;
|
||||
|
||||
auto RBO = g_pHyprRenderer->getOrCreateRenderbuffer(buf, state->monitor->cursorSwapchain->currentOptions().format);
|
||||
if (!RBO) {
|
||||
@@ -501,7 +478,7 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
|
||||
|
||||
RBO->bind();
|
||||
|
||||
g_pHyprOpenGL->beginSimple(state->monitor.get(), damage, RBO);
|
||||
g_pHyprOpenGL->beginSimple(state->monitor.lock(), {0, 0, INT16_MAX, INT16_MAX}, RBO);
|
||||
g_pHyprOpenGL->clear(CColor{0.F, 0.F, 0.F, 0.F});
|
||||
|
||||
CBox xbox = {{}, Vector2D{currentCursorImage.size / currentCursorImage.scale * state->monitor->scale}.round()};
|
||||
@@ -512,14 +489,14 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
|
||||
|
||||
g_pHyprOpenGL->end();
|
||||
glFlush();
|
||||
g_pHyprOpenGL->m_RenderData.pMonitor = nullptr;
|
||||
g_pHyprOpenGL->m_RenderData.pMonitor.reset();
|
||||
|
||||
g_pHyprRenderer->onRenderbufferDestroy(RBO.get());
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void CPointerManager::renderSoftwareCursorsFor(SP<CMonitor> pMonitor, timespec* now, CRegion& damage, std::optional<Vector2D> overridePos) {
|
||||
void CPointerManager::renderSoftwareCursorsFor(PHLMONITOR pMonitor, timespec* now, CRegion& damage, std::optional<Vector2D> overridePos) {
|
||||
if (!hasCursor())
|
||||
return;
|
||||
|
||||
@@ -554,7 +531,7 @@ void CPointerManager::renderSoftwareCursorsFor(SP<CMonitor> pMonitor, timespec*
|
||||
currentCursorImage.surface->resource()->frame(now);
|
||||
}
|
||||
|
||||
Vector2D CPointerManager::getCursorPosForMonitor(SP<CMonitor> pMonitor) {
|
||||
Vector2D CPointerManager::getCursorPosForMonitor(PHLMONITOR pMonitor) {
|
||||
return CBox{pointerPos - pMonitor->vecPosition, {0, 0}}
|
||||
.transform(wlTransformToHyprutils(invertTransform(pMonitor->transform)), pMonitor->vecTransformedSize.x / pMonitor->scale,
|
||||
pMonitor->vecTransformedSize.y / pMonitor->scale)
|
||||
@@ -562,7 +539,7 @@ Vector2D CPointerManager::getCursorPosForMonitor(SP<CMonitor> pMonitor) {
|
||||
pMonitor->scale;
|
||||
}
|
||||
|
||||
Vector2D CPointerManager::transformedHotspot(SP<CMonitor> pMonitor) {
|
||||
Vector2D CPointerManager::transformedHotspot(PHLMONITOR pMonitor) {
|
||||
if (!pMonitor->cursorSwapchain)
|
||||
return {}; // doesn't matter, we have no hw cursor, and this is only for hw cursors
|
||||
|
||||
@@ -572,7 +549,7 @@ Vector2D CPointerManager::transformedHotspot(SP<CMonitor> pMonitor) {
|
||||
.pos();
|
||||
}
|
||||
|
||||
CBox CPointerManager::getCursorBoxLogicalForMonitor(SP<CMonitor> pMonitor) {
|
||||
CBox CPointerManager::getCursorBoxLogicalForMonitor(PHLMONITOR pMonitor) {
|
||||
return getCursorBoxGlobal().translate(-pMonitor->vecPosition);
|
||||
}
|
||||
|
||||
@@ -657,15 +634,13 @@ Vector2D CPointerManager::closestValid(const Vector2D& pos) {
|
||||
}
|
||||
|
||||
void CPointerManager::damageIfSoftware() {
|
||||
auto b = getCursorBoxGlobal();
|
||||
|
||||
static auto PNOHW = CConfigValue<Hyprlang::INT>("cursor:no_hardware_cursors");
|
||||
auto b = getCursorBoxGlobal().expand(4);
|
||||
|
||||
for (auto const& mw : monitorStates) {
|
||||
if (mw->monitor.expired() || !mw->monitor->output)
|
||||
continue;
|
||||
|
||||
if ((mw->softwareLocks > 0 || mw->hardwareFailed || *PNOHW) && b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) {
|
||||
if ((mw->softwareLocks > 0 || mw->hardwareFailed || g_pConfigManager->shouldUseSoftwareCursors()) && b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) {
|
||||
g_pHyprRenderer->damageBox(&b, mw->monitor->shouldSkipScheduleFrameOnMouseEvent());
|
||||
break;
|
||||
}
|
||||
@@ -676,8 +651,11 @@ void CPointerManager::warpTo(const Vector2D& logical) {
|
||||
damageIfSoftware();
|
||||
|
||||
pointerPos = closestValid(logical);
|
||||
recheckEnteredOutputs();
|
||||
onCursorMoved();
|
||||
|
||||
if (!g_pInputManager->isLocked()) {
|
||||
recheckEnteredOutputs();
|
||||
onCursorMoved();
|
||||
}
|
||||
|
||||
damageIfSoftware();
|
||||
}
|
||||
@@ -691,7 +669,7 @@ void CPointerManager::move(const Vector2D& deltaLogical) {
|
||||
|
||||
void CPointerManager::warpAbsolute(Vector2D abs, SP<IHID> dev) {
|
||||
|
||||
SP<CMonitor> currentMonitor = g_pCompositor->m_pLastMonitor.lock();
|
||||
PHLMONITOR currentMonitor = g_pCompositor->m_pLastMonitor.lock();
|
||||
if (!currentMonitor || !dev)
|
||||
return;
|
||||
|
||||
@@ -859,7 +837,14 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
|
||||
});
|
||||
|
||||
listener->frame = pointer->pointerEvents.frame.registerListener([this] (std::any e) {
|
||||
g_pSeatManager->sendPointerFrame();
|
||||
bool shouldSkip = false;
|
||||
if (!g_pSeatManager->mouse.expired() && g_pInputManager->isLocked()) {
|
||||
auto PMONITOR = g_pCompositor->m_pLastMonitor.get();
|
||||
shouldSkip = PMONITOR && PMONITOR->shouldSkipScheduleFrameOnMouseEvent();
|
||||
}
|
||||
g_pSeatManager->isPointerFrameSkipped = shouldSkip;
|
||||
if (!g_pSeatManager->isPointerFrameSkipped)
|
||||
g_pSeatManager->sendPointerFrame();
|
||||
});
|
||||
|
||||
listener->swipeBegin = pointer->pointerEvents.swipeBegin.registerListener([this] (std::any e) {
|
||||
@@ -1061,7 +1046,7 @@ void CPointerManager::detachTablet(SP<CTablet> tablet) {
|
||||
std::erase_if(tabletListeners, [tablet](const auto& e) { return e->tablet.expired() || e->tablet == tablet; });
|
||||
}
|
||||
|
||||
void CPointerManager::damageCursor(SP<CMonitor> pMonitor) {
|
||||
void CPointerManager::damageCursor(PHLMONITOR pMonitor) {
|
||||
for (auto const& mw : monitorStates) {
|
||||
if (mw->monitor != pMonitor)
|
||||
continue;
|
||||
@@ -1080,3 +1065,22 @@ void CPointerManager::damageCursor(SP<CMonitor> pMonitor) {
|
||||
Vector2D CPointerManager::cursorSizeLogical() {
|
||||
return currentCursorImage.size / currentCursorImage.scale;
|
||||
}
|
||||
|
||||
void CPointerManager::storeMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel) {
|
||||
storedTime = time;
|
||||
storedDelta += delta;
|
||||
storedUnaccel += deltaUnaccel;
|
||||
}
|
||||
|
||||
void CPointerManager::setStoredMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel) {
|
||||
storedTime = time;
|
||||
storedDelta = delta;
|
||||
storedUnaccel = deltaUnaccel;
|
||||
}
|
||||
|
||||
void CPointerManager::sendStoredMovement() {
|
||||
PROTO::relativePointer->sendRelativeMotion((uint64_t)storedTime * 1000, storedDelta, storedUnaccel);
|
||||
storedTime = 0;
|
||||
storedDelta = Vector2D{};
|
||||
storedUnaccel = Vector2D{};
|
||||
}
|
||||
|
@@ -43,24 +43,25 @@ class CPointerManager {
|
||||
void setCursorSurface(SP<CWLSurface> buf, const Vector2D& hotspot);
|
||||
void resetCursorImage(bool apply = true);
|
||||
|
||||
void lockSoftwareForMonitor(SP<CMonitor> pMonitor);
|
||||
void unlockSoftwareForMonitor(SP<CMonitor> pMonitor);
|
||||
void lockSoftwareForMonitor(CMonitor* pMonitor);
|
||||
void unlockSoftwareForMonitor(CMonitor* pMonitor);
|
||||
void lockSoftwareForMonitor(PHLMONITOR pMonitor);
|
||||
void unlockSoftwareForMonitor(PHLMONITOR pMonitor);
|
||||
void lockSoftwareAll();
|
||||
void unlockSoftwareAll();
|
||||
bool softwareLockedFor(SP<CMonitor> pMonitor);
|
||||
bool softwareLockedFor(PHLMONITOR pMonitor);
|
||||
|
||||
void renderSoftwareCursorsFor(SP<CMonitor> pMonitor, timespec* now, CRegion& damage /* logical */, std::optional<Vector2D> overridePos = {} /* monitor-local */);
|
||||
void renderSoftwareCursorsFor(PHLMONITOR pMonitor, timespec* now, CRegion& damage /* logical */, std::optional<Vector2D> overridePos = {} /* monitor-local */);
|
||||
|
||||
// this is needed e.g. during screensharing where
|
||||
// the software cursors aren't locked during the cursor move, but they
|
||||
// are rendered later.
|
||||
void damageCursor(SP<CMonitor> pMonitor);
|
||||
void damageCursor(PHLMONITOR pMonitor);
|
||||
|
||||
//
|
||||
Vector2D position();
|
||||
Vector2D cursorSizeLogical();
|
||||
void storeMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel);
|
||||
void setStoredMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel);
|
||||
void sendStoredMovement();
|
||||
|
||||
void recheckEnteredOutputs();
|
||||
|
||||
@@ -77,13 +78,13 @@ class CPointerManager {
|
||||
Vector2D closestValid(const Vector2D& pos);
|
||||
|
||||
// returns the thing in device coordinates. Is NOT offset by the hotspot, relies on set_cursor with hotspot.
|
||||
Vector2D getCursorPosForMonitor(SP<CMonitor> pMonitor);
|
||||
Vector2D getCursorPosForMonitor(PHLMONITOR pMonitor);
|
||||
// returns the thing in logical coordinates of the monitor
|
||||
CBox getCursorBoxLogicalForMonitor(SP<CMonitor> pMonitor);
|
||||
CBox getCursorBoxLogicalForMonitor(PHLMONITOR pMonitor);
|
||||
// returns the thing in global coords
|
||||
CBox getCursorBoxGlobal();
|
||||
|
||||
Vector2D transformedHotspot(SP<CMonitor> pMonitor);
|
||||
Vector2D transformedHotspot(PHLMONITOR pMonitor);
|
||||
|
||||
SP<CTexture> getCurrentCursorTexture();
|
||||
|
||||
@@ -154,11 +155,15 @@ class CPointerManager {
|
||||
|
||||
Vector2D pointerPos = {0, 0};
|
||||
|
||||
uint64_t storedTime = 0;
|
||||
Vector2D storedDelta = {0, 0};
|
||||
Vector2D storedUnaccel = {0, 0};
|
||||
|
||||
struct SMonitorPointerState {
|
||||
SMonitorPointerState(SP<CMonitor> m) : monitor(m) {}
|
||||
SMonitorPointerState(PHLMONITOR m) : monitor(m) {}
|
||||
~SMonitorPointerState() {}
|
||||
|
||||
WP<CMonitor> monitor;
|
||||
PHLMONITORREF monitor;
|
||||
|
||||
int softwareLocks = 0;
|
||||
bool hardwareFailed = false;
|
||||
@@ -171,7 +176,7 @@ class CPointerManager {
|
||||
};
|
||||
|
||||
std::vector<SP<SMonitorPointerState>> monitorStates;
|
||||
SP<SMonitorPointerState> stateFor(SP<CMonitor> mon);
|
||||
SP<SMonitorPointerState> stateFor(PHLMONITOR mon);
|
||||
bool attemptHardwareCursor(SP<SMonitorPointerState> state);
|
||||
SP<Aquamarine::IBuffer> renderHWCursorBuffer(SP<SMonitorPointerState> state, SP<CTexture> texture);
|
||||
bool setHWCursorBuffer(SP<SMonitorPointerState> state, SP<Aquamarine::IBuffer> buf);
|
||||
|
@@ -45,6 +45,8 @@
|
||||
#include "../protocols/GlobalShortcuts.hpp"
|
||||
#include "../protocols/XDGDialog.hpp"
|
||||
#include "../protocols/SinglePixel.hpp"
|
||||
#include "../protocols/SecurityContext.hpp"
|
||||
#include "../protocols/CTMControl.hpp"
|
||||
|
||||
#include "../protocols/core/Seat.hpp"
|
||||
#include "../protocols/core/DataDevice.hpp"
|
||||
@@ -60,7 +62,7 @@
|
||||
#include <aquamarine/buffer/Buffer.hpp>
|
||||
#include <aquamarine/backend/Backend.hpp>
|
||||
|
||||
void CProtocolManager::onMonitorModeChange(CMonitor* pMonitor) {
|
||||
void CProtocolManager::onMonitorModeChange(PHLMONITOR pMonitor) {
|
||||
const bool ISMIRROR = pMonitor->isMirror();
|
||||
|
||||
// onModeChanged we check if the current mirror status matches the global.
|
||||
@@ -82,7 +84,7 @@ CProtocolManager::CProtocolManager() {
|
||||
|
||||
// Outputs are a bit dumb, we have to agree.
|
||||
static auto P = g_pHookSystem->hookDynamic("monitorAdded", [this](void* self, SCallbackInfo& info, std::any param) {
|
||||
auto M = std::any_cast<CMonitor*>(param);
|
||||
auto M = std::any_cast<PHLMONITOR>(param);
|
||||
|
||||
// ignore mirrored outputs. I don't think this will ever be hit as mirrors are applied after
|
||||
// this event is emitted iirc.
|
||||
@@ -101,7 +103,7 @@ CProtocolManager::CProtocolManager() {
|
||||
});
|
||||
|
||||
static auto P2 = g_pHookSystem->hookDynamic("monitorRemoved", [this](void* self, SCallbackInfo& info, std::any param) {
|
||||
auto M = std::any_cast<CMonitor*>(param);
|
||||
auto M = std::any_cast<PHLMONITOR>(param);
|
||||
if (!PROTO::outputs.contains(M->szName))
|
||||
return;
|
||||
PROTO::outputs.at(M->szName)->remove();
|
||||
@@ -155,6 +157,8 @@ CProtocolManager::CProtocolManager() {
|
||||
PROTO::globalShortcuts = std::make_unique<CGlobalShortcutsProtocol>(&hyprland_global_shortcuts_manager_v1_interface, 1, "GlobalShortcuts");
|
||||
PROTO::xdgDialog = std::make_unique<CXDGDialogProtocol>(&xdg_dialog_v1_interface, 1, "XDGDialog");
|
||||
PROTO::singlePixel = std::make_unique<CSinglePixelProtocol>(&wp_single_pixel_buffer_manager_v1_interface, 1, "SinglePixel");
|
||||
PROTO::securityContext = std::make_unique<CSecurityContextProtocol>(&wp_security_context_manager_v1_interface, 1, "SecurityContext");
|
||||
PROTO::ctm = std::make_unique<CHyprlandCTMControlProtocol>(&hyprland_ctm_control_manager_v1_interface, 1, "CTMControl");
|
||||
|
||||
for (auto const& b : g_pCompositor->m_pAqBackend->getImplementations()) {
|
||||
if (b->type() != Aquamarine::AQ_BACKEND_DRM)
|
||||
@@ -225,9 +229,64 @@ CProtocolManager::~CProtocolManager() {
|
||||
PROTO::toplevelExport.reset();
|
||||
PROTO::globalShortcuts.reset();
|
||||
PROTO::xdgDialog.reset();
|
||||
PROTO::singlePixel.reset();
|
||||
PROTO::securityContext.reset();
|
||||
PROTO::ctm.reset();
|
||||
|
||||
PROTO::lease.reset();
|
||||
PROTO::sync.reset();
|
||||
PROTO::mesaDRM.reset();
|
||||
PROTO::linuxDma.reset();
|
||||
}
|
||||
|
||||
bool CProtocolManager::isGlobalPrivileged(const wl_global* global) {
|
||||
if (!global)
|
||||
return false;
|
||||
|
||||
for (auto& [k, v] : PROTO::outputs) {
|
||||
if (global == v->getGlobal())
|
||||
return false;
|
||||
}
|
||||
|
||||
// this is a static whitelist of allowed protocols,
|
||||
// outputs are dynamic so we checked them above
|
||||
// clang-format off
|
||||
static const std::vector<wl_global*> ALLOWED_WHITELIST = {
|
||||
PROTO::seat->getGlobal(),
|
||||
PROTO::data->getGlobal(),
|
||||
PROTO::compositor->getGlobal(),
|
||||
PROTO::subcompositor->getGlobal(),
|
||||
PROTO::shm->getGlobal(),
|
||||
PROTO::viewport->getGlobal(),
|
||||
PROTO::tearing->getGlobal(),
|
||||
PROTO::fractional->getGlobal(),
|
||||
PROTO::cursorShape->getGlobal(),
|
||||
PROTO::idleInhibit->getGlobal(),
|
||||
PROTO::relativePointer->getGlobal(),
|
||||
PROTO::xdgDecoration->getGlobal(),
|
||||
PROTO::alphaModifier->getGlobal(),
|
||||
PROTO::pointerGestures->getGlobal(),
|
||||
PROTO::shortcutsInhibit->getGlobal(),
|
||||
PROTO::textInputV1->getGlobal(),
|
||||
PROTO::textInputV3->getGlobal(),
|
||||
PROTO::constraints->getGlobal(),
|
||||
PROTO::activation->getGlobal(),
|
||||
PROTO::idle->getGlobal(),
|
||||
PROTO::ime->getGlobal(),
|
||||
PROTO::virtualKeyboard->getGlobal(),
|
||||
PROTO::virtualPointer->getGlobal(),
|
||||
PROTO::serverDecorationKDE->getGlobal(),
|
||||
PROTO::tablet->getGlobal(),
|
||||
PROTO::presentation->getGlobal(),
|
||||
PROTO::xdgShell->getGlobal(),
|
||||
PROTO::xdgDialog->getGlobal(),
|
||||
PROTO::singlePixel->getGlobal(),
|
||||
PROTO::primarySelection->getGlobal(),
|
||||
PROTO::sync ? PROTO::sync->getGlobal() : nullptr,
|
||||
PROTO::mesaDRM ? PROTO::mesaDRM->getGlobal() : nullptr,
|
||||
PROTO::linuxDma ? PROTO::linuxDma->getGlobal() : nullptr,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
return std::find(ALLOWED_WHITELIST.begin(), ALLOWED_WHITELIST.end(), global) == ALLOWED_WHITELIST.end();
|
||||
}
|
||||
|
@@ -11,10 +11,12 @@ class CProtocolManager {
|
||||
CProtocolManager();
|
||||
~CProtocolManager();
|
||||
|
||||
bool isGlobalPrivileged(const wl_global* global);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, CHyprSignalListener> m_mModeChangeListeners;
|
||||
|
||||
void onMonitorModeChange(CMonitor* pMonitor);
|
||||
void onMonitorModeChange(PHLMONITOR pMonitor);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CProtocolManager> g_pProtocolManager;
|
||||
|
@@ -128,6 +128,9 @@ class CSeatManager {
|
||||
void setGrab(SP<CSeatGrab> grab); // nullptr removes
|
||||
SP<CSeatGrab> seatGrab;
|
||||
|
||||
bool isPointerFrameSkipped = false;
|
||||
bool isPointerFrameCommit = false;
|
||||
|
||||
private:
|
||||
struct SSeatResourceContainer {
|
||||
SSeatResourceContainer(SP<CWLSeatResource>);
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../protocols/FractionalScale.hpp"
|
||||
#include "../protocols/SessionLock.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
|
||||
@@ -72,7 +73,7 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
|
||||
g_pInputManager->refocus();
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors)
|
||||
g_pHyprRenderer->damageMonitor(m.get());
|
||||
g_pHyprRenderer->damageMonitor(m);
|
||||
});
|
||||
|
||||
m_pSessionLock->listeners.destroy = pLock->events.destroyed.registerListener([this](std::any data) {
|
||||
@@ -80,10 +81,11 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
|
||||
g_pCompositor->focusSurface(nullptr);
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors)
|
||||
g_pHyprRenderer->damageMonitor(m.get());
|
||||
g_pHyprRenderer->damageMonitor(m);
|
||||
});
|
||||
|
||||
g_pCompositor->focusSurface(nullptr);
|
||||
g_pSeatManager->setGrab(nullptr);
|
||||
}
|
||||
|
||||
bool CSessionLockManager::isSessionLocked() {
|
||||
|
@@ -34,7 +34,7 @@ SP<CUUIDToken> CTokenManager::getToken(const std::string& uuid) {
|
||||
|
||||
// cleanup expired tokens
|
||||
const auto NOW = std::chrono::steady_clock::now();
|
||||
std::erase_if(m_mTokens, [this, &NOW](const auto& el) { return el.second->expiresAt < NOW; });
|
||||
std::erase_if(m_mTokens, [&NOW](const auto& el) { return el.second->expiresAt < NOW; });
|
||||
|
||||
if (!m_mTokens.contains(uuid))
|
||||
return {};
|
||||
@@ -46,4 +46,4 @@ void CTokenManager::removeToken(SP<CUUIDToken> token) {
|
||||
if (!token)
|
||||
return;
|
||||
m_mTokens.erase(token->uuid);
|
||||
}
|
||||
}
|
||||
|
@@ -117,9 +117,11 @@ void CXCursorManager::loadTheme(std::string const& name, int size, float scale)
|
||||
cursors = loadStandardCursors(themeName, lastLoadSize);
|
||||
} else {
|
||||
for (auto const& p : paths) {
|
||||
auto dirCursors = loadAllFromDir(p, lastLoadSize);
|
||||
std::copy_if(dirCursors.begin(), dirCursors.end(), std::back_inserter(cursors),
|
||||
[this](auto const& p) { return std::none_of(cursors.begin(), cursors.end(), [&p](auto const& dp) { return dp->shape == p->shape; }); });
|
||||
try {
|
||||
auto dirCursors = loadAllFromDir(p, lastLoadSize);
|
||||
std::copy_if(dirCursors.begin(), dirCursors.end(), std::back_inserter(cursors),
|
||||
[this](auto const& p) { return std::none_of(cursors.begin(), cursors.end(), [&p](auto const& dp) { return dp->shape == p->shape; }); });
|
||||
} catch (std::exception& e) { Debug::log(ERR, "XCursor path {} can't be loaded: threw error {}", p, e.what()); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +197,7 @@ SP<SXCursors> CXCursorManager::createCursor(std::string const& shape, XcursorIma
|
||||
return xcursor;
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> CXCursorManager::themePaths(std::string const& theme) {
|
||||
std::set<std::string> CXCursorManager::themePaths(std::string const& theme) {
|
||||
auto const* path = XcursorLibraryPath();
|
||||
|
||||
auto expandTilde = [](std::string const& path) {
|
||||
@@ -274,10 +276,10 @@ std::unordered_set<std::string> CXCursorManager::themePaths(std::string const& t
|
||||
return themes;
|
||||
};
|
||||
|
||||
std::unordered_set<std::string> paths;
|
||||
std::unordered_set<std::string> inherits;
|
||||
std::set<std::string> paths;
|
||||
std::set<std::string> inherits;
|
||||
|
||||
auto scanTheme = [&path, &paths, &expandTilde, &inherits, &getInheritThemes](auto const& t) {
|
||||
auto scanTheme = [&path, &paths, &expandTilde, &inherits, &getInheritThemes](auto const& t) {
|
||||
std::stringstream ss(path);
|
||||
std::string line;
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
#include <set>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <hyprutils/math/Vector2D.hpp>
|
||||
@@ -34,16 +34,16 @@ class CXCursorManager {
|
||||
void syncGsettings();
|
||||
|
||||
private:
|
||||
SP<SXCursors> createCursor(std::string const& shape, XcursorImages* xImages);
|
||||
std::unordered_set<std::string> themePaths(std::string const& theme);
|
||||
std::string getLegacyShapeName(std::string const& shape);
|
||||
std::vector<SP<SXCursors>> loadStandardCursors(std::string const& name, int size);
|
||||
std::vector<SP<SXCursors>> loadAllFromDir(std::string const& path, int size);
|
||||
SP<SXCursors> createCursor(std::string const& shape, XcursorImages* xImages);
|
||||
std::set<std::string> themePaths(std::string const& theme);
|
||||
std::string getLegacyShapeName(std::string const& shape);
|
||||
std::vector<SP<SXCursors>> loadStandardCursors(std::string const& name, int size);
|
||||
std::vector<SP<SXCursors>> loadAllFromDir(std::string const& path, int size);
|
||||
|
||||
int lastLoadSize = 0;
|
||||
float lastLoadScale = 0;
|
||||
std::string themeName = "";
|
||||
SP<SXCursors> defaultCursor;
|
||||
SP<SXCursors> hyprCursor;
|
||||
std::vector<SP<SXCursors>> cursors;
|
||||
int lastLoadSize = 0;
|
||||
float lastLoadScale = 0;
|
||||
std::string themeName = "";
|
||||
SP<SXCursors> defaultCursor;
|
||||
SP<SXCursors> hyprCursor;
|
||||
std::vector<SP<SXCursors>> cursors;
|
||||
};
|
||||
|
@@ -5,14 +5,13 @@
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../xwayland/XWayland.hpp"
|
||||
#include <hyprutils/math/Vector2D.hpp>
|
||||
|
||||
#define OUTPUT_MANAGER_VERSION 3
|
||||
#define OUTPUT_DONE_DEPRECATED_SINCE_VERSION 3
|
||||
#define OUTPUT_DESCRIPTION_MUTABLE_SINCE_VERSION 3
|
||||
|
||||
CHyprXWaylandManager::CHyprXWaylandManager() {
|
||||
;
|
||||
}
|
||||
CHyprXWaylandManager::CHyprXWaylandManager() = default;
|
||||
|
||||
CHyprXWaylandManager::~CHyprXWaylandManager() {
|
||||
#ifndef NO_XWAYLAND
|
||||
@@ -21,7 +20,7 @@ CHyprXWaylandManager::~CHyprXWaylandManager() {
|
||||
}
|
||||
|
||||
SP<CWLSurfaceResource> CHyprXWaylandManager::getWindowSurface(PHLWINDOW pWindow) {
|
||||
return pWindow->m_pWLSurface->resource();
|
||||
return pWindow ? pWindow->m_pWLSurface->resource() : nullptr;
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::activateSurface(SP<CWLSurfaceResource> pSurface, bool activate) {
|
||||
@@ -40,27 +39,31 @@ void CHyprXWaylandManager::activateSurface(SP<CWLSurfaceResource> pSurface, bool
|
||||
return;
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface) {
|
||||
if (activate) {
|
||||
PWINDOW->m_pXWaylandSurface->setMinimized(false);
|
||||
PWINDOW->m_pXWaylandSurface->restackToTop();
|
||||
if (PWINDOW->m_bIsX11) {
|
||||
if (PWINDOW->m_pXWaylandSurface) {
|
||||
if (activate) {
|
||||
PWINDOW->m_pXWaylandSurface->setMinimized(false);
|
||||
PWINDOW->m_pXWaylandSurface->restackToTop();
|
||||
}
|
||||
PWINDOW->m_pXWaylandSurface->activate(activate);
|
||||
}
|
||||
PWINDOW->m_pXWaylandSurface->activate(activate);
|
||||
} else if (!PWINDOW->m_bIsX11 && PWINDOW->m_pXDGSurface)
|
||||
} else if (PWINDOW->m_pXDGSurface)
|
||||
PWINDOW->m_pXDGSurface->toplevel->setActive(activate);
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) {
|
||||
if (pWindow->m_bIsX11) {
|
||||
setWindowSize(pWindow, pWindow->m_vRealSize.value()); // update xwayland output pos
|
||||
|
||||
if (activate) {
|
||||
setWindowSize(pWindow, pWindow->m_vRealSize.value()); // update xwayland output pos
|
||||
pWindow->m_pXWaylandSurface->setMinimized(false);
|
||||
|
||||
if (!pWindow->isX11OverrideRedirect())
|
||||
pWindow->m_pXWaylandSurface->restackToTop();
|
||||
}
|
||||
|
||||
pWindow->m_pXWaylandSurface->activate(activate);
|
||||
|
||||
} else if (pWindow->m_pXDGSurface && pWindow->m_pXDGSurface->toplevel)
|
||||
pWindow->m_pXDGSurface->toplevel->setActive(activate);
|
||||
|
||||
@@ -74,6 +77,9 @@ void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) {
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow, CBox* pbox) {
|
||||
if (!pWindow)
|
||||
return;
|
||||
|
||||
if (pWindow->m_bIsX11) {
|
||||
const auto SIZEHINTS = pWindow->m_pXWaylandSurface->sizeHints.get();
|
||||
|
||||
@@ -83,7 +89,10 @@ void CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow, CBox* pbox) {
|
||||
pbox->x = pWindow->m_pXWaylandSurface->geometry.x;
|
||||
pbox->y = pWindow->m_pXWaylandSurface->geometry.y;
|
||||
|
||||
if ((SIZEHINTS->flags & 0x2 /* ICCCM USSize */) || (SIZEHINTS->flags & 0x8 /* ICCCM PSize */)) {
|
||||
constexpr int ICCCM_USSize = 0x2;
|
||||
constexpr int ICCCM_PSize = 0x8;
|
||||
|
||||
if ((SIZEHINTS->flags & ICCCM_USSize) || (SIZEHINTS->flags & ICCCM_PSize)) {
|
||||
pbox->w = SIZEHINTS->base_width;
|
||||
pbox->h = SIZEHINTS->base_height;
|
||||
} else {
|
||||
@@ -108,7 +117,7 @@ void CHyprXWaylandManager::setWindowSize(PHLWINDOW pWindow, Vector2D size, bool
|
||||
|
||||
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
size = size.clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
|
||||
|
||||
@@ -117,34 +126,34 @@ void CHyprXWaylandManager::setWindowSize(PHLWINDOW pWindow, Vector2D size, bool
|
||||
Vector2D windowPos = pWindow->m_vRealPosition.value();
|
||||
|
||||
if (pWindow->m_bIsX11 && PMONITOR) {
|
||||
windowPos = windowPos - PMONITOR->vecPosition; // normalize to monitor
|
||||
windowPos -= PMONITOR->vecPosition; // normalize to monitor
|
||||
if (*PXWLFORCESCALEZERO)
|
||||
windowPos = windowPos * PMONITOR->scale; // scale if applicable
|
||||
windowPos = windowPos + PMONITOR->vecXWaylandPosition; // move to correct position for xwayland
|
||||
windowPos *= PMONITOR->scale; // scale if applicable
|
||||
windowPos += PMONITOR->vecXWaylandPosition; // move to correct position for xwayland
|
||||
}
|
||||
|
||||
if (!force && ((pWindow->m_vPendingReportedSize == size && windowPos == pWindow->m_vReportedPosition) || (pWindow->m_vPendingReportedSize == size && !pWindow->m_bIsX11)))
|
||||
if (!force && pWindow->m_vPendingReportedSize == size && (windowPos == pWindow->m_vReportedPosition || !pWindow->m_bIsX11))
|
||||
return;
|
||||
|
||||
pWindow->m_vReportedPosition = windowPos;
|
||||
pWindow->m_vPendingReportedSize = size;
|
||||
|
||||
pWindow->m_fX11SurfaceScaledBy = 1.f;
|
||||
pWindow->m_fX11SurfaceScaledBy = 1.0f;
|
||||
|
||||
if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11 && PMONITOR) {
|
||||
size = size * PMONITOR->scale;
|
||||
size *= PMONITOR->scale;
|
||||
pWindow->m_fX11SurfaceScaledBy = PMONITOR->scale;
|
||||
}
|
||||
|
||||
if (pWindow->m_bIsX11)
|
||||
pWindow->m_pXWaylandSurface->configure({windowPos, size});
|
||||
else if (pWindow->m_pXDGSurface->toplevel)
|
||||
pWindow->m_vPendingSizeAcks.push_back(std::make_pair<>(pWindow->m_pXDGSurface->toplevel->setSize(size), size.floor()));
|
||||
pWindow->m_vPendingSizeAcks.emplace_back(pWindow->m_pXDGSurface->toplevel->setSize(size), size.floor());
|
||||
}
|
||||
|
||||
bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) {
|
||||
if (pWindow->m_bIsX11) {
|
||||
for (auto const& a : pWindow->m_pXWaylandSurface->atoms)
|
||||
for (const auto& a : pWindow->m_pXWaylandSurface->atoms)
|
||||
if (a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DIALOG"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_SPLASH"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLBAR"] ||
|
||||
a == HYPRATOMS["_NET_WM_WINDOW_TYPE_UTILITY"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLTIP"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_POPUP_MENU"] ||
|
||||
a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"] ||
|
||||
@@ -157,16 +166,8 @@ bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pWindow->isModal())
|
||||
return true;
|
||||
|
||||
if (pWindow->m_pXWaylandSurface->transient)
|
||||
return true;
|
||||
|
||||
if (pWindow->m_pXWaylandSurface->role.contains("task_dialog") || pWindow->m_pXWaylandSurface->role.contains("pop-up"))
|
||||
return true;
|
||||
|
||||
if (pWindow->m_pXWaylandSurface->overrideRedirect)
|
||||
if (pWindow->isModal() || pWindow->m_pXWaylandSurface->transient ||
|
||||
(pWindow->m_pXWaylandSurface->role.contains("task_dialog") || pWindow->m_pXWaylandSurface->role.contains("pop-up")) || pWindow->m_pXWaylandSurface->overrideRedirect)
|
||||
return true;
|
||||
|
||||
const auto SIZEHINTS = pWindow->m_pXWaylandSurface->sizeHints.get();
|
||||
@@ -203,53 +204,22 @@ void CHyprXWaylandManager::checkBorders(PHLWINDOW pWindow) {
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::setWindowFullscreen(PHLWINDOW pWindow, bool fullscreen) {
|
||||
if (!pWindow)
|
||||
return;
|
||||
|
||||
if (pWindow->m_bIsX11)
|
||||
pWindow->m_pXWaylandSurface->setFullscreen(fullscreen);
|
||||
else if (pWindow->m_pXDGSurface && pWindow->m_pXDGSurface->toplevel)
|
||||
pWindow->m_pXDGSurface->toplevel->setFullscreen(fullscreen);
|
||||
}
|
||||
|
||||
Vector2D CHyprXWaylandManager::getMaxSizeForWindow(PHLWINDOW pWindow) {
|
||||
if (!validMapped(pWindow))
|
||||
return Vector2D(99999, 99999);
|
||||
|
||||
if ((pWindow->m_bIsX11 && !pWindow->m_pXWaylandSurface->sizeHints) || (!pWindow->m_bIsX11 && !pWindow->m_pXDGSurface->toplevel) ||
|
||||
pWindow->m_sWindowData.noMaxSize.valueOrDefault())
|
||||
return Vector2D(99999, 99999);
|
||||
|
||||
auto MAXSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_pXWaylandSurface->sizeHints->max_width, pWindow->m_pXWaylandSurface->sizeHints->max_height) :
|
||||
pWindow->m_pXDGSurface->toplevel->current.maxSize;
|
||||
|
||||
if (MAXSIZE.x < 5)
|
||||
MAXSIZE.x = 99999;
|
||||
if (MAXSIZE.y < 5)
|
||||
MAXSIZE.y = 99999;
|
||||
|
||||
return MAXSIZE;
|
||||
}
|
||||
|
||||
Vector2D CHyprXWaylandManager::getMinSizeForWindow(PHLWINDOW pWindow) {
|
||||
if (!validMapped(pWindow))
|
||||
return Vector2D(0, 0);
|
||||
|
||||
if ((pWindow->m_bIsX11 && !pWindow->m_pXWaylandSurface->sizeHints) || (!pWindow->m_bIsX11 && !pWindow->m_pXDGSurface->toplevel))
|
||||
return Vector2D(0, 0);
|
||||
|
||||
auto MINSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_pXWaylandSurface->sizeHints->min_width, pWindow->m_pXWaylandSurface->sizeHints->min_height) :
|
||||
pWindow->m_pXDGSurface->toplevel->current.minSize;
|
||||
|
||||
MINSIZE = MINSIZE.clamp({1, 1});
|
||||
|
||||
return MINSIZE;
|
||||
}
|
||||
|
||||
Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) {
|
||||
|
||||
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
|
||||
|
||||
CMonitor* pMonitor = nullptr;
|
||||
PHLMONITOR pMonitor = nullptr;
|
||||
double bestDistance = __FLT_MAX__;
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
for (const auto& m : g_pCompositor->m_vMonitors) {
|
||||
const auto SIZ = *PXWLFORCESCALEZERO ? m->vecTransformedSize : m->vecSize;
|
||||
|
||||
double distance =
|
||||
@@ -257,7 +227,7 @@ Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) {
|
||||
|
||||
if (distance < bestDistance) {
|
||||
bestDistance = distance;
|
||||
pMonitor = m.get();
|
||||
pMonitor = m;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +238,9 @@ Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) {
|
||||
Vector2D result = coord - pMonitor->vecXWaylandPosition;
|
||||
// if scaled, unscale
|
||||
if (*PXWLFORCESCALEZERO)
|
||||
result = result / pMonitor->scale;
|
||||
result /= pMonitor->scale;
|
||||
// add pos
|
||||
result = result + pMonitor->vecPosition;
|
||||
result += pMonitor->vecPosition;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@@ -21,8 +21,6 @@ class CHyprXWaylandManager {
|
||||
void setWindowFullscreen(PHLWINDOW, bool);
|
||||
bool shouldBeFloated(PHLWINDOW, bool pending = false);
|
||||
void checkBorders(PHLWINDOW);
|
||||
Vector2D getMaxSizeForWindow(PHLWINDOW);
|
||||
Vector2D getMinSizeForWindow(PHLWINDOW);
|
||||
Vector2D xwaylandToWaylandCoords(const Vector2D&);
|
||||
};
|
||||
|
||||
|
@@ -98,7 +98,7 @@ void CEventLoopManager::nudgeTimers() {
|
||||
long nextTimerUs = 10 * 1000 * 1000; // 10s
|
||||
|
||||
for (auto const& t : m_sTimers.timers) {
|
||||
if (const auto µs = t->leftUs(); µs < nextTimerUs)
|
||||
if (auto const& µs = t->leftUs(); µs < nextTimerUs)
|
||||
nextTimerUs = µs;
|
||||
}
|
||||
|
||||
|
@@ -87,6 +87,11 @@ void CInputManager::onMouseMoved(IPointer::SMotionEvent e) {
|
||||
|
||||
const auto DELTA = *PNOACCEL == 1 ? e.unaccel : e.delta;
|
||||
|
||||
if (g_pSeatManager->isPointerFrameSkipped)
|
||||
g_pPointerManager->storeMovement((uint64_t)e.timeMs, DELTA, e.unaccel);
|
||||
else
|
||||
g_pPointerManager->setStoredMovement((uint64_t)e.timeMs, DELTA, e.unaccel);
|
||||
|
||||
PROTO::relativePointer->sendRelativeMotion((uint64_t)e.timeMs * 1000, DELTA, e.unaccel);
|
||||
|
||||
g_pPointerManager->move(DELTA);
|
||||
@@ -134,6 +139,15 @@ void CInputManager::sendMotionEventsToFocused() {
|
||||
}
|
||||
|
||||
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState)
|
||||
return;
|
||||
|
||||
Vector2D const mouseCoords = getMouseCoordsInternal();
|
||||
auto const MOUSECOORDSFLOORED = mouseCoords.floor();
|
||||
|
||||
if (MOUSECOORDSFLOORED == m_vLastCursorPosFloored && !refocus)
|
||||
return;
|
||||
|
||||
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
||||
static auto PMOUSEREFOCUS = CConfigValue<Hyprlang::INT>("input:mouse_refocus");
|
||||
static auto PFOLLOWONDND = CConfigValue<Hyprlang::INT>("misc:always_follow_on_dnd");
|
||||
@@ -154,20 +168,11 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
PHLWINDOW pFoundWindow;
|
||||
PHLLS pFoundLayerSurface;
|
||||
|
||||
if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState)
|
||||
return;
|
||||
|
||||
Vector2D mouseCoords = getMouseCoordsInternal();
|
||||
const auto MOUSECOORDSFLOORED = mouseCoords.floor();
|
||||
|
||||
if (MOUSECOORDSFLOORED == m_vLastCursorPosFloored && !refocus)
|
||||
return;
|
||||
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("mouseMove", MOUSECOORDSFLOORED);
|
||||
|
||||
m_vLastCursorPosFloored = MOUSECOORDSFLOORED;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||
const auto PMONITOR = isLocked() && g_pCompositor->m_pLastMonitor ? g_pCompositor->m_pLastMonitor.lock() : g_pCompositor->getMonitorFromCursor();
|
||||
|
||||
// this can happen if there are no displays hooked up to Hyprland
|
||||
if (PMONITOR == nullptr)
|
||||
@@ -184,9 +189,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
// constraints
|
||||
if (!g_pSeatManager->mouse.expired() && isConstrained()) {
|
||||
const auto SURF = CWLSurface::fromResource(g_pCompositor->m_pLastFocus.lock());
|
||||
const auto CONSTRAINT = SURF->constraint();
|
||||
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
|
||||
|
||||
if (SURF && CONSTRAINT) {
|
||||
if (CONSTRAINT) {
|
||||
if (CONSTRAINT->isLocked()) {
|
||||
const auto HINT = CONSTRAINT->logicPositionHint();
|
||||
g_pCompositor->warpCursorTo(HINT, true);
|
||||
@@ -207,7 +212,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
Debug::log(ERR, "BUG THIS: Null SURF/CONSTRAINT in mouse refocus. Ignoring constraints. {:x} {:x}", (uintptr_t)SURF.get(), (uintptr_t)CONSTRAINT.get());
|
||||
}
|
||||
|
||||
if (PMONITOR != g_pCompositor->m_pLastMonitor.get() && (*PMOUSEFOCUSMON || refocus) && m_pForcedFocus.expired())
|
||||
if (PMONITOR != g_pCompositor->m_pLastMonitor && (*PMOUSEFOCUSMON || refocus) && m_pForcedFocus.expired())
|
||||
g_pCompositor->setActiveMonitor(PMONITOR);
|
||||
|
||||
if (g_pSessionLockManager->isSessionLocked()) {
|
||||
@@ -286,7 +291,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
// then, we check if the workspace doesnt have a fullscreen window
|
||||
const auto PWORKSPACE = PMONITOR->activeWorkspace;
|
||||
const auto PWORKSPACE = PMONITOR->activeWorkspace;
|
||||
const auto PWINDOWIDEAL = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !foundSurface && PWORKSPACE->m_efFullscreenMode == FSMODE_FULLSCREEN) {
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
|
||||
@@ -296,8 +302,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PWINDOWIDEAL = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
|
||||
|
||||
if (PWINDOWIDEAL &&
|
||||
((PWINDOWIDEAL->m_bIsFloating && PWINDOWIDEAL->m_bCreatedOverFullscreen) /* floating over fullscreen */
|
||||
|| (PMONITOR->activeSpecialWorkspace == PWINDOWIDEAL->m_pWorkspace) /* on an open special workspace */))
|
||||
@@ -317,7 +321,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FSMODE_MAXIMIZED) {
|
||||
if (!foundSurface) {
|
||||
if (PMONITOR->activeSpecialWorkspace) {
|
||||
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
|
||||
if (pFoundWindow != PWINDOWIDEAL)
|
||||
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
|
||||
|
||||
if (pFoundWindow && !pFoundWindow->onSpecialWorkspace()) {
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
@@ -330,7 +335,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
}
|
||||
|
||||
if (!foundSurface) {
|
||||
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
|
||||
if (pFoundWindow != PWINDOWIDEAL)
|
||||
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
|
||||
|
||||
if (!(pFoundWindow && pFoundWindow->m_bIsFloating && pFoundWindow->m_bCreatedOverFullscreen))
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
@@ -339,7 +345,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
}
|
||||
|
||||
} else {
|
||||
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
|
||||
if (pFoundWindow != PWINDOWIDEAL)
|
||||
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
|
||||
}
|
||||
|
||||
if (pFoundWindow) {
|
||||
@@ -365,7 +372,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
if (g_pPointerManager->softwareLockedFor(PMONITOR->self.lock()) > 0 && !skipFrameSchedule)
|
||||
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_pLastMonitor.get(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
|
||||
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_pLastMonitor.lock(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
|
||||
|
||||
// grabs
|
||||
if (g_pSeatManager->seatGrab && !g_pSeatManager->seatGrab->accepts(foundSurface)) {
|
||||
@@ -715,7 +722,7 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& e) {
|
||||
// notify app if we didnt handle it
|
||||
g_pSeatManager->sendPointerButton(e.timeMs, e.button, e.state);
|
||||
|
||||
if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != g_pCompositor->m_pLastMonitor.get() && PMON)
|
||||
if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != g_pCompositor->m_pLastMonitor && PMON)
|
||||
g_pCompositor->setActiveMonitor(PMON);
|
||||
|
||||
if (g_pSeatManager->seatGrab && e.state == WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||
@@ -752,6 +759,7 @@ void CInputManager::onMouseWheel(IPointer::SAxisEvent e) {
|
||||
static auto PINPUTSCROLLFACTOR = CConfigValue<Hyprlang::FLOAT>("input:scroll_factor");
|
||||
static auto PTOUCHPADSCROLLFACTOR = CConfigValue<Hyprlang::FLOAT>("input:touchpad:scroll_factor");
|
||||
static auto PEMULATEDISCRETE = CConfigValue<Hyprlang::INT>("input:emulate_discrete_scroll");
|
||||
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
||||
|
||||
auto factor = (*PTOUCHPADSCROLLFACTOR <= 0.f || e.source == WL_POINTER_AXIS_SOURCE_FINGER ? *PTOUCHPADSCROLLFACTOR : *PINPUTSCROLLFACTOR);
|
||||
|
||||
@@ -767,24 +775,33 @@ void CInputManager::onMouseWheel(IPointer::SAxisEvent e) {
|
||||
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
|
||||
const auto PWINDOW = g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
|
||||
|
||||
if (PWINDOW && PWINDOW->checkInputOnDecos(INPUT_TYPE_AXIS, MOUSECOORDS, e))
|
||||
return;
|
||||
if (PWINDOW) {
|
||||
if (PWINDOW->checkInputOnDecos(INPUT_TYPE_AXIS, MOUSECOORDS, e))
|
||||
return;
|
||||
|
||||
if (PWINDOW && *POFFWINDOWAXIS != 1) {
|
||||
const auto BOX = PWINDOW->getWindowMainSurfaceBox();
|
||||
if (*POFFWINDOWAXIS != 1) {
|
||||
const auto BOX = PWINDOW->getWindowMainSurfaceBox();
|
||||
|
||||
if (!BOX.containsPoint(MOUSECOORDS) && !PWINDOW->hasPopupAt(MOUSECOORDS)) {
|
||||
if (*POFFWINDOWAXIS == 0)
|
||||
return;
|
||||
if (!BOX.containsPoint(MOUSECOORDS) && !PWINDOW->hasPopupAt(MOUSECOORDS)) {
|
||||
if (*POFFWINDOWAXIS == 0)
|
||||
return;
|
||||
|
||||
const auto TEMPCURX = std::clamp(MOUSECOORDS.x, BOX.x, BOX.x + BOX.w - 1);
|
||||
const auto TEMPCURY = std::clamp(MOUSECOORDS.y, BOX.y, BOX.y + BOX.h - 1);
|
||||
const auto TEMPCURX = std::clamp(MOUSECOORDS.x, BOX.x, BOX.x + BOX.w - 1);
|
||||
const auto TEMPCURY = std::clamp(MOUSECOORDS.y, BOX.y, BOX.y + BOX.h - 1);
|
||||
|
||||
if (*POFFWINDOWAXIS == 3)
|
||||
g_pCompositor->warpCursorTo({TEMPCURX, TEMPCURY}, true);
|
||||
if (*POFFWINDOWAXIS == 3)
|
||||
g_pCompositor->warpCursorTo({TEMPCURX, TEMPCURY}, true);
|
||||
|
||||
g_pSeatManager->sendPointerMotion(e.timeMs, Vector2D{TEMPCURX, TEMPCURY} - BOX.pos());
|
||||
g_pSeatManager->sendPointerFrame();
|
||||
g_pSeatManager->sendPointerMotion(e.timeMs, Vector2D{TEMPCURX, TEMPCURY} - BOX.pos());
|
||||
g_pSeatManager->sendPointerFrame();
|
||||
}
|
||||
}
|
||||
|
||||
if (g_pSeatManager->state.pointerFocus) {
|
||||
const auto PCURRWINDOW = g_pCompositor->getWindowFromSurface(g_pSeatManager->state.pointerFocus.lock());
|
||||
|
||||
if (*PFOLLOWMOUSE == 1 && PCURRWINDOW && PWINDOW != PCURRWINDOW)
|
||||
simulateMouseMovement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -900,7 +917,7 @@ void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
|
||||
keeb.get());
|
||||
|
||||
keeb->keyboardEvents.keymap.registerStaticListener(
|
||||
[this](void* owner, std::any data) {
|
||||
[](void* owner, std::any data) {
|
||||
auto PKEEB = ((IKeyboard*)owner)->self.lock();
|
||||
const auto LAYOUT = PKEEB->getActiveLayout();
|
||||
|
||||
@@ -1354,7 +1371,7 @@ void CInputManager::refocus() {
|
||||
mouseMoveUnified(0, true);
|
||||
}
|
||||
|
||||
void CInputManager::refocusLastWindow(CMonitor* pMonitor) {
|
||||
void CInputManager::refocusLastWindow(PHLMONITOR pMonitor) {
|
||||
if (!pMonitor) {
|
||||
refocus();
|
||||
return;
|
||||
@@ -1371,13 +1388,19 @@ void CInputManager::refocusLastWindow(CMonitor* pMonitor) {
|
||||
foundSurface = m_dExclusiveLSes[m_dExclusiveLSes.size() - 1]->surface->resource();
|
||||
|
||||
// then any surfaces above windows on the same monitor
|
||||
if (!foundSurface)
|
||||
if (!foundSurface) {
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
|
||||
&surfaceCoords, &pFoundLayerSurface);
|
||||
if (pFoundLayerSurface && pFoundLayerSurface->interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND)
|
||||
foundSurface = nullptr;
|
||||
}
|
||||
|
||||
if (!foundSurface)
|
||||
if (!foundSurface) {
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
|
||||
&surfaceCoords, &pFoundLayerSurface);
|
||||
if (pFoundLayerSurface && pFoundLayerSurface->interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND)
|
||||
foundSurface = nullptr;
|
||||
}
|
||||
|
||||
if (!foundSurface && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->isWorkspaceVisibleNotCovered(g_pCompositor->m_pLastWindow->m_pWorkspace)) {
|
||||
// then the last focused window if we're on the same workspace as it
|
||||
@@ -1413,19 +1436,20 @@ void CInputManager::unconstrainMouse() {
|
||||
}
|
||||
|
||||
bool CInputManager::isConstrained() {
|
||||
for (auto const& c : m_vConstraints) {
|
||||
const auto C = c.lock();
|
||||
return std::any_of(m_vConstraints.begin(), m_vConstraints.end(), [](auto const& c) {
|
||||
const auto constraint = c.lock();
|
||||
return constraint && constraint->isActive() && constraint->owner()->resource() == g_pCompositor->m_pLastFocus;
|
||||
});
|
||||
}
|
||||
|
||||
if (!C)
|
||||
continue;
|
||||
bool CInputManager::isLocked() {
|
||||
if (!isConstrained())
|
||||
return false;
|
||||
|
||||
if (!C->isActive() || C->owner()->resource() != g_pCompositor->m_pLastFocus)
|
||||
continue;
|
||||
const auto SURF = CWLSurface::fromResource(g_pCompositor->m_pLastFocus.lock());
|
||||
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return CONSTRAINT && CONSTRAINT->isLocked();
|
||||
}
|
||||
|
||||
void CInputManager::updateCapabilities() {
|
||||
@@ -1637,31 +1661,12 @@ std::string CInputManager::getNameForNewDevice(std::string internalName) {
|
||||
auto proposedNewName = deviceNameToInternalString(internalName);
|
||||
int dupeno = 0;
|
||||
|
||||
while (std::find_if(m_vKeyboards.begin(), m_vKeyboards.end(),
|
||||
[&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vKeyboards.end())
|
||||
auto makeNewName = [&]() { return (proposedNewName.empty() ? "unknown-device" : proposedNewName) + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); };
|
||||
|
||||
while (std::find_if(m_vHIDs.begin(), m_vHIDs.end(), [&](const auto& other) { return other->hlName == makeNewName(); }) != m_vHIDs.end())
|
||||
dupeno++;
|
||||
|
||||
while (std::find_if(m_vPointers.begin(), m_vPointers.end(),
|
||||
[&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vPointers.end())
|
||||
dupeno++;
|
||||
|
||||
while (std::find_if(m_vTouches.begin(), m_vTouches.end(),
|
||||
[&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vTouches.end())
|
||||
dupeno++;
|
||||
|
||||
while (std::find_if(m_vTabletPads.begin(), m_vTabletPads.end(),
|
||||
[&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vTabletPads.end())
|
||||
dupeno++;
|
||||
|
||||
while (std::find_if(m_vTablets.begin(), m_vTablets.end(),
|
||||
[&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vTablets.end())
|
||||
dupeno++;
|
||||
|
||||
while (std::find_if(m_vTabletTools.begin(), m_vTabletTools.end(),
|
||||
[&](const auto& other) { return other->hlName == proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); }) != m_vTabletTools.end())
|
||||
dupeno++;
|
||||
|
||||
return proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno)));
|
||||
return makeNewName();
|
||||
}
|
||||
|
||||
void CInputManager::releaseAllMouseButtons() {
|
||||
|
@@ -108,10 +108,11 @@ class CInputManager {
|
||||
|
||||
void unconstrainMouse();
|
||||
bool isConstrained();
|
||||
bool isLocked();
|
||||
|
||||
Vector2D getMouseCoordsInternal();
|
||||
void refocus();
|
||||
void refocusLastWindow(CMonitor* pMonitor);
|
||||
void refocusLastWindow(PHLMONITOR pMonitor);
|
||||
void simulateMouseMovement();
|
||||
void sendMotionEventsToFocused();
|
||||
|
||||
|
@@ -100,14 +100,14 @@ void CInputPopup::updateBox() {
|
||||
cursorBoxParent = {0, 0, (int)parentBox.w, (int)parentBox.h};
|
||||
}
|
||||
|
||||
Vector2D currentPopupSize = surface->getViewporterCorrectedSize();
|
||||
Vector2D currentPopupSize = surface->getViewporterCorrectedSize() / surface->resource()->current.scale;
|
||||
|
||||
CMonitor* pMonitor = g_pCompositor->getMonitorFromVector(parentBox.middle());
|
||||
PHLMONITOR pMonitor = g_pCompositor->getMonitorFromVector(parentBox.middle());
|
||||
|
||||
Vector2D popupOffset(0, 0);
|
||||
Vector2D popupOffset(0, 0);
|
||||
|
||||
if (parentBox.y + cursorBoxParent.y + cursorBoxParent.height + currentPopupSize.y > pMonitor->vecPosition.y + pMonitor->vecSize.y)
|
||||
popupOffset.y = -currentPopupSize.y;
|
||||
popupOffset.y -= currentPopupSize.y;
|
||||
else
|
||||
popupOffset.y = cursorBoxParent.height;
|
||||
|
||||
|
@@ -15,9 +15,8 @@ void CInputManager::onSwipeBegin(IPointer::SSwipeBeginEvent e) {
|
||||
|
||||
int onMonitor = 0;
|
||||
for (auto const& w : g_pCompositor->m_vWorkspaces) {
|
||||
if (w->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID && !g_pCompositor->isWorkspaceSpecial(w->m_iID)) {
|
||||
if (w->m_pMonitor == g_pCompositor->m_pLastMonitor && !g_pCompositor->isWorkspaceSpecial(w->m_iID))
|
||||
onMonitor++;
|
||||
}
|
||||
}
|
||||
|
||||
if (onMonitor < 2 && !*PSWIPENEW)
|
||||
@@ -33,7 +32,7 @@ void CInputManager::beginWorkspaceSwipe() {
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin = PWORKSPACE;
|
||||
m_sActiveSwipe.delta = 0;
|
||||
m_sActiveSwipe.pMonitor = g_pCompositor->m_pLastMonitor.get();
|
||||
m_sActiveSwipe.pMonitor = g_pCompositor->m_pLastMonitor;
|
||||
m_sActiveSwipe.avgSpeed = 0;
|
||||
m_sActiveSwipe.speedPoints = 0;
|
||||
|
||||
@@ -179,7 +178,7 @@ void CInputManager::endWorkspaceSwipe() {
|
||||
}
|
||||
m_sActiveSwipe.pWorkspaceBegin->rememberPrevWorkspace(pSwitchedTo);
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor.lock());
|
||||
|
||||
if (PWORKSPACEL)
|
||||
PWORKSPACEL->m_bForceRendering = false;
|
||||
@@ -264,7 +263,7 @@ void CInputManager::updateWorkspaceSwipe(double delta) {
|
||||
|
||||
if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID || !PWORKSPACE) {
|
||||
if (*PSWIPENEW) {
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor.lock());
|
||||
|
||||
if (VERTANIMS)
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE));
|
||||
@@ -304,7 +303,7 @@ void CInputManager::updateWorkspaceSwipe(double delta) {
|
||||
|
||||
if (workspaceIDRight < m_sActiveSwipe.pWorkspaceBegin->m_iID || !PWORKSPACE) {
|
||||
if (*PSWIPENEW) {
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor.lock());
|
||||
|
||||
if (VERTANIMS)
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE));
|
||||
@@ -341,7 +340,7 @@ void CInputManager::updateWorkspaceSwipe(double delta) {
|
||||
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDRight);
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor.lock());
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID);
|
||||
|
||||
|
@@ -201,7 +201,7 @@ void CInputManager::newTablet(SP<Aquamarine::ITablet> pDevice) {
|
||||
m_vHIDs.push_back(PNEWTABLET);
|
||||
|
||||
try {
|
||||
PNEWTABLET->hlName = deviceNameToInternalString(pDevice->getName());
|
||||
PNEWTABLET->hlName = g_pInputManager->getNameForNewDevice(pDevice->getName());
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Tablet had no name???"); // logic error
|
||||
}
|
||||
@@ -228,6 +228,12 @@ SP<CTabletTool> CInputManager::ensureTabletToolPresent(SP<Aquamarine::ITabletToo
|
||||
const auto PTOOL = m_vTabletTools.emplace_back(CTabletTool::create(pTool));
|
||||
m_vHIDs.push_back(PTOOL);
|
||||
|
||||
try {
|
||||
PTOOL->hlName = g_pInputManager->getNameForNewDevice(pTool->getName());
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Tablet had no name???"); // logic error
|
||||
}
|
||||
|
||||
PTOOL->events.destroy.registerStaticListener(
|
||||
[this](void* owner, std::any d) {
|
||||
auto TOOL = ((CTabletTool*)owner)->self;
|
||||
@@ -243,7 +249,7 @@ void CInputManager::newTabletPad(SP<Aquamarine::ITabletPad> pDevice) {
|
||||
m_vHIDs.push_back(PNEWPAD);
|
||||
|
||||
try {
|
||||
PNEWPAD->hlName = deviceNameToInternalString(pDevice->getName());
|
||||
PNEWPAD->hlName = g_pInputManager->getNameForNewDevice(pDevice->getName());
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Pad had no name???"); // logic error
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) {
|
||||
|
||||
auto PMONITOR = g_pCompositor->getMonitorFromName(!e.device->boundOutput.empty() ? e.device->boundOutput : "");
|
||||
|
||||
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_pLastMonitor.get();
|
||||
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_pLastMonitor.lock();
|
||||
|
||||
g_pCompositor->warpCursorTo({PMONITOR->vecPosition.x + e.pos.x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e.pos.y * PMONITOR->vecSize.y}, true);
|
||||
|
||||
@@ -39,7 +39,6 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) {
|
||||
const auto PWORKSPACE = PMONITOR->activeWorkspace;
|
||||
const bool VERTANIMS = PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" ||
|
||||
PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert");
|
||||
// TODO: support no_gaps_when_only?
|
||||
const double TARGETLEFT = ((VERTANIMS ? gapsOut.top : gapsOut.left) + *PBORDERSIZE) / (VERTANIMS ? PMONITOR->vecSize.y : PMONITOR->vecSize.x);
|
||||
const double TARGETRIGHT = 1 - (((VERTANIMS ? gapsOut.bottom : gapsOut.right) + *PBORDERSIZE) / (VERTANIMS ? PMONITOR->vecSize.y : PMONITOR->vecSize.x));
|
||||
const double POSITION = (VERTANIMS ? e.pos.y : e.pos.x);
|
||||
@@ -124,7 +123,7 @@ void CInputManager::onTouchMove(ITouch::SMotionEvent e) {
|
||||
return;
|
||||
}
|
||||
if (validMapped(m_sTouchData.touchFocusWindow)) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusWindow->m_iMonitorID);
|
||||
const auto PMONITOR = m_sTouchData.touchFocusWindow->m_pMonitor.lock();
|
||||
|
||||
g_pCompositor->warpCursorTo({PMONITOR->vecPosition.x + e.pos.x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e.pos.y * PMONITOR->vecSize.y}, true);
|
||||
|
||||
@@ -134,7 +133,7 @@ void CInputManager::onTouchMove(ITouch::SMotionEvent e) {
|
||||
|
||||
g_pSeatManager->sendTouchMotion(e.timeMs, e.touchID, local);
|
||||
} else if (!m_sTouchData.touchFocusLS.expired()) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusLS->monitorID);
|
||||
const auto PMONITOR = m_sTouchData.touchFocusLS->monitor.lock();
|
||||
|
||||
g_pCompositor->warpCursorTo({PMONITOR->vecPosition.x + e.pos.x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e.pos.y * PMONITOR->vecSize.y}, true);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user