Compare commits

..

10 Commits

Author SHA1 Message Date
Vaxry
4520b30d49 version: bump to 0.44.1 2024-10-09 13:54:39 +01:00
trianta
8405aa111d output: update state even if no owner exists (#8044) 2024-10-09 13:47:52 +01:00
Vaxry
ad46257cce output/xdg-output: avoid sending events to released globals
ref #6835
2024-10-09 13:47:52 +01:00
Vaxry
0cfbe618b5 keyboard: update group state on change for the sym resolve state
fixes #8038
2024-10-09 13:47:52 +01:00
Vaxry
7d0944acdf defaultConfig: add a nofocus rule for weird X windows
ref #6543
2024-10-09 13:47:52 +01:00
Vaxry
b9990468f3 pointer: expand sw cursor damage box
fixes #8031

just a bit, rounding errors I guess
2024-10-09 13:47:52 +01:00
vaxerski
736a8735b3 keybinds: fixup xkb_states for resolve_by_sym
fixes #7750
2024-10-09 13:47:52 +01:00
Vaxry
b54eecbd79 config: give simple help for super+q not working
only on default config :P
2024-10-09 13:47:52 +01:00
Ikalco
657aeb3946 screencopy: fix screencopy frames not being cleaned up (#8017)
---------

Co-authored-by: Vaxry <vaxry@vaxry.net>
2024-10-09 13:47:52 +01:00
Aqa-Ib
6807430b18 layout: fix auto group when opening a new window in a non-focused workspace using window rules (#8006) 2024-10-09 13:47:52 +01:00
164 changed files with 2059 additions and 3528 deletions

View File

@@ -39,7 +39,7 @@ jobs:
tar -cvf Hyprland.tar.xz hyprland
- name: Release
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: Build archive
path: Hyprland.tar.xz

View File

@@ -17,14 +17,14 @@ jobs:
run: sudo apt install pandoc
- name: Clone repository
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
token: ${{ secrets.PAT }}
- name: Build man pages
run: make man
- uses: stefanzweifel/git-auto-commit-action@v5
- uses: stefanzweifel/git-auto-commit-action@v4
name: Commit
with:
commit_message: "[gha] build man pages"

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
token: ${{ secrets.PAT }}
@@ -22,6 +22,6 @@ jobs:
run: nix/update-inputs.sh
- name: Commit
uses: stefanzweifel/git-auto-commit-action@v5
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: "[gha] Nix: update inputs"

View File

@@ -11,7 +11,7 @@ jobs:
steps:
- name: Checkout Hyprland
id: checkout
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
submodules: recursive
@@ -20,6 +20,7 @@ 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

View File

@@ -13,7 +13,7 @@ jobs:
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Scan with Flawfinder
uses: david-a-wheeler/flawfinder@8e4a779ad59dbfaee5da586aa9210853b701959c

View File

@@ -19,7 +19,7 @@ jobs:
pull-requests: write
steps:
- uses: actions/stale@v9
- uses: actions/stale@v5
with:
repo-token: ${{ secrets.STALEBOT_PAT }}
stale-issue-label: "stale"

4
.gitignore vendored
View File

@@ -14,7 +14,6 @@ _deps
build/
result*
/.pre-commit-config.yaml
/.vscode/
/.idea/
.envrc
@@ -40,6 +39,3 @@ PKGBUILD
src/version.h
hyprpm/Makefile
hyprctl/Makefile
**/.#*.*
**/#*.*#

View File

@@ -15,7 +15,6 @@ 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")
@@ -72,8 +71,6 @@ 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)
@@ -103,7 +100,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>=0.4.2)
pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine)
add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}")
@@ -222,16 +219,6 @@ 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})
@@ -287,7 +274,7 @@ endfunction()
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads)
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.4.0)
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.2.0)
if(hyprland_protocols_dep_FOUND)
pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir)
message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}")
@@ -314,8 +301,6 @@ 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)
@@ -346,7 +331,6 @@ 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()

View File

@@ -1,12 +1,12 @@
PREFIX = /usr/local
legacyrenderer:
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./buildZ
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 Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
cmake --build ./build --config Release --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

View File

@@ -100,7 +100,7 @@ easy IPC, much more QoL stuff than other compositors and more...
<!----------------------------------------------------------------------------->
[Configure]: https://wiki.hyprland.org/Configuring/
[Configure]: https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
[Stars]: https://starchart.cc/hyprwm/Hyprland
[Hypr]: https://github.com/hyprwm/Hypr

View File

@@ -1 +1 @@
0.45.0
0.44.1

View File

@@ -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/)
- Read the [Configuring Page](https://wiki.hyprland.org/Configuring/Configuring-Hyprland)
<br/>

View File

@@ -3,14 +3,12 @@ Description=Hyprland - Tiling compositor with the looks
Documentation=man:Hyprland(1)
BindsTo=graphical-session.target
Before=graphical-session.target
Wants=xdg-desktop-autostart.target
Wants=graphical-session-pre.target
After=graphical-session-pre.target
[Service]
Type=notify
ExecStart=@PREFIX@/@BINDIR@/Hyprland
ExecStop=@PREFIX@/@BINDIR@/hyprctl dispatch exit
ExecStopPost=systemctl --user unset-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP
ExecStart=/usr/bin/Hyprland
ExecStop=/usr/bin/hyprctl dispatch exit
Restart=on-failure
Slice=session.slice

View File

@@ -1,7 +1,5 @@
[Desktop Entry]
Name=Hyprland (systemd session)
Name=Hyprland
Comment=An intelligent dynamic tiling Wayland compositor
Exec=systemctl --user start --wait hyprland-session
Type=Application
DesktopNames=Hyprland
Keywords=tiling;wayland;compositor;

View File

@@ -1,6 +1,6 @@
# This is an example Hyprland config file.
# Refer to the wiki for more information.
# https://wiki.hyprland.org/Configuring/
# https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
# Please note not all available settings / options are set here.
# For a full list, see the wiki
@@ -86,12 +86,10 @@ decoration {
active_opacity = 1.0
inactive_opacity = 1.0
shadow {
enabled = true
range = 4
render_power = 3
color = rgba(1a1a1aee)
}
drop_shadow = true
shadow_range = 4
shadow_render_power = 3
col.shadow = rgba(1a1a1aee)
# https://wiki.hyprland.org/Configuring/Variables/#blur
blur {
@@ -105,47 +103,20 @@ decoration {
# https://wiki.hyprland.org/Configuring/Variables/#animations
animations {
enabled = yes, please :)
enabled = true
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
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
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
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
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
}
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
# "Smart gaps" / "No gaps when only"
# uncomment all if you wish to use that.
# workspace = w[t1], gapsout:0, gapsin:0
# workspace = w[tg1], gapsout:0, gapsin:0
# workspace = f[1], gapsout:0, gapsin:0
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[t1]
# windowrulev2 = rounding 0, floating:0, onworkspace:w[t1]
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[tg1]
# windowrulev2 = rounding 0, floating:0, onworkspace:w[tg1]
# 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

View File

@@ -2,6 +2,4 @@
Name=Hyprland
Comment=An intelligent dynamic tiling Wayland compositor
Exec=Hyprland
Type=Application
DesktopNames=Hyprland
Keywords=tiling;wayland;compositor;
Type=Application

148
flake.lock generated
View File

@@ -16,11 +16,11 @@
]
},
"locked": {
"lastModified": 1730968822,
"narHash": "sha256-NocDjINsh6ismkhb0Xr6xPRksmhuB2WGf8ZmXMhxu7Y=",
"lastModified": 1727261104,
"narHash": "sha256-rxDI7WrxIRV9it9mDCHcLa7xQykf1JloXnoXr5xQ8zI=",
"owner": "hyprwm",
"repo": "aquamarine",
"rev": "a49bc3583ff223f426cb3526fdaa4bcaa247ec14",
"rev": "b82fdaff917582a9d568969e15e61b398c71e990",
"type": "github"
},
"original": {
@@ -29,43 +29,6 @@
"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": [
@@ -79,11 +42,11 @@
]
},
"locked": {
"lastModified": 1728669738,
"narHash": "sha256-EDNAU9AYcx8OupUzbTbWE1d3HYdeG0wO6Msg3iL1muk=",
"lastModified": 1727532803,
"narHash": "sha256-ZaZ7h7PY8mQc4vtGmVqWLAq9CAO02gHMyNR5yY8zDmM=",
"owner": "hyprwm",
"repo": "hyprcursor",
"rev": "0264e698149fcb857a66a53018157b41f8d97bb0",
"rev": "b98726e431d4d3ed58bd58bee1047cdb81cec69f",
"type": "github"
},
"original": {
@@ -102,11 +65,36 @@
]
},
"locked": {
"lastModified": 1728345020,
"narHash": "sha256-xGbkc7U/Roe0/Cv3iKlzijIaFBNguasI31ynL2IlEoM=",
"lastModified": 1727451107,
"narHash": "sha256-qV9savtHwmZUa0eJE294WYJjKPGB2+bJhwByFShsVyo=",
"owner": "hyprwm",
"repo": "hyprland-protocols",
"rev": "a7c183800e74f337753de186522b9017a07a8cee",
"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",
"type": "github"
},
"original": {
@@ -128,11 +116,11 @@
]
},
"locked": {
"lastModified": 1728168612,
"narHash": "sha256-AnB1KfiXINmuiW7BALYrKqcjCnsLZPifhb/7BsfPbns=",
"lastModified": 1725997860,
"narHash": "sha256-d/rZ/fHR5l1n7PeyLw0StWMNLXVU9c4HFyfskw568so=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "f054f2e44d6a0b74607a6bc0f52dba337a3db38e",
"rev": "dfeb5811dd6485490cce18d6cc1e38a055eea876",
"type": "github"
},
"original": {
@@ -151,11 +139,11 @@
]
},
"locked": {
"lastModified": 1730968903,
"narHash": "sha256-zFvzLXcSm0Ia4XI1SE4FQ9KE63hlGrRWhLtwMolWuR8=",
"lastModified": 1727300645,
"narHash": "sha256-OvAtVLaSRPnbXzOwlR1fVqCXR7i+ICRX3aPMCdIiv+c=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "3ce0cde8709cdacbfba471f8e828433b58a561e9",
"rev": "3f5293432b6dc6a99f26aca2eba3876d2660665c",
"type": "github"
},
"original": {
@@ -189,11 +177,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1730785428,
"narHash": "sha256-Zwl8YgTVJTEum+L+0zVAWvXAGbWAuXHax3KzuejaDyo=",
"lastModified": 1727348695,
"narHash": "sha256-J+PeFKSDV+pHL7ukkfpVzCOO7mBSrrpJ3svwBFABbhI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4aa36568d413aca0ea84a1684d2d46f55dbabad7",
"rev": "1925c603f17fc89f4c8f6bf6f631a802ad85d784",
"type": "github"
},
"original": {
@@ -203,45 +191,6 @@
"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": 1730814269,
"narHash": "sha256-fWPHyhYE6xvMI1eGY3pwBTq85wcy1YXqdzTZF+06nOg=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "d70155fdc00df4628446352fc58adc640cd705c2",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"aquamarine": "aquamarine",
@@ -251,7 +200,6 @@
"hyprutils": "hyprutils",
"hyprwayland-scanner": "hyprwayland-scanner",
"nixpkgs": "nixpkgs",
"pre-commit-hooks": "pre-commit-hooks",
"systems": "systems",
"xdph": "xdph"
}
@@ -273,9 +221,7 @@
},
"xdph": {
"inputs": {
"hyprland-protocols": [
"hyprland-protocols"
],
"hyprland-protocols": "hyprland-protocols_2",
"hyprlang": [
"hyprlang"
],
@@ -293,11 +239,11 @@
]
},
"locked": {
"lastModified": 1730743262,
"narHash": "sha256-iTLqj3lU8kFehPm5tXpctzkD274t/k1nwSSq3qCWXeg=",
"lastModified": 1727524473,
"narHash": "sha256-1DGktDtSWIJpnDbVoj/qpvJSH5zg6JbOfuh6xqZMap0=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"rev": "09b23cef06fe248e61cec8862c04b9bcb62f4b6d",
"rev": "7e500e679ede40e79cf2d89b5f5fa3e34923bd26",
"type": "github"
},
"original": {

View File

@@ -51,16 +51,10 @@
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 @ {
@@ -82,7 +76,7 @@
pkgsCrossFor = eachSystem (system: crossSystem:
import nixpkgs {
localSystem = system;
inherit crossSystem;
crossSystem = crossSystem;
overlays = with self.overlays; [
hyprland-packages
hyprland-extras
@@ -97,18 +91,6 @@
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: {
@@ -116,13 +98,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;
@@ -137,11 +119,10 @@
hardeningDisable = ["fortify"];
inputsFrom = [pkgsFor.${system}.hyprland];
packages = [pkgsFor.${system}.clang-tools];
inherit (self.checks.${system}.pre-commit-check) shellHook;
};
});
formatter = eachSystem (system: pkgsFor.${system}.callPackage ./nix/formatter.nix {});
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
nixosModules.default = import ./nix/module.nix inputs;
homeManagerModules.default = import ./nix/hm-module.nix self;

View File

@@ -1,7 +1,5 @@
#pragma once
#include <string_view>
const std::string_view USAGE = R"#(usage: hyprctl [flags] <command> [args...|--help]
commands:

View File

@@ -17,7 +17,6 @@
#include <iostream>
#include <string>
#include <print>
#include <fstream>
#include <string>
#include <vector>
@@ -45,11 +44,11 @@ struct SInstanceData {
bool valid = true;
};
void log(const std::string& str) {
void log(std::string str) {
if (quiet)
return;
std::println("{}", str);
std::cout << str << "\n";
}
std::string getRuntimeDir() {
@@ -106,7 +105,7 @@ std::vector<SInstanceData> instances() {
static volatile bool sigintReceived = false;
void intHandler(int sig) {
sigintReceived = true;
std::println("[hyprctl] SIGINT received, closing connection");
std::cout << "[hyprctl] SIGINT received, closing connection" << std::endl;
}
int rollingRead(const int socket) {
@@ -116,12 +115,12 @@ int rollingRead(const int socket) {
constexpr size_t BUFFER_SIZE = 8192;
std::array<char, BUFFER_SIZE> buffer = {0};
long sizeWritten = 0;
std::println("[hyprctl] reading from socket following up log:");
std::cout << "[hyprctl] reading from socket following up log:" << std::endl;
while (!sigintReceived) {
sizeWritten = read(socket, buffer.data(), BUFFER_SIZE);
if (sizeWritten < 0 && errno != EAGAIN) {
if (errno != EINTR)
std::println("Couldn't read (5): {}: {}", strerror(errno), errno);
std::cout << "Couldn't read (5) " << strerror(errno) << ":" << errno << std::endl;
close(socket);
return 5;
}
@@ -130,7 +129,7 @@ int rollingRead(const int socket) {
break;
if (sizeWritten > 0) {
std::println("{}", std::string(buffer.data(), sizeWritten));
std::cout << std::string(buffer.data(), sizeWritten);
buffer.fill('\0');
}
@@ -324,7 +323,7 @@ int main(int argc, char** argv) {
bool parseArgs = true;
if (argc < 2) {
std::println("{}", USAGE);
std::cout << USAGE << std::endl;
return 1;
}
@@ -361,7 +360,7 @@ int main(int argc, char** argv) {
++i;
if (i >= ARGS.size()) {
std::println("{}", USAGE);
std::cout << USAGE << std::endl;
return 1;
}
@@ -372,24 +371,24 @@ int main(int argc, char** argv) {
const std::string& cmd = ARGS[0];
if (cmd == "hyprpaper") {
std::println("{}", HYPRPAPER_HELP);
std::cout << HYPRPAPER_HELP << std::endl;
} else if (cmd == "notify") {
std::println("{}", NOTIFY_HELP);
std::cout << NOTIFY_HELP << std::endl;
} else if (cmd == "output") {
std::println("{}", OUTPUT_HELP);
std::cout << OUTPUT_HELP << std::endl;
} else if (cmd == "plugin") {
std::println("{}", PLUGIN_HELP);
std::cout << PLUGIN_HELP << std::endl;
} else if (cmd == "setprop") {
std::println("{}", SETPROP_HELP);
std::cout << SETPROP_HELP << std::endl;
} else if (cmd == "switchxkblayout") {
std::println("{}", SWITCHXKBLAYOUT_HELP);
std::cout << SWITCHXKBLAYOUT_HELP << std::endl;
} else {
std::println("{}", USAGE);
std::cout << USAGE << std::endl;
}
return 1;
} else {
std::println("{}", USAGE);
std::cout << USAGE << std::endl;
return 1;
}
@@ -400,7 +399,7 @@ int main(int argc, char** argv) {
}
if (fullRequest.empty()) {
std::println("{}", USAGE);
std::cout << USAGE << std::endl;
return 1;
}
@@ -477,7 +476,7 @@ int main(int argc, char** argv) {
else if (fullRequest.contains("/decorations"))
exitStatus = request(fullRequest, 1);
else if (fullRequest.contains("/--help"))
std::println("{}", USAGE);
std::cout << USAGE << std::endl;
else if (fullRequest.contains("/rollinglog") && needRoll)
exitStatus = request(fullRequest, 0, true);
else {

View File

@@ -1,6 +1,6 @@
#include "DataState.hpp"
#include <toml++/toml.hpp>
#include <print>
#include <iostream>
#include <filesystem>
#include <fstream>
#include "PluginManager.hpp"
@@ -8,7 +8,7 @@
std::string DataState::getDataStatePath() {
const auto HOME = getenv("HOME");
if (!HOME) {
std::println(stderr, "DataState: no $HOME");
std::cerr << "DataState: no $HOME\n";
throw std::runtime_error("no $HOME");
return "";
}
@@ -242,4 +242,4 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) {
}
return false;
}
}

View File

@@ -1,15 +1,12 @@
#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>
@@ -34,7 +31,6 @@ 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();
}
@@ -51,10 +47,10 @@ SHyprlandVersion CPluginManager::getHyprlandVersion() {
once = true;
const auto HLVERCALL = execAndGet("hyprctl version");
if (m_bVerbose)
std::println("{}", verboseString("version returned: {}", HLVERCALL));
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "version returned: " << HLVERCALL << "\n";
if (!HLVERCALL.contains("Tag:")) {
std::println(stderr, "\n{}", failureString("You don't seem to be running Hyprland."));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " You don't seem to be running Hyprland.";
return SHyprlandVersion{};
}
@@ -80,7 +76,7 @@ SHyprlandVersion CPluginManager::getHyprlandVersion() {
} catch (...) { ; }
if (m_bVerbose)
std::println("{}", verboseString("parsed commit {} at branch {} on {}, commits {}", hlcommit, hlbranch, hldate, commits));
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "parsed commit " << hlcommit << " at branch " << hlbranch << " on " << hldate << ", commits " << commits << "\n";
ver = SHyprlandVersion{hlbranch, hlcommit, hldate, commits};
return ver;
@@ -106,21 +102,20 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
const auto HLVER = getHyprlandVersion();
if (!hasDeps()) {
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio"));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not clone the plugin repository. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio\n";
return false;
}
if (DataState::pluginRepoExists(url)) {
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. Repository already installed."));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not clone the plugin repository. Repository already installed.\n";
return false;
}
auto GLOBALSTATE = DataState::getGlobalState();
if (!GLOBALSTATE.dontWarnInstall) {
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.");
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";
GLOBALSTATE.dontWarnInstall = true;
DataState::updateGlobalState(GLOBALSTATE);
}
@@ -134,7 +129,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::println(stderr, "Aborting.");
std::cout << "Aborting.\n";
return false;
}
@@ -149,7 +144,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::println(stderr, "\n{}", failureString("Could not prepare working dir for hyprpm"));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not prepare working dir for hyprpm\n";
return false;
}
@@ -158,59 +153,59 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
m_szWorkingPluginDirectory = "/tmp/hyprpm/" + USERNAME;
if (!createSafeDirectory(m_szWorkingPluginDirectory)) {
std::println(stderr, "\n{}", failureString("Could not prepare working dir for repo"));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not prepare working dir for repo\n";
return false;
}
progress.printMessageAbove(infoString("Cloning {}", url));
progress.printMessageAbove(std::string{Colors::RESET} + "Cloning " + url);
std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + url + " " + USERNAME);
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. shell returned:\n{}", ret));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not clone the plugin repository. shell returned:\n" << ret << "\n";
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::println(stderr, "\n{}", failureString("Could not check out revision {}. shell returned:\n{}", rev, ret));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not check out revision " << rev << ". shell returned:\n" << ret << "\n";
return false;
}
ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " submodule update --init");
if (m_bVerbose)
std::println("{}", verboseString("git submodule update --init returned: {}", ret));
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "git submodule update --init returned: " << ret << "\n";
}
progress.m_iSteps = 1;
progress.printMessageAbove(successString("cloned"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " cloned");
progress.m_szCurrentMessage = "Reading the manifest";
progress.print();
std::unique_ptr<CManifest> pManifest;
if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
progress.printMessageAbove(successString("found hyprpm manifest"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " 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(successString("found hyprload manifest"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " found hyprload manifest");
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
}
if (!pManifest) {
std::println(stderr, "\n{}", failureString("The provided plugin repository does not have a valid manifest"));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " The provided plugin repository does not have a valid manifest\n";
return false;
}
if (!pManifest->m_bGood) {
std::println(stderr, "\n{}", failureString("The provided plugin repository has a corrupted manifest"));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " The provided plugin repository has a corrupted manifest\n";
return false;
}
progress.m_iSteps = 2;
progress.printMessageAbove(successString("parsed manifest, found " + std::to_string(pManifest->m_vPlugins.size()) + " plugins:"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " parsed manifest, found " + std::to_string(pManifest->m_vPlugins.size()) + " plugins:");
for (auto const& pl : pManifest->m_vPlugins) {
std::string message = "" + pl.name + " by ";
std::string message = std::string{Colors::RESET} + " " + pl.name + " by ";
for (auto const& a : pl.authors) {
message += a + ", ";
}
@@ -225,19 +220,19 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
if (!pManifest->m_sRepository.commitPins.empty()) {
// check commit pins
progress.printMessageAbove(infoString("Manifest has {} pins, checking", pManifest->m_sRepository.commitPins.size()));
progress.printMessageAbove(std::string{Colors::RESET} + "Manifest has " + std::to_string(pManifest->m_sRepository.commitPins.size()) + " pins, checking");
for (auto const& [hl, plugin] : pManifest->m_sRepository.commitPins) {
if (hl != HLVER.hash)
continue;
progress.printMessageAbove(successString("commit pin {} matched hl, resetting", plugin));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " commit pin " + plugin + " matched hl, resetting");
execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " submodule update --init");
if (m_bVerbose)
std::println("{}", verboseString("git submodule update --init returned: {}", ret));
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "git submodule update --init returned: " << ret << "\n";
break;
}
@@ -249,12 +244,12 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
const auto HEADERSSTATUS = headersValid();
if (HEADERSSTATUS != HEADERS_OK) {
std::println("\n{}", headerError(HEADERSSTATUS));
std::cerr << "\n" << headerError(HEADERSSTATUS);
return false;
}
progress.m_iSteps = 3;
progress.printMessageAbove(successString("Hyprland headers OK"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " Hyprland headers OK");
progress.m_szCurrentMessage = "Building plugin(s)";
progress.print();
@@ -262,36 +257,35 @@ 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(failureString("Not building {}: your Hyprland version is too old.\n", p.name));
progress.printMessageAbove(std::string{Colors::RED} + "" + Colors::RESET + " Not building " + p.name + ": your Hyprland version is too old.\n");
p.failed = true;
continue;
}
progress.printMessageAbove(infoString("Building {}", p.name));
progress.printMessageAbove(std::string{Colors::RESET} + "Building " + p.name);
for (auto const& bs : p.buildSteps) {
const std::string& cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
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::println("{}", verboseString("shell returned: " + out));
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n";
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
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));
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");
p.failed = true;
continue;
}
progress.printMessageAbove(successString("built {} into {}", p.name, p.output));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " built " + p.name + " into " + p.output);
}
progress.printMessageAbove(successString("all plugins built"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " all plugins built");
progress.m_iSteps = 4;
progress.m_szCurrentMessage = "Installing repository";
progress.print();
@@ -310,13 +304,13 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
}
DataState::addNewPluginRepo(repo);
progress.printMessageAbove(successString("installed repository"));
progress.printMessageAbove(successString("you can now enable the plugin(s) with hyprpm enable"));
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.m_iSteps = 5;
progress.m_szCurrentMessage = "Done!";
progress.print();
std::print("\n");
std::cout << "\n";
// remove build files
std::filesystem::remove_all(m_szWorkingPluginDirectory);
@@ -326,7 +320,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
bool CPluginManager::removePluginRepo(const std::string& urlOrName) {
if (!DataState::pluginRepoExists(urlOrName)) {
std::println(stderr, "\n{}", failureString("Could not remove the repository. Repository is not installed."));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not remove the repository. Repository is not installed.\n";
return false;
}
@@ -337,7 +331,7 @@ bool CPluginManager::removePluginRepo(const std::string& urlOrName) {
std::getline(std::cin, input);
if (input.size() > 0 && input[0] != 'Y' && input[0] != 'y') {
std::println("Aborting.");
std::cout << "Aborting.\n";
return false;
}
@@ -353,15 +347,15 @@ eHeadersErrors CPluginManager::headersValid() {
return HEADERS_MISSING;
// find headers commit
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());
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));
@@ -412,7 +406,7 @@ bool CPluginManager::updateHeaders(bool force) {
const auto HLVER = getHyprlandVersion();
if (!hasDeps()) {
std::println("\n{}", failureString("Could not update. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio"));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not update. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio\n";
return false;
}
@@ -422,7 +416,7 @@ bool CPluginManager::updateHeaders(bool force) {
}
if (!force && headersValid() == HEADERS_OK) {
std::println("\n{}", successString("Headers up to date."));
std::cout << "\n" << std::string{Colors::GREEN} + "" + Colors::RESET + " Headers up to date.\n";
return true;
}
@@ -436,73 +430,74 @@ bool CPluginManager::updateHeaders(bool force) {
const auto WORKINGDIR = "/tmp/hyprpm/hyprland-" + USERNAME;
if (!createSafeDirectory(WORKINGDIR)) {
std::println("\n{}", failureString("Could not prepare working dir for hl"));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not prepare working dir for hl\n";
return false;
}
progress.printMessageAbove(statusString("!", Colors::YELLOW, "Cloning https://github.com/hyprwm/Hyprland, this might take a moment."));
progress.printMessageAbove(std::string{Colors::YELLOW} + "!" + Colors::RESET + " Cloning https://github.com/hyprwm/hyprland, this might take a moment.");
const bool bShallow = (HLVER.branch == "main") && !m_bNoShallow;
const bool bShallow = (HLVER.branch == "main" || HLVER.branch == "") && !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(verboseString("will shallow since: {}", SHALLOW_DATE));
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "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(failureString("Clone failed. Retrying without shallow."));
progress.printMessageAbove(std::string{Colors::RED} + "" + Colors::RESET + " 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::println(stderr, "\n{}", failureString("Could not clone the Hyprland repository. shell returned:\n{}", ret));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not clone the hyprland repository. shell returned:\n" << ret << "\n";
return false;
}
progress.printMessageAbove(successString("Hyprland cloned"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " cloned");
progress.m_iSteps = 2;
progress.m_szCurrentMessage = "Checking out sources";
progress.print();
if (m_bVerbose)
progress.printMessageAbove(verboseString("will run: cd {} && git checkout {} 2>&1", WORKINGDIR, HLVER.hash));
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "will run: " + "cd " + WORKINGDIR + " && git checkout " + HLVER.hash + " 2>&1");
ret = execAndGet("cd " + WORKINGDIR + " && git checkout " + HLVER.hash + " 2>&1");
if (ret.contains("fatal: unable to read tree")) {
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."));
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";
return false;
}
if (m_bVerbose)
progress.printMessageAbove(verboseString("git returned (co): {}", ret));
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "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(verboseString("git returned (rs): {}", ret));
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "git returned (rs): " + ret);
progress.printMessageAbove(successString("checked out to running ver"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " checked out to running ver");
progress.m_iSteps = 3;
progress.m_szCurrentMessage = "Building Hyprland";
progress.print();
progress.printMessageAbove(statusString("!", Colors::YELLOW, "configuring Hyprland"));
progress.printMessageAbove(std::string{Colors::YELLOW} + "!" + Colors::RESET + " configuring Hyprland");
if (m_bVerbose)
progress.printMessageAbove(verboseString("setting PREFIX for cmake to {}", DataState::getHeadersPath()));
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "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(verboseString("cmake returned: {}", ret));
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "cmake returned: " + ret);
if (ret.contains("CMake Error at")) {
// missing deps, let the user know.
@@ -511,46 +506,48 @@ bool CPluginManager::updateHeaders(bool force) {
missing = missing.substr(0, missing.find("-- Configuring incomplete"));
missing = missing.substr(0, missing.find_last_of('\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));
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";
return false;
}
progress.printMessageAbove(successString("configured Hyprland"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " configured Hyprland");
progress.m_iSteps = 4;
progress.m_szCurrentMessage = "Installing sources";
progress.print();
const std::string& cmd =
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(verboseString("installation will run: {}", cmd));
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "installation will run: " + cmd);
ret = execAndGet(cmd);
if (m_bVerbose)
std::println("{}", verboseString("installer returned: {}", ret));
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "installer returned: " << ret << "\n";
// remove build files
std::filesystem::remove_all(WORKINGDIR);
auto HEADERSVALID = headersValid();
if (HEADERSVALID == HEADERS_OK) {
progress.printMessageAbove(successString("installed headers"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " installed headers");
progress.m_iSteps = 5;
progress.m_szCurrentMessage = "Done!";
progress.print();
std::print("\n");
std::cout << "\n";
} else {
progress.printMessageAbove(failureString("failed to install headers with error code {} ({})", (int)HEADERSVALID, headerErrorShort(HEADERSVALID)));
progress.printMessageAbove(std::string{Colors::RED} + "" + Colors::RESET + " failed to install headers with error code " + std::to_string((int)HEADERSVALID) + " (" +
headerErrorShort(HEADERSVALID) + ")");
progress.m_iSteps = 5;
progress.m_szCurrentMessage = "Failed";
progress.print();
std::print(stderr, "\n\n{}", headerError(HEADERSVALID));
std::cout << "\n";
std::cerr << "\n" << headerError(HEADERSVALID);
return false;
}
@@ -560,14 +557,14 @@ bool CPluginManager::updateHeaders(bool force) {
bool CPluginManager::updatePlugins(bool forceUpdateAll) {
if (headersValid() != HEADERS_OK) {
std::println("{}", failureString("headers are not up-to-date, please run hyprpm update."));
std::cout << "\n" << std::string{Colors::RED} + "" + Colors::RESET + " headers are not up-to-date, please run hyprpm update.\n";
return false;
}
const auto REPOS = DataState::getAllRepositories();
if (REPOS.size() < 1) {
std::println("{}", failureString("No repos to update."));
std::cout << "\n" << std::string{Colors::RED} + "" + Colors::RESET + " No repos to update.\n";
return true;
}
@@ -589,26 +586,25 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
progress.m_szCurrentMessage = "Updating " + repo.name;
progress.print();
progress.printMessageAbove(infoString("checking for updates for {}", repo.name));
progress.printMessageAbove(std::string{Colors::RESET} + "checking for updates for " + repo.name);
createSafeDirectory(m_szWorkingPluginDirectory);
progress.printMessageAbove(infoString("Cloning {}", repo.url));
progress.printMessageAbove(std::string{Colors::RESET} + "Cloning " + repo.url);
std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + repo.url + " " + USERNAME);
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
std::println("{}", failureString("could not clone repo: shell returned: {}", ret));
std::cout << "\n" << std::string{Colors::RED} + "" + Colors::RESET + " could not clone repo: shell returned:\n" + ret;
return false;
}
if (!repo.rev.empty()) {
progress.printMessageAbove(infoString("Plugin has revision set, resetting: {}", repo.rev));
progress.printMessageAbove(std::string{Colors::RESET} + "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::println(stderr, "\n{}", failureString("could not check out revision {}: shell returned:\n{}", repo.rev, ret));
std::cout << "\n" << std::string{Colors::RED} + "" + Colors::RESET + " could not check out revision " + repo.rev + ": shell returned:\n" + ret;
return false;
}
}
@@ -624,7 +620,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
if (!update) {
std::filesystem::remove_all(m_szWorkingPluginDirectory);
progress.printMessageAbove(successString("repository {} is up-to-date.", repo.name));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " repository " + repo.name + " is up-to-date.");
progress.m_iSteps++;
progress.print();
continue;
@@ -632,41 +628,41 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
// we need to update
progress.printMessageAbove(successString("repository {} has updates.", repo.name));
progress.printMessageAbove(infoString("Building {}", repo.name));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " repository " + repo.name + " has updates.");
progress.printMessageAbove(std::string{Colors::RESET} + "Building " + repo.name);
progress.m_iSteps++;
progress.print();
std::unique_ptr<CManifest> pManifest;
if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
progress.printMessageAbove(successString("found hyprpm manifest"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " 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(successString("found hyprload manifest"));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " found hyprload manifest");
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
}
if (!pManifest) {
std::println(stderr, "\n{}", failureString("The provided plugin repository does not have a valid manifest"));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " The provided plugin repository does not have a valid manifest\n";
continue;
}
if (!pManifest->m_bGood) {
std::println(stderr, "\n{}", failureString("The provided plugin repository has a corrupted manifest"));
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " The provided plugin repository has a corrupted manifest\n";
continue;
}
if (repo.rev.empty() && !pManifest->m_sRepository.commitPins.empty()) {
// check commit pins unless a revision is specified
progress.printMessageAbove(infoString("Manifest has {} pins, checking", pManifest->m_sRepository.commitPins.size()));
progress.printMessageAbove(std::string{Colors::RESET} + "Manifest has " + std::to_string(pManifest->m_sRepository.commitPins.size()) + " pins, checking");
for (auto const& [hl, plugin] : pManifest->m_sRepository.commitPins) {
if (hl != HLVER.hash)
continue;
progress.printMessageAbove(successString("commit pin {} matched hl, resetting", plugin));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " commit pin " + plugin + " matched hl, resetting");
execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
}
@@ -676,33 +672,32 @@ 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(failureString("Not building {}: your Hyprland version is too old.\n", p.name));
progress.printMessageAbove(std::string{Colors::RED} + "" + Colors::RESET + " Not building " + p.name + ": your Hyprland version is too old.\n");
p.failed = true;
continue;
}
progress.printMessageAbove(infoString("Building {}", p.name));
progress.printMessageAbove(std::string{Colors::RESET} + "Building " + p.name);
for (auto const& bs : p.buildSteps) {
const std::string& cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
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::println("{}", verboseString("shell returned: {}", out));
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n";
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
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));
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";
p.failed = true;
continue;
}
progress.printMessageAbove(successString("built {} into {}", p.name, p.output));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " built " + p.name + " into " + p.output);
}
// add repo toml to DataState
@@ -723,7 +718,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
std::filesystem::remove_all(m_szWorkingPluginDirectory);
progress.printMessageAbove(successString("updated {}", repo.name));
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " updated " + repo.name);
}
progress.m_iSteps++;
@@ -738,7 +733,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
progress.m_szCurrentMessage = "Done!";
progress.print();
std::print("\n");
std::cout << "\n";
return true;
}
@@ -746,27 +741,27 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
bool CPluginManager::enablePlugin(const std::string& name) {
bool ret = DataState::setPluginEnabled(name, true);
if (ret)
std::println("{}", successString("Enabled {}", name));
std::cout << Colors::GREEN << "" << Colors::RESET << " Enabled " << name << "\n";
return ret;
}
bool CPluginManager::disablePlugin(const std::string& name) {
bool ret = DataState::setPluginEnabled(name, false);
if (ret)
std::println("{}", successString("Disabled {}", name));
std::cout << Colors::GREEN << "" << Colors::RESET << " Disabled " << name << "\n";
return ret;
}
ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
if (headersValid() != HEADERS_OK) {
std::println(stderr, "\n{}", failureString("headers are not up-to-date, please run hyprpm update."));
std::cerr << "\n" << std::string{Colors::RED} + "" + Colors::RESET + " headers are not up-to-date, please run hyprpm update.\n";
return LOADSTATE_HEADERS_OUTDATED;
}
const auto HOME = getenv("HOME");
const auto HIS = getenv("HYPRLAND_INSTANCE_SIGNATURE");
if (!HOME || !HIS) {
std::println(stderr, "PluginManager: no $HOME or HIS");
std::cerr << "PluginManager: no $HOME or HIS\n";
return LOADSTATE_FAIL;
}
const auto HYPRPMPATH = DataState::getDataStatePath() + "/";
@@ -775,14 +770,14 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
std::vector<std::string> loadedPlugins;
std::println("{}", successString("Ensuring plugin load state"));
std::cout << Colors::GREEN << "" << Colors::RESET << " Ensuring plugin load state\n";
// 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 = "";
@@ -825,7 +820,7 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
if (!enabled(p)) {
// unload
loadUnloadPlugin(HYPRPMPATH + repoForName(p) + "/" + p + ".so", false);
std::println("{}", successString("Unloaded {}", p));
std::cout << Colors::GREEN << "" << Colors::RESET << " Unloaded " << p << "\n";
}
}
@@ -839,11 +834,11 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
continue;
loadUnloadPlugin(HYPRPMPATH + repoForName(p.name) + "/" + p.filename, true);
std::println("{}", successString("Loaded {}", p.name));
std::cout << Colors::GREEN << "" << Colors::RESET << " Loaded " << p.name << "\n";
}
}
std::println("{}", successString("Plugin load state ensured"));
std::cout << Colors::GREEN << "" << Colors::RESET << " Plugin load state ensured\n";
return LOADSTATE_OK;
}
@@ -861,17 +856,16 @@ void CPluginManager::listAllPlugins() {
const auto REPOS = DataState::getAllRepositories();
for (auto const& r : REPOS) {
std::println("{}", infoString("Repository {}:", r.name));
std::cout << std::string{Colors::RESET} + "Repository " + r.name + ":\n";
for (auto const& p : r.plugins) {
std::println(" │ Plugin {}", p.name);
std::cout << std::string{Colors::RESET} + " │ Plugin " + p.name;
if (!p.failed)
std::println(" └─ enabled: {}", (p.enabled ? std::string{Colors::GREEN} + "true" : std::string{Colors::RED} + "false"));
std::cout << "\n └─ enabled: " << (p.enabled ? Colors::GREEN : Colors::RED) << (p.enabled ? "true" : "false") << Colors::RESET << "\n";
else
std::println(" └─ enabled: {}Plugin failed to build", Colors::RED);
std::println("{}", Colors::RESET);
std::cout << "\n └─ enabled: " << Colors::RED << "Plugin failed to build" << Colors::RESET << "\n";
}
}
}
@@ -882,19 +876,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 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_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_DUPLICATED: {
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");
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";
}
default: break;
}
return failureString("Unknown header error. Please run hyprpm update to fix those.\n");
return std::string{Colors::RED} + "" + Colors::RESET + " Unknown header error. Please run hyprpm update to fix those.\n";
}
std::string CPluginManager::headerErrorShort(const eHeadersErrors err) {

View File

@@ -2,7 +2,6 @@
#include <memory>
#include <string>
#include <utility>
enum eHeadersErrors {
HEADERS_OK = 0,
@@ -69,7 +68,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;

View File

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

View File

@@ -1,16 +1,15 @@
#include "progress/CProgressBar.hpp"
#include "helpers/Colors.hpp"
#include "helpers/StringUtils.hpp"
#include "core/PluginManager.hpp"
#include "core/DataState.hpp"
#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <print>
#include <chrono>
#include <thread>
constexpr std::string_view HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
const std::string 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.
@@ -23,8 +22,7 @@ constexpr std::string_view HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
Flags:
--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
--notify | -n Send a hyprland notification for important events (e.g. load fail)
--help | -h Show this menu
--verbose | -v Enable too much logging
--force | -f Force an operation ignoring checks (e.g. update -f)
@@ -32,38 +30,36 @@ constexpr std::string_view 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::println(stderr, "{}", HELP);
std::cout << HELP;
return 1;
}
std::vector<std::string> command;
bool notify = false, notifyFail = false, verbose = false, force = false, noShallow = false;
bool notify = 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::println("{}", HELP);
std::cout << 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::println("{}", statusString("!", Colors::RED, "Using --force, I hope you know what you are doing."));
std::cout << Colors::RED << "!" << Colors::RESET << " Using --force, I hope you know what you are doing.\n";
} else {
std::println(stderr, "Unrecognized option {}", ARGS[i]);
std::cerr << "Unrecognized option " << ARGS[i] << "\n";
return 1;
}
} else {
@@ -72,7 +68,7 @@ int main(int argc, char** argv, char** envp) {
}
if (command.empty()) {
std::println(stderr, "{}", HELP);
std::cout << HELP;
return 0;
}
@@ -82,7 +78,7 @@ int main(int argc, char** argv, char** envp) {
if (command[0] == "add") {
if (command.size() < 2) {
std::println(stderr, "{}", failureString("Not enough args for add."));
std::cerr << Colors::RED << "" << Colors::RESET << " Not enough args for add.\n";
return 1;
}
@@ -94,7 +90,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::println(stderr, "{}", failureString("Not enough args for remove."));
std::cerr << Colors::RED << "" << Colors::RESET << " Not enough args for remove.\n";
return 1;
}
@@ -120,12 +116,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::println(stderr, "{}", failureString("Not enough args for enable."));
std::cerr << Colors::RED << "" << Colors::RESET << " Not enough args for enable.\n";
return 1;
}
if (!g_pPluginManager->enablePlugin(command[1])) {
std::println(stderr, "{}", failureString("Couldn't enable plugin (missing?)"));
std::cerr << Colors::RED << "" << Colors::RESET << " Couldn't enable plugin (missing?)\n";
return 1;
}
@@ -134,12 +130,12 @@ int main(int argc, char** argv, char** envp) {
return 1;
} else if (command[0] == "disable") {
if (command.size() < 2) {
std::println(stderr, "{}", failureString("Not enough args for disable."));
std::cerr << Colors::RED << "" << Colors::RESET << " Not enough args for disable.\n";
return 1;
}
if (!g_pPluginManager->disablePlugin(command[1])) {
std::println(stderr, "{}", failureString("Couldn't disable plugin (missing?)"));
std::cerr << Colors::RED << "" << Colors::RESET << " Couldn't disable plugin (missing?)\n";
return 1;
}
@@ -158,15 +154,15 @@ int main(int argc, char** argv, char** envp) {
break;
default: break;
}
} else if (notify && !notifyFail) {
} else if (notify) {
g_pPluginManager->notify(ICON_OK, 0, 4000, "[hyprpm] Loaded plugins");
}
} else if (command[0] == "list") {
g_pPluginManager->listAllPlugins();
} else {
std::println(stderr, "{}", HELP);
std::cout << HELP;
return 1;
}
return 0;
}
}

View File

@@ -1,11 +1,11 @@
#include "CProgressBar.hpp"
#include <sys/ioctl.h>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <format>
#include <print>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
@@ -16,12 +16,11 @@ 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::println("\r{}\r{}", spaces, msg);
std::cout << "\r" << spaces << "\r" << msg << "\n";
print();
}
@@ -30,16 +29,15 @@ void CProgressBar::print() {
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
if (m_bFirstPrint)
std::print("\n");
std::cout << "\n";
m_bFirstPrint = false;
std::string spaces;
spaces.reserve(w.ws_col);
for (size_t i = 0; i < w.ws_col; ++i) {
spaces += ' ';
}
std::print("\r{}\r", spaces);
std::cout << "\r" << spaces << "\r";
std::string message = "";
@@ -76,7 +74,7 @@ void CProgressBar::print() {
message += " " + std::format("{} / {}", m_iSteps, m_iMaxSteps) + " ";
// draw message
std::print("{} {}", message, m_szCurrentMessage);
std::cout << message + " " + m_szCurrentMessage;
std::fflush(stdout);
}
}

View File

@@ -14,4 +14,4 @@ class CProgressBar {
private:
bool m_bFirstPrint = true;
};
};

View File

@@ -21,7 +21,6 @@ add_project_arguments(
'-Wno-missing-field-initializers',
'-Wno-narrowing',
'-Wno-pointer-arith', datarootdir,
'-DHYPRLAND_VERSION="' + meson.project_version() + '"',
],
language: 'cpp',
)
@@ -31,7 +30,7 @@ if cpp_compiler.check_header('execinfo.h')
add_project_arguments('-DHAS_EXECINFO', language: 'cpp')
endif
aquamarine = dependency('aquamarine', version: '>=0.4.2')
aquamarine = dependency('aquamarine')
add_project_arguments(['-DAQUAMARINE_VERSION="@0@"'.format(aquamarine.version())], language: 'cpp')
xcb_dep = dependency('xcb', required: get_option('xwayland'))
@@ -53,9 +52,7 @@ 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()
@@ -82,8 +79,6 @@ if get_option('tracy_enable') and get_option('buildtype') != 'debugoptimized'
warning('Profiling builds should set -- buildtype = debugoptimized')
endif
subdir('protocols')
subdir('src')
subdir('hyprctl')

View File

@@ -56,7 +56,6 @@
adapters = flatten [
stdenvAdapters.useMoldLinker
(lib.optional debug stdenvAdapters.keepDebugInfo)
];
customStdenv = foldl' (acc: adapter: adapter acc) stdenv adapters;
@@ -69,7 +68,7 @@ in
inherit version;
src = cleanSourceWith {
filter = name: _type: let
filter = name: type: let
baseName = baseNameOf (toString name);
in
! (hasSuffix ".nix" baseName);
@@ -148,6 +147,9 @@ in
then "debugoptimized"
else "release";
# we want as much debug info as possible
dontStrip = debug;
mesonFlags = flatten [
(mapAttrsToList mesonEnable {
"xwayland" = enableXWayland;

View File

@@ -1,64 +0,0 @@
{
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
'';
}

View File

@@ -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,13 +40,7 @@ in {
inherit date;
};
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
# 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-debug = final.hyprland.override {debug = true;};
hyprland-legacy-renderer = final.hyprland.override {legacyRenderer = true;};
# deprecated packages
@@ -69,14 +63,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.default
inputs.xdph.overlays.xdg-desktop-portal-hyprland
];
# 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";

View File

@@ -7,7 +7,7 @@ wayland_protos = dependency(
hyprland_protos = dependency(
'hyprland-protocols',
version: '>=0.4',
version: '>=0.2',
fallback: 'hyprland-protocols',
)
@@ -36,7 +36,6 @@ 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',
@@ -65,7 +64,6 @@ 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 = []

View File

@@ -1,5 +1,4 @@
#include "Compositor.hpp"
#include "debug/Log.hpp"
#include "helpers/Splashes.hpp"
#include "config/ConfigValue.hpp"
#include "managers/CursorManager.hpp"
@@ -9,9 +8,7 @@
#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>
@@ -27,14 +24,12 @@
#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>
@@ -141,37 +136,37 @@ CCompositor::CCompositor() {
m_szHyprTempDataRoot = std::string{getenv("XDG_RUNTIME_DIR")} + "/hypr";
if (m_szHyprTempDataRoot.starts_with("/hypr")) {
std::println("Bailing out, $XDG_RUNTIME_DIR is invalid");
std::cout << "Bailing out, XDG_RUNTIME_DIR is invalid\n";
throw std::runtime_error("CCompositor() failed");
}
if (!m_szHyprTempDataRoot.starts_with("/run/user"))
std::println("[!!WARNING!!] XDG_RUNTIME_DIR looks non-standard. Proceeding anyways...");
std::cout << "[!!WARNING!!] XDG_RUNTIME_DIR looks non-standard. Proceeding anyways...\n";
std::random_device dev;
std::mt19937 engine(dev());
std::uniform_int_distribution<> distribution(0, INT32_MAX);
m_szInstanceSignature = std::format("{}_{}_{}", GIT_COMMIT_HASH, std::time(NULL), distribution(engine));
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL)) + "_" + std::to_string(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::println("Bailing out, {} is not a directory", m_szHyprTempDataRoot);
std::cout << "Bailing out, " << m_szHyprTempDataRoot << " is not a directory\n";
throw std::runtime_error("CCompositor() failed");
}
m_szInstancePath = m_szHyprTempDataRoot + "/" + m_szInstanceSignature;
if (std::filesystem::exists(m_szInstancePath)) {
std::println("Bailing out, {} exists??", m_szInstancePath);
std::cout << "Bailing out, " << m_szInstancePath << " exists??\n";
throw std::runtime_error("CCompositor() failed");
}
if (mkdir(m_szInstancePath.c_str(), S_IRWXU) < 0) {
std::println("Bailing out, couldn't create {}", m_szInstancePath);
std::cout << "Bailing out, couldn't create " << m_szInstancePath << "\n";
throw std::runtime_error("CCompositor() failed");
}
@@ -215,22 +210,11 @@ 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
@@ -413,8 +397,8 @@ void CCompositor::initAllSignals() {
m_bSessionActive = true;
for (auto const& m : m_vMonitors) {
scheduleFrameForMonitor(m);
g_pHyprRenderer->applyMonitorRule(m, &m->activeMonitorRule, true);
scheduleFrameForMonitor(m.get());
g_pHyprRenderer->applyMonitorRule(m.get(), &m->activeMonitorRule, true);
}
g_pConfigManager->m_bWantsMonitorReload = true;
@@ -499,7 +483,7 @@ void CCompositor::cleanup() {
m_vWindows.clear();
for (auto const& m : m_vMonitors) {
g_pHyprOpenGL->destroyMonitorResources(m);
g_pHyprOpenGL->destroyMonitorResources(m.get());
m->output->state->setEnabled(false);
m->state.commit();
@@ -718,39 +702,39 @@ void CCompositor::startCompositor() {
g_pEventLoopManager->enterLoop();
}
PHLMONITOR CCompositor::getMonitorFromID(const MONITORID& id) {
CMonitor* CCompositor::getMonitorFromID(const MONITORID& id) {
for (auto const& m : m_vMonitors) {
if (m->ID == id) {
return m;
return m.get();
}
}
return nullptr;
}
PHLMONITOR CCompositor::getMonitorFromName(const std::string& name) {
CMonitor* CCompositor::getMonitorFromName(const std::string& name) {
for (auto const& m : m_vMonitors) {
if (m->szName == name) {
return m;
return m.get();
}
}
return nullptr;
}
PHLMONITOR CCompositor::getMonitorFromDesc(const std::string& desc) {
CMonitor* CCompositor::getMonitorFromDesc(const std::string& desc) {
for (auto const& m : m_vMonitors) {
if (m->szDescription.starts_with(desc))
return m;
return m.get();
}
return nullptr;
}
PHLMONITOR CCompositor::getMonitorFromCursor() {
CMonitor* CCompositor::getMonitorFromCursor() {
return getMonitorFromVector(g_pPointerManager->position());
}
PHLMONITOR CCompositor::getMonitorFromVector(const Vector2D& point) {
PHLMONITOR mon;
CMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
SP<CMonitor> mon;
for (auto const& m : m_vMonitors) {
if (CBox{m->vecPosition, m->vecSize}.containsPoint(point)) {
mon = m;
@@ -759,8 +743,8 @@ PHLMONITOR CCompositor::getMonitorFromVector(const Vector2D& point) {
}
if (!mon) {
float bestDistance = 0.f;
PHLMONITOR pBestMon;
float bestDistance = 0.f;
SP<CMonitor> pBestMon;
for (auto const& m : m_vMonitors) {
float dist = vecToRectDistanceSquared(point, m->vecPosition, m->vecPosition + m->vecSize);
@@ -773,13 +757,13 @@ PHLMONITOR CCompositor::getMonitorFromVector(const Vector2D& point) {
if (!pBestMon) { // ?????
Debug::log(WARN, "getMonitorFromVector no close mon???");
return m_vMonitors.front();
return m_vMonitors.front().get();
}
return pBestMon;
return pBestMon.get();
}
return mon;
return mon.get();
}
void CCompositor::removeWindowFromVectorSafe(PHLWINDOW pWindow) {
@@ -791,9 +775,9 @@ void CCompositor::removeWindowFromVectorSafe(PHLWINDOW pWindow) {
}
}
bool CCompositor::monitorExists(PHLMONITOR pMonitor) {
bool CCompositor::monitorExists(CMonitor* pMonitor) {
for (auto const& m : m_vRealMonitors) {
if (m == pMonitor)
if (m.get() == pMonitor)
return true;
}
@@ -811,10 +795,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;
@@ -833,25 +817,22 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
if (special && !w->onSpecialWorkspace()) // because special floating may creep up into regular
continue;
const auto PWINDOWMONITOR = w->m_pMonitor.lock();
const auto BB = w->getWindowBoxUnified(properties);
const auto PWINDOWMONITOR = getMonitorFromID(w->m_iMonitorID);
// to avoid focusing windows behind special workspaces from other monitors
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;
}
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;
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()) {
@@ -909,12 +890,10 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
if (special != w->onSpecialWorkspace())
continue;
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;
}
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;
}
return nullptr;
@@ -988,20 +967,20 @@ Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindo
return vec - pWindow->m_vRealPosition.goal() - std::get<1>(iterData) + Vector2D{geom.x, geom.y};
}
PHLMONITOR CCompositor::getMonitorFromOutput(SP<Aquamarine::IOutput> out) {
CMonitor* CCompositor::getMonitorFromOutput(SP<Aquamarine::IOutput> out) {
for (auto const& m : m_vMonitors) {
if (m->output == out) {
return m;
return m.get();
}
}
return nullptr;
}
PHLMONITOR CCompositor::getRealMonitorFromOutput(SP<Aquamarine::IOutput> out) {
CMonitor* CCompositor::getRealMonitorFromOutput(SP<Aquamarine::IOutput> out) {
for (auto const& m : m_vRealMonitors) {
if (m->output == out) {
return m;
return m.get();
}
}
@@ -1062,13 +1041,13 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
return;
}
if (m_pLastWindow.lock() == pWindow && g_pSeatManager->state.keyboardFocus == pSurface && g_pSeatManager->state.keyboardFocus)
if (m_pLastWindow.lock() == pWindow && g_pSeatManager->state.keyboardFocus == pSurface)
return;
if (pWindow->m_bPinned)
pWindow->m_pWorkspace = m_pLastMonitor->activeWorkspace;
const auto PMONITOR = pWindow->m_pMonitor.lock();
const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID);
if (!isWorkspaceVisible(pWindow->m_pWorkspace)) {
const auto PWORKSPACE = pWindow->m_pWorkspace;
@@ -1189,7 +1168,7 @@ void CCompositor::focusSurface(SP<CWLSurfaceResource> pSurface, PHLWINDOW pWindo
SURF->constraint()->activate();
}
SP<CWLSurfaceResource> CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, PHLMONITOR monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
SP<CWLSurfaceResource> CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonitor* 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)
@@ -1264,7 +1243,7 @@ bool CCompositor::isWorkspaceVisibleNotCovered(PHLWORKSPACE w) {
if (!valid(w))
return false;
const auto PMONITOR = w->m_pMonitor.lock();
const auto PMONITOR = getMonitorFromID(w->m_iMonitorID);
if (PMONITOR->activeSpecialWorkspace)
return PMONITOR->activeSpecialWorkspace->m_iID == w->m_iID;
@@ -1359,7 +1338,7 @@ PHLWINDOW CCompositor::getTopLeftWindowOnWorkspace(const WORKSPACEID& id) {
if (!PWORKSPACE)
return nullptr;
const auto PMONITOR = PWORKSPACE->m_pMonitor.lock();
const auto PMONITOR = getMonitorFromID(PWORKSPACE->m_iMonitorID);
for (auto const& w : m_vWindows) {
if (w->workspaceID() != id || !w->m_bIsMapped || w->isHidden())
@@ -1389,9 +1368,6 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) {
if (!validMapped(pWindow))
return;
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) {
@@ -1410,7 +1386,7 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) {
}
if (pw->m_bIsMapped)
g_pHyprRenderer->damageMonitor(pw->m_pMonitor.lock());
g_pHyprRenderer->damageMonitor(getMonitorFromID(pw->m_iMonitorID));
};
if (top)
@@ -1449,7 +1425,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) {
auto w = ww.lock();
if (w->monitorID() != monid && w->m_pMonitor)
if (w->m_iMonitorID != monid)
continue;
if (!w->m_bFadingOut || w->m_fAlpha.value() == 0.f) {
@@ -1479,7 +1455,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) {
continue;
}
if (ls->monitorID() != monid && ls->monitor)
if (ls->monitorID != monid)
continue;
// mark blur for recalc
@@ -1542,7 +1518,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 = pWindow->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
if (!PMONITOR)
return nullptr; // ??
@@ -1563,13 +1539,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_pMonitor == w->m_pMonitor && pWindow->m_pWorkspace != w->m_pWorkspace)
if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_pWorkspace != w->m_pWorkspace)
continue;
if (PWORKSPACE->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen)
continue;
if (!*PMONITORFALLBACK && pWindow->m_pMonitor != w->m_pMonitor)
if (!*PMONITORFALLBACK && pWindow->m_iMonitorID != w->m_iMonitorID)
continue;
const auto BWINDOWIDEALBB = w->getWindowIdealBoundingBoxIgnoreReserved();
@@ -1655,13 +1631,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_pMonitor == w->m_pMonitor && pWindow->m_pWorkspace != w->m_pWorkspace)
if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_pWorkspace != w->m_pWorkspace)
continue;
if (PWORKSPACE->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen)
continue;
if (!*PMONITORFALLBACK && pWindow->m_pMonitor != w->m_pMonitor)
if (!*PMONITORFALLBACK && pWindow->m_iMonitorID != w->m_iMonitorID)
continue;
const auto DIST = w->middle().distance(pWindow->middle());
@@ -1785,7 +1761,7 @@ bool CCompositor::isPointOnAnyMonitor(const Vector2D& point) {
return false;
}
bool CCompositor::isPointOnReservedArea(const Vector2D& point, const PHLMONITOR pMonitor) {
bool CCompositor::isPointOnReservedArea(const Vector2D& point, const CMonitor* pMonitor) {
const auto PMONITOR = pMonitor ? pMonitor : getMonitorFromVector(point);
const auto XY1 = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
@@ -1794,11 +1770,11 @@ bool CCompositor::isPointOnReservedArea(const Vector2D& point, const PHLMONITOR
return !VECINRECT(point, XY1.x, XY1.y, XY2.x, XY2.y);
}
PHLMONITOR CCompositor::getMonitorInDirection(const char& dir) {
return getMonitorInDirection(m_pLastMonitor.lock(), dir);
CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
return this->getMonitorInDirection(m_pLastMonitor.get(), dir);
}
PHLMONITOR CCompositor::getMonitorInDirection(PHLMONITOR pSourceMonitor, const char& dir) {
CMonitor* CCompositor::getMonitorInDirection(CMonitor* pSourceMonitor, const char& dir) {
if (!pSourceMonitor)
return nullptr;
@@ -1806,7 +1782,7 @@ PHLMONITOR CCompositor::getMonitorInDirection(PHLMONITOR pSourceMonitor, const c
const auto SIZEA = pSourceMonitor->vecSize;
auto longestIntersect = -1;
PHLMONITOR longestIntersectMonitor = nullptr;
CMonitor* longestIntersectMonitor = nullptr;
for (auto const& m : m_vMonitors) {
if (m == m_pLastMonitor)
@@ -1820,7 +1796,7 @@ PHLMONITOR CCompositor::getMonitorInDirection(PHLMONITOR pSourceMonitor, const c
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;
longestIntersectMonitor = m.get();
}
}
break;
@@ -1829,7 +1805,7 @@ PHLMONITOR CCompositor::getMonitorInDirection(PHLMONITOR pSourceMonitor, const c
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;
longestIntersectMonitor = m.get();
}
}
break;
@@ -1839,7 +1815,7 @@ PHLMONITOR CCompositor::getMonitorInDirection(PHLMONITOR pSourceMonitor, const c
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;
longestIntersectMonitor = m.get();
}
}
break;
@@ -1849,7 +1825,7 @@ PHLMONITOR CCompositor::getMonitorInDirection(PHLMONITOR pSourceMonitor, const c
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;
longestIntersectMonitor = m.get();
}
}
break;
@@ -1893,8 +1869,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:shadow:color");
static auto PSHADOWCOLINACTIVE = CConfigValue<Hyprlang::INT>("decoration:shadow:color_inactive");
static auto PSHADOWCOL = CConfigValue<Hyprlang::INT>("decoration:col.shadow");
static auto PSHADOWCOLINACTIVE = CConfigValue<Hyprlang::INT>("decoration:col.shadow_inactive");
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
static auto PDIMENABLED = CConfigValue<Hyprlang::INT>("decoration:dim_inactive");
@@ -1965,10 +1941,11 @@ 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 != INT64_MAX ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
} else {
pWindow->m_cRealShadowColor = CColor(*PSHADOWCOLINACTIVE != INT_MAX ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
}
} else {
pWindow->m_cRealShadowColor.setValueAndWarp(CColor(0, 0, 0, 0)); // no shadow
}
@@ -1995,12 +1972,12 @@ MONITORID CCompositor::getNextAvailableMonitorID(std::string const& name) {
return nextID;
}
void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitorB) {
void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) {
const auto PWORKSPACEA = pMonitorA->activeWorkspace;
const auto PWORKSPACEB = pMonitorB->activeWorkspace;
PWORKSPACEA->m_pMonitor = pMonitorB;
PWORKSPACEA->m_iMonitorID = pMonitorB->ID;
PWORKSPACEA->moveToMonitor(pMonitorB->ID);
for (auto const& w : m_vWindows) {
@@ -2010,7 +1987,7 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
continue;
}
w->m_pMonitor = pMonitorB;
w->m_iMonitorID = pMonitorB->ID;
// additionally, move floating and fs windows manually
if (w->m_bIsFloating)
@@ -2025,7 +2002,7 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
}
}
PWORKSPACEB->m_pMonitor = pMonitorA;
PWORKSPACEB->m_iMonitorID = pMonitorA->ID;
PWORKSPACEB->moveToMonitor(pMonitorA->ID);
for (auto const& w : m_vWindows) {
@@ -2035,7 +2012,7 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
continue;
}
w->m_pMonitor = pMonitorA;
w->m_iMonitorID = pMonitorA->ID;
// additionally, move floating and fs windows manually
if (w->m_bIsFloating)
@@ -2082,16 +2059,16 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
EMIT_HOOK_EVENT("moveWorkspace", (std::vector<std::any>{PWORKSPACEB, pMonitorA}));
}
PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
if (name == "current")
return g_pCompositor->m_pLastMonitor.lock();
return g_pCompositor->m_pLastMonitor.get();
else if (isDirection(name))
return getMonitorInDirection(name[0]);
else if (name[0] == '+' || name[0] == '-') {
// relative
if (m_vMonitors.size() == 1)
return *m_vMonitors.begin();
return m_vMonitors.begin()->get();
const auto OFFSET = name[0] == '-' ? name : name.substr(1);
@@ -2124,7 +2101,7 @@ PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
currentPlace = std::clamp(currentPlace, 0, (int)m_vMonitors.size() - 1);
}
return m_vMonitors[currentPlace];
return m_vMonitors[currentPlace].get();
} else if (isNumber(name)) {
// change by ID
MONITORID monID = MONITOR_INVALID;
@@ -2148,7 +2125,7 @@ PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
continue;
if (m->matchesStaticSelector(name)) {
return m;
return m.get();
}
}
}
@@ -2156,16 +2133,16 @@ PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
return nullptr;
}
void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMonitor, bool noWarpCursor) {
void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMonitor, bool noWarpCursor) {
// We trust the monitor to be correct.
if (pWorkspace->m_pMonitor == pMonitor)
if (pWorkspace->m_iMonitorID == pMonitor->ID)
return;
Debug::log(LOG, "moveWorkspaceToMonitor: Moving {} to monitor {}", pWorkspace->m_iID, pMonitor->ID);
const auto POLDMON = pWorkspace->m_pMonitor.lock();
const auto POLDMON = getMonitorFromID(pWorkspace->m_iMonitorID);
const bool SWITCHINGISACTIVE = POLDMON ? POLDMON->activeWorkspace == pWorkspace : false;
@@ -2175,7 +2152,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
nextWorkspaceOnMonitorID = pWorkspace->m_iID;
else {
for (auto const& w : m_vWorkspaces) {
if (w->m_pMonitor == POLDMON && w->m_iID != pWorkspace->m_iID && !w->m_bIsSpecialWorkspace) {
if (w->m_iMonitorID == POLDMON->ID && w->m_iID != pWorkspace->m_iID && !w->m_bIsSpecialWorkspace) {
nextWorkspaceOnMonitorID = w->m_iID;
break;
}
@@ -2200,7 +2177,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
}
// move the workspace
pWorkspace->m_pMonitor = pMonitor;
pWorkspace->m_iMonitorID = pMonitor->ID;
pWorkspace->moveToMonitor(pMonitor->ID);
for (auto const& w : m_vWindows) {
@@ -2210,7 +2187,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
continue;
}
w->m_pMonitor = pMonitor;
w->m_iMonitorID = pMonitor->ID;
// additionally, move floating and fs windows manually
if (w->m_bIsMapped && !w->isHidden()) {
@@ -2231,7 +2208,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
}
}
if (SWITCHINGISACTIVE && POLDMON == g_pCompositor->m_pLastMonitor) { // if it was active, preserve its' status. If it wasn't, don't.
if (SWITCHINGISACTIVE && POLDMON == g_pCompositor->m_pLastMonitor.get()) { // 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)) {
@@ -2303,7 +2280,7 @@ void CCompositor::updateFullscreenFadeOnWorkspace(PHLWORKSPACE pWorkspace) {
}
}
const auto PMONITOR = pWorkspace->m_pMonitor.lock();
const auto PMONITOR = getMonitorFromID(pWorkspace->m_iMonitorID);
if (pWorkspace->m_iID == PMONITOR->activeWorkspaceID() || pWorkspace->m_iID == PMONITOR->activeSpecialWorkspaceID()) {
for (auto const& ls : PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
@@ -2346,7 +2323,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 = PWINDOW->m_pMonitor.lock();
const auto PMONITOR = getMonitorFromID(PWINDOW->m_iMonitorID);
const auto PWORKSPACE = PWINDOW->m_pWorkspace;
const eFullscreenMode CURRENT_EFFECTIVE_MODE = (eFullscreenMode)std::bit_floor((uint8_t)PWINDOW->m_sFullscreenState.internal);
@@ -2364,7 +2341,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, sFullscreenS
if (!CHANGEINTERNAL) {
PWINDOW->updateDynamicRules();
updateWindowAnimatedDecorationValues(PWINDOW);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
return;
}
@@ -2379,7 +2356,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, sFullscreenS
PWINDOW->updateDynamicRules();
updateWindowAnimatedDecorationValues(PWINDOW);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
// make all windows on the same workspace under the fullscreen window
for (auto const& w : m_vWindows) {
@@ -2443,7 +2420,7 @@ void CCompositor::updateWorkspaceWindowData(const WORKSPACEID& id) {
}
}
void CCompositor::scheduleFrameForMonitor(PHLMONITOR pMonitor, IOutput::scheduleFrameReason reason) {
void CCompositor::scheduleFrameForMonitor(CMonitor* pMonitor, IOutput::scheduleFrameReason reason) {
if ((m_pAqBackend->hasSession() && !m_pAqBackend->session->active) || !m_bSessionActive)
return;
@@ -2456,31 +2433,13 @@ void CCompositor::scheduleFrameForMonitor(PHLMONITOR pMonitor, IOutput::schedule
pMonitor->output->scheduleFrame(reason);
}
PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp_) {
auto regexp = trim(regexp_);
PHLWINDOW CCompositor::getWindowByRegex(const std::string& 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));
@@ -2499,6 +2458,21 @@ 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) {
@@ -2560,7 +2534,7 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
if (*PNOWARPS && !force) {
const auto PMONITORNEW = getMonitorFromVector(pos);
if (PMONITORNEW != m_pLastMonitor)
if (PMONITORNEW != m_pLastMonitor.get())
setActiveMonitor(PMONITORNEW);
return;
}
@@ -2568,7 +2542,7 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
g_pPointerManager->warpTo(pos);
const auto PMONITORNEW = getMonitorFromVector(pos);
if (PMONITORNEW != m_pLastMonitor)
if (PMONITORNEW != m_pLastMonitor.get())
setActiveMonitor(PMONITORNEW);
}
@@ -2667,12 +2641,13 @@ 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, getMonitorFromID(monID), NAME, SPECIAL, isEmpty));
const auto PWORKSPACE = m_vWorkspaces.emplace_back(CWorkspace::create(id, monID, NAME, SPECIAL, isEmpty));
PWORKSPACE->m_fAlpha.setValueAndWarp(0);
@@ -2694,8 +2669,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(PHLMONITOR pMonitor) {
if (m_pLastMonitor == pMonitor)
void CCompositor::setActiveMonitor(CMonitor* pMonitor) {
if (m_pLastMonitor.get() == pMonitor)
return;
if (!pMonitor) {
@@ -2737,12 +2712,6 @@ 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) {
@@ -2758,57 +2727,31 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor
if (FULLSCREEN)
setWindowFullscreenInternal(pWindow, FSMODE_NONE);
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)
if (!pWindow->m_bIsFloating) {
g_pLayoutManager->getCurrentLayout()->onWindowRemovedTiling(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));
pWindow->moveToWorkspace(pWorkspace);
pWindow->m_iMonitorID = pWorkspace->m_iMonitorID;
g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow);
} else {
if (!pWindow->m_bIsFloating)
g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow);
const auto PWINDOWMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
const auto POSTOMON = pWindow->m_vRealPosition.goal() - PWINDOWMONITOR->vecPosition;
if (pWindow->m_bIsFloating)
pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition;
const auto PWORKSPACEMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
pWindow->moveToWorkspace(pWorkspace);
pWindow->m_iMonitorID = pWorkspace->m_iMonitorID;
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();
}
@@ -2837,13 +2780,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<PHLMONITOR> toArrange;
std::vector<PHLMONITOR> arranged;
std::vector<CMonitor*> toArrange;
std::vector<CMonitor*> arranged;
for (auto const& m : m_vMonitors)
toArrange.push_back(m);
toArrange.push_back(m.get());
Debug::log(LOG, "arrangeMonitors: {} to arrange", toArrange.size());
@@ -2942,7 +2885,7 @@ void CCompositor::enterUnsafeState() {
m_bUnsafeState = true;
setActiveMonitor(m_pUnsafeOutput.lock());
setActiveMonitor(m_pUnsafeOutput);
}
void CCompositor::leaveUnsafeState() {
@@ -2953,10 +2896,10 @@ void CCompositor::leaveUnsafeState() {
m_bUnsafeState = false;
PHLMONITOR pNewMonitor = nullptr;
CMonitor* pNewMonitor = nullptr;
for (auto const& pMonitor : m_vMonitors) {
if (pMonitor->output != m_pUnsafeOutput->output) {
pNewMonitor = pMonitor;
pNewMonitor = pMonitor.get();
break;
}
}
@@ -2967,7 +2910,7 @@ void CCompositor::leaveUnsafeState() {
m_pUnsafeOutput->onDisconnect();
for (auto const& m : m_vMonitors) {
scheduleFrameForMonitor(m);
scheduleFrameForMonitor(m.get());
}
}
@@ -3017,7 +2960,7 @@ PHLWINDOW CCompositor::windowForCPointer(CWindow* pWindow) {
return {};
}
static void checkDefaultCursorWarp(PHLMONITOR monitor) {
static void checkDefaultCursorWarp(SP<CMonitor> monitor) {
static auto PCURSORMONITOR = CConfigValue<std::string>("cursor:default_monitor");
static bool cursorDefaultDone = false;
static bool firstLaunch = true;
@@ -3043,7 +2986,7 @@ static void checkDefaultCursorWarp(PHLMONITOR 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) {
if (g_pCompositor->getMonitorFromCursor() == monitor.get()) {
g_pCompositor->warpCursorTo(POS, true);
g_pInputManager->refocus();
}
@@ -3053,7 +2996,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;
g_pCompositor->m_pUnsafeOutput = PNEWMONITOR.get();
output->name = "FALLBACK"; // we are allowed to do this :)
}
@@ -3076,22 +3019,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;
g_pHyprRenderer->m_pMostHzMonitor = PNEWMONITOR.get();
g_pCompositor->m_bReadyToProcess = true;
g_pConfigManager->m_bWantsMonitorReload = true;
g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR, IOutput::AQ_SCHEDULE_NEW_MONITOR);
g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR.get(), IOutput::AQ_SCHEDULE_NEW_MONITOR);
checkDefaultCursorWarp(PNEWMONITOR);
for (auto const& w : g_pCompositor->m_vWindows) {
if (w->m_pMonitor == PNEWMONITOR) {
if (w->m_iMonitorID == PNEWMONITOR->ID) {
w->m_iLastSurfaceMonitorID = MONITOR_INVALID;
w->updateSurfaceScaleTransformDetails();
}
}
g_pHyprRenderer->damageMonitor(PNEWMONITOR);
PNEWMONITOR->onMonitorFrame();
g_pHyprRenderer->damageMonitor(PNEWMONITOR.get());
Events::listener_monitorFrame(PNEWMONITOR.get(), nullptr);
}

View File

@@ -59,8 +59,8 @@ class CCompositor {
std::string m_szInstancePath = "";
std::string m_szCurrentSplash = "error";
std::vector<PHLMONITOR> m_vMonitors;
std::vector<PHLMONITOR> m_vRealMonitors; // for all monitors, even those turned off
std::vector<SP<CMonitor>> m_vMonitors;
std::vector<SP<CMonitor>> 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;
PHLMONITORREF m_pLastMonitor;
WP<CMonitor> 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;
PHLMONITORREF m_pUnsafeOutput; // fallback output for the unsafe state
CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state
bool m_bIsShuttingDown = false;
bool m_bFinalRequests = false;
bool m_bDesktopEnvSet = false;
@@ -97,22 +97,22 @@ class CCompositor {
// ------------------------------------------------- //
PHLMONITOR getMonitorFromID(const MONITORID&);
PHLMONITOR getMonitorFromName(const std::string&);
PHLMONITOR getMonitorFromDesc(const std::string&);
PHLMONITOR getMonitorFromCursor();
PHLMONITOR getMonitorFromVector(const Vector2D&);
CMonitor* getMonitorFromID(const MONITORID&);
CMonitor* getMonitorFromName(const std::string&);
CMonitor* getMonitorFromDesc(const std::string&);
CMonitor* getMonitorFromCursor();
CMonitor* getMonitorFromVector(const Vector2D&);
void removeWindowFromVectorSafe(PHLWINDOW);
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr);
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
bool monitorExists(PHLMONITOR);
bool monitorExists(CMonitor*);
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&, PHLMONITOR monitor, Vector2D*, PHLLS*);
SP<CWLSurfaceResource> vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, PHLLS*);
SP<CWLSurfaceResource> vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl);
Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, SP<CWLSurfaceResource>);
PHLMONITOR getMonitorFromOutput(SP<Aquamarine::IOutput>);
PHLMONITOR getRealMonitorFromOutput(SP<Aquamarine::IOutput>);
CMonitor* getMonitorFromOutput(SP<Aquamarine::IOutput>);
CMonitor* 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 PHLMONITOR monitor = nullptr);
PHLMONITOR getMonitorInDirection(const char&);
PHLMONITOR getMonitorInDirection(PHLMONITOR, const char&);
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
CMonitor* getMonitorInDirection(const char&);
CMonitor* getMonitorInDirection(CMonitor*, const char&);
void updateAllWindowsAnimatedDecorationValues();
void updateWorkspaceWindows(const WORKSPACEID& id);
void updateWindowAnimatedDecorationValues(PHLWINDOW);
MONITORID getNextAvailableMonitorID(std::string const& name);
void moveWorkspaceToMonitor(PHLWORKSPACE, PHLMONITOR, bool noWarpCursor = false);
void swapActiveWorkspaces(PHLMONITOR, PHLMONITOR);
PHLMONITOR getMonitorFromString(const std::string&);
void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
void swapActiveWorkspaces(CMonitor*, CMonitor*);
CMonitor* 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(PHLMONITOR, Aquamarine::IOutput::scheduleFrameReason reason = Aquamarine::IOutput::AQ_SCHEDULE_CLIENT_UNKNOWN);
void scheduleFrameForMonitor(CMonitor*, 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(PHLMONITOR);
void setActiveMonitor(CMonitor*);
bool isWorkspaceSpecial(const WORKSPACEID&);
WORKSPACEID getNewSpecialID();
void performUserChecks();

View File

@@ -104,30 +104,6 @@ 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:
@@ -158,55 +134,49 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
},
SConfigOptionDescription{
.value = "decoration:shadow:enabled",
.value = "decoration:drop_shadow",
.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: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",
.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:shadow:color",
.value = "decoration:col.shadow",
.description = "shadow's color. Alpha dictates shadow's opacity.",
.type = CONFIG_OPTION_COLOR,
.data = SConfigOptionDescription::SColorData{0xee1a1a1a},
},
SConfigOptionDescription{
.value = "decoration:shadow:color_inactive",
.value = "decoration:col.shadow_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},
@@ -778,12 +748,6 @@ 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",
@@ -814,24 +778,6 @@ 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:
@@ -1262,8 +1208,8 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
SConfigOptionDescription{
.value = "cursor:no_hardware_cursors",
.description = "disables hardware cursors",
.type = CONFIG_OPTION_CHOICE,
.data = SConfigOptionDescription::SChoiceData{0, "Disabled,Enabled,Auto"},
.type = CONFIG_OPTION_BOOL,
.data = SConfigOptionDescription::SBoolData{false},
},
SConfigOptionDescription{
.value = "cursor:no_break_fs_vrr",
@@ -1488,6 +1434,12 @@ 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",
@@ -1548,6 +1500,12 @@ 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",

View File

@@ -341,10 +341,6 @@ 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});
@@ -381,11 +377,7 @@ 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});
@@ -432,15 +424,14 @@ 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: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: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:dim_inactive", Hyprlang::INT{0});
m_pConfig->addConfigValue("decoration:dim_strength", {0.5f});
m_pConfig->addConfigValue("decoration:dim_special", {0.2f});
@@ -453,6 +444,7 @@ 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});
@@ -465,6 +457,7 @@ 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});
@@ -555,7 +548,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{2});
m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{0});
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});
@@ -592,7 +585,6 @@ 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"});
@@ -696,13 +688,14 @@ 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.");
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();
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();
} 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.");
}
@@ -951,9 +944,9 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
for (auto const& m : g_pCompositor->m_vMonitors) {
// mark blur dirty
g_pHyprOpenGL->markBlurDirtyForMonitor(m);
g_pHyprOpenGL->markBlurDirtyForMonitor(m.get());
g_pCompositor->scheduleFrameForMonitor(m);
g_pCompositor->scheduleFrameForMonitor(m.get());
// Force the compositor to fully re-render all monitors
m->forceFullFrames = 2;
@@ -1091,7 +1084,7 @@ std::string CConfigManager::getDeviceString(const std::string& dev, const std::s
return VAL;
}
SMonitorRule CConfigManager::getMonitorRuleFor(const PHLMONITOR PMONITOR) {
SMonitorRule CConfigManager::getMonitorRuleFor(const SP<CMonitor> PMONITOR) {
auto applyWlrOutputConfig = [PMONITOR](SMonitorRule rule) -> SMonitorRule {
const auto CONFIG = PROTO::outputManagement->getOutputStateFor(PMONITOR);
@@ -1514,7 +1507,7 @@ void CConfigManager::performMonitorReload() {
auto rule = getMonitorRuleFor(m);
if (!g_pHyprRenderer->applyMonitorRule(m, &rule)) {
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule)) {
overAgain = true;
break;
}
@@ -1572,14 +1565,14 @@ void CConfigManager::ensureMonitorStatus() {
auto rule = getMonitorRuleFor(rm);
if (rule.disabled == rm->m_bEnabled)
g_pHyprRenderer->applyMonitorRule(rm, &rule);
g_pHyprRenderer->applyMonitorRule(rm.get(), &rule);
}
}
void CConfigManager::ensureVRR(PHLMONITOR pMonitor) {
void CConfigManager::ensureVRR(CMonitor* pMonitor) {
static auto PVRR = reinterpret_cast<Hyprlang::INT* const*>(getConfigValuePtr("misc:vrr"));
static auto ensureVRRForDisplay = [&](PHLMONITOR m) -> void {
static auto ensureVRRForDisplay = [&](CMonitor* m) -> void {
if (!m->output || m->createdByUser)
return;
@@ -1611,6 +1604,9 @@ void CConfigManager::ensureVRR(PHLMONITOR pMonitor) {
m->vrrActive = true;
return;
} else if (USEVRR == 2) {
/* fullscreen */
m->vrrActive = true;
const auto PWORKSPACE = m->activeWorkspace;
if (!PWORKSPACE)
@@ -1619,9 +1615,6 @@ void CConfigManager::ensureVRR(PHLMONITOR 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);
@@ -1634,8 +1627,6 @@ void CConfigManager::ensureVRR(PHLMONITOR 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);
@@ -1651,7 +1642,7 @@ void CConfigManager::ensureVRR(PHLMONITOR pMonitor) {
}
for (auto const& m : g_pCompositor->m_vMonitors) {
ensureVRRForDisplay(m);
ensureVRRForDisplay(m.get());
}
}
@@ -1663,7 +1654,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));
}
PHLMONITOR CConfigManager::getBoundMonitorForWS(const std::string& wsname) {
CMonitor* CConfigManager::getBoundMonitorForWS(const std::string& wsname) {
auto monitor = getBoundMonitorStringForWS(wsname);
if (monitor.substr(0, 5) == "desc:")
return g_pCompositor->getMonitorFromDesc(monitor.substr(5));
@@ -2784,18 +2775,6 @@ 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(

View File

@@ -169,11 +169,11 @@ class CConfigManager {
static std::string getMainConfigPath();
const std::string getConfigString();
SMonitorRule getMonitorRuleFor(const PHLMONITOR);
SMonitorRule getMonitorRuleFor(const SP<CMonitor>);
SWorkspaceRule getWorkspaceRuleFor(PHLWORKSPACE workspace);
std::string getDefaultWorkspaceFor(const std::string&);
PHLMONITOR getBoundMonitorForWS(const std::string&);
CMonitor* getBoundMonitorForWS(const std::string&);
std::string getBoundMonitorStringForWS(const std::string&);
const std::deque<SWorkspaceRule>& getAllWorkspaceRules();
@@ -198,9 +198,7 @@ class CConfigManager {
void appendMonitorRule(const SMonitorRule&);
bool replaceMonitorRule(const SMonitorRule&);
void ensureMonitorStatus();
void ensureVRR(PHLMONITOR pMonitor = nullptr);
bool shouldUseSoftwareCursors();
void ensureVRR(CMonitor* pMonitor = nullptr);
std::string parseKeyword(const std::string&, const std::string&);

View File

@@ -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/
# https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
# Please note not all available settings / options are set here.
# For a full list, see the wiki
@@ -99,12 +99,10 @@ decoration {
active_opacity = 1.0
inactive_opacity = 1.0
shadow {
enabled = true
range = 4
render_power = 3
color = rgba(1a1a1aee)
}
drop_shadow = true
shadow_range = 4
shadow_render_power = 3
col.shadow = rgba(1a1a1aee)
# https://wiki.hyprland.org/Configuring/Variables/#blur
blur {
@@ -118,47 +116,20 @@ decoration {
# https://wiki.hyprland.org/Configuring/Variables/#animations
animations {
enabled = yes, please :)
enabled = true
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
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
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
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
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
}
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
# "Smart gaps" / "No gaps when only"
# uncomment all if you wish to use that.
# workspace = w[t1], gapsout:0, gapsin:0
# workspace = w[tg1], gapsout:0, gapsin:0
# workspace = f[1], gapsout:0, gapsin:0
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[t1]
# windowrulev2 = rounding 0, floating:0, onworkspace:w[t1]
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[tg1]
# windowrulev2 = rounding 0, floating:0, onworkspace:w[tg1]
# 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

View File

@@ -54,7 +54,7 @@ static std::string formatToString(uint32_t drmFormat) {
return "Invalid";
}
static std::string availableModesForOutput(PHLMONITOR pMonitor, eHyprCtlOutputFormat format) {
static std::string availableModesForOutput(CMonitor* pMonitor, eHyprCtlOutputFormat format) {
std::string result;
for (auto const& m : pMonitor->output->modes) {
@@ -107,7 +107,6 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor>
"activelyTearing": {},
"disabled": {},
"currentFormat": "{}",
"mirrorOf": "{}",
"availableModes": [{}]
}},)#",
@@ -118,19 +117,18 @@ 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),
m->pMirrorOf ? std::format("{}", m->pMirrorOf->ID) : "none", availableModesForOutput(m, format));
availableModesForOutput(m.get(), 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\tmirrorOf: {}\n\tavailableModes: {}\n\n",
"dpmsStatus: {}\n\tvrr: {}\n\tsolitary: {:x}\n\tactivelyTearing: {}\n\tdisabled: {}\n\tcurrentFormat: {}\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),
m->pMirrorOf ? std::format("{}", m->pMirrorOf->ID) : "none", availableModesForOutput(m, format));
m->tearingState.activelyTearing, !m->m_bEnabled, formatToString(m->output->state->state().drmFormat), availableModesForOutput(m.get(), format));
}
return result;
@@ -244,7 +242,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->monitorID(), escapeJSONStrings(w->m_szClass), escapeJSONStrings(w->m_szTitle), escapeJSONStrings(w->m_szInitialClass),
(int64_t)w->m_iMonitorID, 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));
@@ -256,7 +254,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->monitorID(), 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->m_iMonitorID, 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));
}
@@ -290,7 +288,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 = w->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(w->m_iMonitorID);
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
return std::format(R"#({{
"id": {},
@@ -551,15 +549,6 @@ 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";
@@ -591,13 +580,11 @@ 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),
(getModState(k, XKB_MOD_NAME_CAPS) ? "true" : "false"), (getModState(k, XKB_MOD_NAME_NUM) ? "true" : "false"), (k->active ? "true" : "false"));
(k->active ? "true" : "false"));
}
trimTrailingComma(result);
@@ -681,11 +668,9 @@ 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\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 += 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 += "\n\nTablets:\n";
@@ -868,33 +853,26 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
std::replace(commitMsg.begin(), commitMsg.end(), '#', ' ');
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
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);
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";
#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
#ifdef ISDEBUG
#ifndef 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": "{}",
@@ -902,13 +880,13 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
"commits": "{}",
"buildAquamarine": "{}",
"flags": [)#",
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);
GIT_BRANCH, GIT_COMMIT_HASH, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), escapeJSONStrings(commitMsg), GIT_COMMIT_DATE, GIT_TAG, GIT_COMMITS,
AQUAMARINE_VERSION);
#ifdef LEGACY_RENDERER
result += "\"legacyrenderer\",";
#endif
#ifdef ISDEBUG
#ifndef ISDEBUG
result += "\"debug\",";
#endif
#ifdef NO_XWAYLAND
@@ -1043,10 +1021,9 @@ 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" ||
COMMAND.starts_with("windowrule")) {
if (COMMAND.contains("decoration:") || COMMAND.contains("border") || COMMAND == "workspace" || COMMAND.contains("zoom_factor") || COMMAND == "source") {
for (auto const& m : g_pCompositor->m_vMonitors) {
g_pHyprRenderer->damageMonitor(m);
g_pHyprRenderer->damageMonitor(m.get());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
}
}
@@ -1265,8 +1242,101 @@ std::string dispatchSeterror(eHyprCtlOutputFormat format, std::string request) {
}
std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) {
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);
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";
}
std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string request) {
@@ -1701,16 +1771,8 @@ 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);
g_pHyprRenderer->damageMonitor(m.get());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
}
}

View File

@@ -7,7 +7,6 @@
// exposed for main.cpp
std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request);
std::string versionRequest(eHyprCtlOutputFormat format, std::string request);
class CHyprCtl {
public:

View File

@@ -7,7 +7,7 @@ CHyprDebugOverlay::CHyprDebugOverlay() {
m_pTexture = makeShared<CTexture>();
}
void CHyprMonitorDebugOverlay::renderData(PHLMONITOR pMonitor, float durationUs) {
void CHyprMonitorDebugOverlay::renderData(CMonitor* 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(PHLMONITOR pMonitor, float durationUs)
m_pMonitor = pMonitor;
}
void CHyprMonitorDebugOverlay::renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs) {
void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* 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(PHLMONITOR pMonitor, float du
m_pMonitor = pMonitor;
}
void CHyprMonitorDebugOverlay::frameData(PHLMONITOR pMonitor) {
void CHyprMonitorDebugOverlay::frameData(CMonitor* 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(PHLMONITOR pMonitor) {
m_pMonitor = pMonitor;
// anim data too
const auto PMONITORFORTICKS = g_pHyprRenderer->m_pMostHzMonitor ? g_pHyprRenderer->m_pMostHzMonitor.lock() : g_pCompositor->m_pLastMonitor.lock();
const auto PMONITORFORTICKS = g_pHyprRenderer->m_pMostHzMonitor ? g_pHyprRenderer->m_pMostHzMonitor : g_pCompositor->m_pLastMonitor.get();
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(PHLMONITOR pMonitor, float durationUs) {
void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) {
m_mMonitorOverlays[pMonitor].renderData(pMonitor, durationUs);
}
void CHyprDebugOverlay::renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs) {
void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) {
m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, durationUs);
}
void CHyprDebugOverlay::frameData(PHLMONITOR pMonitor) {
void CHyprDebugOverlay::frameData(CMonitor* pMonitor) {
m_mMonitorOverlays[pMonitor].frameData(pMonitor);
}
void CHyprDebugOverlay::draw() {
const auto PMONITOR = g_pCompositor->m_vMonitors.front();
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
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].draw(offsetY);
offsetY += m_mMonitorOverlays[m.get()].draw(offsetY);
offsetY += 5; // for padding between mons
}

View File

@@ -5,7 +5,7 @@
#include "../render/Texture.hpp"
#include <deque>
#include <cairo/cairo.h>
#include <map>
#include <unordered_map>
class CHyprRenderer;
@@ -13,9 +13,9 @@ class CHyprMonitorDebugOverlay {
public:
int draw(int offset);
void renderData(PHLMONITOR pMonitor, float durationUs);
void renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs);
void frameData(PHLMONITOR pMonitor);
void renderData(CMonitor* pMonitor, float durationUs);
void renderDataNoOverlay(CMonitor* pMonitor, float durationUs);
void frameData(CMonitor* 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;
PHLMONITORREF m_pMonitor;
CMonitor* m_pMonitor = nullptr;
CBox m_wbLastDrawnBox;
friend class CHyprRenderer;
@@ -33,17 +33,17 @@ class CHyprDebugOverlay {
public:
CHyprDebugOverlay();
void draw();
void renderData(PHLMONITOR, float durationUs);
void renderDataNoOverlay(PHLMONITOR, float durationUs);
void frameData(PHLMONITOR);
void renderData(CMonitor*, float durationUs);
void renderDataNoOverlay(CMonitor*, float durationUs);
void frameData(CMonitor*);
private:
std::map<PHLMONITORREF, CHyprMonitorDebugOverlay> m_mMonitorOverlays;
std::unordered_map<CMonitor*, 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;

View File

@@ -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 = icon != eIcons::ICON_NONE ? " " + text /* tiny bit of padding otherwise icon touches text */ : text;
PNOTIF->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);
g_pCompositor->scheduleFrameForMonitor(m.get());
}
}
@@ -61,7 +61,7 @@ void CHyprNotificationOverlay::dismissNotifications(const int amount) {
}
}
CBox CHyprNotificationOverlay::drawNotifications(PHLMONITOR pMonitor) {
CBox CHyprNotificationOverlay::drawNotifications(CMonitor* 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(PHLMONITOR 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(PHLMONITOR pMonitor) {
void CHyprNotificationOverlay::draw(CMonitor* pMonitor) {
const auto MONSIZE = pMonitor->vecTransformedSize;

View File

@@ -41,13 +41,13 @@ class CHyprNotificationOverlay {
CHyprNotificationOverlay();
~CHyprNotificationOverlay();
void draw(PHLMONITOR pMonitor);
void draw(CMonitor* 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(PHLMONITOR pMonitor);
CBox drawNotifications(CMonitor* 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;
PHLMONITORREF m_pLastMonitor;
Vector2D m_vecLastSize = Vector2D(-1, -1);
CMonitor* m_pLastMonitor = nullptr;
Vector2D m_vecLastSize = Vector2D(-1, -1);
SP<CTexture> m_pTexture;
};

View File

@@ -4,7 +4,7 @@
#include "RollingLogFollow.hpp"
#include <fstream>
#include <print>
#include <iostream>
#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::println("{}", ((coloredLogs && !**coloredLogs) ? str : coloredStr));
std::cout << ((coloredLogs && !**coloredLogs) ? str : coloredStr) << "\n";
}

View File

@@ -3,7 +3,6 @@
class CWorkspace;
class CWindow;
class CLayerSurface;
class CMonitor;
/* Shared pointer to a workspace */
typedef SP<CWorkspace> PHLWORKSPACE;
@@ -19,8 +18,3 @@ 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;

View File

@@ -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));
auto pMonitor = resource->monitor.empty() ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->getMonitorFromName(resource->monitor);
CMonitor* 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();
pMonitor = g_pCompositor->m_vMonitors.front().get();
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->monitor = pMonitor;
pLS->monitorID = pMonitor->ID;
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(monitor.lock());
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(monitorID));
});
}
@@ -82,9 +82,9 @@ CLayerSurface::~CLayerSurface() {
void CLayerSurface::onDestroy() {
Debug::log(LOG, "LayerSurface {:x} destroyed", (uintptr_t)layerSurface.get());
const auto PMONITOR = monitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
if (!PMONITOR)
if (!g_pCompositor->getMonitorFromID(monitorID))
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 = monitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
if (!PMONITOR)
return;
@@ -175,7 +175,8 @@ void CLayerSurface::onMap() {
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
g_pHyprRenderer->damageBox(&geomFixed);
const bool FULLSCREEN = PMONITOR->activeWorkspace && PMONITOR->activeWorkspace->m_bHasFullscreenWindow && PMONITOR->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN;
const auto WORKSPACE = PMONITOR->activeWorkspace;
const bool FULLSCREEN = WORKSPACE->m_bHasFullscreenWindow && WORKSPACE->m_efFullscreenMode == FSMODE_FULLSCREEN;
startAnimation(!(layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS));
readyToDelete = false;
@@ -196,7 +197,7 @@ void CLayerSurface::onUnmap() {
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
if (!monitor || g_pCompositor->m_bUnsafeState) {
if (!g_pCompositor->getMonitorFromID(monitorID) || g_pCompositor->m_bUnsafeState) {
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
g_pCompositor->addToFadingOutSafe(self.lock());
@@ -220,9 +221,9 @@ void CLayerSurface::onUnmap() {
g_pCompositor->addToFadingOutSafe(self.lock());
const auto PMONITOR = monitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == surface->resource() || g_pSeatManager->state.pointerFocus == surface->resource();
const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource();
if (!PMONITOR)
return;
@@ -231,7 +232,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 && g_pCompositor->m_pLastFocus != surface->resource())
else if (g_pCompositor->m_pLastFocus)
g_pSeatManager->setKeyboardFocus(g_pCompositor->m_pLastFocus.lock());
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
@@ -255,13 +256,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 = monitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
if (!PMONITOR)
return;
@@ -320,18 +321,8 @@ void CLayerSurface::onCommit() {
realSize.setValueAndWarp(geometry.size());
}
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);
}
if (mapped) {
const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource();
const bool WASEXCLUSIVE = interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
const bool ISEXCLUSIVE = layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
@@ -341,13 +332,11 @@ 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 == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
if (WASLASTFOCUS && !layerSurface->current.interactivity) {
// 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(monitor.lock());
} else if (WASLASTFOCUS && WASEXCLUSIVE && layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
g_pInputManager->simulateMouseMovement();
g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID));
} else if (!WASEXCLUSIVE && ISEXCLUSIVE) {
// if now exclusive and not previously
g_pSeatManager->setGrab(nullptr);
@@ -556,7 +545,3 @@ int CLayerSurface::popupsCount() {
popupHead->breadthfirst([](CPopup* p, void* data) { *(int*)data += 1; }, &no);
return no;
}
MONITORID CLayerSurface::monitorID() {
return monitor ? monitor->ID : MONITOR_INVALID;
}

View File

@@ -42,7 +42,7 @@ class CLayerSurface {
bool mapped = false;
uint32_t layer = 0;
PHLMONITORREF monitor;
MONITORID monitorID = -1;
bool fadingOut = false;
bool readyToDelete = false;
@@ -70,7 +70,6 @@ class CLayerSurface {
void onMap();
void onUnmap();
void onCommit();
MONITORID monitorID();
private:
struct {
@@ -84,6 +83,6 @@ class CLayerSurface {
// For the list lookup
bool operator==(const CLayerSurface& rhs) const {
return layerSurface == rhs.layerSurface && monitor == rhs.monitor;
return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID;
}
};

View File

@@ -4,8 +4,6 @@
#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) {
@@ -108,8 +106,6 @@ void CPopup::onUnmap() {
return;
}
m_bMapped = false;
m_vLastSize = m_pResource->surface->surface->current.size;
const auto COORDS = coordsGlobal();
@@ -120,6 +116,8 @@ 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));
@@ -133,11 +131,6 @@ 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) {
@@ -295,13 +288,12 @@ bool CPopup::visible() {
return false;
}
void CPopup::bfHelper(std::vector<CPopup*> const& nodes, std::function<void(CPopup*, void*)> fn, void* data) {
void CPopup::bfHelper(std::vector<CPopup*> 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) {
@@ -324,7 +316,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 || !p->m_bMapped)
if (!p->m_pResource)
continue;
if (!allowsInput) {

View File

@@ -81,5 +81,5 @@ class CPopup {
Vector2D localToGlobal(const Vector2D& rel);
Vector2D t1ParentCoords();
static void bfHelper(std::vector<CPopup*> const& nodes, std::function<void(CPopup*, void*)> fn, void* data);
static void bfHelper(std::vector<CPopup*> nodes, std::function<void(CPopup*, void*)> fn, void* data);
};

View File

@@ -113,7 +113,7 @@ SBoxExtents CWindow::getFullWindowExtents() {
const int BORDERSIZE = getRealBorderSize();
if (m_sWindowData.dimAround.valueOrDefault()) {
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR)
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); 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 = m_pMonitor.lock(); PMONITOR)
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); 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 = m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
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 = m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
if (PMONITOR)
return {PMONITOR->vecPosition.x, PMONITOR->vecPosition.y, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
}
@@ -240,6 +240,10 @@ 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());
}
@@ -352,9 +356,9 @@ void CWindow::updateSurfaceScaleTransformDetails(bool force) {
const auto PLASTMONITOR = g_pCompositor->getMonitorFromID(m_iLastSurfaceMonitorID);
m_iLastSurfaceMonitorID = monitorID();
m_iLastSurfaceMonitorID = m_iMonitorID;
const auto PNEWMONITOR = m_pMonitor.lock();
const auto PNEWMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
if (!PNEWMONITOR)
return;
@@ -366,10 +370,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);
}
const auto PMONITOR = m_pMonitor.lock();
m_pWLSurface->resource()->breadthfirst(
[PMONITOR](SP<CWLSurfaceResource> s, const Vector2D& offset, void* d) {
[this](SP<CWLSurfaceResource> s, const Vector2D& offset, void* d) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
const auto PSURFACE = CWLSurface::fromResource(s);
if (PSURFACE && PSURFACE->m_fLastScale == PMONITOR->scale)
return;
@@ -404,7 +408,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
const auto OLDWORKSPACE = m_pWorkspace;
m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->monitorID() : -1;
m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->m_iMonitorID : -1;
m_fMovingToWorkspaceAlpha.setValueAndWarp(1.F);
m_fMovingToWorkspaceAlpha = 0.F;
m_fMovingToWorkspaceAlpha.setCallbackOnEnd([this](void* thisptr) { m_iMonitorMovedFrom = -1; });
@@ -415,11 +419,11 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
g_pCompositor->updateWorkspaceWindows(OLDWORKSPACE->m_iID);
g_pCompositor->updateWorkspaceWindowData(OLDWORKSPACE->m_iID);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(OLDWORKSPACE->monitorID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(OLDWORKSPACE->m_iMonitorID);
g_pCompositor->updateWorkspaceWindows(workspaceID());
g_pCompositor->updateWorkspaceWindowData(workspaceID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(monitorID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
@@ -431,14 +435,14 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
if (const auto SWALLOWED = m_pSwallowed.lock()) {
SWALLOWED->moveToWorkspace(pWorkspace);
SWALLOWED->m_pMonitor = m_pMonitor;
SWALLOWED->m_iMonitorID = m_iMonitorID;
}
// 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 = OLDWORKSPACE->m_pMonitor.lock(); PMONITOR)
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(OLDWORKSPACE->m_iMonitorID); PMONITOR)
PMONITOR->setSpecialWorkspace(nullptr);
}
}
@@ -447,21 +451,15 @@ PHLWINDOW CWindow::X11TransientFor() {
if (!m_pXWaylandSurface || !m_pXWaylandSurface->parent)
return nullptr;
auto s = m_pXWaylandSurface->parent;
std::vector<SP<CXWaylandSurface>> visited;
auto s = m_pXWaylandSurface->parent;
auto oldParent = s;
while (s) {
// 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 cyclic loop of m_pXWaylandSurface being parent of itself, #TODO reject this from even being created?
if (!s->parent || s->parent == oldParent)
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;
@@ -517,19 +515,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 = m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
if (PMONITOR && PMONITOR->activeSpecialWorkspace && PMONITOR->activeSpecialWorkspace == m_pWorkspace)
PMONITOR->setSpecialWorkspace(nullptr);
}
const auto PMONITOR = m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
if (PMONITOR && PMONITOR->solitaryClient.lock().get() == this)
PMONITOR->solitaryClient.reset();
g_pCompositor->updateWorkspaceWindows(workspaceID());
g_pCompositor->updateWorkspaceWindowData(workspaceID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(monitorID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
m_pWorkspace.reset();
@@ -738,8 +736,9 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
}
m_sWindowData.maxSize = CWindowOverridableVar(VEC, priority);
clampWindowSize(std::nullopt, m_sWindowData.maxSize.value());
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());
} catch (std::exception& e) { Debug::log(ERR, "maxsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
} else if (r.szRule.starts_with("minsize")) {
try {
@@ -752,8 +751,9 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
}
m_sWindowData.minSize = CWindowOverridableVar(VEC, priority);
clampWindowSize(m_sWindowData.minSize.value(), std::nullopt);
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());
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(monitorID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
}
// 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(monitorID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
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(monitorID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
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(monitorID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_iMonitorID);
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
if (!addresses.empty())
@@ -1087,7 +1087,7 @@ void CWindow::updateGroupOutputs() {
const auto WS = m_pWorkspace;
while (curr.get() != this) {
curr->m_pMonitor = m_pMonitor;
curr->m_iMonitorID = m_iMonitorID;
curr->moveToWorkspace(WS);
curr->m_vRealPosition = m_vRealPosition.goal();
@@ -1184,7 +1184,7 @@ void CWindow::setSuspended(bool suspend) {
m_bSuspended = suspend;
}
bool CWindow::visibleOnMonitor(PHLMONITOR pMonitor) {
bool CWindow::visibleOnMonitor(CMonitor* 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 = m_pMonitor.lock();
const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
if (!PWSMON)
return;
@@ -1253,16 +1253,6 @@ 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;
}
@@ -1275,10 +1265,6 @@ 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);
}
@@ -1465,7 +1451,7 @@ void CWindow::onX11Configure(CBox box) {
m_pXWaylandSurface->configure(box);
m_vPendingReportedSize = box.size();
m_vReportedSize = box.size();
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR)
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); PMONITOR)
m_fX11SurfaceScaledBy = PMONITOR->scale;
return;
}
@@ -1491,7 +1477,7 @@ void CWindow::onX11Configure(CBox box) {
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
if (*PXWLFORCESCALEZERO) {
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR) {
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); PMONITOR) {
m_vRealSize.setValueAndWarp(m_vRealSize.goal() / PMONITOR->scale);
m_fX11SurfaceScaledBy = PMONITOR->scale;
}
@@ -1535,7 +1521,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 || std::string{*PSWALLOWREGEX} == STRVAL_EMPTY || (*PSWALLOWREGEX).empty())
if (!*PSWALLOW || (*PSWALLOWREGEX).empty())
return nullptr;
// check parent

View File

@@ -144,13 +144,6 @@ 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
@@ -279,12 +272,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;
@@ -364,7 +357,6 @@ class CWindow {
// swallowing
PHLWINDOWREF m_pSwallowed;
bool m_bGroupSwallowed = false;
// focus stuff
bool m_bStayFocused = false;
@@ -403,12 +395,10 @@ class CWindow {
}
// methods
CBox getFullWindowBoundingBox();
SBoxExtents getFullWindowExtents();
CBox getWindowBoxUnified(uint64_t props);
inline CBox getWindowMainSurfaceBox() const {
return {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y};
}
CBox getFullWindowBoundingBox();
SBoxExtents getFullWindowExtents();
CBox getWindowBoxUnified(uint64_t props);
CBox getWindowMainSurfaceBox();
CBox getWindowIdealBoundingBoxIgnoreReserved();
void addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco);
void updateWindowDecos();
@@ -434,13 +424,11 @@ class CWindow {
float rounding();
bool canBeTorn();
void setSuspended(bool suspend);
bool visibleOnMonitor(PHLMONITOR pMonitor);
bool visibleOnMonitor(CMonitor* 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);
@@ -567,7 +555,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->monitorID());
std::format_to(out, ", monitor: {}", w->m_iMonitorID);
if (formatClass)
std::format_to(out, ", class: {}", w->m_szClass);
return std::format_to(out, "]");

View File

@@ -5,14 +5,14 @@
#include <hyprutils/string/String.hpp>
using namespace Hyprutils::String;
PHLWORKSPACE CWorkspace::create(WORKSPACEID id, PHLMONITOR monitor, std::string name, bool special, bool isEmpty) {
PHLWORKSPACE workspace = makeShared<CWorkspace>(id, monitor, name, special, isEmpty);
PHLWORKSPACE CWorkspace::create(WORKSPACEID id, MONITORID monitorID, std::string name, bool special, bool isEmpty) {
PHLWORKSPACE workspace = makeShared<CWorkspace>(id, monitorID, name, special, isEmpty);
workspace->init(workspace);
return workspace;
}
CWorkspace::CWorkspace(WORKSPACEID id, PHLMONITOR monitor, std::string name, bool special, bool isEmpty) {
m_pMonitor = monitor;
CWorkspace::CWorkspace(WORKSPACEID id, MONITORID monitorID, std::string name, bool special, bool isEmpty) {
m_iMonitorID = monitorID;
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 = m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
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 = m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
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 = m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
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_pMonitor == m_pMonitor) {
if (prev->m_iMonitorID == m_iMonitorID) {
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 == m_pMonitor : false))
if (!(PMONITOR ? PMONITOR->ID == m_iMonitorID : false))
return false;
continue;
}
@@ -512,16 +512,12 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) {
}
void CWorkspace::markInert() {
m_bInert = true;
m_iID = WORKSPACE_INVALID;
m_bVisible = false;
m_pMonitor.reset();
m_bInert = true;
m_iID = WORKSPACE_INVALID;
m_iMonitorID = MONITOR_INVALID;
m_bVisible = false;
}
bool CWorkspace::inert() {
return m_bInert;
}
MONITORID CWorkspace::monitorID() {
return m_pMonitor ? m_pMonitor->ID : MONITOR_INVALID;
}

View File

@@ -17,16 +17,16 @@ class CWindow;
class CWorkspace {
public:
static PHLWORKSPACE create(WORKSPACEID id, PHLMONITOR monitor, std::string name, bool special = false, bool isEmpty = true);
static PHLWORKSPACE create(WORKSPACEID id, MONITORID monitorID, std::string name, bool special = false, bool isEmpty = true);
// use create() don't use this
CWorkspace(WORKSPACEID id, PHLMONITOR monitor, std::string name, bool special = false, bool isEmpty = true);
CWorkspace(WORKSPACEID id, MONITORID monitorID, 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 = "";
PHLMONITORREF m_pMonitor;
WORKSPACEID m_iID = WORKSPACE_INVALID;
std::string m_szName = "";
MONITORID m_iMonitorID = MONITOR_INVALID;
// Previous workspace ID and name is stored during a workspace change, allowing travel
// to the previous workspace.
SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor;
@@ -68,7 +68,6 @@ class CWorkspace {
void setActive(bool on);
void moveToMonitor(const MONITORID&);
MONITORID monitorID();
PHLWINDOW getLastFocusedWindow();
void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace);

View File

@@ -36,5 +36,5 @@ class IHID {
CSignal destroy;
} events;
std::string deviceName, hlName;
std::string deviceName;
};

View File

@@ -94,6 +94,7 @@ 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;

View File

@@ -104,6 +104,7 @@ class IPointer : public IHID {
CSignal holdEnd;
} pointerEvents;
std::string hlName;
bool connected = false; // means connected to the cursor
std::string boundOutput = "";

View File

@@ -44,6 +44,7 @@ class ITouch : public IHID {
CSignal frame;
} touchEvents;
std::string hlName = "";
std::string boundOutput = "";
WP<ITouch> self;

View File

@@ -197,7 +197,7 @@ CTabletPad::CTabletPad(SP<Aquamarine::ITabletPad> pad_) : pad(pad_) {
});
});
listeners.attach = pad->events.attach.registerListener([](std::any d) {
listeners.attach = pad->events.attach.registerListener([this](std::any d) {
; // TODO: this doesn't do anything in aq atm
});

View File

@@ -92,6 +92,7 @@ class CTablet : public IHID {
WP<CTablet> self;
bool relativeInput = false;
std::string hlName = "";
std::string boundOutput = "";
CBox activeArea;
CBox boundBox; // output-local
@@ -153,6 +154,8 @@ class CTabletPad : public IHID {
WP<CTabletPad> self;
WP<CTabletTool> parent;
std::string hlName;
private:
CTabletPad(SP<Aquamarine::ITabletPad> pad);
@@ -207,6 +210,8 @@ class CTabletTool : public IHID {
std::vector<uint32_t> buttonsDown;
Vector2D absolutePos; // last known absolute position.
std::string hlName;
private:
CTabletTool(SP<Aquamarine::ITabletTool> tool);

View File

@@ -24,4 +24,12 @@ 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);
};

105
src/events/Monitors.cpp Normal file
View File

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

View File

@@ -12,7 +12,6 @@
#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;
@@ -44,16 +43,18 @@ 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.lock();
auto PMONITOR = g_pCompositor->m_pLastMonitor.get();
if (!g_pCompositor->m_pLastMonitor) {
g_pCompositor->setActiveMonitor(g_pCompositor->getMonitorFromVector({}));
PMONITOR = g_pCompositor->m_pLastMonitor.lock();
PMONITOR = g_pCompositor->m_pLastMonitor.get();
}
auto PWORKSPACE = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace;
PWINDOW->m_pMonitor = PMONITOR;
PWINDOW->m_iMonitorID = PMONITOR->ID;
PWINDOW->m_pWorkspace = PWORKSPACE;
PWINDOW->m_bIsMapped = true;
PWINDOW->m_bReadyToDelete = false;
@@ -144,18 +145,18 @@ void Events::listener_mapWindow(void* owner, void* data) {
const auto MONITORSTR = trim(r.szRule.substr(r.szRule.find(' ')));
if (MONITORSTR == "unset") {
PWINDOW->m_pMonitor = PMONITOR;
PWINDOW->m_iMonitorID = PMONITOR->ID;
} else {
if (isNumber(MONITORSTR)) {
const MONITORID MONITOR = std::stoi(MONITORSTR);
if (const auto PM = g_pCompositor->getMonitorFromID(MONITOR); PM)
PWINDOW->m_pMonitor = PM;
if (!g_pCompositor->getMonitorFromID(MONITOR))
PWINDOW->m_iMonitorID = 0;
else
PWINDOW->m_pMonitor = g_pCompositor->m_vMonitors.at(0);
PWINDOW->m_iMonitorID = MONITOR;
} else {
const auto PMONITOR = g_pCompositor->getMonitorFromName(MONITORSTR);
if (PMONITOR)
PWINDOW->m_pMonitor = PMONITOR;
PWINDOW->m_iMonitorID = PMONITOR->ID;
else {
Debug::log(ERR, "No monitor in monitor {} rule", MONITORSTR);
continue;
@@ -163,10 +164,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
}
}
const auto PMONITORFROMID = PWINDOW->m_pMonitor.lock();
const auto PMONITORFROMID = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (PWINDOW->m_pMonitor != PMONITOR) {
g_pKeybindManager->m_mDispatchers["focusmonitor"](std::to_string(PWINDOW->monitorID()));
if (PWINDOW->m_iMonitorID != PMONITOR->ID) {
g_pKeybindManager->m_mDispatchers["focusmonitor"](std::to_string(PWINDOW->m_iMonitorID));
PMONITOR = PMONITORFROMID;
}
PWINDOW->m_pWorkspace = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace;
@@ -296,23 +297,23 @@ void Events::listener_mapWindow(void* owner, void* data) {
auto pWorkspace = g_pCompositor->getWorkspaceByID(REQUESTEDWORKSPACEID);
if (!pWorkspace)
pWorkspace = g_pCompositor->createNewWorkspace(REQUESTEDWORKSPACEID, PWINDOW->monitorID(), requestedWorkspaceName);
pWorkspace = g_pCompositor->createNewWorkspace(REQUESTEDWORKSPACEID, PWINDOW->m_iMonitorID, requestedWorkspaceName);
PWORKSPACE = pWorkspace;
PWINDOW->m_pWorkspace = pWorkspace;
PWINDOW->m_pMonitor = pWorkspace->m_pMonitor;
PWINDOW->m_iMonitorID = pWorkspace->m_iMonitorID;
if (PWINDOW->m_pMonitor.lock()->activeSpecialWorkspace && !pWorkspace->m_bIsSpecialWorkspace)
if (g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeSpecialWorkspace && !pWorkspace->m_bIsSpecialWorkspace)
workspaceSilent = true;
if (!workspaceSilent) {
if (pWorkspace->m_bIsSpecialWorkspace)
pWorkspace->m_pMonitor->setSpecialWorkspace(pWorkspace);
g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID)->setSpecialWorkspace(pWorkspace);
else if (PMONITOR->activeWorkspaceID() != REQUESTEDWORKSPACEID)
g_pKeybindManager->m_mDispatchers["workspace"](requestedWorkspaceName);
PMONITOR = g_pCompositor->m_pLastMonitor.lock();
PMONITOR = g_pCompositor->m_pLastMonitor.get();
}
} else
workspaceSilent = false;
@@ -320,10 +321,6 @@ 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;
@@ -332,31 +329,24 @@ 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);
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 MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW);
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 = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW);
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);
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);
Debug::log(LOG, "Rule size, applying to {}", PWINDOW);
PWINDOW->clampWindowSize(Vector2D{SIZEXSTR.starts_with("<") ? 0 : SIZEX, SIZEYSTR.starts_with("<") ? 0 : SIZEY}, Vector2D{SIZEX, SIZEY});
PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY);
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal();
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
PWINDOW->setHidden(false);
} catch (...) { Debug::log(LOG, "Rule size failed, rule: {} -> {}", r.szRule, r.szValue); }
@@ -465,15 +455,18 @@ 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 = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW);
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);
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);
Debug::log(LOG, "Rule size (tiled), applying to {}", PWINDOW);
@@ -559,12 +552,20 @@ void Events::listener_mapWindow(void* owner, void* data) {
g_pCompositor->focusWindow(nullptr);
}
// swallow
if (SWALLOWER) {
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(SWALLOWER);
g_pHyprRenderer->damageWindow(SWALLOWER);
SWALLOWER->setHidden(true);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID());
// 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);
}
}
PWINDOW->m_bFirstMap = false;
@@ -625,7 +626,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
return;
}
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (PMONITOR) {
PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.value() - PMONITOR->vecPosition;
PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.value();
@@ -646,13 +647,7 @@ 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();
}
@@ -677,8 +672,6 @@ 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;
@@ -718,6 +711,8 @@ 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
@@ -756,30 +751,33 @@ void Events::listener_commitWindow(void* owner, void* data) {
const auto MINSIZE = PWINDOW->m_pXDGSurface->toplevel->current.minSize;
const auto MAXSIZE = PWINDOW->m_pXDGSurface->toplevel->current.maxSize;
PWINDOW->clampWindowSize(MINSIZE, MAXSIZE > Vector2D{1, 1} ? std::optional<Vector2D>{MAXSIZE} : std::nullopt);
g_pHyprRenderer->damageWindow(PWINDOW);
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);
}
}
if (!PWINDOW->m_pWorkspace->m_bVisible)
return;
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;
}
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 (!PWINDOW->m_bIsX11) {
PWINDOW->m_pSubsurfaceHead->recheckDamageForSubsurfaces();
@@ -787,6 +785,7 @@ 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()};
@@ -901,7 +900,7 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_pXWaylandSurface->geometry.size());
if (*PXWLFORCESCALEZERO) {
if (const auto PMONITOR = PWINDOW->m_pMonitor.lock(); PMONITOR) {
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR) {
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goal() / PMONITOR->scale);
}
}

View File

@@ -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_pMonitor != g_pCompositor->m_pLastMonitor)) {
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)) {
// 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_pMonitor != g_pCompositor->m_pLastMonitor) || ws->m_iID >= 0)
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID) || 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_pMonitor != g_pCompositor->m_pLastMonitor && !onAllMonitors))
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID && !onAllMonitors))
continue;
validWSes.push_back(ws->m_iID);
@@ -863,10 +863,3 @@ 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);
};

View File

@@ -40,7 +40,6 @@ 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) {

View File

@@ -11,21 +11,18 @@
#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)->self.lock());
g_pHyprRenderer->renderMonitor((CMonitor*)data);
return 1;
}
@@ -46,15 +43,10 @@ void CMonitor::onConnect(bool noRule) {
outTimeline = CSyncTimeline::create(output->getBackend()->drmFD());
}
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.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.needsFrame =
output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); });
output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(this, 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);
@@ -71,7 +63,7 @@ void CMonitor::onConnect(bool noRule) {
Debug::log(LOG, "Removing monitor {} from realMonitors", szName);
std::erase_if(g_pCompositor->m_vRealMonitors, [&](PHLMONITOR& el) { return el.get() == this; });
std::erase_if(g_pCompositor->m_vRealMonitors, [&](SP<CMonitor>& el) { return el.get() == this; });
});
listeners.state = output->events.state.registerListener([this](std::any d) {
@@ -84,7 +76,7 @@ void CMonitor::onConnect(bool noRule) {
return;
Debug::log(LOG, "Reapplying monitor rule for {} from a state request", szName);
g_pHyprRenderer->applyMonitorRule(self.lock(), &activeMonitorRule, true);
g_pHyprRenderer->applyMonitorRule(this, &activeMonitorRule, true);
return;
}
@@ -98,7 +90,7 @@ void CMonitor::onConnect(bool noRule) {
SMonitorRule rule = activeMonitorRule;
rule.resolution = SIZE;
g_pHyprRenderer->applyMonitorRule(self.lock(), &rule);
g_pHyprRenderer->applyMonitorRule(this, &rule);
});
tearingState.canTear = output->getBackend()->type() == Aquamarine::AQ_BACKEND_DRM;
@@ -149,7 +141,7 @@ void CMonitor::onConnect(bool noRule) {
return;
}
PHLMONITOR* thisWrapper = nullptr;
SP<CMonitor>* thisWrapper = nullptr;
// find the wrap
for (auto& m : g_pCompositor->m_vRealMonitors) {
@@ -171,7 +163,7 @@ void CMonitor::onConnect(bool noRule) {
// set mode, also applies
if (!noRule)
g_pHyprRenderer->applyMonitorRule(self.lock(), &monitorRule, true);
g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true);
if (!state.commit())
Debug::log(WARN, "state.commit() failed in CMonitor::onCommit");
@@ -187,7 +179,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, self.lock());
g_pCompositor->moveWorkspaceToMonitor(ws, this);
ws->startAnim(true, true, true);
ws->m_szLastMonitor = "";
}
@@ -204,13 +196,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(self.lock());
g_pCompositor->setActiveMonitor(this);
g_pHyprRenderer->arrangeLayersForMonitor(ID);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
// ensure VRR (will enable if necessary)
g_pConfigManager->ensureVRR(self.lock());
g_pConfigManager->ensureVRR(this);
// verify last mon valid
bool found = false;
@@ -222,19 +214,19 @@ void CMonitor::onConnect(bool noRule) {
}
if (!found)
g_pCompositor->setActiveMonitor(self.lock());
g_pCompositor->setActiveMonitor(this);
renderTimer = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, ratHandler, this);
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEW_MONITOR);
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_NEW_MONITOR);
PROTO::gamma->applyGammaToState(self.lock());
PROTO::gamma->applyGammaToState(this);
events.connect.emit();
g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", szName});
g_pEventManager->postEvent(SHyprIPCEvent{"monitoraddedv2", std::format("{},{},{}", ID, szName, szShortDescription)});
EMIT_HOOK_EVENT("monitorAdded", self.lock());
EMIT_HOOK_EVENT("monitorAdded", this);
}
void CMonitor::onDisconnect(bool destroy) {
@@ -242,7 +234,7 @@ void CMonitor::onDisconnect(bool destroy) {
if (g_pCompositor->m_bIsShuttingDown)
return;
g_pEventManager->postEvent(SHyprIPCEvent{"monitorremoved", szName});
EMIT_HOOK_EVENT("monitorRemoved", self.lock());
EMIT_HOOK_EVENT("monitorRemoved", this);
g_pCompositor->arrangeMonitors();
}};
@@ -259,21 +251,21 @@ void CMonitor::onDisconnect(bool destroy) {
events.disconnect.emit();
// Cleanup everything. Move windows back, snap cursor, shit.
PHLMONITOR BACKUPMON = nullptr;
CMonitor* BACKUPMON = nullptr;
for (auto const& m : g_pCompositor->m_vMonitors) {
if (m.get() != this) {
BACKUPMON = m;
BACKUPMON = m.get();
break;
}
}
// remove mirror
if (pMirrorOf) {
pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == self; }));
pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; }));
// unlock software for mirrored monitor
g_pPointerManager->unlockSoftwareForMonitor(pMirrorOf.lock());
pMirrorOf.reset();
g_pPointerManager->unlockSoftwareForMonitor(pMirrorOf);
pMirrorOf = nullptr;
}
if (!mirrors.empty()) {
@@ -314,8 +306,9 @@ void CMonitor::onDisconnect(bool destroy) {
// move workspaces
std::deque<PHLWORKSPACE> wspToMove;
for (auto const& w : g_pCompositor->m_vWorkspaces) {
if (w->m_pMonitor == self || !w->m_pMonitor)
if (w->m_iMonitorID == ID || !g_pCompositor->getMonitorFromID(w->m_iMonitorID)) {
wspToMove.push_back(w);
}
}
for (auto const& w : wspToMove) {
@@ -334,38 +327,37 @@ 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 == self)
g_pCompositor->setActiveMonitor(BACKUPMON ? BACKUPMON : g_pCompositor->m_pUnsafeOutput.lock());
if (g_pCompositor->m_pLastMonitor.get() == this)
g_pCompositor->setActiveMonitor(BACKUPMON ? BACKUPMON : g_pCompositor->m_pUnsafeOutput);
if (g_pHyprRenderer->m_pMostHzMonitor == self) {
int mostHz = 0;
PHLMONITOR pMonitorMostHz = nullptr;
if (g_pHyprRenderer->m_pMostHzMonitor == this) {
int mostHz = 0;
CMonitor* pMonitorMostHz = nullptr;
for (auto const& m : g_pCompositor->m_vMonitors) {
if (m->refreshRate > mostHz && m != self) {
pMonitorMostHz = m;
if (m->refreshRate > mostHz && m.get() != this) {
pMonitorMostHz = m.get();
mostHz = m->refreshRate;
}
}
g_pHyprRenderer->m_pMostHzMonitor = pMonitorMostHz;
}
std::erase_if(g_pCompositor->m_vMonitors, [&](PHLMONITOR& el) { return el.get() == this; });
std::erase_if(g_pCompositor->m_vMonitors, [&](SP<CMonitor>& 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() == self) {
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
damage.damageEntire();
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
} else if (damage.damage(rg))
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
}
void CMonitor::addDamage(const CRegion* rg) {
@@ -374,13 +366,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() == self) {
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
damage.damageEntire();
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
}
if (damage.damage(*box))
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
}
bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
@@ -392,7 +384,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.0f / *PMINRR) {
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000 / *PMINRR) {
// damage whole screen because some previous cursor box damages were skipped
damage.damageEntire();
return false;
@@ -456,7 +448,7 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
if (PNEWWORKSPACE) {
// workspace exists, move it to the newly connected monitor
g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, self.lock());
g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, this);
activeWorkspace = PNEWWORKSPACE;
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
PNEWWORKSPACE->startAnim(true, true, true);
@@ -464,7 +456,7 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
if (newDefaultWorkspaceName == "")
newDefaultWorkspaceName = std::to_string(wsID);
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(CWorkspace::create(wsID, self.lock(), newDefaultWorkspaceName));
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(CWorkspace::create(wsID, ID, newDefaultWorkspaceName));
}
activeWorkspace = PNEWWORKSPACE;
@@ -485,7 +477,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
return;
}
if (PMIRRORMON == self) {
if (PMIRRORMON == this) {
Debug::log(ERR, "Cannot mirror self!");
return;
}
@@ -494,13 +486,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 == self; }));
pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; }));
// unlock software for mirrored monitor
g_pPointerManager->unlockSoftwareForMonitor(pMirrorOf.lock());
g_pPointerManager->unlockSoftwareForMonitor(pMirrorOf);
}
pMirrorOf.reset();
pMirrorOf = nullptr;
// set rule
const auto RULE = g_pConfigManager->getMonitorRuleFor(self.lock());
@@ -509,7 +501,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
// push to mvmonitors
PHLMONITOR* thisWrapper = nullptr;
SP<CMonitor>* thisWrapper = nullptr;
// find the wrap
for (auto& m : g_pCompositor->m_vRealMonitors) {
@@ -528,12 +520,12 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
setupDefaultWS(RULE);
g_pHyprRenderer->applyMonitorRule(self.lock(), (SMonitorRule*)&RULE, true); // will apply the offset and stuff
g_pHyprRenderer->applyMonitorRule(this, (SMonitorRule*)&RULE, true); // will apply the offset and stuff
} else {
PHLMONITOR BACKUPMON = nullptr;
CMonitor* BACKUPMON = nullptr;
for (auto const& m : g_pCompositor->m_vMonitors) {
if (m.get() != this) {
BACKUPMON = m;
BACKUPMON = m.get();
break;
}
}
@@ -541,8 +533,9 @@ 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_pMonitor == self || !w->m_pMonitor)
if (w->m_iMonitorID == ID) {
wspToMove.push_back(w);
}
}
for (auto const& w : wspToMove) {
@@ -556,14 +549,14 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
pMirrorOf = PMIRRORMON;
pMirrorOf->mirrors.push_back(self);
pMirrorOf->mirrors.push_back(this);
// remove from mvmonitors
std::erase_if(g_pCompositor->m_vMonitors, [&](const auto& other) { return other == self; });
std::erase_if(g_pCompositor->m_vMonitors, [&](const auto& other) { return other.get() == this; });
g_pCompositor->arrangeMonitors();
g_pCompositor->setActiveMonitor(g_pCompositor->m_vMonitors.front());
g_pCompositor->setActiveMonitor(g_pCompositor->m_vMonitors.front().get());
g_pCompositor->sanityCheckWorkspaces();
@@ -625,7 +618,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_pMonitor == self)) {
!(g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bPinned && g_pCompositor->m_pLastWindow->m_iMonitorID == ID)) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
auto pWindow = pWorkspace->getLastFocusedWindow();
@@ -653,11 +646,11 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
EMIT_HOOK_EVENT("workspace", pWorkspace);
}
g_pHyprRenderer->damageMonitor(self.lock());
g_pHyprRenderer->damageMonitor(this);
g_pCompositor->updateFullscreenFadeOnWorkspace(pWorkspace);
g_pConfigManager->ensureVRR(self.lock());
g_pConfigManager->ensureVRR(this);
g_pCompositor->updateSuspendedStates();
@@ -673,7 +666,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
if (activeSpecialWorkspace == pWorkspace)
return;
g_pHyprRenderer->damageMonitor(self.lock());
g_pHyprRenderer->damageMonitor(this);
if (!pWorkspace) {
// remove special if exists
@@ -686,7 +679,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_pMonitor == self)) {
if (!(g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bPinned && g_pCompositor->m_pLastWindow->m_iMonitorID == ID)) {
if (const auto PLAST = activeWorkspace->getLastFocusedWindow(); PLAST)
g_pCompositor->focusWindow(PLAST);
else
@@ -695,7 +688,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
g_pCompositor->updateFullscreenFadeOnWorkspace(activeWorkspace);
g_pConfigManager->ensureVRR(self.lock());
g_pConfigManager->ensureVRR(this);
g_pCompositor->updateSuspendedStates();
@@ -709,7 +702,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
bool animate = true;
//close if open elsewhere
const auto PMONITORWORKSPACEOWNER = pWorkspace->m_pMonitor.lock();
const auto PMONITORWORKSPACEOWNER = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
if (PMONITORWORKSPACEOWNER->activeSpecialWorkspace == pWorkspace) {
PMONITORWORKSPACEOWNER->activeSpecialWorkspace.reset();
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITORWORKSPACEOWNER->ID);
@@ -722,7 +715,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
}
// open special
pWorkspace->m_pMonitor = self;
pWorkspace->m_iMonitorID = ID;
activeSpecialWorkspace = pWorkspace;
activeSpecialWorkspace->m_bVisible = true;
if (animate)
@@ -730,7 +723,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
for (auto const& w : g_pCompositor->m_vWindows) {
if (w->m_pWorkspace == pWorkspace) {
w->m_pMonitor = self;
w->m_iMonitorID = ID;
w->updateSurfaceScaleTransformDetails();
w->setAnimationsToMove();
@@ -754,7 +747,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_pMonitor == self)) {
if (!(g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bPinned && g_pCompositor->m_pLastWindow->m_iMonitorID == ID)) {
if (const auto PLAST = pWorkspace->getLastFocusedWindow(); PLAST)
g_pCompositor->focusWindow(PLAST);
else
@@ -763,11 +756,11 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
g_pEventManager->postEvent(SHyprIPCEvent{"activespecial", pWorkspace->m_szName + "," + szName});
g_pHyprRenderer->damageMonitor(self.lock());
g_pHyprRenderer->damageMonitor(this);
g_pCompositor->updateFullscreenFadeOnWorkspace(pWorkspace);
g_pConfigManager->ensureVRR(self.lock());
g_pConfigManager->ensureVRR(this);
g_pCompositor->updateSuspendedStates();
}
@@ -820,12 +813,6 @@ 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.
@@ -844,7 +831,7 @@ bool CMonitor::attemptDirectScanout() {
return false;
// we can't scanout shm buffers.
if (!PSURFACE->current.buffer || !PSURFACE->current.buffer->buffer || !PSURFACE->current.texture || !PSURFACE->current.texture->m_pEglImage /* dmabuf */)
if (!PSURFACE->current.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());
@@ -940,74 +927,6 @@ 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;
}
@@ -1039,7 +958,7 @@ bool CMonitorState::commit() {
if (!updateSwapchain())
return false;
EMIT_HOOK_EVENT("preMonitorCommit", m_pOwner->self.lock());
EMIT_HOOK_EVENT("preMonitorCommit", m_pOwner);
ensureBufferPresent();

View File

@@ -54,7 +54,7 @@ class CMonitorState {
private:
void ensureBufferPresent();
CMonitor* m_pOwner = nullptr;
CMonitor* m_pOwner;
};
class CMonitor {
@@ -125,15 +125,11 @@ class CMonitor {
SP<CSyncTimeline> outTimeline;
uint64_t commitSeq = 0;
PHLMONITORREF self;
WP<CMonitor> self;
// mirroring
PHLMONITORREF pMirrorOf;
std::vector<PHLMONITORREF> mirrors;
// ctm
Mat3x3 ctm = Mat3x3::identity();
bool ctmUpdated = false;
CMonitor* pMirrorOf = nullptr;
std::vector<CMonitor*> mirrors;
// for tearing
PHLWINDOWREF solitaryClient;
@@ -183,10 +179,6 @@ 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;

View File

@@ -1,5 +1,4 @@
#include "Timer.hpp"
#include <chrono>
void CTimer::reset() {
m_tpLastReset = std::chrono::steady_clock::now();
@@ -9,8 +8,8 @@ std::chrono::steady_clock::duration CTimer::getDuration() {
return std::chrono::steady_clock::now() - m_tpLastReset;
}
float CTimer::getMillis() {
return std::chrono::duration_cast<std::chrono::microseconds>(getDuration()).count() / 1000.f;
long CTimer::getMillis() {
return std::chrono::duration_cast<std::chrono::milliseconds>(getDuration()).count();
}
float CTimer::getSeconds() {

View File

@@ -6,7 +6,7 @@ class CTimer {
public:
void reset();
float getSeconds();
float getMillis();
long getMillis();
const std::chrono::steady_clock::time_point& chrono() const;
private:

View File

@@ -18,9 +18,9 @@ class CWLSurfaceResource;
AQUAMARINE_FORWARD(ISwitch);
struct SRenderData {
PHLMONITORREF pMonitor;
timespec* when;
double x, y;
CMonitor* 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;
PHLMONITORREF pMonitor;
CMonitor* pMonitor = nullptr;
};
struct SSwitchDevice {

View File

@@ -3,9 +3,6 @@
#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();
@@ -14,7 +11,7 @@ CHyprError::CHyprError() {
if (!m_bIsCreated)
return;
g_pHyprRenderer->damageMonitor(g_pCompositor->m_pLastMonitor.lock());
g_pHyprRenderer->damageMonitor(g_pCompositor->m_pLastMonitor.get());
m_bMonitorChanged = true;
});
@@ -47,7 +44,7 @@ void CHyprError::createQueued() {
m_fFadeOpacity.setValueAndWarp(0.f);
m_fFadeOpacity = 1.f;
const auto PMONITOR = g_pCompositor->m_vMonitors.front();
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
const auto SCALE = PMONITOR->scale;
@@ -133,8 +130,6 @@ void CHyprError::createQueued() {
}
m_szQueued = "";
m_fLastHeight = yoffset + PAD + 1 - (TOPBAR ? 0 : Y - PAD);
pango_font_description_free(pangoFD);
g_object_unref(layoutText);
@@ -163,8 +158,6 @@ void CHyprError::createQueued() {
m_cQueued = CColor();
g_pHyprRenderer->damageMonitor(PMONITOR);
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
}
void CHyprError::draw() {
@@ -181,11 +174,6 @@ 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"));
@@ -215,11 +203,3 @@ void CHyprError::destroy() {
else
m_szQueued = "";
}
bool CHyprError::active() {
return m_bIsCreated;
}
float CHyprError::height() {
return m_fLastHeight;
}

View File

@@ -11,12 +11,9 @@ class CHyprError {
CHyprError();
~CHyprError();
void queueCreate(std::string message, const CColor& color);
void draw();
void destroy();
bool active();
float height(); // logical
void queueCreate(std::string message, const CColor& color);
void draw();
void destroy();
private:
void createQueued();
@@ -26,8 +23,7 @@ class CHyprError {
bool m_bIsCreated = false;
SP<CTexture> m_pTexture;
CAnimatedVariable<float> m_fFadeOpacity;
CBox m_bDamageBox = {0, 0, 0, 0};
float m_fLastHeight = 0.F;
CBox m_bDamageBox = {0, 0, 0, 0};
bool m_bMonitorChanged = false;
};

View File

@@ -101,17 +101,18 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
if (pNode->isNode)
return;
PHLMONITOR PMONITOR = nullptr;
CMonitor* PMONITOR = nullptr;
if (g_pCompositor->isWorkspaceSpecial(pNode->workspaceID)) {
for (auto const& m : g_pCompositor->m_vMonitors) {
if (m->activeSpecialWorkspaceID() == pNode->workspaceID) {
PMONITOR = m;
PMONITOR = m.get();
break;
}
}
} else
PMONITOR = g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_pMonitor.lock();
} else {
PMONITOR = g_pCompositor->getMonitorFromID(g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_iMonitorID);
}
if (!PMONITOR) {
Debug::log(ERR, "Orphaned Node {}!!", pNode);
@@ -141,10 +142,11 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
PWINDOW->unsetWindowData(PRIORITY_LAYOUT);
PWINDOW->updateWindowData();
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 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();
auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN);
auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT);
@@ -154,6 +156,27 @@ 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;
@@ -234,7 +257,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
m_lDwindleNodesData.push_back(SDwindleNodeData());
const auto PNODE = &m_lDwindleNodesData.back();
const auto PMONITOR = pWindow->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
static auto PUSEACTIVE = CConfigValue<Hyprlang::INT>("dwindle:use_active_for_splits");
static auto PDEFAULTSPLIT = CConfigValue<Hyprlang::FLOAT>("dwindle:default_split_ratio");
@@ -307,9 +330,16 @@ 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());
@@ -441,7 +471,9 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
NEWPARENT->recalcSizePosRecursive(false, horizontalOverride, verticalOverride);
recalculateMonitor(pWindow->monitorID());
recalculateMonitor(pWindow->m_iMonitorID);
pWindow->applyGroupRules();
}
void CHyprDwindleLayout::onWindowRemovedTiling(PHLWINDOW pWindow) {
@@ -507,7 +539,7 @@ void CHyprDwindleLayout::recalculateMonitor(const MONITORID& monid) {
}
void CHyprDwindleLayout::calculateWorkspace(const PHLWORKSPACE& pWorkspace) {
const auto PMONITOR = pWorkspace->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
if (!PMONITOR)
return;
@@ -563,9 +595,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
const auto PNODE = getNodeFromWindow(PWINDOW);
if (!PNODE) {
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->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goal() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goal() + pixResize).y, 20.0));
PWINDOW->updateWindowDecos();
return;
}
@@ -574,7 +604,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 = PWINDOW->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
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);
@@ -747,7 +777,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 = pWindow->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
const auto PWORKSPACE = pWindow->m_pWorkspace;
// save position and size if floating
@@ -857,9 +887,9 @@ void CHyprDwindleLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
const auto PMONITORFOCAL = g_pCompositor->getMonitorFromVector(focalPoint);
if (PMONITORFOCAL != pWindow->m_pMonitor) {
if (PMONITORFOCAL->ID != pWindow->m_iMonitorID) {
pWindow->moveToWorkspace(PMONITORFOCAL->activeWorkspace);
pWindow->m_pMonitor = PMONITORFOCAL;
pWindow->m_iMonitorID = PMONITORFOCAL->ID;
}
onWindowCreatedTiling(pWindow);
@@ -897,7 +927,7 @@ void CHyprDwindleLayout::switchWindows(PHLWINDOW pWindow, PHLWINDOW pWindow2) {
PNODE->pWindow = pWindow2;
if (PNODE->workspaceID != PNODE2->workspaceID) {
std::swap(pWindow2->m_pMonitor, pWindow->m_pMonitor);
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
std::swap(pWindow2->m_pWorkspace, pWindow->m_pWorkspace);
}

View File

@@ -13,16 +13,13 @@ void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) {
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) {
const auto PMONITOR = pWindow->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
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;
@@ -88,7 +85,7 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
CBox desiredGeometry = {0};
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
const auto PMONITOR = pWindow->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
if (pWindow->m_bIsX11) {
Vector2D xy = {desiredGeometry.x, desiredGeometry.y};
@@ -184,27 +181,35 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
}
bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) {
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;
static auto PAUTOGROUP = CConfigValue<Hyprlang::INT>("group:auto_group");
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());
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).
if ((*PAUTOGROUP || g_pInputManager->m_bWasDraggingWindow) // check if auto_group is enabled, or, if the user is manually dragging the window into the group.
&& OPENINGON // check if OPENINGON exists.
&& OPENINGON != pWindow // fixes a freeze when activating togglefloat to transform a floating group into a tiled 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 XWayland windows that should be floated.
pWindow->m_bIsFloating = OPENINGON->m_bIsFloating; // match the floating state. Needed to autogroup a new tiled window into a floated group.
switch (pWindow->m_bIsFloating) {
case false:
if (OPENINGON->m_bIsFloating)
pWindow->m_bIsFloating = true;
break;
case true:
if (!OPENINGON->m_bIsFloating)
pWindow->m_bIsFloating = false;
break;
}
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(*USECURRPOS ? OPENINGON : OPENINGON->getGroupTail())->insertWindowToGroup(pWindow);
OPENINGON->setGroupCurrent(pWindow);
pWindow->applyGroupRules();
pWindow->updateWindowDecos();
recalculateWindow(pWindow);
@@ -330,37 +335,21 @@ void IHyprLayout::onEndDragWindow() {
g_pInputManager->currentlyDraggedWindow.reset();
g_pInputManager->m_bWasDraggingWindow = true;
if (g_pInputManager->dragMode == MBIND_MOVE) {
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) {
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
PHLWINDOW pWindow = g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING, DRAGGINGWINDOW);
PHLWINDOW pWindow = g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING | FLOATING_ONLY, DRAGGINGWINDOW);
if (pWindow) {
if (pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, DRAGGINGWINDOW))
return;
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
if (pWindow->m_sGroupData.pNextWindow.lock() && DRAGGINGWINDOW->canBeGroupedInto(pWindow)) {
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW);
pWindow->setGroupCurrent(DRAGGINGWINDOW);
@@ -372,159 +361,12 @@ 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;
@@ -547,8 +389,6 @@ 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;
@@ -579,13 +419,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
if (g_pInputManager->dragMode == MBIND_MOVE) {
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};
CBox wb = {m_vBeginDragPositionXY + DELTA, DRAGGINGWINDOW->m_vRealSize.goal()};
wb.round();
if (*PANIMATEMOUSE)
@@ -616,11 +450,9 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
else if (m_eGrabbedCorner == CORNER_BOTTOMLEFT)
newSize = newSize + Vector2D(-DELTA.x, DELTA.y);
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) {
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()))) {
const float RATIO = m_vBeginDragSizeXY.y / m_vBeginDragSizeXY.x;
@@ -649,11 +481,6 @@ 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();
@@ -678,7 +505,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle);
if (PMONITOR && !SPECIAL) {
DRAGGINGWINDOW->m_pMonitor = PMONITOR;
DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID;
DRAGGINGWINDOW->moveToWorkspace(PMONITOR->activeWorkspace);
DRAGGINGWINDOW->updateGroupOutputs();
@@ -706,8 +533,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_pMonitor = PNEWMON;
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.value() + pWindow->m_vRealSize.value() / 2.f);
pWindow->m_iMonitorID = PNEWMON->ID;
pWindow->moveToWorkspace(PNEWMON->activeSpecialWorkspace ? PNEWMON->activeSpecialWorkspace : PNEWMON->activeWorkspace);
pWindow->updateGroupOutputs();
@@ -726,16 +553,16 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
pWindow->m_vLastFloatingSize = PSAVEDSIZE;
// move to narnia because we don't wanna find our own node. onWindowCreatedTiling should apply the coords back.
// move to narnia because we don't wanna find our own node. onWindowCreated should apply the coords back.
pWindow->m_vPosition = Vector2D(-999999, -999999);
onWindowCreatedTiling(pWindow);
onWindowCreated(pWindow);
pWindow->m_vRealPosition.setValue(PSAVEDPOS);
pWindow->m_vRealSize.setValue(PSAVEDSIZE);
// fix pseudo leaving artifacts
g_pHyprRenderer->damageMonitor(pWindow->m_pMonitor.lock());
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
if (pWindow == g_pCompositor->m_pLastWindow)
m_pLastTiledWindow = pWindow;
@@ -758,7 +585,7 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
pWindow->m_vSize = wb.pos();
pWindow->m_vPosition = wb.size();
g_pHyprRenderer->damageMonitor(pWindow->m_pMonitor.lock());
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
pWindow->unsetWindowData(PRIORITY_LAYOUT);
pWindow->updateWindowData();
@@ -848,7 +675,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_pMonitor != g_pCompositor->m_pLastMonitor)
pWindowCandidate->isX11OverrideRedirect() || pWindowCandidate->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)
return nullptr;
return pWindowCandidate;
@@ -880,17 +707,18 @@ 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 = g_pXWaylandManager->getMaxSizeForWindow(pWindow);
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);
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);
sizeOverride = {SIZEX, SIZEY};

View File

@@ -18,19 +18,11 @@ struct SLayoutMessageHeader {
enum eFullscreenMode : int8_t;
enum eRectCorner {
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),
CORNER_NONE = 0,
CORNER_TOPLEFT,
CORNER_TOPRIGHT,
CORNER_BOTTOMRIGHT,
CORNER_BOTTOMLEFT
};
enum eDirection {

View File

@@ -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 = pWindow->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
const bool BNEWBEFOREACTIVE = *PNEWONACTIVE == "before";
const bool BNEWISMASTER = *PNEWSTATUS == "master";
@@ -101,15 +101,23 @@ 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());
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();
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);
@@ -223,7 +231,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
}
// recalc
recalculateMonitor(pWindow->monitorID());
recalculateMonitor(pWindow->m_iMonitorID);
}
void CHyprMasterLayout::onWindowRemovedTiling(PHLWINDOW pWindow) {
@@ -273,7 +281,7 @@ void CHyprMasterLayout::onWindowRemovedTiling(PHLWINDOW pWindow) {
}
}
}
recalculateMonitor(pWindow->monitorID());
recalculateMonitor(pWindow->m_iMonitorID);
}
void CHyprMasterLayout::recalculateMonitor(const MONITORID& monid) {
@@ -291,7 +299,7 @@ void CHyprMasterLayout::recalculateMonitor(const MONITORID& monid) {
}
void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) {
const auto PMONITOR = pWorkspace->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
if (!PMONITOR)
return;
@@ -588,17 +596,18 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) {
}
void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
PHLMONITOR PMONITOR = nullptr;
CMonitor* PMONITOR = nullptr;
if (g_pCompositor->isWorkspaceSpecial(pNode->workspaceID)) {
for (auto const& m : g_pCompositor->m_vMonitors) {
if (m->activeSpecialWorkspaceID() == pNode->workspaceID) {
PMONITOR = m;
PMONITOR = m.get();
break;
}
}
} else
PMONITOR = g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_pMonitor.lock();
} else {
PMONITOR = g_pCompositor->getMonitorFromID(g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_iMonitorID);
}
if (!PMONITOR) {
Debug::log(ERR, "Orphaned Node {}!!", pNode);
@@ -622,11 +631,12 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
PWINDOW->unsetWindowData(PRIORITY_LAYOUT);
PWINDOW->updateWindowData();
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 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();
auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN);
auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT);
@@ -639,6 +649,25 @@ 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;
@@ -700,14 +729,12 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
const auto PNODE = getNodeFromWindow(PWINDOW);
if (!PNODE) {
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->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goal() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goal() + pixResize).y, 20.0));
PWINDOW->updateWindowDecos();
return;
}
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
static auto ALWAYSCENTER = CConfigValue<Hyprlang::INT>("master:always_center_master");
static auto PSMARTRESIZING = CConfigValue<Hyprlang::INT>("master:smart_resizing");
@@ -836,7 +863,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 = pWindow->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
const auto PWORKSPACE = pWindow->m_pWorkspace;
// save position and size if floating
@@ -892,7 +919,7 @@ void CHyprMasterLayout::recalculateWindow(PHLWINDOW pWindow) {
if (!PNODE)
return;
recalculateMonitor(pWindow->monitorID());
recalculateMonitor(pWindow->m_iMonitorID);
}
SWindowRenderLayoutHints CHyprMasterLayout::requestRenderHints(PHLWINDOW pWindow) {
@@ -918,9 +945,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_pMonitor = PWINDOW2->m_pMonitor;
pWindow->m_iMonitorID = PWINDOW2->m_iMonitorID;
if (!silent) {
const auto pMonitor = pWindow->m_pMonitor.lock();
const auto pMonitor = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
g_pCompositor->setActiveMonitor(pMonitor);
}
onWindowCreatedTiling(pWindow);
@@ -942,7 +969,7 @@ void CHyprMasterLayout::switchWindows(PHLWINDOW pWindow, PHLWINDOW pWindow2) {
return;
if (PNODE->workspaceID != PNODE2->workspaceID) {
std::swap(pWindow2->m_pMonitor, pWindow->m_pMonitor);
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
std::swap(pWindow2->m_pWorkspace, pWindow->m_pWorkspace);
}
@@ -953,9 +980,9 @@ void CHyprMasterLayout::switchWindows(PHLWINDOW pWindow, PHLWINDOW pWindow2) {
pWindow->setAnimationsToMove();
pWindow2->setAnimationsToMove();
recalculateMonitor(pWindow->monitorID());
recalculateMonitor(pWindow->m_iMonitorID);
if (PNODE2->workspaceID != PNODE->workspaceID)
recalculateMonitor(pWindow2->monitorID());
recalculateMonitor(pWindow2->m_iMonitorID);
g_pHyprRenderer->damageWindow(pWindow);
g_pHyprRenderer->damageWindow(pWindow2);
@@ -974,7 +1001,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->monitorID());
recalculateMonitor(pWindow->m_iMonitorID);
}
PHLWINDOW CHyprMasterLayout::getNextWindow(PHLWINDOW pWindow, bool next) {
@@ -1181,7 +1208,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
PNODE->isMaster = true;
}
recalculateMonitor(header.pWindow->monitorID());
recalculateMonitor(header.pWindow->m_iMonitorID);
} else if (command == "removemaster") {
@@ -1213,7 +1240,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
PNODE->isMaster = false;
}
recalculateMonitor(header.pWindow->monitorID());
recalculateMonitor(header.pWindow->m_iMonitorID);
} else if (command == "orientationleft" || command == "orientationright" || command == "orientationtop" || command == "orientationbottom" || command == "orientationcenter") {
const auto PWINDOW = header.pWindow;
@@ -1235,7 +1262,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
else if (command == "orientationcenter")
PWORKSPACEDATA->orientation = ORIENTATION_CENTER;
recalculateMonitor(header.pWindow->monitorID());
recalculateMonitor(header.pWindow->m_iMonitorID);
} else if (command == "orientationnext") {
runOrientationCycle(header, nullptr, 1);
@@ -1270,7 +1297,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
}
}
recalculateMonitor(PWINDOW->monitorID());
recalculateMonitor(PWINDOW->m_iMonitorID);
} else if (command == "rollprev") {
const auto PWINDOW = header.pWindow;
const auto PNODE = getNodeFromWindow(PWINDOW);
@@ -1296,7 +1323,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
}
}
recalculateMonitor(PWINDOW->monitorID());
recalculateMonitor(PWINDOW->m_iMonitorID);
}
return 0;
@@ -1334,7 +1361,7 @@ void CHyprMasterLayout::runOrientationCycle(SLayoutMessageHeader& header, CVarLi
nextOrPrev = cycle.size() + (nextOrPrev % (int)cycle.size());
PWORKSPACEDATA->orientation = cycle.at(nextOrPrev);
recalculateMonitor(header.pWindow->monitorID());
recalculateMonitor(header.pWindow->m_iMonitorID);
}
void CHyprMasterLayout::buildOrientationCycleVectorFromEOperation(std::vector<eOrientation>& cycle) {

View File

@@ -29,8 +29,6 @@
#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}

View File

@@ -5,9 +5,7 @@
#include "init/initHelpers.hpp"
#include "debug/HyprCtl.hpp"
#include <cstdio>
#include <hyprutils/string/String.hpp>
#include <print>
using namespace Hyprutils::String;
#include <fcntl.h>
@@ -19,15 +17,14 @@ using namespace Hyprutils::String;
#include <filesystem>
void help() {
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)");
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";
}
int main(int argc, char** argv) {
@@ -36,9 +33,9 @@ int main(int argc, char** argv) {
throwError("XDG_RUNTIME_DIR is not set!");
// export HYPRLAND_CMD
std::string cmd = argv[0];
for (int i = 1; i < argc; ++i)
cmd += std::string(" ") + argv[i];
std::string cmd = "";
for (auto i = 0; i < argc; ++i)
cmd += std::string(i == 0 ? "" : " ") + argv[i];
setenv("HYPRLAND_CMD", cmd.c_str(), 1);
setenv("XDG_BACKEND", "wayland", 1);
@@ -55,7 +52,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::println("[ WARNING ] Running Hyprland with superuser privileges might damage your system");
std::cout << "[ WARNING ] Running Hyprland with superuser privileges might damage your system\n";
ignoreSudo = true;
} else if (it->compare("--socket") == 0) {
@@ -81,7 +78,7 @@ int main(int argc, char** argv) {
if (fcntl(socketFd, F_GETFD) == -1)
throw std::exception();
} catch (...) {
std::println(stderr, "[ ERROR ] Invalid Wayland FD!");
std::cerr << "[ ERROR ] Invalid Wayland FD!\n";
help();
return 1;
@@ -103,7 +100,7 @@ int main(int argc, char** argv) {
throw std::exception();
}
} catch (...) {
std::println(stderr, "[ ERROR ] Config file '{}' doesn't exist!", configPath);
std::cerr << "[ ERROR ] Config file '" << configPath << "' doesn't exist!\n";
help();
return 1;
@@ -119,13 +116,30 @@ int main(int argc, char** argv) {
return 0;
} else if (it->compare("-v") == 0 || it->compare("--version") == 0) {
std::println("{}", versionRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, ""));
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;
return 0;
} else if (it->compare("--systeminfo") == 0) {
std::println("{}", systemInfoRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, ""));
const auto SYSINFO = systemInfoRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, "");
std::cout << SYSINFO << "\n";
return 0;
} else {
std::println(stderr, "[ ERROR ] Unknown option '{}' !", it->c_str());
std::cerr << "[ ERROR ] Unknown option '" << it->c_str() << "'!\n";
help();
return 1;
@@ -133,32 +147,30 @@ int main(int argc, char** argv) {
}
if (!ignoreSudo && Init::isSudo()) {
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.");
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";
return 1;
} else if (ignoreSudo && Init::isSudo()) {
std::println("Superuser privileges check is omitted. I hope you know what you're doing.");
std::cout << "Superuser privileges check is omitted. I hope you know what you're doing.\n";
}
if (socketName.empty() ^ (socketFd == -1)) {
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.");
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";
return 1;
}
std::println("Welcome to Hyprland!");
std::cout << "Welcome to Hyprland!\n";
// 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 (const std::exception& e) {
std::println(stderr, "Hyprland threw in ctor: {}\nCannot continue.", e.what());
} catch (std::exception& e) {
std::cout << "Hyprland threw in ctor: " << e.what() << "\nCannot continue.\n";
return 1;
}

View File

@@ -64,7 +64,7 @@ void CAnimationManager::tick() {
if (!*PANIMENABLED)
animGlobalDisabled = true;
static auto* const PSHADOWSENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:shadow:enabled");
static auto* const PSHADOWSENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:drop_shadow");
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();
PHLMONITOR PMONITOR = nullptr;
CMonitor* PMONITOR = nullptr;
bool animationsDisabled = animGlobalDisabled;
if (PWINDOW) {
@@ -99,12 +99,12 @@ void CAnimationManager::tick() {
PDECO->damageEntire();
}
PMONITOR = PWINDOW->m_pMonitor.lock();
PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (!PMONITOR)
continue;
animationsDisabled = PWINDOW->m_sWindowData.noAnim.valueOr(animationsDisabled);
} else if (PWORKSPACE) {
PMONITOR = PWORKSPACE->m_pMonitor.lock();
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
if (!PMONITOR)
continue;
@@ -259,7 +259,7 @@ void CAnimationManager::tick() {
// manually schedule a frame
if (PMONITOR)
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_ANIMATION);
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
}
// 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 = pWindow->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
if (!PMONITOR)
return; // unsafe state most likely

View File

@@ -309,7 +309,7 @@ void CCursorManager::updateTheme() {
for (auto const& m : g_pCompositor->m_vMonitors) {
m->forceFullFrames = 5;
g_pCompositor->scheduleFrameForMonitor(m, Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
g_pCompositor->scheduleFrameForMonitor(m.get(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
}
}

View File

@@ -126,7 +126,6 @@ CKeybindManager::CKeybindManager() {
m_mDispatchers["denywindowfromgroup"] = denyWindowFromGroup;
m_mDispatchers["event"] = event;
m_mDispatchers["global"] = global;
m_mDispatchers["setprop"] = setProp;
m_tScrollTimer.reset();
@@ -272,11 +271,11 @@ void updateRelativeCursorCoords() {
g_pCompositor->m_pLastWindow->m_vRelativeCursorCoordsOnLastWarp = g_pInputManager->getMouseCoordsInternal() - g_pCompositor->m_pLastWindow->m_vPosition;
}
bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) {
if (!monitor)
return false;
const auto LASTMONITOR = g_pCompositor->m_pLastMonitor.lock();
const auto LASTMONITOR = g_pCompositor->m_pLastMonitor.get();
if (!LASTMONITOR)
return false;
if (LASTMONITOR == monitor) {
@@ -350,9 +349,9 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
g_pInputManager->m_pForcedFocus.reset();
}
if (PLASTWINDOW && PLASTWINDOW->m_pMonitor != PWINDOWTOCHANGETO->m_pMonitor) {
if (PLASTWINDOW && PLASTWINDOW->m_iMonitorID != PWINDOWTOCHANGETO->m_iMonitorID) {
// event
const auto PNEWMON = PWINDOWTOCHANGETO->m_pMonitor.lock();
const auto PNEWMON = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID);
g_pCompositor->setActiveMonitor(PNEWMON);
}
@@ -1012,7 +1011,7 @@ static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional<
}
g_pCompositor->updateWorkspaceWindows(PWINDOW->workspaceID());
g_pCompositor->updateWorkspaceWindowData(PWINDOW->workspaceID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->monitorID());
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
return {};
@@ -1036,7 +1035,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 = PWINDOW->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
auto RESERVEDOFFSET = Vector2D();
if (args == "1")
@@ -1082,7 +1081,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_pMonitor != PWORKSPACETOCHANGETO->m_pMonitor)
if (PER_MON && PCURRENTWORKSPACE->m_iMonitorID != PWORKSPACETOCHANGETO->m_iMonitorID)
return {WORKSPACE_NOT_CHANGED, ""};
return {ID, PWORKSPACETOCHANGETO->m_szName};
}
@@ -1097,7 +1096,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.lock();
const auto PMONITOR = g_pCompositor->m_pLastMonitor.get();
if (!PMONITOR)
return {.success = false, .error = "Last monitor not found"};
@@ -1136,7 +1135,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
g_pInputManager->releaseAllMouseButtons();
const auto PMONITORWORKSPACEOWNER = PMONITOR == pWorkspaceToChangeTo->m_pMonitor ? PMONITOR : pWorkspaceToChangeTo->m_pMonitor.lock();
const auto PMONITORWORKSPACEOWNER = PMONITOR->ID == pWorkspaceToChangeTo->m_iMonitorID ? PMONITOR : g_pCompositor->getMonitorFromID(pWorkspaceToChangeTo->m_iMonitorID);
if (!PMONITORWORKSPACEOWNER)
return {.success = false, .error = "Workspace to switch to has no monitor"};
@@ -1261,7 +1260,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
}
auto pWorkspace = g_pCompositor->getWorkspaceByID(WORKSPACEID);
PHLMONITOR pMonitor = nullptr;
CMonitor* pMonitor = nullptr;
const auto POLDWS = PWINDOW->m_pWorkspace;
static auto PALLOWWORKSPACECYCLES = CConfigValue<Hyprlang::INT>("binds:allow_workspace_cycles");
@@ -1271,11 +1270,11 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
if (pWorkspace) {
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
pMonitor = pWorkspace->m_pMonitor.lock();
pMonitor = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
g_pCompositor->setActiveMonitor(pMonitor);
} else {
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->monitorID(), workspaceName, false);
pMonitor = pWorkspace->m_pMonitor.lock();
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->m_iMonitorID, workspaceName, false);
pMonitor = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
}
@@ -1284,7 +1283,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
if (pWorkspace->m_bIsSpecialWorkspace)
pMonitor->setSpecialWorkspace(pWorkspace);
else if (POLDWS->m_bIsSpecialWorkspace)
POLDWS->m_pMonitor.lock()->setSpecialWorkspace(nullptr);
g_pCompositor->getMonitorFromID(POLDWS->m_iMonitorID)->setSpecialWorkspace(nullptr);
if (*PALLOWWORKSPACECYCLES)
pWorkspace->rememberPrevWorkspace(POLDWS);
@@ -1329,7 +1328,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
if (pWorkspace) {
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
} else {
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->monitorID(), workspaceName, false);
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->m_iMonitorID, workspaceName, false);
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
}
@@ -1476,7 +1475,7 @@ SDispatchResult CKeybindManager::moveActiveTo(std::string args) {
if (PLASTWINDOW->m_bIsFloating) {
std::optional<float> vPosx, vPosy;
const auto PMONITOR = PLASTWINDOW->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(PLASTWINDOW->m_iMonitorID);
const auto BORDERSIZE = PLASTWINDOW->getRealBorderSize();
switch (arg) {
@@ -1796,7 +1795,7 @@ SDispatchResult CKeybindManager::exitHyprland(std::string argz) {
}
SDispatchResult CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
PHLMONITOR PMONITOR = g_pCompositor->getMonitorFromString(args);
CMonitor* PMONITOR = g_pCompositor->getMonitorFromString(args);
if (!PMONITOR) {
Debug::log(ERR, "Ignoring moveCurrentWorkspaceToMonitor: monitor doesnt exist");
@@ -1855,7 +1854,7 @@ SDispatchResult CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args
return {.success = false, .error = "focusWorkspaceOnCurrentMonitor invalid workspace!"};
}
const auto PCURRMONITOR = g_pCompositor->m_pLastMonitor.lock();
const auto PCURRMONITOR = g_pCompositor->m_pLastMonitor.get();
if (!PCURRMONITOR) {
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor monitor doesn't exist!");
@@ -1883,8 +1882,8 @@ SDispatchResult CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args
workspaceID = pWorkspace->m_iID;
}
if (pWorkspace->m_pMonitor != PCURRMONITOR) {
const auto POLDMONITOR = pWorkspace->m_pMonitor.lock();
if (pWorkspace->m_iMonitorID != PCURRMONITOR->ID) {
const auto POLDMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
if (!POLDMONITOR) { // wat
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor old monitor doesn't exist!");
return {.success = false, .error = "focusWorkspaceOnCurrentMonitor old monitor doesn't exist!"};
@@ -1945,7 +1944,7 @@ SDispatchResult CKeybindManager::forceRendererReload(std::string args) {
continue;
auto rule = g_pConfigManager->getMonitorRuleFor(m);
if (!g_pHyprRenderer->applyMonitorRule(m, &rule, true)) {
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule, true)) {
overAgain = true;
break;
}
@@ -2428,7 +2427,7 @@ SDispatchResult CKeybindManager::dpms(std::string arg) {
}
if (enable)
g_pHyprRenderer->damageMonitor(m);
g_pHyprRenderer->damageMonitor(m.get());
m->events.dpmsChanged.emit();
}
@@ -2510,7 +2509,7 @@ SDispatchResult CKeybindManager::pinActive(std::string args) {
PWINDOW->m_bPinned = !PWINDOW->m_bPinned;
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (!PMONITOR) {
Debug::log(ERR, "pin: monitor not found");
@@ -2659,14 +2658,15 @@ void CKeybindManager::moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowIn
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); // This removes groupped property!
if (pWindow->m_pMonitor != pWindowInDirection->m_pMonitor) {
if (pWindow->m_iMonitorID != pWindowInDirection->m_iMonitorID) {
pWindow->moveToWorkspace(pWindowInDirection->m_pWorkspace);
pWindow->m_pMonitor = pWindowInDirection->m_pMonitor;
pWindow->m_iMonitorID = pWindowInDirection->m_iMonitorID;
}
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(*USECURRPOS ? pWindowInDirection : pWindowInDirection->getGroupTail())->insertWindowToGroup(pWindow);
pWindowInDirection = *USECURRPOS ? pWindowInDirection : pWindowInDirection->getGroupTail();
pWindowInDirection->insertWindowToGroup(pWindow);
pWindowInDirection->setGroupCurrent(pWindow);
pWindow->updateWindowDecos();
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
@@ -2891,97 +2891,3 @@ 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 {};
}

View File

@@ -146,7 +146,7 @@ class CKeybindManager {
void updateXKBTranslationState();
bool ensureMouseBindState();
static bool tryMoveFocusToMonitor(PHLMONITOR monitor);
static bool tryMoveFocusToMonitor(CMonitor* monitor);
static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = "");
static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection);
static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO);
@@ -217,7 +217,6 @@ 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;

View File

@@ -2,7 +2,6 @@
#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"
@@ -14,7 +13,7 @@
CPointerManager::CPointerManager() {
hooks.monitorAdded = g_pHookSystem->hookDynamic("monitorAdded", [this](void* self, SCallbackInfo& info, std::any data) {
auto PMONITOR = std::any_cast<PHLMONITOR>(data);
auto PMONITOR = std::any_cast<CMonitor*>(data)->self.lock();
onMonitorLayoutChange();
@@ -29,7 +28,7 @@ CPointerManager::CPointerManager() {
});
hooks.monitorPreRender = g_pHookSystem->hookDynamic("preMonitorCommit", [this](void* self, SCallbackInfo& info, std::any data) {
auto state = stateFor(std::any_cast<PHLMONITOR>(data));
auto state = stateFor(std::any_cast<CMonitor*>(data)->self.lock());
if (!state)
return;
@@ -51,16 +50,34 @@ void CPointerManager::unlockSoftwareAll() {
updateCursorBackend();
}
void CPointerManager::lockSoftwareForMonitor(PHLMONITOR mon) {
auto const state = stateFor(mon);
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);
state->softwareLocks++;
if (state->softwareLocks == 1)
updateCursorBackend();
}
void CPointerManager::unlockSoftwareForMonitor(PHLMONITOR mon) {
auto const state = stateFor(mon);
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);
state->softwareLocks--;
if (state->softwareLocks < 0)
state->softwareLocks = 0;
@@ -69,8 +86,8 @@ void CPointerManager::unlockSoftwareForMonitor(PHLMONITOR mon) {
updateCursorBackend();
}
bool CPointerManager::softwareLockedFor(PHLMONITOR mon) {
auto const state = stateFor(mon);
bool CPointerManager::softwareLockedFor(SP<CMonitor> mon) {
auto state = stateFor(mon);
return state->softwareLocks > 0 || state->hardwareFailed;
}
@@ -82,7 +99,7 @@ bool CPointerManager::hasCursor() {
return currentCursorImage.pBuffer || currentCursorImage.surface;
}
SP<CPointerManager::SMonitorPointerState> CPointerManager::stateFor(PHLMONITOR mon) {
SP<CPointerManager::SMonitorPointerState> CPointerManager::stateFor(SP<CMonitor> 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));
@@ -247,16 +264,19 @@ void CPointerManager::resetCursorImage(bool apply) {
}
void CPointerManager::updateCursorBackend() {
const auto CURSORBOX = getCursorBoxGlobal();
static auto PNOHW = CConfigValue<Hyprlang::INT>("cursor:no_hardware_cursors");
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)
@@ -265,7 +285,7 @@ void CPointerManager::updateCursorBackend() {
continue;
}
if (state->softwareLocks > 0 || g_pConfigManager->shouldUseSoftwareCursors() || !attemptHardwareCursor(state)) {
if (state->softwareLocks > 0 || *PNOHW || !attemptHardwareCursor(state)) {
Debug::log(TRACE, "Output {} rejected hardware cursors, falling back to sw", m->szName);
state->box = getCursorBoxLogicalForMonitor(state->monitor.lock());
state->hardwareFailed = true;
@@ -308,7 +328,7 @@ void CPointerManager::onCursorMoved() {
continue;
const auto CURSORPOS = getCursorPosForMonitor(m);
m->output->moveCursor(CURSORPOS, m->shouldSkipScheduleFrameOnMouseEvent());
m->output->moveCursor(CURSORPOS);
}
if (recalc)
@@ -322,7 +342,7 @@ bool CPointerManager::attemptHardwareCursor(SP<CPointerManager::SMonitorPointerS
return false;
const auto CURSORPOS = getCursorPosForMonitor(state->monitor.lock());
state->monitor->output->moveCursor(CURSORPOS, state->monitor->shouldSkipScheduleFrameOnMouseEvent());
state->monitor->output->moveCursor(CURSORPOS);
auto texture = getCurrentCursorTexture();
@@ -365,15 +385,16 @@ bool CPointerManager::setHWCursorBuffer(SP<SMonitorPointerState> state, SP<Aquam
state->cursorFrontBuffer = buf;
if (!state->monitor->shouldSkipScheduleFrameOnMouseEvent())
g_pCompositor->scheduleFrameForMonitor(state->monitor.lock(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
g_pCompositor->scheduleFrameForMonitor(state->monitor.get(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
return true;
}
SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager::SMonitorPointerState> state, SP<CTexture> texture) {
auto maxSize = state->monitor->output->cursorPlaneSize();
auto const& cursorSize = currentCursorImage.size;
auto output = state->monitor->output;
auto maxSize = output->cursorPlaneSize();
auto cursorSize = currentCursorImage.size;
if (maxSize == Vector2D{})
return nullptr;
@@ -420,8 +441,10 @@ 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;
g_pHyprOpenGL->m_RenderData.pMonitor = state->monitor.get();
auto RBO = g_pHyprRenderer->getOrCreateRenderbuffer(buf, state->monitor->cursorSwapchain->currentOptions().format);
if (!RBO) {
@@ -478,7 +501,7 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
RBO->bind();
g_pHyprOpenGL->beginSimple(state->monitor.lock(), {0, 0, INT16_MAX, INT16_MAX}, RBO);
g_pHyprOpenGL->beginSimple(state->monitor.get(), damage, RBO);
g_pHyprOpenGL->clear(CColor{0.F, 0.F, 0.F, 0.F});
CBox xbox = {{}, Vector2D{currentCursorImage.size / currentCursorImage.scale * state->monitor->scale}.round()};
@@ -489,14 +512,14 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
g_pHyprOpenGL->end();
glFlush();
g_pHyprOpenGL->m_RenderData.pMonitor.reset();
g_pHyprOpenGL->m_RenderData.pMonitor = nullptr;
g_pHyprRenderer->onRenderbufferDestroy(RBO.get());
return buf;
}
void CPointerManager::renderSoftwareCursorsFor(PHLMONITOR pMonitor, timespec* now, CRegion& damage, std::optional<Vector2D> overridePos) {
void CPointerManager::renderSoftwareCursorsFor(SP<CMonitor> pMonitor, timespec* now, CRegion& damage, std::optional<Vector2D> overridePos) {
if (!hasCursor())
return;
@@ -531,7 +554,7 @@ void CPointerManager::renderSoftwareCursorsFor(PHLMONITOR pMonitor, timespec* no
currentCursorImage.surface->resource()->frame(now);
}
Vector2D CPointerManager::getCursorPosForMonitor(PHLMONITOR pMonitor) {
Vector2D CPointerManager::getCursorPosForMonitor(SP<CMonitor> pMonitor) {
return CBox{pointerPos - pMonitor->vecPosition, {0, 0}}
.transform(wlTransformToHyprutils(invertTransform(pMonitor->transform)), pMonitor->vecTransformedSize.x / pMonitor->scale,
pMonitor->vecTransformedSize.y / pMonitor->scale)
@@ -539,7 +562,7 @@ Vector2D CPointerManager::getCursorPosForMonitor(PHLMONITOR pMonitor) {
pMonitor->scale;
}
Vector2D CPointerManager::transformedHotspot(PHLMONITOR pMonitor) {
Vector2D CPointerManager::transformedHotspot(SP<CMonitor> pMonitor) {
if (!pMonitor->cursorSwapchain)
return {}; // doesn't matter, we have no hw cursor, and this is only for hw cursors
@@ -549,7 +572,7 @@ Vector2D CPointerManager::transformedHotspot(PHLMONITOR pMonitor) {
.pos();
}
CBox CPointerManager::getCursorBoxLogicalForMonitor(PHLMONITOR pMonitor) {
CBox CPointerManager::getCursorBoxLogicalForMonitor(SP<CMonitor> pMonitor) {
return getCursorBoxGlobal().translate(-pMonitor->vecPosition);
}
@@ -634,13 +657,15 @@ Vector2D CPointerManager::closestValid(const Vector2D& pos) {
}
void CPointerManager::damageIfSoftware() {
auto b = getCursorBoxGlobal().expand(4);
auto b = getCursorBoxGlobal().expand(4);
static auto PNOHW = CConfigValue<Hyprlang::INT>("cursor:no_hardware_cursors");
for (auto const& mw : monitorStates) {
if (mw->monitor.expired() || !mw->monitor->output)
continue;
if ((mw->softwareLocks > 0 || mw->hardwareFailed || g_pConfigManager->shouldUseSoftwareCursors()) && b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) {
if ((mw->softwareLocks > 0 || mw->hardwareFailed || *PNOHW) && b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) {
g_pHyprRenderer->damageBox(&b, mw->monitor->shouldSkipScheduleFrameOnMouseEvent());
break;
}
@@ -651,11 +676,8 @@ void CPointerManager::warpTo(const Vector2D& logical) {
damageIfSoftware();
pointerPos = closestValid(logical);
if (!g_pInputManager->isLocked()) {
recheckEnteredOutputs();
onCursorMoved();
}
recheckEnteredOutputs();
onCursorMoved();
damageIfSoftware();
}
@@ -669,7 +691,7 @@ void CPointerManager::move(const Vector2D& deltaLogical) {
void CPointerManager::warpAbsolute(Vector2D abs, SP<IHID> dev) {
PHLMONITOR currentMonitor = g_pCompositor->m_pLastMonitor.lock();
SP<CMonitor> currentMonitor = g_pCompositor->m_pLastMonitor.lock();
if (!currentMonitor || !dev)
return;
@@ -837,14 +859,7 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
});
listener->frame = pointer->pointerEvents.frame.registerListener([this] (std::any e) {
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();
g_pSeatManager->sendPointerFrame();
});
listener->swipeBegin = pointer->pointerEvents.swipeBegin.registerListener([this] (std::any e) {
@@ -1046,7 +1061,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(PHLMONITOR pMonitor) {
void CPointerManager::damageCursor(SP<CMonitor> pMonitor) {
for (auto const& mw : monitorStates) {
if (mw->monitor != pMonitor)
continue;
@@ -1065,22 +1080,3 @@ void CPointerManager::damageCursor(PHLMONITOR 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{};
}

View File

@@ -43,25 +43,24 @@ class CPointerManager {
void setCursorSurface(SP<CWLSurface> buf, const Vector2D& hotspot);
void resetCursorImage(bool apply = true);
void lockSoftwareForMonitor(PHLMONITOR pMonitor);
void unlockSoftwareForMonitor(PHLMONITOR pMonitor);
void lockSoftwareForMonitor(SP<CMonitor> pMonitor);
void unlockSoftwareForMonitor(SP<CMonitor> pMonitor);
void lockSoftwareForMonitor(CMonitor* pMonitor);
void unlockSoftwareForMonitor(CMonitor* pMonitor);
void lockSoftwareAll();
void unlockSoftwareAll();
bool softwareLockedFor(PHLMONITOR pMonitor);
bool softwareLockedFor(SP<CMonitor> pMonitor);
void renderSoftwareCursorsFor(PHLMONITOR pMonitor, timespec* now, CRegion& damage /* logical */, std::optional<Vector2D> overridePos = {} /* monitor-local */);
void renderSoftwareCursorsFor(SP<CMonitor> 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(PHLMONITOR pMonitor);
void damageCursor(SP<CMonitor> 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();
@@ -78,13 +77,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(PHLMONITOR pMonitor);
Vector2D getCursorPosForMonitor(SP<CMonitor> pMonitor);
// returns the thing in logical coordinates of the monitor
CBox getCursorBoxLogicalForMonitor(PHLMONITOR pMonitor);
CBox getCursorBoxLogicalForMonitor(SP<CMonitor> pMonitor);
// returns the thing in global coords
CBox getCursorBoxGlobal();
Vector2D transformedHotspot(PHLMONITOR pMonitor);
Vector2D transformedHotspot(SP<CMonitor> pMonitor);
SP<CTexture> getCurrentCursorTexture();
@@ -155,15 +154,11 @@ class CPointerManager {
Vector2D pointerPos = {0, 0};
uint64_t storedTime = 0;
Vector2D storedDelta = {0, 0};
Vector2D storedUnaccel = {0, 0};
struct SMonitorPointerState {
SMonitorPointerState(PHLMONITOR m) : monitor(m) {}
SMonitorPointerState(SP<CMonitor> m) : monitor(m) {}
~SMonitorPointerState() {}
PHLMONITORREF monitor;
WP<CMonitor> monitor;
int softwareLocks = 0;
bool hardwareFailed = false;
@@ -176,7 +171,7 @@ class CPointerManager {
};
std::vector<SP<SMonitorPointerState>> monitorStates;
SP<SMonitorPointerState> stateFor(PHLMONITOR mon);
SP<SMonitorPointerState> stateFor(SP<CMonitor> 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);

View File

@@ -45,8 +45,6 @@
#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"
@@ -62,7 +60,7 @@
#include <aquamarine/buffer/Buffer.hpp>
#include <aquamarine/backend/Backend.hpp>
void CProtocolManager::onMonitorModeChange(PHLMONITOR pMonitor) {
void CProtocolManager::onMonitorModeChange(CMonitor* pMonitor) {
const bool ISMIRROR = pMonitor->isMirror();
// onModeChanged we check if the current mirror status matches the global.
@@ -84,7 +82,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<PHLMONITOR>(param);
auto M = std::any_cast<CMonitor*>(param);
// ignore mirrored outputs. I don't think this will ever be hit as mirrors are applied after
// this event is emitted iirc.
@@ -103,7 +101,7 @@ CProtocolManager::CProtocolManager() {
});
static auto P2 = g_pHookSystem->hookDynamic("monitorRemoved", [this](void* self, SCallbackInfo& info, std::any param) {
auto M = std::any_cast<PHLMONITOR>(param);
auto M = std::any_cast<CMonitor*>(param);
if (!PROTO::outputs.contains(M->szName))
return;
PROTO::outputs.at(M->szName)->remove();
@@ -157,8 +155,6 @@ 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)
@@ -229,63 +225,9 @@ 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::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();
}

View File

@@ -11,12 +11,10 @@ class CProtocolManager {
CProtocolManager();
~CProtocolManager();
bool isGlobalPrivileged(const wl_global* global);
private:
std::unordered_map<std::string, CHyprSignalListener> m_mModeChangeListeners;
void onMonitorModeChange(PHLMONITOR pMonitor);
void onMonitorModeChange(CMonitor* pMonitor);
};
inline std::unique_ptr<CProtocolManager> g_pProtocolManager;

View File

@@ -128,9 +128,6 @@ class CSeatManager {
void setGrab(SP<CSeatGrab> grab); // nullptr removes
SP<CSeatGrab> seatGrab;
bool isPointerFrameSkipped = false;
bool isPointerFrameCommit = false;
private:
struct SSeatResourceContainer {
SSeatResourceContainer(SP<CWLSeatResource>);

View File

@@ -3,7 +3,6 @@
#include "../config/ConfigValue.hpp"
#include "../protocols/FractionalScale.hpp"
#include "../protocols/SessionLock.hpp"
#include "../managers/SeatManager.hpp"
#include <algorithm>
#include <ranges>
@@ -73,7 +72,7 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
g_pInputManager->refocus();
for (auto const& m : g_pCompositor->m_vMonitors)
g_pHyprRenderer->damageMonitor(m);
g_pHyprRenderer->damageMonitor(m.get());
});
m_pSessionLock->listeners.destroy = pLock->events.destroyed.registerListener([this](std::any data) {
@@ -81,11 +80,10 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
g_pCompositor->focusSurface(nullptr);
for (auto const& m : g_pCompositor->m_vMonitors)
g_pHyprRenderer->damageMonitor(m);
g_pHyprRenderer->damageMonitor(m.get());
});
g_pCompositor->focusSurface(nullptr);
g_pSeatManager->setGrab(nullptr);
}
bool CSessionLockManager::isSessionLocked() {

View File

@@ -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, [&NOW](const auto& el) { return el.second->expiresAt < NOW; });
std::erase_if(m_mTokens, [this, &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);
}
}

View File

@@ -117,11 +117,9 @@ void CXCursorManager::loadTheme(std::string const& name, int size, float scale)
cursors = loadStandardCursors(themeName, lastLoadSize);
} else {
for (auto const& p : paths) {
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()); }
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; }); });
}
}

View File

@@ -5,13 +5,14 @@
#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() = default;
CHyprXWaylandManager::CHyprXWaylandManager() {
;
}
CHyprXWaylandManager::~CHyprXWaylandManager() {
#ifndef NO_XWAYLAND
@@ -20,7 +21,7 @@ CHyprXWaylandManager::~CHyprXWaylandManager() {
}
SP<CWLSurfaceResource> CHyprXWaylandManager::getWindowSurface(PHLWINDOW pWindow) {
return pWindow ? pWindow->m_pWLSurface->resource() : nullptr;
return pWindow->m_pWLSurface->resource();
}
void CHyprXWaylandManager::activateSurface(SP<CWLSurfaceResource> pSurface, bool activate) {
@@ -39,31 +40,27 @@ void CHyprXWaylandManager::activateSurface(SP<CWLSurfaceResource> pSurface, bool
return;
}
if (PWINDOW->m_bIsX11) {
if (PWINDOW->m_pXWaylandSurface) {
if (activate) {
PWINDOW->m_pXWaylandSurface->setMinimized(false);
PWINDOW->m_pXWaylandSurface->restackToTop();
}
PWINDOW->m_pXWaylandSurface->activate(activate);
if (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface) {
if (activate) {
PWINDOW->m_pXWaylandSurface->setMinimized(false);
PWINDOW->m_pXWaylandSurface->restackToTop();
}
} else if (PWINDOW->m_pXDGSurface)
PWINDOW->m_pXWaylandSurface->activate(activate);
} else if (!PWINDOW->m_bIsX11 && 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);
@@ -77,9 +74,6 @@ 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();
@@ -89,10 +83,7 @@ void CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow, CBox* pbox) {
pbox->x = pWindow->m_pXWaylandSurface->geometry.x;
pbox->y = pWindow->m_pXWaylandSurface->geometry.y;
constexpr int ICCCM_USSize = 0x2;
constexpr int ICCCM_PSize = 0x8;
if ((SIZEHINTS->flags & ICCCM_USSize) || (SIZEHINTS->flags & ICCCM_PSize)) {
if ((SIZEHINTS->flags & 0x2 /* ICCCM USSize */) || (SIZEHINTS->flags & 0x8 /* ICCCM PSize */)) {
pbox->w = SIZEHINTS->base_width;
pbox->h = SIZEHINTS->base_height;
} else {
@@ -117,7 +108,7 @@ void CHyprXWaylandManager::setWindowSize(PHLWINDOW pWindow, Vector2D size, bool
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
const auto PMONITOR = pWindow->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
size = size.clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
@@ -126,34 +117,34 @@ void CHyprXWaylandManager::setWindowSize(PHLWINDOW pWindow, Vector2D size, bool
Vector2D windowPos = pWindow->m_vRealPosition.value();
if (pWindow->m_bIsX11 && PMONITOR) {
windowPos -= PMONITOR->vecPosition; // normalize to monitor
windowPos = windowPos - PMONITOR->vecPosition; // normalize to monitor
if (*PXWLFORCESCALEZERO)
windowPos *= PMONITOR->scale; // scale if applicable
windowPos += PMONITOR->vecXWaylandPosition; // move to correct position for xwayland
windowPos = windowPos * PMONITOR->scale; // scale if applicable
windowPos = windowPos + PMONITOR->vecXWaylandPosition; // move to correct position for xwayland
}
if (!force && pWindow->m_vPendingReportedSize == size && (windowPos == pWindow->m_vReportedPosition || !pWindow->m_bIsX11))
if (!force && ((pWindow->m_vPendingReportedSize == size && windowPos == pWindow->m_vReportedPosition) || (pWindow->m_vPendingReportedSize == size && !pWindow->m_bIsX11)))
return;
pWindow->m_vReportedPosition = windowPos;
pWindow->m_vPendingReportedSize = size;
pWindow->m_fX11SurfaceScaledBy = 1.0f;
pWindow->m_fX11SurfaceScaledBy = 1.f;
if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11 && PMONITOR) {
size *= PMONITOR->scale;
size = 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.emplace_back(pWindow->m_pXDGSurface->toplevel->setSize(size), size.floor());
pWindow->m_vPendingSizeAcks.push_back(std::make_pair<>(pWindow->m_pXDGSurface->toplevel->setSize(size), size.floor()));
}
bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) {
if (pWindow->m_bIsX11) {
for (const auto& a : pWindow->m_pXWaylandSurface->atoms)
for (auto const& 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"] ||
@@ -166,8 +157,16 @@ bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) {
return true;
}
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)
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)
return true;
const auto SIZEHINTS = pWindow->m_pXWaylandSurface->sizeHints.get();
@@ -204,9 +203,6 @@ 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)
@@ -214,42 +210,46 @@ void CHyprXWaylandManager::setWindowFullscreen(PHLWINDOW pWindow, bool fullscree
}
Vector2D CHyprXWaylandManager::getMaxSizeForWindow(PHLWINDOW pWindow) {
constexpr int NO_MAX_SIZE_LIMIT = 99999;
if (!validMapped(pWindow) ||
((pWindow->m_bIsX11 && !pWindow->m_pXWaylandSurface->sizeHints) || (!pWindow->m_bIsX11 && !pWindow->m_pXDGSurface->toplevel) ||
pWindow->m_sWindowData.noMaxSize.valueOrDefault()))
return Vector2D(NO_MAX_SIZE_LIMIT, NO_MAX_SIZE_LIMIT);
if (!validMapped(pWindow))
return Vector2D(99999, 99999);
Vector2D maxSize = pWindow->m_bIsX11 ? Vector2D(pWindow->m_pXWaylandSurface->sizeHints->max_width, pWindow->m_pXWaylandSurface->sizeHints->max_height) :
pWindow->m_pXDGSurface->toplevel->current.maxSize;
if ((pWindow->m_bIsX11 && !pWindow->m_pXWaylandSurface->sizeHints) || (!pWindow->m_bIsX11 && !pWindow->m_pXDGSurface->toplevel) ||
pWindow->m_sWindowData.noMaxSize.valueOrDefault())
return Vector2D(99999, 99999);
if (maxSize.x < 5)
maxSize.x = NO_MAX_SIZE_LIMIT;
if (maxSize.y < 5)
maxSize.y = NO_MAX_SIZE_LIMIT;
auto MAXSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_pXWaylandSurface->sizeHints->max_width, pWindow->m_pXWaylandSurface->sizeHints->max_height) :
pWindow->m_pXDGSurface->toplevel->current.maxSize;
return 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) || ((pWindow->m_bIsX11 && !pWindow->m_pXWaylandSurface->sizeHints) || (!pWindow->m_bIsX11 && !pWindow->m_pXDGSurface->toplevel)))
if (!validMapped(pWindow))
return Vector2D(0, 0);
Vector2D minSize = pWindow->m_bIsX11 ? Vector2D(pWindow->m_pXWaylandSurface->sizeHints->min_width, pWindow->m_pXWaylandSurface->sizeHints->min_height) :
pWindow->m_pXDGSurface->toplevel->current.minSize;
if ((pWindow->m_bIsX11 && !pWindow->m_pXWaylandSurface->sizeHints) || (!pWindow->m_bIsX11 && !pWindow->m_pXDGSurface->toplevel))
return Vector2D(0, 0);
minSize = minSize.clamp({1, 1});
auto MINSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_pXWaylandSurface->sizeHints->min_width, pWindow->m_pXWaylandSurface->sizeHints->min_height) :
pWindow->m_pXDGSurface->toplevel->current.minSize;
return minSize;
MINSIZE = MINSIZE.clamp({1, 1});
return MINSIZE;
}
Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) {
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
PHLMONITOR pMonitor = nullptr;
CMonitor* pMonitor = nullptr;
double bestDistance = __FLT_MAX__;
for (const auto& m : g_pCompositor->m_vMonitors) {
for (auto const& m : g_pCompositor->m_vMonitors) {
const auto SIZ = *PXWLFORCESCALEZERO ? m->vecTransformedSize : m->vecSize;
double distance =
@@ -257,7 +257,7 @@ Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) {
if (distance < bestDistance) {
bestDistance = distance;
pMonitor = m;
pMonitor = m.get();
}
}
@@ -268,9 +268,9 @@ Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) {
Vector2D result = coord - pMonitor->vecXWaylandPosition;
// if scaled, unscale
if (*PXWLFORCESCALEZERO)
result /= pMonitor->scale;
result = result / pMonitor->scale;
// add pos
result += pMonitor->vecPosition;
result = result + pMonitor->vecPosition;
return result;
}
}

View File

@@ -98,7 +98,7 @@ void CEventLoopManager::nudgeTimers() {
long nextTimerUs = 10 * 1000 * 1000; // 10s
for (auto const& t : m_sTimers.timers) {
if (auto const& µs = t->leftUs(); µs < nextTimerUs)
if (const auto µs = t->leftUs(); µs < nextTimerUs)
nextTimerUs = µs;
}

View File

@@ -87,11 +87,6 @@ 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);
@@ -139,15 +134,6 @@ 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");
@@ -168,11 +154,20 @@ 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 = isLocked() && g_pCompositor->m_pLastMonitor ? g_pCompositor->m_pLastMonitor.lock() : g_pCompositor->getMonitorFromCursor();
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
// this can happen if there are no displays hooked up to Hyprland
if (PMONITOR == nullptr)
@@ -189,9 +184,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 ? SURF->constraint() : nullptr;
const auto CONSTRAINT = SURF->constraint();
if (CONSTRAINT) {
if (SURF && CONSTRAINT) {
if (CONSTRAINT->isLocked()) {
const auto HINT = CONSTRAINT->logicPositionHint();
g_pCompositor->warpCursorTo(HINT, true);
@@ -212,7 +207,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 && (*PMOUSEFOCUSMON || refocus) && m_pForcedFocus.expired())
if (PMONITOR != g_pCompositor->m_pLastMonitor.get() && (*PMOUSEFOCUSMON || refocus) && m_pForcedFocus.expired())
g_pCompositor->setActiveMonitor(PMONITOR);
if (g_pSessionLockManager->isSessionLocked()) {
@@ -291,8 +286,7 @@ 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 PWINDOWIDEAL = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
const auto PWORKSPACE = PMONITOR->activeWorkspace;
if (PWORKSPACE->m_bHasFullscreenWindow && !foundSurface && PWORKSPACE->m_efFullscreenMode == FSMODE_FULLSCREEN) {
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
@@ -302,6 +296,8 @@ 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 */))
@@ -321,8 +317,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FSMODE_MAXIMIZED) {
if (!foundSurface) {
if (PMONITOR->activeSpecialWorkspace) {
if (pFoundWindow != PWINDOWIDEAL)
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
if (pFoundWindow && !pFoundWindow->onSpecialWorkspace()) {
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
@@ -335,8 +330,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
}
if (!foundSurface) {
if (pFoundWindow != PWINDOWIDEAL)
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
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);
@@ -345,8 +339,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
}
} else {
if (pFoundWindow != PWINDOWIDEAL)
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
}
if (pFoundWindow) {
@@ -372,7 +365,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.lock(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_pLastMonitor.get(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
// grabs
if (g_pSeatManager->seatGrab && !g_pSeatManager->seatGrab->accepts(foundSurface)) {
@@ -722,7 +715,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 && PMON)
if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != g_pCompositor->m_pLastMonitor.get() && PMON)
g_pCompositor->setActiveMonitor(PMON);
if (g_pSeatManager->seatGrab && e.state == WL_POINTER_BUTTON_STATE_PRESSED) {
@@ -759,7 +752,6 @@ 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);
@@ -775,33 +767,24 @@ 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) {
if (PWINDOW->checkInputOnDecos(INPUT_TYPE_AXIS, MOUSECOORDS, e))
return;
if (PWINDOW && PWINDOW->checkInputOnDecos(INPUT_TYPE_AXIS, MOUSECOORDS, e))
return;
if (*POFFWINDOWAXIS != 1) {
const auto BOX = PWINDOW->getWindowMainSurfaceBox();
if (PWINDOW && *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();
}
}
if (g_pSeatManager->state.pointerFocus) {
const auto PCURRWINDOW = g_pCompositor->getWindowFromSurface(g_pSeatManager->state.pointerFocus.lock());
if (*PFOLLOWMOUSE == 1 && PCURRWINDOW && PWINDOW != PCURRWINDOW)
simulateMouseMovement();
g_pSeatManager->sendPointerMotion(e.timeMs, Vector2D{TEMPCURX, TEMPCURY} - BOX.pos());
g_pSeatManager->sendPointerFrame();
}
}
}
@@ -917,7 +900,7 @@ void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
keeb.get());
keeb->keyboardEvents.keymap.registerStaticListener(
[](void* owner, std::any data) {
[this](void* owner, std::any data) {
auto PKEEB = ((IKeyboard*)owner)->self.lock();
const auto LAYOUT = PKEEB->getActiveLayout();
@@ -1371,7 +1354,7 @@ void CInputManager::refocus() {
mouseMoveUnified(0, true);
}
void CInputManager::refocusLastWindow(PHLMONITOR pMonitor) {
void CInputManager::refocusLastWindow(CMonitor* pMonitor) {
if (!pMonitor) {
refocus();
return;
@@ -1388,19 +1371,13 @@ void CInputManager::refocusLastWindow(PHLMONITOR 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
@@ -1436,20 +1413,19 @@ void CInputManager::unconstrainMouse() {
}
bool CInputManager::isConstrained() {
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;
});
}
for (auto const& c : m_vConstraints) {
const auto C = c.lock();
bool CInputManager::isLocked() {
if (!isConstrained())
return false;
if (!C)
continue;
const auto SURF = CWLSurface::fromResource(g_pCompositor->m_pLastFocus.lock());
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
if (!C->isActive() || C->owner()->resource() != g_pCompositor->m_pLastFocus)
continue;
return CONSTRAINT && CONSTRAINT->isLocked();
return true;
}
return false;
}
void CInputManager::updateCapabilities() {
@@ -1661,12 +1637,31 @@ std::string CInputManager::getNameForNewDevice(std::string internalName) {
auto proposedNewName = deviceNameToInternalString(internalName);
int dupeno = 0;
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())
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())
dupeno++;
return makeNewName();
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)));
}
void CInputManager::releaseAllMouseButtons() {

View File

@@ -108,11 +108,10 @@ class CInputManager {
void unconstrainMouse();
bool isConstrained();
bool isLocked();
Vector2D getMouseCoordsInternal();
void refocus();
void refocusLastWindow(PHLMONITOR pMonitor);
void refocusLastWindow(CMonitor* pMonitor);
void simulateMouseMovement();
void sendMotionEventsToFocused();

View File

@@ -100,14 +100,14 @@ void CInputPopup::updateBox() {
cursorBoxParent = {0, 0, (int)parentBox.w, (int)parentBox.h};
}
Vector2D currentPopupSize = surface->getViewporterCorrectedSize() / surface->resource()->current.scale;
Vector2D currentPopupSize = surface->getViewporterCorrectedSize();
PHLMONITOR pMonitor = g_pCompositor->getMonitorFromVector(parentBox.middle());
CMonitor* 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;

View File

@@ -15,8 +15,9 @@ void CInputManager::onSwipeBegin(IPointer::SSwipeBeginEvent e) {
int onMonitor = 0;
for (auto const& w : g_pCompositor->m_vWorkspaces) {
if (w->m_pMonitor == g_pCompositor->m_pLastMonitor && !g_pCompositor->isWorkspaceSpecial(w->m_iID))
if (w->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID && !g_pCompositor->isWorkspaceSpecial(w->m_iID)) {
onMonitor++;
}
}
if (onMonitor < 2 && !*PSWIPENEW)
@@ -32,7 +33,7 @@ void CInputManager::beginWorkspaceSwipe() {
m_sActiveSwipe.pWorkspaceBegin = PWORKSPACE;
m_sActiveSwipe.delta = 0;
m_sActiveSwipe.pMonitor = g_pCompositor->m_pLastMonitor;
m_sActiveSwipe.pMonitor = g_pCompositor->m_pLastMonitor.get();
m_sActiveSwipe.avgSpeed = 0;
m_sActiveSwipe.speedPoints = 0;
@@ -178,7 +179,7 @@ void CInputManager::endWorkspaceSwipe() {
}
m_sActiveSwipe.pWorkspaceBegin->rememberPrevWorkspace(pSwitchedTo);
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor.lock());
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
if (PWORKSPACEL)
PWORKSPACEL->m_bForceRendering = false;
@@ -263,7 +264,7 @@ void CInputManager::updateWorkspaceSwipe(double delta) {
if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID || !PWORKSPACE) {
if (*PSWIPENEW) {
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor.lock());
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
if (VERTANIMS)
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE));
@@ -303,7 +304,7 @@ void CInputManager::updateWorkspaceSwipe(double delta) {
if (workspaceIDRight < m_sActiveSwipe.pWorkspaceBegin->m_iID || !PWORKSPACE) {
if (*PSWIPENEW) {
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor.lock());
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
if (VERTANIMS)
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE));
@@ -340,7 +341,7 @@ void CInputManager::updateWorkspaceSwipe(double delta) {
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDRight);
}
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor.lock());
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID);

View File

@@ -201,7 +201,7 @@ void CInputManager::newTablet(SP<Aquamarine::ITablet> pDevice) {
m_vHIDs.push_back(PNEWTABLET);
try {
PNEWTABLET->hlName = g_pInputManager->getNameForNewDevice(pDevice->getName());
PNEWTABLET->hlName = deviceNameToInternalString(pDevice->getName());
} catch (std::exception& e) {
Debug::log(ERR, "Tablet had no name???"); // logic error
}
@@ -228,12 +228,6 @@ 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;
@@ -249,7 +243,7 @@ void CInputManager::newTabletPad(SP<Aquamarine::ITabletPad> pDevice) {
m_vHIDs.push_back(PNEWPAD);
try {
PNEWPAD->hlName = g_pInputManager->getNameForNewDevice(pDevice->getName());
PNEWPAD->hlName = deviceNameToInternalString(pDevice->getName());
} catch (std::exception& e) {
Debug::log(ERR, "Pad had no name???"); // logic error
}

View File

@@ -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.lock();
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_pLastMonitor.get();
g_pCompositor->warpCursorTo({PMONITOR->vecPosition.x + e.pos.x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e.pos.y * PMONITOR->vecSize.y}, true);
@@ -39,6 +39,7 @@ 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);
@@ -123,7 +124,7 @@ void CInputManager::onTouchMove(ITouch::SMotionEvent e) {
return;
}
if (validMapped(m_sTouchData.touchFocusWindow)) {
const auto PMONITOR = m_sTouchData.touchFocusWindow->m_pMonitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusWindow->m_iMonitorID);
g_pCompositor->warpCursorTo({PMONITOR->vecPosition.x + e.pos.x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e.pos.y * PMONITOR->vecSize.y}, true);
@@ -133,7 +134,7 @@ void CInputManager::onTouchMove(ITouch::SMotionEvent e) {
g_pSeatManager->sendTouchMotion(e.timeMs, e.touchID, local);
} else if (!m_sTouchData.touchFocusLS.expired()) {
const auto PMONITOR = m_sTouchData.touchFocusLS->monitor.lock();
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusLS->monitorID);
g_pCompositor->warpCursorTo({PMONITOR->vecPosition.x + e.pos.x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e.pos.y * PMONITOR->vecSize.y}, true);

View File

@@ -1,86 +0,0 @@
#include "CTMControl.hpp"
#include "../Compositor.hpp"
#include "core/Output.hpp"
CHyprlandCTMControlResource::CHyprlandCTMControlResource(SP<CHyprlandCtmControlManagerV1> resource_) : resource(resource_) {
if (!good())
return;
resource->setDestroy([this](CHyprlandCtmControlManagerV1* pMgr) { PROTO::ctm->destroyResource(this); });
resource->setOnDestroy([this](CHyprlandCtmControlManagerV1* pMgr) { PROTO::ctm->destroyResource(this); });
resource->setSetCtmForOutput([this](CHyprlandCtmControlManagerV1* r, wl_resource* output, wl_fixed_t mat0, wl_fixed_t mat1, wl_fixed_t mat2, wl_fixed_t mat3, wl_fixed_t mat4,
wl_fixed_t mat5, wl_fixed_t mat6, wl_fixed_t mat7, wl_fixed_t mat8) {
const auto OUTPUTRESOURCE = CWLOutputResource::fromResource(output);
if (!OUTPUTRESOURCE)
return; // ?!
const auto PMONITOR = OUTPUTRESOURCE->monitor.lock();
if (!PMONITOR)
return; // ?!?!
const std::array<float, 9> MAT = {wl_fixed_to_double(mat0), wl_fixed_to_double(mat1), wl_fixed_to_double(mat2), wl_fixed_to_double(mat3), wl_fixed_to_double(mat4),
wl_fixed_to_double(mat5), wl_fixed_to_double(mat6), wl_fixed_to_double(mat7), wl_fixed_to_double(mat8)};
for (auto& el : MAT) {
if (el < 0.F) {
resource->error(HYPRLAND_CTM_CONTROL_MANAGER_V1_ERROR_INVALID_MATRIX, "a matrix component was < 0");
return;
}
}
ctms[PMONITOR->szName] = MAT;
LOGM(LOG, "CTM set for output {}: {}", PMONITOR->szName, ctms.at(PMONITOR->szName).toString());
});
resource->setCommit([this](CHyprlandCtmControlManagerV1* r) {
LOGM(LOG, "Committing ctms to outputs");
for (auto& m : g_pCompositor->m_vMonitors) {
if (!ctms.contains(m->szName)) {
PROTO::ctm->setCTM(m, Mat3x3::identity());
continue;
}
PROTO::ctm->setCTM(m, ctms.at(m->szName));
}
});
}
CHyprlandCTMControlResource::~CHyprlandCTMControlResource() {
for (auto& m : g_pCompositor->m_vMonitors) {
PROTO::ctm->setCTM(m, Mat3x3::identity());
}
}
bool CHyprlandCTMControlResource::good() {
return resource->resource();
}
CHyprlandCTMControlProtocol::CHyprlandCTMControlProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
;
}
void CHyprlandCTMControlProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CHyprlandCTMControlResource>(makeShared<CHyprlandCtmControlManagerV1>(client, ver, id)));
if (!RESOURCE->good()) {
wl_client_post_no_memory(client);
m_vManagers.pop_back();
return;
}
LOGM(LOG, "New CTM Manager at 0x{:x}", (uintptr_t)RESOURCE.get());
}
void CHyprlandCTMControlProtocol::destroyResource(CHyprlandCTMControlResource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; });
}
void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) {
monitor->setCTM(ctm);
}

View File

@@ -1,44 +0,0 @@
#pragma once
#include <memory>
#include <vector>
#include <cstdint>
#include "WaylandProtocol.hpp"
#include "hyprland-ctm-control-v1.hpp"
#include <unordered_map>
class CMonitor;
class CHyprlandCTMControlResource {
public:
CHyprlandCTMControlResource(SP<CHyprlandCtmControlManagerV1> resource_);
~CHyprlandCTMControlResource();
bool good();
private:
SP<CHyprlandCtmControlManagerV1> resource;
std::unordered_map<std::string, Mat3x3> ctms;
};
class CHyprlandCTMControlProtocol : public IWaylandProtocol {
public:
CHyprlandCTMControlProtocol(const wl_interface* iface, const int& ver, const std::string& name);
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
private:
void destroyResource(CHyprlandCTMControlResource* resource);
void setCTM(PHLMONITOR monitor, const Mat3x3& ctm);
//
std::vector<SP<CHyprlandCTMControlResource>> m_vManagers;
friend class CHyprlandCTMControlResource;
};
namespace PROTO {
inline UP<CHyprlandCTMControlProtocol> ctm;
};

Some files were not shown because too many files have changed in this diff Show More