mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-16 04:23:49 -07:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
254fc2bc60 | ||
|
428862016c |
70
.github/ISSUE_TEMPLATE/bug.yml
vendored
70
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -5,7 +5,7 @@ body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Already reported ? *
|
||||
description: Before opening a new bug report, please take a moment to search through the current open issues. If the same bug is already reported, don't open new issue - instead go upvote/comment on an existing one.
|
||||
description: Before opening a new bug report, please take a moment to search through the current open and closed issues to check if it already exists.
|
||||
options:
|
||||
- label: I have searched the existing open and closed issues.
|
||||
required: true
|
||||
@@ -19,28 +19,27 @@ body:
|
||||
**BEFORE CONTINUING**, please check if this bug is a regression or not, and if it is, we need you to bisect with the help of the wiki: https://wiki.hyprland.org/Crashes-and-Bugs/#bisecting-an-issue
|
||||
multiple: true
|
||||
options:
|
||||
- "Definitely a regression - something broke after update (requires bisect)"
|
||||
- "Probably not a regression / I don't remember it happening before"
|
||||
- "Not a regression - it's bug regarding new feature"
|
||||
- "Not a regression - it's an old bug"
|
||||
- "I don't know, I started using Hyprland only recently"
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: ver
|
||||
attributes:
|
||||
label: System Info and Hyprland Version
|
||||
label: System Info and Version
|
||||
description: |
|
||||
Paste the output of `hyprctl systeminfo` here. If you can't
|
||||
Paste the output of `hyprctl systeminfo -c` here. If you can't
|
||||
launch Hyprland, paste the output of `Hyprland --systeminfo`.
|
||||
If `Hyprland --systeminfo` errors out (added in 0.44.0), find
|
||||
and paste the Hyprland version manually.
|
||||
value: "<details>
|
||||
<summary>System/Version info</summary>
|
||||
|
||||
|
||||
```
|
||||
```sh
|
||||
|
||||
<Paste the output of the command here, without removing any formatting around this>
|
||||
<Paste the output of the command here>
|
||||
|
||||
```
|
||||
|
||||
@@ -62,56 +61,15 @@ body:
|
||||
attributes:
|
||||
label: How to reproduce
|
||||
description: "How can someone else reproduce the issue?"
|
||||
placeholder: |
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Additional info section
|
||||
|
||||
In the section below you will be asked to upload some files.
|
||||
|
||||
When including text files (such as logs or config), please **always ATTACH** them, and not paste them directly.
|
||||
|
||||
This is important to avoid clutter, spam, and make the issues more readable.
|
||||
Thanks for your understanding.
|
||||
|
||||
# The main reason to disallow pasting directly or in a dropdown, is to not clutter
|
||||
# the issue with unnecessary keywords, making the github issue search useless.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Attach not paste
|
||||
options:
|
||||
- label: I understand that all text files must be *attached*, and not pasted directly. If not respected, this issue will likely get closed as spam
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >-
|
||||
Please be sure to upload the following files below if they are relevant to the issue:
|
||||
|
||||
- Logs can be found in $XDG_RUNTIME_DIR/hypr (sort by date to grab the latest)
|
||||
- Crash reports are stored in ~/.cache/hyprland or $XDG_CACHE_HOME/hyprland
|
||||
- Hyprland config files - `hyprctl systeminfo -c > /tmp/hyprland_config_dump.txt` use this command to dump full configuration to a single file.
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist of files to include below
|
||||
options:
|
||||
- label: Hyprland config - `hyprctl systeminfo -c` (always include)
|
||||
- label: Crash report (always include in case of crash)
|
||||
- label: Video (always include in case of a visual bug)
|
||||
- label: Logs (might contain useful info such as errors)
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Additional info & File uploads
|
||||
label: Crash reports, logs, images, videos
|
||||
description: |
|
||||
Tip: You can attach files by clicking this area to highlight it and then dragging files in.
|
||||
Anything that can help. Please always ATTACH and not paste them.
|
||||
Logs can be found in $XDG_RUNTIME_DIR/hypr
|
||||
Crash reports are stored in ~/.cache/hyprland or $XDG_CACHE_HOME/hyprland
|
||||
|
||||
|
9
.github/actions/setup_base/action.yml
vendored
9
.github/actions/setup_base/action.yml
vendored
@@ -63,15 +63,6 @@ runs:
|
||||
librsvg \
|
||||
re2
|
||||
|
||||
- name: Get glaze
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/stephenberry/glaze.git
|
||||
cd glaze
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
cmake --install build
|
||||
|
||||
- name: Get hyprwayland-scanner-git
|
||||
shell: bash
|
||||
run: |
|
||||
|
25
.github/workflows/ci.yaml
vendored
25
.github/workflows/ci.yaml
vendored
@@ -107,7 +107,6 @@ jobs:
|
||||
run: make release
|
||||
|
||||
clang-format:
|
||||
permissions: read-all
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork
|
||||
name: "Code Style (Arch)"
|
||||
runs-on: ubuntu-latest
|
||||
@@ -127,27 +126,3 @@ jobs:
|
||||
|
||||
- name: clang-format check
|
||||
run: ninja -C build clang-format-check
|
||||
|
||||
- name: clang-format apply
|
||||
if: ${{ failure() && github.event_name == 'pull_request' }}
|
||||
run: ninja -C build clang-format
|
||||
|
||||
- name: Create patch
|
||||
if: ${{ failure() && github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
echo 'Please fix the formatting issues by running [`clang-format`](https://wiki.hyprland.org/Contributing-and-Debugging/PR-Guidelines/#code-style), or directly apply this patch:' > clang-format.patch
|
||||
echo '<details>' >> clang-format.patch
|
||||
echo '<summary>clang-format.patch</summary>' >> clang-format.patch
|
||||
echo >> clang-format.patch
|
||||
echo '```diff' >> clang-format.patch
|
||||
git diff >> clang-format.patch
|
||||
echo '```' >> clang-format.patch
|
||||
echo >> clang-format.patch
|
||||
echo '</details>' >> clang-format.patch
|
||||
|
||||
- name: Comment patch
|
||||
if: ${{ failure() && github.event_name == 'pull_request' }}
|
||||
uses: mshick/add-pr-comment@v2
|
||||
with:
|
||||
message-path: |
|
||||
clang-format.patch
|
||||
|
@@ -104,7 +104,7 @@ find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
|
||||
pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.5)
|
||||
pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2)
|
||||
pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7)
|
||||
pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.4.0)
|
||||
pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.2.3)
|
||||
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1)
|
||||
|
||||
add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}")
|
||||
@@ -197,12 +197,6 @@ if(NOT HAS_TIMERFD AND epoll_FOUND)
|
||||
target_link_libraries(Hyprland PkgConfig::epoll)
|
||||
endif()
|
||||
|
||||
check_include_file("sys/inotify.h" HAS_INOTIFY)
|
||||
pkg_check_modules(inotify IMPORTED_TARGET libinotify)
|
||||
if(NOT HAS_INOTIFY AND inotify_FOUND)
|
||||
target_link_libraries(Hyprland PkgConfig::inotify)
|
||||
endif()
|
||||
|
||||
if(LEGACY_RENDERER)
|
||||
message(STATUS "Using the legacy GLES2 renderer!")
|
||||
add_compile_definitions(LEGACY_RENDERER)
|
||||
@@ -254,15 +248,7 @@ target_precompile_headers(Hyprland PRIVATE
|
||||
|
||||
message(STATUS "Setting link libraries")
|
||||
|
||||
target_link_libraries(
|
||||
Hyprland
|
||||
rt
|
||||
PkgConfig::aquamarine_dep
|
||||
PkgConfig::hyprlang_dep
|
||||
PkgConfig::hyprutils_dep
|
||||
PkgConfig::hyprcursor_dep
|
||||
PkgConfig::hyprgraphics_dep
|
||||
PkgConfig::deps)
|
||||
target_link_libraries(Hyprland rt PkgConfig::aquamarine_dep PkgConfig::hyprlang_dep PkgConfig::hyprutils_dep PkgConfig::hyprcursor_dep PkgConfig::hyprgraphics_dep PkgConfig::deps)
|
||||
if(udis_dep_FOUND)
|
||||
target_link_libraries(Hyprland PkgConfig::udis_dep)
|
||||
else()
|
||||
@@ -304,7 +290,7 @@ endfunction()
|
||||
|
||||
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads)
|
||||
|
||||
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.6.0)
|
||||
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.4.0)
|
||||
if(hyprland_protocols_dep_FOUND)
|
||||
pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir)
|
||||
message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}")
|
||||
@@ -330,12 +316,8 @@ protocolnew("protocols" "kde-server-decoration" true)
|
||||
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" "xx-color-management-v4" true)
|
||||
protocolnew("protocols" "frog-color-management-v1" true)
|
||||
protocolnew("protocols" "wayland-drm" true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-ctm-control-v1" true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-surface-v1" true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-lock-notify-v1" true)
|
||||
|
||||
protocolnew("staging/tearing-control" "tearing-control-v1" false)
|
||||
protocolnew("staging/fractional-scale" "fractional-scale-v1" false)
|
||||
@@ -373,13 +355,7 @@ protocolwayland()
|
||||
|
||||
# tools
|
||||
add_subdirectory(hyprctl)
|
||||
|
||||
if(NO_HYPRPM)
|
||||
message(STATUS "hyprpm is disabled")
|
||||
else()
|
||||
add_subdirectory(hyprpm)
|
||||
message(STATUS "hyprpm is enabled (NO_HYPRPM not defined)")
|
||||
endif()
|
||||
|
||||
# binary and symlink
|
||||
install(TARGETS Hyprland)
|
||||
@@ -390,6 +366,7 @@ install(
|
||||
${CMAKE_INSTALL_FULL_BINDIR}/Hyprland \
|
||||
\"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}/hyprland\" \
|
||||
)")
|
||||
|
||||
# session file
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.desktop
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions)
|
||||
|
@@ -81,7 +81,6 @@ general {
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
||||
decoration {
|
||||
rounding = 10
|
||||
rounding_power = 2
|
||||
|
||||
# Change transparency of focused and unfocused windows
|
||||
active_opacity = 1.0
|
||||
|
@@ -22,6 +22,5 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
]
|
||||
}
|
173
flake.lock
generated
173
flake.lock
generated
@@ -16,11 +16,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737636397,
|
||||
"narHash": "sha256-F5MbBj3QVorycVSFE9qjuOTLtIQBqt2VWbXa0uwzm98=",
|
||||
"lastModified": 1734364797,
|
||||
"narHash": "sha256-2h1c+P0v3l0Z/ypUSsAPhU/yiSRgFwjVFODWp0S3d/w=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "aquamarine",
|
||||
"rev": "7fe006981fae53e931f513026fc754e322f13145",
|
||||
"rev": "8e77618b403a82fde2105a8e3cd7cabe7ef00952",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -79,11 +79,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737634937,
|
||||
"narHash": "sha256-Ffw4ujFpi++6pPHe+gCBOfDgAoNlzVPZN6MReC1beu8=",
|
||||
"lastModified": 1734364709,
|
||||
"narHash": "sha256-+2bZJL2u5hva7rSp65OfKJBK+k03T6GB/NCvpoS1OOo=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprcursor",
|
||||
"rev": "9c5dd1f7c825ee47f72727ad0a4e16ca46a2688e",
|
||||
"rev": "f388aacd22be4a6e4d634fbaf6f75eb0713d239a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -105,11 +105,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737634889,
|
||||
"narHash": "sha256-9JZE3KxcXOqZH9zs3UeadngDiK/yIACTiAR8HSA/TNI=",
|
||||
"lastModified": 1733684019,
|
||||
"narHash": "sha256-2kYREgmSmbLsmDpLEq96hxVAU3qz8aCvVhF65yCFZHY=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprgraphics",
|
||||
"rev": "0d77b4895ad5f1bb3b0ee43103a5246c58b65591",
|
||||
"rev": "fb2c0268645a77403af3b8a4ce8fa7ba5917f15d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -128,11 +128,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737556638,
|
||||
"narHash": "sha256-laKgI3mr2qz6tas/q3tuGPxMdsGhBi/w+HO+hO2f1AY=",
|
||||
"lastModified": 1728345020,
|
||||
"narHash": "sha256-xGbkc7U/Roe0/Cv3iKlzijIaFBNguasI31ynL2IlEoM=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"rev": "4c75dd5c015c8a0e5a34c6d02a018a650f57feb5",
|
||||
"rev": "a7c183800e74f337753de186522b9017a07a8cee",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -141,35 +141,8 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-qt-support": {
|
||||
"inputs": {
|
||||
"hyprlang": "hyprlang",
|
||||
"nixpkgs": [
|
||||
"hyprland-qtutils",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland-qtutils",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737634706,
|
||||
"narHash": "sha256-nGCibkfsXz7ARx5R+SnisRtMq21IQIhazp6viBU8I/A=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-qt-support",
|
||||
"rev": "8810df502cdee755993cb803eba7b23f189db795",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-qt-support",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-qtutils": {
|
||||
"inputs": {
|
||||
"hyprland-qt-support": "hyprland-qt-support",
|
||||
"hyprutils": [
|
||||
"hyprutils"
|
||||
],
|
||||
@@ -181,11 +154,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737811848,
|
||||
"narHash": "sha256-WZ7LeiKHk5Y94MU5gHIWn0r8asWxYOvie4LqfCjVIZU=",
|
||||
"lastModified": 1733940128,
|
||||
"narHash": "sha256-hmfXWj2GA9cj1QUkPFYtAAeohhs615zL4E3APy3FnvQ=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-qtutils",
|
||||
"rev": "9c0831ff98856c0f312fcb8b57553fbe3dd34d5b",
|
||||
"rev": "3833097e50473a152dd614d4b468886840b4ea78",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -195,34 +168,6 @@
|
||||
}
|
||||
},
|
||||
"hyprlang": {
|
||||
"inputs": {
|
||||
"hyprutils": "hyprutils",
|
||||
"nixpkgs": [
|
||||
"hyprland-qtutils",
|
||||
"hyprland-qt-support",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland-qtutils",
|
||||
"hyprland-qt-support",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737634606,
|
||||
"narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"rev": "f41271d35cc0f370d300413d756c2677f386af9d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprlang_2": {
|
||||
"inputs": {
|
||||
"hyprutils": [
|
||||
"hyprutils"
|
||||
@@ -235,11 +180,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737634606,
|
||||
"narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=",
|
||||
"lastModified": 1734364628,
|
||||
"narHash": "sha256-ii8fzJfI953n/EmIxVvq64ZAwhvwuuPHWfGd61/mJG8=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"rev": "f41271d35cc0f370d300413d756c2677f386af9d",
|
||||
"rev": "16e59c1eb13d9fb6de066f54e7555eb5e8a4aba5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -249,35 +194,6 @@
|
||||
}
|
||||
},
|
||||
"hyprutils": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"hyprland-qtutils",
|
||||
"hyprland-qt-support",
|
||||
"hyprlang",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland-qtutils",
|
||||
"hyprland-qt-support",
|
||||
"hyprlang",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737632363,
|
||||
"narHash": "sha256-X9I8POSlHxBVjD0fiX1O2j7U9Zi1+4rIkrsyHP0uHXY=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "006620eb29d54ea9086538891404c78563d1bae1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprutils_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
@@ -287,11 +203,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737725508,
|
||||
"narHash": "sha256-jGmcPc6y/prg/4A8KGYqJ27nSPaProCMiFadaxNAKvA=",
|
||||
"lastModified": 1733502241,
|
||||
"narHash": "sha256-KAUNC4Dgq8WQjYov5auBw/usaHixhacvb7cRDd0AG/k=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "fb0c2d1de3d1ef7396d19c18ac09e12bd956929e",
|
||||
"rev": "104117aed6dd68561be38b50f218190aa47f2cd8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -310,11 +226,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1735493474,
|
||||
"narHash": "sha256-fktzv4NaqKm94VAkAoVqO/nqQlw+X0/tJJNAeCSfzK4=",
|
||||
"lastModified": 1726874836,
|
||||
"narHash": "sha256-VKR0sf0PSNCB0wPHVKSAn41mCNVCnegWmgkrneKDhHM=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprwayland-scanner",
|
||||
"rev": "de913476b59ee88685fdc018e77b8f6637a2ae0b",
|
||||
"rev": "500c81a9e1a76760371049a8d99e008ea77aa59e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -325,11 +241,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1737632463,
|
||||
"narHash": "sha256-38J9QfeGSej341ouwzqf77WIHAScihAKCt8PQJ+NH28=",
|
||||
"lastModified": 1734119587,
|
||||
"narHash": "sha256-AKU6qqskl0yf2+JdRdD0cfxX4b9x3KKV5RqA6wijmPM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0aa475546ed21629c4f5bbf90e38c846a99ec9e9",
|
||||
"rev": "3566ab7246670a43abd2ffa913cc62dad9cdf7d5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -339,20 +255,37 @@
|
||||
"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": 1737465171,
|
||||
"narHash": "sha256-R10v2hoJRLq8jcL4syVFag7nIGE7m13qO48wRIukWNg=",
|
||||
"lastModified": 1734279981,
|
||||
"narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "9364dc02281ce2d37a1f55b6e51f7c0f65a75f17",
|
||||
"rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -368,8 +301,8 @@
|
||||
"hyprgraphics": "hyprgraphics",
|
||||
"hyprland-protocols": "hyprland-protocols",
|
||||
"hyprland-qtutils": "hyprland-qtutils",
|
||||
"hyprlang": "hyprlang_2",
|
||||
"hyprutils": "hyprutils_2",
|
||||
"hyprlang": "hyprlang",
|
||||
"hyprutils": "hyprutils",
|
||||
"hyprwayland-scanner": "hyprwayland-scanner",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pre-commit-hooks": "pre-commit-hooks",
|
||||
@@ -414,11 +347,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737634991,
|
||||
"narHash": "sha256-dBAnb7Kbnier30cA7AgxVSxxARmxKZ1vHZT33THSIr8=",
|
||||
"lastModified": 1734124279,
|
||||
"narHash": "sha256-YNpFfiQjYt2o6LGcMN9NkjVvprC8ELrIpLHlbZbclRM=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "xdg-desktop-portal-hyprland",
|
||||
"rev": "e09dfe2726c8008f983e45a0aa1a3b7416aaeb8a",
|
||||
"rev": "0c6861f819f6d31f6195c9864709b2556f00b5cf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@@ -284,10 +284,8 @@ int requestHyprpaper(std::string arg) {
|
||||
void batchRequest(std::string arg, bool json) {
|
||||
std::string commands = arg.substr(arg.find_first_of(' ') + 1);
|
||||
|
||||
if (json) {
|
||||
if (json)
|
||||
RE2::GlobalReplace(&commands, ";\\s*", ";j/");
|
||||
commands.insert(0, "j/");
|
||||
}
|
||||
|
||||
std::string rq = "[[BATCH]]" + commands;
|
||||
request(rq);
|
||||
|
@@ -11,23 +11,9 @@ set(CMAKE_CXX_STANDARD 23)
|
||||
|
||||
pkg_check_modules(hyprpm_deps REQUIRED IMPORTED_TARGET tomlplusplus hyprutils>=0.2.4)
|
||||
|
||||
find_package(glaze QUIET)
|
||||
if (NOT glaze_FOUND)
|
||||
set(GLAZE_VERSION v4.2.3)
|
||||
message(STATUS "glaze dependency not found, retrieving ${GLAZE_VERSION} with FetchContent")
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
glaze
|
||||
GIT_REPOSITORY https://github.com/stephenberry/glaze.git
|
||||
GIT_TAG ${GLAZE_VERSION}
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(glaze)
|
||||
endif()
|
||||
|
||||
add_executable(hyprpm ${SRCFILES})
|
||||
|
||||
target_link_libraries(hyprpm PUBLIC PkgConfig::hyprpm_deps glaze::glaze)
|
||||
target_link_libraries(hyprpm PUBLIC PkgConfig::hyprpm_deps)
|
||||
|
||||
# binary
|
||||
install(TARGETS hyprpm)
|
||||
|
@@ -14,7 +14,7 @@ hyprpm [<FLAGS>]... <ARGUMENT>
|
||||
| (list) "List all installed plugins"
|
||||
| (enable <PLUGINS>) "Load a plugin"
|
||||
| (disable <PLUGINS>) "Unload a plugin"
|
||||
| (reload) "Reload plugins to match the enabled/disabled state. Use -f to force reload."
|
||||
| (reload) "Reload all plugins"
|
||||
;
|
||||
|
||||
<PLUGINS> ::= {{{ hyprpm list | awk '/Plugin/{print $4}' }}};
|
||||
|
@@ -1,10 +1,11 @@
|
||||
#include "DataState.hpp"
|
||||
#include <toml++/toml.hpp>
|
||||
#include <print>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include "PluginManager.hpp"
|
||||
|
||||
std::filesystem::path DataState::getDataStatePath() {
|
||||
std::string DataState::getDataStatePath() {
|
||||
const auto HOME = getenv("HOME");
|
||||
if (!HOME) {
|
||||
std::println(stderr, "DataState: no $HOME");
|
||||
@@ -15,29 +16,12 @@ std::filesystem::path DataState::getDataStatePath() {
|
||||
const auto XDG_DATA_HOME = getenv("XDG_DATA_HOME");
|
||||
|
||||
if (XDG_DATA_HOME)
|
||||
return std::filesystem::path{XDG_DATA_HOME} / "hyprpm";
|
||||
return std::filesystem::path{HOME} / ".local/share/hyprpm";
|
||||
return std::string{XDG_DATA_HOME} + "/hyprpm";
|
||||
return std::string{HOME} + "/.local/share/hyprpm";
|
||||
}
|
||||
|
||||
std::string DataState::getHeadersPath() {
|
||||
return getDataStatePath() / "headersRoot";
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> DataState::getPluginStates() {
|
||||
ensureStateStoreExists();
|
||||
|
||||
std::vector<std::filesystem::path> states;
|
||||
for (const auto& entry : std::filesystem::directory_iterator(getDataStatePath())) {
|
||||
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||
continue;
|
||||
|
||||
const auto stateFile = entry.path() / "state.toml";
|
||||
if (!std::filesystem::exists(stateFile))
|
||||
continue;
|
||||
|
||||
states.emplace_back(stateFile);
|
||||
}
|
||||
return states;
|
||||
return getDataStatePath() + "/headersRoot";
|
||||
}
|
||||
|
||||
void DataState::ensureStateStoreExists() {
|
||||
@@ -53,7 +37,7 @@ void DataState::ensureStateStoreExists() {
|
||||
void DataState::addNewPluginRepo(const SPluginRepository& repo) {
|
||||
ensureStateStoreExists();
|
||||
|
||||
const auto PATH = getDataStatePath() / repo.name;
|
||||
const auto PATH = getDataStatePath() + "/" + repo.name;
|
||||
|
||||
std::filesystem::create_directories(PATH);
|
||||
// clang-format off
|
||||
@@ -66,21 +50,19 @@ void DataState::addNewPluginRepo(const SPluginRepository& repo) {
|
||||
}}
|
||||
};
|
||||
for (auto const& p : repo.plugins) {
|
||||
const auto filename = p.name + ".so";
|
||||
|
||||
// copy .so to the good place
|
||||
if (std::filesystem::exists(p.filename))
|
||||
std::filesystem::copy_file(p.filename, PATH / filename);
|
||||
std::filesystem::copy_file(p.filename, PATH + "/" + p.name + ".so");
|
||||
|
||||
DATA.emplace(p.name, toml::table{
|
||||
{"filename", filename},
|
||||
{"filename", p.name + ".so"},
|
||||
{"enabled", p.enabled},
|
||||
{"failed", p.failed}
|
||||
});
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
std::ofstream ofs(PATH / "state.toml", std::ios::trunc);
|
||||
std::ofstream ofs(PATH + "/state.toml", std::ios::trunc);
|
||||
ofs << DATA;
|
||||
ofs.close();
|
||||
}
|
||||
@@ -90,8 +72,15 @@ bool DataState::pluginRepoExists(const std::string& urlOrName) {
|
||||
|
||||
const auto PATH = getDataStatePath();
|
||||
|
||||
for (const auto& stateFile : getPluginStates()) {
|
||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
||||
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||
continue;
|
||||
|
||||
if (!std::filesystem::exists(entry.path().string() + "/state.toml"))
|
||||
continue;
|
||||
|
||||
auto STATE = toml::parse_file(entry.path().string() + "/state.toml");
|
||||
|
||||
const auto NAME = STATE["repository"]["name"].value_or("");
|
||||
const auto URL = STATE["repository"]["url"].value_or("");
|
||||
|
||||
@@ -107,22 +96,29 @@ void DataState::removePluginRepo(const std::string& urlOrName) {
|
||||
|
||||
const auto PATH = getDataStatePath();
|
||||
|
||||
for (const auto& stateFile : getPluginStates()) {
|
||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
||||
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||
continue;
|
||||
|
||||
if (!std::filesystem::exists(entry.path().string() + "/state.toml"))
|
||||
continue;
|
||||
|
||||
auto STATE = toml::parse_file(entry.path().string() + "/state.toml");
|
||||
|
||||
const auto NAME = STATE["repository"]["name"].value_or("");
|
||||
const auto URL = STATE["repository"]["url"].value_or("");
|
||||
|
||||
if (URL == urlOrName || NAME == urlOrName) {
|
||||
|
||||
// unload the plugins!!
|
||||
for (const auto& file : std::filesystem::directory_iterator(stateFile.parent_path())) {
|
||||
for (const auto& file : std::filesystem::directory_iterator(entry.path())) {
|
||||
if (!file.path().string().ends_with(".so"))
|
||||
continue;
|
||||
|
||||
g_pPluginManager->loadUnloadPlugin(std::filesystem::absolute(file.path()), false);
|
||||
}
|
||||
|
||||
std::filesystem::remove_all(stateFile.parent_path());
|
||||
std::filesystem::remove_all(entry.path());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -143,7 +139,7 @@ void DataState::updateGlobalState(const SGlobalState& state) {
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
std::ofstream ofs(PATH / "state.toml", std::ios::trunc);
|
||||
std::ofstream ofs(PATH + "/state.toml", std::ios::trunc);
|
||||
ofs << DATA;
|
||||
ofs.close();
|
||||
}
|
||||
@@ -151,12 +147,12 @@ void DataState::updateGlobalState(const SGlobalState& state) {
|
||||
SGlobalState DataState::getGlobalState() {
|
||||
ensureStateStoreExists();
|
||||
|
||||
const auto stateFile = getDataStatePath() / "state.toml";
|
||||
const auto PATH = getDataStatePath();
|
||||
|
||||
if (!std::filesystem::exists(stateFile))
|
||||
if (!std::filesystem::exists(PATH + "/state.toml"))
|
||||
return SGlobalState{};
|
||||
|
||||
auto DATA = toml::parse_file(stateFile.c_str());
|
||||
auto DATA = toml::parse_file(PATH + "/state.toml");
|
||||
|
||||
SGlobalState state;
|
||||
state.headersHashCompiled = DATA["state"]["hash"].value_or("");
|
||||
@@ -171,8 +167,15 @@ std::vector<SPluginRepository> DataState::getAllRepositories() {
|
||||
const auto PATH = getDataStatePath();
|
||||
|
||||
std::vector<SPluginRepository> repos;
|
||||
for (const auto& stateFile : getPluginStates()) {
|
||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||
continue;
|
||||
|
||||
if (!std::filesystem::exists(entry.path().string() + "/state.toml"))
|
||||
continue;
|
||||
|
||||
auto STATE = toml::parse_file(entry.path().string() + "/state.toml");
|
||||
|
||||
const auto NAME = STATE["repository"]["name"].value_or("");
|
||||
const auto URL = STATE["repository"]["url"].value_or("");
|
||||
@@ -207,8 +210,15 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) {
|
||||
|
||||
const auto PATH = getDataStatePath();
|
||||
|
||||
for (const auto& stateFile : getPluginStates()) {
|
||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
||||
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||
continue;
|
||||
|
||||
if (!std::filesystem::exists(entry.path().string() + "/state.toml"))
|
||||
continue;
|
||||
|
||||
auto STATE = toml::parse_file(entry.path().string() + "/state.toml");
|
||||
|
||||
for (const auto& [key, val] : STATE) {
|
||||
if (key == "repository")
|
||||
continue;
|
||||
@@ -221,11 +231,10 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) {
|
||||
if (FAILED)
|
||||
return false;
|
||||
|
||||
auto modifiedState = STATE;
|
||||
(*modifiedState[key].as_table()).insert_or_assign("enabled", enabled);
|
||||
(*STATE[key].as_table()).insert_or_assign("enabled", enabled);
|
||||
|
||||
std::ofstream state(stateFile, std::ios::trunc);
|
||||
state << modifiedState;
|
||||
std::ofstream state(entry.path().string() + "/state.toml", std::ios::trunc);
|
||||
state << STATE;
|
||||
state.close();
|
||||
|
||||
return true;
|
||||
|
@@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Plugin.hpp"
|
||||
@@ -10,9 +9,8 @@ struct SGlobalState {
|
||||
};
|
||||
|
||||
namespace DataState {
|
||||
std::filesystem::path getDataStatePath();
|
||||
std::string getDataStatePath();
|
||||
std::string getHeadersPath();
|
||||
std::vector<std::filesystem::path> getPluginStates();
|
||||
void ensureStateStoreExists();
|
||||
void addNewPluginRepo(const SPluginRepository& repo);
|
||||
void removePluginRepo(const std::string& urlOrName);
|
||||
|
@@ -7,8 +7,10 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <print>
|
||||
#include <thread>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <format>
|
||||
@@ -19,7 +21,6 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <toml++/toml.hpp>
|
||||
#include <glaze/glaze.hpp>
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <hyprutils/os/Process.hpp>
|
||||
@@ -82,13 +83,13 @@ SHyprlandVersion CPluginManager::getHyprlandVersion(bool running) {
|
||||
hlbranch = hlbranch.substr(0, hlbranch.find(" at commit "));
|
||||
|
||||
std::string hldate = HLVERCALL.substr(HLVERCALL.find("Date: ") + 6);
|
||||
hldate = hldate.substr(0, hldate.find('\n'));
|
||||
hldate = hldate.substr(0, hldate.find("\n"));
|
||||
|
||||
std::string hlcommits;
|
||||
|
||||
if (HLVERCALL.contains("commits:")) {
|
||||
hlcommits = HLVERCALL.substr(HLVERCALL.find("commits:") + 9);
|
||||
hlcommits = hlcommits.substr(0, hlcommits.find(' '));
|
||||
hlcommits = hlcommits.substr(0, hlcommits.find(" "));
|
||||
}
|
||||
|
||||
int commits = 0;
|
||||
@@ -377,7 +378,7 @@ eHeadersErrors CPluginManager::headersValid() {
|
||||
|
||||
// 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);
|
||||
auto headers = execAndGet(cmd.c_str());
|
||||
|
||||
if (!headers.contains("-I/"))
|
||||
return HEADERS_MISSING;
|
||||
@@ -780,7 +781,7 @@ bool CPluginManager::disablePlugin(const std::string& name) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState(bool forceReload) {
|
||||
ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||
if (headersValid() != HEADERS_OK) {
|
||||
std::println(stderr, "\n{}", failureString("headers are not up-to-date, please run hyprpm update."));
|
||||
return LOADSTATE_HEADERS_OUTDATED;
|
||||
@@ -789,28 +790,35 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState(bool forceReload)
|
||||
const auto HOME = getenv("HOME");
|
||||
const auto HIS = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||
if (!HOME || !HIS) {
|
||||
std::println(stderr, "PluginManager: no $HOME or $HYPRLAND_INSTANCE_SIGNATURE");
|
||||
std::println(stderr, "PluginManager: no $HOME or HIS");
|
||||
return LOADSTATE_FAIL;
|
||||
}
|
||||
const auto HYPRPMPATH = DataState::getDataStatePath();
|
||||
const auto HYPRPMPATH = DataState::getDataStatePath() + "/";
|
||||
|
||||
const auto json = glz::read_json<glz::json_t::array_t>(execAndGet("hyprctl plugins list -j"));
|
||||
if (!json) {
|
||||
std::println(stderr, "PluginManager: couldn't parse hyprctl output");
|
||||
return LOADSTATE_FAIL;
|
||||
}
|
||||
auto pluginLines = execAndGet("hyprctl plugins list | grep Plugin");
|
||||
|
||||
std::vector<std::string> loadedPlugins;
|
||||
for (const auto& plugin : json.value()) {
|
||||
if (!plugin.is_object() || !plugin.contains("name")) {
|
||||
std::println(stderr, "PluginManager: couldn't parse plugin object");
|
||||
return LOADSTATE_FAIL;
|
||||
}
|
||||
loadedPlugins.emplace_back(plugin["name"].get<std::string>());
|
||||
}
|
||||
|
||||
std::println("{}", successString("Ensuring plugin load state"));
|
||||
|
||||
// iterate line by line
|
||||
while (!pluginLines.empty()) {
|
||||
auto plLine = pluginLines.substr(0, pluginLines.find('\n'));
|
||||
|
||||
if (pluginLines.find('\n') != std::string::npos)
|
||||
pluginLines = pluginLines.substr(pluginLines.find('\n') + 1);
|
||||
else
|
||||
pluginLines = "";
|
||||
|
||||
if (plLine.back() != ':')
|
||||
continue;
|
||||
|
||||
plLine = plLine.substr(7);
|
||||
plLine = plLine.substr(0, plLine.find(" by "));
|
||||
|
||||
loadedPlugins.push_back(plLine);
|
||||
}
|
||||
|
||||
// get state
|
||||
const auto REPOS = DataState::getAllRepositories();
|
||||
|
||||
@@ -841,11 +849,11 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState(bool forceReload)
|
||||
// (and Hyprland needs to restart)
|
||||
bool hyprlandVersionMismatch = false;
|
||||
|
||||
// unload disabled plugins (or all if forceReload is true)
|
||||
// unload disabled plugins
|
||||
for (auto const& p : loadedPlugins) {
|
||||
if (forceReload || !enabled(p)) {
|
||||
if (!enabled(p)) {
|
||||
// unload
|
||||
if (!loadUnloadPlugin(HYPRPMPATH / repoForName(p) / (p + ".so"), false)) {
|
||||
if (!loadUnloadPlugin(HYPRPMPATH + repoForName(p) + "/" + p + ".so", false)) {
|
||||
std::println("{}", infoString("{} will be unloaded after restarting Hyprland", p));
|
||||
hyprlandVersionMismatch = true;
|
||||
} else
|
||||
@@ -859,10 +867,10 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState(bool forceReload)
|
||||
if (!p.enabled)
|
||||
continue;
|
||||
|
||||
if (!forceReload && std::find_if(loadedPlugins.begin(), loadedPlugins.end(), [&](const auto& other) { return other == p.name; }) != loadedPlugins.end())
|
||||
if (std::find_if(loadedPlugins.begin(), loadedPlugins.end(), [&](const auto& other) { return other == p.name; }) != loadedPlugins.end())
|
||||
continue;
|
||||
|
||||
if (!loadUnloadPlugin(HYPRPMPATH / repoForName(p.name) / p.filename, true)) {
|
||||
if (!loadUnloadPlugin(HYPRPMPATH + repoForName(p.name) + "/" + p.filename, true)) {
|
||||
std::println("{}", infoString("{} will be loaded after restarting Hyprland", p.name));
|
||||
hyprlandVersionMismatch = true;
|
||||
} else
|
||||
|
@@ -51,7 +51,7 @@ class CPluginManager {
|
||||
|
||||
bool enablePlugin(const std::string& name);
|
||||
bool disablePlugin(const std::string& name);
|
||||
ePluginLoadStateReturn ensurePluginsLoadState(bool forceReload = false);
|
||||
ePluginLoadStateReturn ensurePluginsLoadState();
|
||||
|
||||
bool loadUnloadPlugin(const std::string& path, bool load);
|
||||
SHyprlandVersion getHyprlandVersion(bool running = true);
|
||||
|
@@ -73,7 +73,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
|
||||
if (command.empty()) {
|
||||
std::println(stderr, "{}", HELP);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_pPluginManager = std::make_unique<CPluginManager>();
|
||||
@@ -154,7 +154,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
if (ret != LOADSTATE_OK)
|
||||
return 1;
|
||||
} else if (command[0] == "reload") {
|
||||
auto ret = g_pPluginManager->ensurePluginsLoadState(force);
|
||||
auto ret = g_pPluginManager->ensurePluginsLoadState();
|
||||
|
||||
if (ret != LOADSTATE_OK && notify) {
|
||||
switch (ret) {
|
||||
@@ -165,7 +165,6 @@ int main(int argc, char** argv, char** envp) {
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return 1;
|
||||
} else if (notify && !notifyFail) {
|
||||
g_pPluginManager->notify(ICON_OK, 0, 4000, "[hyprpm] Loaded plugins");
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@ executable(
|
||||
dependency('hyprutils', version: '>= 0.1.1'),
|
||||
dependency('threads'),
|
||||
dependency('tomlplusplus'),
|
||||
dependency('glaze', method: 'cmake'),
|
||||
],
|
||||
install: true,
|
||||
)
|
||||
|
@@ -58,7 +58,6 @@ endif
|
||||
|
||||
backtrace_dep = cpp_compiler.find_library('execinfo', required: false)
|
||||
epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs
|
||||
inotify_dep = dependency('libinotify', required: false) # inotify on BSDs
|
||||
|
||||
re2 = dependency('re2', required: true)
|
||||
|
||||
@@ -102,14 +101,11 @@ endif
|
||||
subdir('protocols')
|
||||
subdir('src')
|
||||
subdir('hyprctl')
|
||||
subdir('hyprpm/src')
|
||||
subdir('assets')
|
||||
subdir('example')
|
||||
subdir('docs')
|
||||
|
||||
if get_option('hyprpm').enabled()
|
||||
subdir('hyprpm/src')
|
||||
endif
|
||||
|
||||
# Generate hyprland.pc
|
||||
pkg_install_dir = join_paths(get_option('datadir'), 'pkgconfig')
|
||||
|
||||
|
@@ -2,5 +2,4 @@ option('xwayland', type: 'feature', value: 'auto', description: 'Enable support
|
||||
option('systemd', type: 'feature', value: 'auto', description: 'Enable systemd integration')
|
||||
option('uwsm', type: 'feature', value: 'enabled', description: 'Enable uwsm integration (only if systemd is enabled)')
|
||||
option('legacy_renderer', type: 'feature', value: 'disabled', description: 'Enable legacy renderer')
|
||||
option('hyprpm', type: 'feature', value: 'enabled', description: 'Enable hyprpm')
|
||||
option('tracy_enable', type: 'boolean', value: false , description: 'Enable profiling')
|
||||
|
@@ -5,14 +5,12 @@
|
||||
pkg-config,
|
||||
pkgconf,
|
||||
makeWrapper,
|
||||
cmake,
|
||||
meson,
|
||||
ninja,
|
||||
aquamarine,
|
||||
binutils,
|
||||
cairo,
|
||||
git,
|
||||
glaze,
|
||||
hyprcursor,
|
||||
hyprgraphics,
|
||||
hyprland-protocols,
|
||||
@@ -52,12 +50,12 @@
|
||||
nvidiaPatches ? false,
|
||||
hidpiXWayland ? false,
|
||||
}: let
|
||||
inherit (builtins) baseNameOf foldl' readFile;
|
||||
inherit (builtins) baseNameOf foldl';
|
||||
inherit (lib.asserts) assertMsg;
|
||||
inherit (lib.attrsets) mapAttrsToList;
|
||||
inherit (lib.lists) flatten concatLists optional optionals;
|
||||
inherit (lib.sources) cleanSourceWith cleanSource;
|
||||
inherit (lib.strings) hasSuffix makeBinPath optionalString mesonBool mesonEnable trim;
|
||||
inherit (lib.strings) hasSuffix makeBinPath optionalString mesonBool mesonEnable;
|
||||
|
||||
adapters = flatten [
|
||||
stdenvAdapters.useMoldLinker
|
||||
@@ -93,7 +91,7 @@ in
|
||||
DATE = date;
|
||||
DIRTY = optionalString (commit == "") "dirty";
|
||||
HASH = commit;
|
||||
TAG = "v${trim (readFile "${finalAttrs.src}/VERSION")}";
|
||||
TAG = "v${builtins.readFile "${finalAttrs.src}/VERSION"}";
|
||||
|
||||
depsBuildBuild = [
|
||||
pkg-config
|
||||
@@ -104,7 +102,6 @@ in
|
||||
makeWrapper
|
||||
meson
|
||||
ninja
|
||||
cmake # needed for glaze
|
||||
pkg-config
|
||||
];
|
||||
|
||||
@@ -119,7 +116,6 @@ in
|
||||
aquamarine
|
||||
cairo
|
||||
git
|
||||
glaze
|
||||
hyprcursor
|
||||
hyprgraphics
|
||||
hyprland-protocols
|
||||
@@ -163,7 +159,6 @@ in
|
||||
"xwayland" = enableXWayland;
|
||||
"legacy_renderer" = legacyRenderer;
|
||||
"uwsm" = false;
|
||||
"hyprpm" = false;
|
||||
})
|
||||
(mapAttrsToList mesonBool {
|
||||
"b_pch" = false;
|
||||
|
209
nix/module.nix
209
nix/module.nix
@@ -7,206 +7,15 @@ inputs: {
|
||||
inherit (pkgs.stdenv.hostPlatform) system;
|
||||
cfg = config.programs.hyprland;
|
||||
|
||||
# basically 1:1 taken from https://github.com/nix-community/home-manager/blob/master/modules/services/window-managers/hyprland.nix
|
||||
toHyprconf = {
|
||||
attrs,
|
||||
indentLevel ? 0,
|
||||
importantPrefixes ? ["$"],
|
||||
}: let
|
||||
inherit
|
||||
(lib)
|
||||
all
|
||||
concatMapStringsSep
|
||||
concatStrings
|
||||
concatStringsSep
|
||||
filterAttrs
|
||||
foldl
|
||||
generators
|
||||
hasPrefix
|
||||
isAttrs
|
||||
isList
|
||||
mapAttrsToList
|
||||
replicate
|
||||
;
|
||||
|
||||
initialIndent = concatStrings (replicate indentLevel " ");
|
||||
|
||||
toHyprconf' = indent: attrs: let
|
||||
sections =
|
||||
filterAttrs (n: v: isAttrs v || (isList v && all isAttrs v)) attrs;
|
||||
|
||||
mkSection = n: attrs:
|
||||
if lib.isList attrs
|
||||
then (concatMapStringsSep "\n" (a: mkSection n a) attrs)
|
||||
else ''
|
||||
${indent}${n} {
|
||||
${toHyprconf' " ${indent}" attrs}${indent}}
|
||||
'';
|
||||
|
||||
mkFields = generators.toKeyValue {
|
||||
listsAsDuplicateKeys = true;
|
||||
inherit indent;
|
||||
};
|
||||
|
||||
allFields =
|
||||
filterAttrs (n: v: !(isAttrs v || (isList v && all isAttrs v)))
|
||||
attrs;
|
||||
|
||||
isImportantField = n: _:
|
||||
foldl (acc: prev:
|
||||
if hasPrefix prev n
|
||||
then true
|
||||
else acc)
|
||||
false
|
||||
importantPrefixes;
|
||||
|
||||
importantFields = filterAttrs isImportantField allFields;
|
||||
|
||||
fields =
|
||||
builtins.removeAttrs allFields
|
||||
(mapAttrsToList (n: _: n) importantFields);
|
||||
in
|
||||
mkFields importantFields
|
||||
+ concatStringsSep "\n" (mapAttrsToList mkSection sections)
|
||||
+ mkFields fields;
|
||||
in
|
||||
toHyprconf' initialIndent attrs;
|
||||
in {
|
||||
options = {
|
||||
programs.hyprland = {
|
||||
plugins = lib.mkOption {
|
||||
type = with lib.types; listOf (either package path);
|
||||
default = [];
|
||||
description = ''
|
||||
List of Hyprland plugins to use. Can either be packages or
|
||||
absolute plugin paths.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types; let
|
||||
valueType =
|
||||
nullOr (oneOf [
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
path
|
||||
(attrsOf valueType)
|
||||
(listOf valueType)
|
||||
])
|
||||
// {
|
||||
description = "Hyprland configuration value";
|
||||
};
|
||||
in
|
||||
valueType;
|
||||
default = {};
|
||||
description = ''
|
||||
Hyprland configuration written in Nix. Entries with the same key
|
||||
should be written as lists. Variables' and colors' names should be
|
||||
quoted. See <https://wiki.hyprland.org> for more examples.
|
||||
|
||||
::: {.note}
|
||||
Use the [](#programs.hyprland.plugins) option to
|
||||
declare plugins.
|
||||
:::
|
||||
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
decoration = {
|
||||
shadow_offset = "0 5";
|
||||
"col.shadow" = "rgba(00000099)";
|
||||
};
|
||||
|
||||
"$mod" = "SUPER";
|
||||
|
||||
bindm = [
|
||||
# mouse movements
|
||||
"$mod, mouse:272, movewindow"
|
||||
"$mod, mouse:273, resizewindow"
|
||||
"$mod ALT, mouse:272, resizewindow"
|
||||
];
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
# window resize
|
||||
bind = $mod, S, submap, resize
|
||||
|
||||
submap = resize
|
||||
binde = , right, resizeactive, 10 0
|
||||
binde = , left, resizeactive, -10 0
|
||||
binde = , up, resizeactive, 0 -10
|
||||
binde = , down, resizeactive, 0 10
|
||||
bind = , escape, submap, reset
|
||||
submap = reset
|
||||
'';
|
||||
description = ''
|
||||
Extra configuration lines to add to `/etc/xdg/hypr/hyprland.conf`.
|
||||
'';
|
||||
};
|
||||
|
||||
sourceFirst =
|
||||
lib.mkEnableOption ''
|
||||
putting source entries at the top of the configuration
|
||||
''
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
|
||||
importantPrefixes = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = ["$" "bezier" "name"] ++ lib.optionals cfg.sourceFirst ["source"];
|
||||
example = ["$" "bezier"];
|
||||
description = ''
|
||||
List of prefix of attributes to source at the top of the config.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
programs.hyprland = {
|
||||
package = lib.mkDefault inputs.self.packages.${system}.hyprland;
|
||||
portalPackage = lib.mkDefault (inputs.self.packages.${system}.xdg-desktop-portal-hyprland.override {
|
||||
package = inputs.self.packages.${system}.hyprland;
|
||||
portalPackage = inputs.self.packages.${system}.xdg-desktop-portal-hyprland.override {
|
||||
hyprland = cfg.finalPackage;
|
||||
});
|
||||
};
|
||||
in {
|
||||
config = {
|
||||
programs.hyprland = {
|
||||
package = lib.mkDefault package;
|
||||
portalPackage = lib.mkDefault portalPackage;
|
||||
};
|
||||
};
|
||||
}
|
||||
(lib.mkIf cfg.enable {
|
||||
environment.etc."xdg/hypr/hyprland.conf" = let
|
||||
shouldGenerate = cfg.extraConfig != "" || cfg.settings != {} || cfg.plugins != [];
|
||||
|
||||
pluginsToHyprconf = plugins:
|
||||
toHyprconf {
|
||||
attrs = {
|
||||
plugin = let
|
||||
mkEntry = entry:
|
||||
if lib.types.package.check entry
|
||||
then "${entry}/lib/lib${entry.pname}.so"
|
||||
else entry;
|
||||
in
|
||||
map mkEntry cfg.plugins;
|
||||
};
|
||||
inherit (cfg) importantPrefixes;
|
||||
};
|
||||
in
|
||||
lib.mkIf shouldGenerate {
|
||||
text =
|
||||
lib.optionalString (cfg.plugins != [])
|
||||
(pluginsToHyprconf cfg.plugins)
|
||||
+ lib.optionalString (cfg.settings != {})
|
||||
(toHyprconf {
|
||||
attrs = cfg.settings;
|
||||
inherit (cfg) importantPrefixes;
|
||||
})
|
||||
+ lib.optionalString (cfg.extraConfig != "") cfg.extraConfig;
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
@@ -1,366 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="frog_color_management_v1">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2023 Joshua Ashton for Valve Software
|
||||
Copyright © 2023 Xaver Hugl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="experimental color management protocol">
|
||||
The aim of this color management extension is to get HDR games working quickly,
|
||||
and have an easy way to test implementations in the wild before the upstream
|
||||
protocol is ready to be merged.
|
||||
For that purpose it's intentionally limited and cut down and does not serve
|
||||
all uses cases.
|
||||
</description>
|
||||
|
||||
<interface name="frog_color_management_factory_v1" version="1">
|
||||
<description summary="color management factory">
|
||||
The color management factory singleton creates color managed surface objects.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor"></request>
|
||||
|
||||
<request name="get_color_managed_surface">
|
||||
<description summary="create color management interface for surface">
|
||||
</description>
|
||||
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="target surface" />
|
||||
<arg name="callback" type="new_id" interface="frog_color_managed_surface"
|
||||
summary="new color managed surface object" />
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="frog_color_managed_surface" version="1">
|
||||
<description summary="color managed surface">
|
||||
Interface for changing surface color management and HDR state.
|
||||
|
||||
An implementation must: support every part of the version
|
||||
of the frog_color_managed_surface interface it exposes.
|
||||
Including all known enums associated with a given version.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy color managed surface">
|
||||
Destroying the color managed surface resets all known color
|
||||
state for the surface back to 'undefined' implementation-specific
|
||||
values.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="transfer_function">
|
||||
<description summary="known transfer functions">
|
||||
Extended information on the transfer functions described
|
||||
here can be found in the Khronos Data Format specification:
|
||||
https://registry.khronos.org/DataFormat/specs/1.3/dataformat.1.3.html
|
||||
</description>
|
||||
<entry name="undefined" value="0"
|
||||
summary="specifies undefined, implementation-specific handling of the surface's transfer function." />
|
||||
<entry name="srgb" value="1"
|
||||
summary="specifies the sRGB non-linear EOTF. An implementation may: display this as Gamma 2.2 for the purposes of being consistent with content rendering across displays, rendering_intent and user expectations." />
|
||||
<entry name="gamma_22" value="2" summary="specifies gamma 2.2 power curve as the EOTF" />
|
||||
<entry name="st2084_pq" value="3"
|
||||
summary="specifies the SMPTE ST2084 Perceptual Quantizer (PQ) EOTF" />
|
||||
<entry name="scrgb_linear" value="4"
|
||||
summary="specifies the scRGB (extended sRGB) linear EOTF. Note: Primaries outside the gamut triangle specified can be expressed with negative values for this transfer function." />
|
||||
</enum>
|
||||
|
||||
<request name="set_known_transfer_function">
|
||||
<description summary="sets a known transfer function for a surface" />
|
||||
<arg name="transfer_function" type="uint" enum="transfer_function"
|
||||
summary="transfer function for the surface" />
|
||||
</request>
|
||||
|
||||
<enum name="primaries">
|
||||
<description summary="known primaries" />
|
||||
<entry name="undefined" value="0"
|
||||
summary="specifies undefined, implementation-specific handling" />
|
||||
<entry name="rec709" value="1" summary="specifies Rec.709/sRGB primaries with D65 white point" />
|
||||
<entry name="rec2020" value="2"
|
||||
summary="specifies Rec.2020/HDR10 primaries with D65 white point" />
|
||||
</enum>
|
||||
|
||||
<request name="set_known_container_color_volume">
|
||||
<description summary="sets the container color volume (primaries) for a surface" />
|
||||
<arg name="primaries" type="uint" enum="primaries" summary="primaries for the surface" />
|
||||
</request>
|
||||
|
||||
<enum name="render_intent">
|
||||
<description summary="known render intents">
|
||||
Extended information on render intents described
|
||||
here can be found in ICC.1:2022:
|
||||
|
||||
https://www.color.org/specification/ICC.1-2022-05.pdf
|
||||
</description>
|
||||
<entry name="perceptual" value="0" summary="perceptual" />
|
||||
</enum>
|
||||
|
||||
<request name="set_render_intent">
|
||||
<description summary="sets the render intent for a surface">
|
||||
NOTE: On a surface with "perceptual" (default) render intent, handling of the container's
|
||||
color volume
|
||||
is implementation-specific, and may differ between different transfer functions it is paired
|
||||
with:
|
||||
ie. sRGB + 709 rendering may have it's primaries widened to more of the available display's
|
||||
gamut
|
||||
to be be more pleasing for the viewer.
|
||||
Compared to scRGB Linear + 709 being treated faithfully as 709
|
||||
(including utilizing negatives out of the 709 gamut triangle)
|
||||
</description>
|
||||
<arg name="render_intent" type="uint" enum="render_intent"
|
||||
summary="render intent for the surface" />
|
||||
</request>
|
||||
|
||||
<request name="set_hdr_metadata">
|
||||
<description summary="set HDR metadata for a surface">
|
||||
Forwards HDR metadata from the client to the compositor.
|
||||
|
||||
HDR Metadata Infoframe as per CTA 861.G spec.
|
||||
|
||||
Usage of this HDR metadata is implementation specific and
|
||||
outside of the scope of this protocol.
|
||||
</description>
|
||||
<arg name="mastering_display_primary_red_x" type="uint">
|
||||
<description summary="red primary x coordinate">
|
||||
Mastering Red Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_display_primary_red_y" type="uint">
|
||||
<description summary="red primary y coordinate">
|
||||
Mastering Red Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_display_primary_green_x" type="uint">
|
||||
<description summary="green primary x coordinate">
|
||||
Mastering Green Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_display_primary_green_y" type="uint">
|
||||
<description summary="green primary y coordinate">
|
||||
Mastering Green Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_display_primary_blue_x" type="uint">
|
||||
<description summary="blue primary x coordinate">
|
||||
Mastering Blue Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_display_primary_blue_y" type="uint">
|
||||
<description summary="blue primary y coordinate">
|
||||
Mastering Blue Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_white_point_x" type="uint">
|
||||
<description summary="white point x coordinate">
|
||||
Mastering White Point X Coordinate of the Data.
|
||||
|
||||
These are coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_white_point_y" type="uint">
|
||||
<description summary="white point y coordinate">
|
||||
Mastering White Point Y Coordinate of the Data.
|
||||
|
||||
These are coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="max_display_mastering_luminance" type="uint">
|
||||
<description summary="max display mastering luminance">
|
||||
Max Mastering Display Luminance.
|
||||
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="min_display_mastering_luminance" type="uint">
|
||||
<description summary="min display mastering luminance">
|
||||
Min Mastering Display Luminance.
|
||||
This value is coded as an unsigned 16-bit value in units of
|
||||
0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF
|
||||
represents 6.5535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="max_cll" type="uint">
|
||||
<description summary="max content light level">
|
||||
Max Content Light Level.
|
||||
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="max_fall" type="uint">
|
||||
<description summary="max frame average light level">
|
||||
Max Frame Average Light Level.
|
||||
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
</request>
|
||||
|
||||
<event name="preferred_metadata">
|
||||
<description summary="preferred metadata for a surface">
|
||||
Current preferred metadata for a surface.
|
||||
The application should use this information to tone-map its buffers
|
||||
to this target before committing.
|
||||
|
||||
This metadata does not necessarily correspond to any physical output, but
|
||||
rather what the compositor thinks would be best for a given surface.
|
||||
</description>
|
||||
<arg name="transfer_function" type="uint" enum="transfer_function">
|
||||
<description summary="output's current transfer function">
|
||||
Specifies a known transfer function that corresponds to the
|
||||
output the surface is targeting.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_red_x" type="uint">
|
||||
<description summary="red primary x coordinate">
|
||||
Output Red Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_red_y" type="uint">
|
||||
<description summary="red primary y coordinate">
|
||||
Output Red Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_green_x" type="uint">
|
||||
<description summary="green primary x coordinate">
|
||||
Output Green Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_green_y" type="uint">
|
||||
<description summary="green primary y coordinate">
|
||||
Output Green Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_blue_x" type="uint">
|
||||
<description summary="blue primary x coordinate">
|
||||
Output Blue Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_blue_y" type="uint">
|
||||
<description summary="blue primary y coordinate">
|
||||
Output Blue Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_white_point_x" type="uint">
|
||||
<description summary="white point x coordinate">
|
||||
Output White Point X Coordinate of the Data.
|
||||
|
||||
These are coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_white_point_y" type="uint">
|
||||
<description summary="white point y coordinate">
|
||||
Output White Point Y Coordinate of the Data.
|
||||
|
||||
These are coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="max_luminance" type="uint">
|
||||
<description summary="maximum luminance">
|
||||
Max Output Luminance
|
||||
The max luminance in nits that the output is capable of rendering in small areas.
|
||||
Content should: not exceed this value to avoid clipping.
|
||||
|
||||
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="min_luminance" type="uint">
|
||||
<description summary="minimum luminance">
|
||||
Min Output Luminance
|
||||
The min luminance that the output is capable of rendering.
|
||||
Content should: not exceed this value to avoid clipping.
|
||||
|
||||
This value is coded as an unsigned 16-bit value in units of
|
||||
0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF
|
||||
represents 6.5535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="max_full_frame_luminance" type="uint">
|
||||
<description summary="maximum full frame luminance">
|
||||
Max Full Frame Luminance
|
||||
The max luminance in nits that the output is capable of rendering for the
|
||||
full frame sustained.
|
||||
|
||||
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
</event>
|
||||
</interface>
|
||||
</protocol>
|
@@ -7,7 +7,7 @@ wayland_protos = dependency(
|
||||
|
||||
hyprland_protos = dependency(
|
||||
'hyprland-protocols',
|
||||
version: '>=0.6',
|
||||
version: '>=0.4',
|
||||
fallback: 'hyprland-protocols',
|
||||
)
|
||||
|
||||
@@ -33,14 +33,10 @@ protocols = [
|
||||
'wayland-drm.xml',
|
||||
'wlr-data-control-unstable-v1.xml',
|
||||
'wlr-screencopy-unstable-v1.xml',
|
||||
'xx-color-management-v4.xml',
|
||||
'frog-color-management-v1.xml',
|
||||
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',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-surface-v1.xml',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-lock-notify-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',
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -2,18 +2,14 @@
|
||||
|
||||
#include "Compositor.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "desktop/DesktopTypes.hpp"
|
||||
#include "helpers/Splashes.hpp"
|
||||
#include "config/ConfigValue.hpp"
|
||||
#include "config/ConfigWatcher.hpp"
|
||||
#include "managers/CursorManager.hpp"
|
||||
#include "managers/TokenManager.hpp"
|
||||
#include "managers/PointerManager.hpp"
|
||||
#include "managers/SeatManager.hpp"
|
||||
#include "managers/VersionKeeperManager.hpp"
|
||||
#include "managers/DonationNagManager.hpp"
|
||||
#include "managers/eventLoop/EventLoopManager.hpp"
|
||||
#include <algorithm>
|
||||
#include <aquamarine/output/Output.hpp>
|
||||
#include <bit>
|
||||
#include <ctime>
|
||||
@@ -21,23 +17,20 @@
|
||||
#include <print>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <ranges>
|
||||
#include <print>
|
||||
#include <unordered_set>
|
||||
#include "debug/HyprCtl.hpp"
|
||||
#include "debug/CrashReporter.hpp"
|
||||
#ifdef USES_SYSTEMD
|
||||
#include <helpers/SdDaemon.hpp> // for SdNotify
|
||||
#endif
|
||||
#include <ranges>
|
||||
#include "helpers/varlist/VarList.hpp"
|
||||
#include "helpers/fs/FsUtils.hpp"
|
||||
#include "protocols/FractionalScale.hpp"
|
||||
#include "protocols/PointerConstraints.hpp"
|
||||
#include "protocols/LayerShell.hpp"
|
||||
#include "protocols/XDGShell.hpp"
|
||||
#include "protocols/XDGOutput.hpp"
|
||||
#include "protocols/SecurityContext.hpp"
|
||||
#include "protocols/ColorManagement.hpp"
|
||||
#include "protocols/core/Compositor.hpp"
|
||||
#include "protocols/core/Subcompositor.hpp"
|
||||
#include "desktop/LayerSurface.hpp"
|
||||
@@ -46,24 +39,6 @@
|
||||
#include "helpers/ByteOperations.hpp"
|
||||
#include "render/decorations/CHyprGroupBarDecoration.hpp"
|
||||
|
||||
#include "managers/KeybindManager.hpp"
|
||||
#include "managers/SessionLockManager.hpp"
|
||||
#include "managers/XWaylandManager.hpp"
|
||||
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "render/OpenGL.hpp"
|
||||
#include "managers/input/InputManager.hpp"
|
||||
#include "managers/AnimationManager.hpp"
|
||||
#include "managers/EventManager.hpp"
|
||||
#include "managers/HookSystemManager.hpp"
|
||||
#include "managers/ProtocolManager.hpp"
|
||||
#include "managers/LayoutManager.hpp"
|
||||
#include "plugins/PluginSystem.hpp"
|
||||
#include "helpers/Watchdog.hpp"
|
||||
#include "hyprerror/HyprError.hpp"
|
||||
#include "debug/HyprNotificationOverlay.hpp"
|
||||
#include "debug/HyprDebugOverlay.hpp"
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <aquamarine/input/Input.hpp>
|
||||
|
||||
@@ -75,7 +50,7 @@
|
||||
using namespace Hyprutils::String;
|
||||
using namespace Aquamarine;
|
||||
|
||||
static int handleCritSignal(int signo, void* data) {
|
||||
int handleCritSignal(int signo, void* data) {
|
||||
Debug::log(LOG, "Hyprland received signal {}", signo);
|
||||
|
||||
if (signo == SIGTERM || signo == SIGINT || signo == SIGKILL)
|
||||
@@ -84,7 +59,7 @@ static int handleCritSignal(int signo, void* data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handleUnrecoverableSignal(int sig) {
|
||||
void handleUnrecoverableSignal(int sig) {
|
||||
|
||||
// remove our handlers
|
||||
signal(SIGABRT, SIG_DFL);
|
||||
@@ -108,7 +83,7 @@ static void handleUnrecoverableSignal(int sig) {
|
||||
abort();
|
||||
}
|
||||
|
||||
static void handleUserSignal(int sig) {
|
||||
void handleUserSignal(int sig) {
|
||||
if (sig == SIGUSR1) {
|
||||
// means we have to unwind a timed out event
|
||||
throw std::exception();
|
||||
@@ -128,7 +103,7 @@ static eLogLevel aqLevelToHl(Aquamarine::eBackendLogLevel level) {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
static void aqLog(Aquamarine::eBackendLogLevel level, std::string msg) {
|
||||
void aqLog(Aquamarine::eBackendLogLevel level, std::string msg) {
|
||||
Debug::log(aqLevelToHl(level), "[AQ] {}", msg);
|
||||
}
|
||||
|
||||
@@ -163,10 +138,7 @@ void CCompositor::restoreNofile() {
|
||||
Debug::log(ERR, "Failed restoring NOFILE limits");
|
||||
}
|
||||
|
||||
CCompositor::CCompositor(bool onlyConfig) : m_bOnlyConfigVerification(onlyConfig), m_iHyprlandPID(getpid()) {
|
||||
if (onlyConfig)
|
||||
return;
|
||||
|
||||
CCompositor::CCompositor() : m_iHyprlandPID(getpid()) {
|
||||
m_szHyprTempDataRoot = std::string{getenv("XDG_RUNTIME_DIR")} + "/hypr";
|
||||
|
||||
if (m_szHyprTempDataRoot.starts_with("/hypr")) {
|
||||
@@ -230,7 +202,7 @@ CCompositor::CCompositor(bool onlyConfig) : m_bOnlyConfigVerification(onlyConfig
|
||||
}
|
||||
|
||||
CCompositor::~CCompositor() {
|
||||
if (!m_bIsShuttingDown && !m_bOnlyConfigVerification)
|
||||
if (!m_bIsShuttingDown)
|
||||
cleanup();
|
||||
}
|
||||
|
||||
@@ -266,16 +238,6 @@ static bool filterGlobals(const wl_client* client, const wl_global* global, void
|
||||
//
|
||||
void CCompositor::initServer(std::string socketName, int socketFd) {
|
||||
|
||||
if (m_bOnlyConfigVerification) {
|
||||
g_pHookSystem = makeUnique<CHookSystemManager>();
|
||||
g_pKeybindManager = makeUnique<CKeybindManager>();
|
||||
g_pAnimationManager = makeUnique<CHyprAnimationManager>();
|
||||
g_pConfigManager = makeUnique<CConfigManager>();
|
||||
|
||||
std::println("\n\n======== Config parsing result:\n\n{}", g_pConfigManager->verify());
|
||||
return;
|
||||
}
|
||||
|
||||
m_sWLDisplay = wl_display_create();
|
||||
|
||||
wl_display_set_global_filter(m_sWLDisplay, ::filterGlobals, nullptr);
|
||||
@@ -463,7 +425,7 @@ void CCompositor::initAllSignals() {
|
||||
|
||||
for (auto const& m : m_vMonitors) {
|
||||
scheduleFrameForMonitor(m);
|
||||
m->applyMonitorRule(&m->activeMonitorRule, true);
|
||||
g_pHyprRenderer->applyMonitorRule(m, &m->activeMonitorRule, true);
|
||||
}
|
||||
|
||||
g_pConfigManager->m_bWantsMonitorReload = true;
|
||||
@@ -472,6 +434,11 @@ void CCompositor::initAllSignals() {
|
||||
Debug::log(LOG, "Session got deactivated!");
|
||||
|
||||
m_bSessionActive = false;
|
||||
|
||||
for (auto const& m : m_vMonitors) {
|
||||
m->noFrameSchedule = true;
|
||||
m->framesToSkip = 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
nullptr);
|
||||
@@ -567,10 +534,12 @@ void CCompositor::cleanup() {
|
||||
g_pProtocolManager.reset();
|
||||
g_pHyprRenderer.reset();
|
||||
g_pHyprOpenGL.reset();
|
||||
g_pThreadManager.reset();
|
||||
g_pConfigManager.reset();
|
||||
g_pLayoutManager.reset();
|
||||
g_pHyprError.reset();
|
||||
g_pConfigManager.reset();
|
||||
g_pAnimationManager.reset();
|
||||
g_pKeybindManager.reset();
|
||||
g_pHookSystem.reset();
|
||||
g_pWatchdog.reset();
|
||||
@@ -579,9 +548,6 @@ void CCompositor::cleanup() {
|
||||
g_pSeatManager.reset();
|
||||
g_pHyprCtl.reset();
|
||||
g_pEventLoopManager.reset();
|
||||
g_pVersionKeeperMgr.reset();
|
||||
g_pDonationNagManager.reset();
|
||||
g_pConfigWatcher.reset();
|
||||
|
||||
if (m_pAqBackend)
|
||||
m_pAqBackend.reset();
|
||||
@@ -599,92 +565,92 @@ void CCompositor::initManagers(eManagersInitStage stage) {
|
||||
switch (stage) {
|
||||
case STAGE_PRIORITY: {
|
||||
Debug::log(LOG, "Creating the EventLoopManager!");
|
||||
g_pEventLoopManager = makeUnique<CEventLoopManager>(m_sWLDisplay, m_sWLEventLoop);
|
||||
g_pEventLoopManager = std::make_unique<CEventLoopManager>(m_sWLDisplay, m_sWLEventLoop);
|
||||
|
||||
Debug::log(LOG, "Creating the HookSystem!");
|
||||
g_pHookSystem = makeUnique<CHookSystemManager>();
|
||||
g_pHookSystem = std::make_unique<CHookSystemManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the KeybindManager!");
|
||||
g_pKeybindManager = makeUnique<CKeybindManager>();
|
||||
g_pKeybindManager = std::make_unique<CKeybindManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the AnimationManager!");
|
||||
g_pAnimationManager = makeUnique<CHyprAnimationManager>();
|
||||
g_pAnimationManager = std::make_unique<CAnimationManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the ConfigManager!");
|
||||
g_pConfigManager = makeUnique<CConfigManager>();
|
||||
g_pConfigManager = std::make_unique<CConfigManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the CHyprError!");
|
||||
g_pHyprError = makeUnique<CHyprError>();
|
||||
g_pHyprError = std::make_unique<CHyprError>();
|
||||
|
||||
Debug::log(LOG, "Creating the LayoutManager!");
|
||||
g_pLayoutManager = makeUnique<CLayoutManager>();
|
||||
g_pLayoutManager = std::make_unique<CLayoutManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the TokenManager!");
|
||||
g_pTokenManager = makeUnique<CTokenManager>();
|
||||
g_pTokenManager = std::make_unique<CTokenManager>();
|
||||
|
||||
g_pConfigManager->init();
|
||||
g_pWatchdog = makeUnique<CWatchdog>(); // requires config
|
||||
g_pWatchdog = std::make_unique<CWatchdog>(); // requires config
|
||||
// wait for watchdog to initialize to not hit data races in reading config values.
|
||||
while (!g_pWatchdog->m_bWatchdogInitialized) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Creating the PointerManager!");
|
||||
g_pPointerManager = makeUnique<CPointerManager>();
|
||||
g_pPointerManager = std::make_unique<CPointerManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the EventManager!");
|
||||
g_pEventManager = makeUnique<CEventManager>();
|
||||
g_pEventManager = std::make_unique<CEventManager>();
|
||||
} break;
|
||||
case STAGE_BASICINIT: {
|
||||
Debug::log(LOG, "Creating the CHyprOpenGLImpl!");
|
||||
g_pHyprOpenGL = makeUnique<CHyprOpenGLImpl>();
|
||||
g_pHyprOpenGL = std::make_unique<CHyprOpenGLImpl>();
|
||||
|
||||
Debug::log(LOG, "Creating the ProtocolManager!");
|
||||
g_pProtocolManager = makeUnique<CProtocolManager>();
|
||||
g_pProtocolManager = std::make_unique<CProtocolManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the SeatManager!");
|
||||
g_pSeatManager = makeUnique<CSeatManager>();
|
||||
g_pSeatManager = std::make_unique<CSeatManager>();
|
||||
} break;
|
||||
case STAGE_LATE: {
|
||||
Debug::log(LOG, "Creating the ThreadManager!");
|
||||
g_pThreadManager = std::make_unique<CThreadManager>();
|
||||
|
||||
Debug::log(LOG, "Creating CHyprCtl");
|
||||
g_pHyprCtl = makeUnique<CHyprCtl>();
|
||||
g_pHyprCtl = std::make_unique<CHyprCtl>();
|
||||
|
||||
Debug::log(LOG, "Creating the InputManager!");
|
||||
g_pInputManager = makeUnique<CInputManager>();
|
||||
g_pInputManager = std::make_unique<CInputManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the HyprRenderer!");
|
||||
g_pHyprRenderer = makeUnique<CHyprRenderer>();
|
||||
g_pHyprRenderer = std::make_unique<CHyprRenderer>();
|
||||
|
||||
Debug::log(LOG, "Creating the XWaylandManager!");
|
||||
g_pXWaylandManager = makeUnique<CHyprXWaylandManager>();
|
||||
g_pXWaylandManager = std::make_unique<CHyprXWaylandManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the SessionLockManager!");
|
||||
g_pSessionLockManager = makeUnique<CSessionLockManager>();
|
||||
g_pSessionLockManager = std::make_unique<CSessionLockManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the HyprDebugOverlay!");
|
||||
g_pDebugOverlay = makeUnique<CHyprDebugOverlay>();
|
||||
g_pDebugOverlay = std::make_unique<CHyprDebugOverlay>();
|
||||
|
||||
Debug::log(LOG, "Creating the HyprNotificationOverlay!");
|
||||
g_pHyprNotificationOverlay = makeUnique<CHyprNotificationOverlay>();
|
||||
g_pHyprNotificationOverlay = std::make_unique<CHyprNotificationOverlay>();
|
||||
|
||||
Debug::log(LOG, "Creating the PluginSystem!");
|
||||
g_pPluginSystem = makeUnique<CPluginSystem>();
|
||||
g_pPluginSystem = std::make_unique<CPluginSystem>();
|
||||
g_pConfigManager->handlePluginLoads();
|
||||
|
||||
Debug::log(LOG, "Creating the DecorationPositioner!");
|
||||
g_pDecorationPositioner = makeUnique<CDecorationPositioner>();
|
||||
g_pDecorationPositioner = std::make_unique<CDecorationPositioner>();
|
||||
|
||||
Debug::log(LOG, "Creating the CursorManager!");
|
||||
g_pCursorManager = makeUnique<CCursorManager>();
|
||||
g_pCursorManager = std::make_unique<CCursorManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the VersionKeeper!");
|
||||
g_pVersionKeeperMgr = makeUnique<CVersionKeeperManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the DonationNag!");
|
||||
g_pDonationNagManager = makeUnique<CDonationNagManager>();
|
||||
g_pVersionKeeperMgr = std::make_unique<CVersionKeeperManager>();
|
||||
|
||||
Debug::log(LOG, "Starting XWayland");
|
||||
g_pXWayland = makeUnique<CXWayland>(g_pCompositor->m_bWantsXwayland);
|
||||
g_pXWayland = std::make_unique<CXWayland>(g_pCompositor->m_bEnableXwayland);
|
||||
} break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
@@ -1003,11 +969,11 @@ SP<CWLSurfaceResource> CCompositor::vectorWindowToSurface(const Vector2D& pos, P
|
||||
|
||||
if (PPOPUP) {
|
||||
const auto OFF = PPOPUP->coordsRelativeToParent();
|
||||
sl = pos - pWindow->m_vRealPosition->goal() - OFF;
|
||||
sl = pos - pWindow->m_vRealPosition.goal() - OFF;
|
||||
return PPOPUP->m_pWLSurface->resource();
|
||||
}
|
||||
|
||||
auto [surf, local] = pWindow->m_pWLSurface->resource()->at(pos - pWindow->m_vRealPosition->goal(), true);
|
||||
auto [surf, local] = pWindow->m_pWLSurface->resource()->at(pos - pWindow->m_vRealPosition.goal(), true);
|
||||
if (surf) {
|
||||
sl = local;
|
||||
return surf;
|
||||
@@ -1021,7 +987,7 @@ Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindo
|
||||
return {};
|
||||
|
||||
if (pWindow->m_bIsX11)
|
||||
return vec - pWindow->m_vRealPosition->goal();
|
||||
return vec - pWindow->m_vRealPosition.goal();
|
||||
|
||||
const auto PPOPUP = pWindow->m_pPopupHead->at(vec);
|
||||
if (PPOPUP)
|
||||
@@ -1040,9 +1006,9 @@ Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindo
|
||||
CBox geom = pWindow->m_pXDGSurface->current.geometry;
|
||||
|
||||
if (std::get<1>(iterData) == Vector2D{-1337, -1337})
|
||||
return vec - pWindow->m_vRealPosition->goal();
|
||||
return vec - pWindow->m_vRealPosition.goal();
|
||||
|
||||
return vec - pWindow->m_vRealPosition->goal() - std::get<1>(iterData) + Vector2D{geom.x, geom.y};
|
||||
return vec - pWindow->m_vRealPosition.goal() - std::get<1>(iterData) + Vector2D{geom.x, geom.y};
|
||||
}
|
||||
|
||||
PHLMONITOR CCompositor::getMonitorFromOutput(SP<Aquamarine::IOutput> out) {
|
||||
@@ -1131,7 +1097,6 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
||||
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
||||
// This is to fix incorrect feedback on the focus history.
|
||||
PWORKSPACE->m_pLastFocusedWindow = pWindow;
|
||||
if (m_pLastMonitor->activeWorkspace)
|
||||
PWORKSPACE->rememberPrevWorkspace(m_pLastMonitor->activeWorkspace);
|
||||
if (PWORKSPACE->m_bIsSpecialWorkspace)
|
||||
m_pLastMonitor->changeWorkspace(PWORKSPACE, false, true); // if special ws, open on current monitor
|
||||
@@ -1168,7 +1133,6 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
||||
g_pXWaylandManager->activateWindow(pWindow, true); // sets the m_pLastWindow
|
||||
|
||||
pWindow->updateDynamicRules();
|
||||
pWindow->onFocusAnimUpdate();
|
||||
|
||||
updateWindowAnimatedDecorationValues(pWindow);
|
||||
|
||||
@@ -1251,7 +1215,7 @@ void CCompositor::focusSurface(SP<CWLSurfaceResource> pSurface, PHLWINDOW pWindo
|
||||
SP<CWLSurfaceResource> CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, PHLMONITOR monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
|
||||
for (auto const& lsl : monitor->m_aLayerSurfaceLayers | std::views::reverse) {
|
||||
for (auto const& ls : lsl | std::views::reverse) {
|
||||
if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->mapped) || ls->alpha->value() == 0.f)
|
||||
if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->mapped) || ls->alpha.value() == 0.f)
|
||||
continue;
|
||||
|
||||
auto SURFACEAT = ls->popupHead->at(pos, true);
|
||||
@@ -1269,7 +1233,7 @@ SP<CWLSurfaceResource> CCompositor::vectorToLayerPopupSurface(const Vector2D& po
|
||||
|
||||
SP<CWLSurfaceResource> CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<PHLLSREF>* layerSurfaces, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
|
||||
for (auto const& ls : *layerSurfaces | std::views::reverse) {
|
||||
if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha->value() == 0.f)
|
||||
if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.value() == 0.f)
|
||||
continue;
|
||||
|
||||
auto [surf, local] = ls->layerSurface->surface->at(pos - ls->geometry.pos(), true);
|
||||
@@ -1418,7 +1382,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) {
|
||||
if (w->monitorID() != monid && w->m_pMonitor)
|
||||
continue;
|
||||
|
||||
if (!w->m_bFadingOut || w->m_fAlpha->value() == 0.f) {
|
||||
if (!w->m_bFadingOut || w->m_fAlpha.value() == 0.f) {
|
||||
|
||||
w->m_bFadingOut = false;
|
||||
|
||||
@@ -1500,21 +1464,7 @@ void CCompositor::addToFadingOutSafe(PHLWINDOW pWindow) {
|
||||
}
|
||||
|
||||
PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) {
|
||||
if (!isDirection(dir))
|
||||
return nullptr;
|
||||
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return nullptr; // ??
|
||||
|
||||
const auto WINDOWIDEALBB = pWindow->isFullscreen() ? CBox{PMONITOR->vecPosition, PMONITOR->vecSize} : pWindow->getWindowIdealBoundingBoxIgnoreReserved();
|
||||
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
||||
|
||||
return getWindowInDirection(WINDOWIDEALBB, PWORKSPACE, dir, pWindow, pWindow->m_bIsFloating);
|
||||
}
|
||||
|
||||
PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorkspace, char dir, PHLWINDOW ignoreWindow, bool useVectorAngles) {
|
||||
if (!isDirection(dir))
|
||||
return nullptr;
|
||||
|
||||
@@ -1522,24 +1472,34 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks
|
||||
static auto PMETHOD = CConfigValue<Hyprlang::INT>("binds:focus_preferred_method");
|
||||
static auto PMONITORFALLBACK = CConfigValue<Hyprlang::INT>("binds:window_direction_monitor_fallback");
|
||||
|
||||
const auto POSA = box.pos();
|
||||
const auto SIZEA = box.size();
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return nullptr; // ??
|
||||
|
||||
const auto WINDOWIDEALBB = pWindow->isFullscreen() ? CBox{PMONITOR->vecPosition, PMONITOR->vecSize} : pWindow->getWindowIdealBoundingBoxIgnoreReserved();
|
||||
|
||||
const auto POSA = Vector2D(WINDOWIDEALBB.x, WINDOWIDEALBB.y);
|
||||
const auto SIZEA = Vector2D(WINDOWIDEALBB.width, WINDOWIDEALBB.height);
|
||||
|
||||
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
||||
auto leaderValue = -1;
|
||||
PHLWINDOW leaderWindow = nullptr;
|
||||
|
||||
if (!useVectorAngles) {
|
||||
if (!pWindow->m_bIsFloating) {
|
||||
|
||||
// for tiled windows, we calc edges
|
||||
for (auto const& w : m_vWindows) {
|
||||
if (w == ignoreWindow || !w->m_pWorkspace || !w->m_bIsMapped || w->isHidden() || (!w->isFullscreen() && w->m_bIsFloating) || !w->m_pWorkspace->isVisible())
|
||||
if (w == pWindow || !w->m_pWorkspace || !w->m_bIsMapped || w->isHidden() || (!w->isFullscreen() && w->m_bIsFloating) || !w->m_pWorkspace->isVisible())
|
||||
continue;
|
||||
|
||||
if (pWorkspace->m_pMonitor == w->m_pMonitor && pWorkspace != w->m_pWorkspace)
|
||||
if (pWindow->m_pMonitor == w->m_pMonitor && pWindow->m_pWorkspace != w->m_pWorkspace)
|
||||
continue;
|
||||
|
||||
if (pWorkspace->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen)
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen)
|
||||
continue;
|
||||
|
||||
if (!*PMONITORFALLBACK && pWorkspace->m_pMonitor != w->m_pMonitor)
|
||||
if (!*PMONITORFALLBACK && pWindow->m_pMonitor != w->m_pMonitor)
|
||||
continue;
|
||||
|
||||
const auto BWINDOWIDEALBB = w->getWindowIdealBoundingBoxIgnoreReserved();
|
||||
@@ -1601,6 +1561,9 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// for floating windows, we calculate best distance and angle.
|
||||
// if there is a window with angle better than THRESHOLD, only distance counts
|
||||
|
||||
if (dir == 'u')
|
||||
dir = 't';
|
||||
if (dir == 'd')
|
||||
@@ -1619,20 +1582,20 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks
|
||||
constexpr float THRESHOLD = 0.3 * M_PI;
|
||||
|
||||
for (auto const& w : m_vWindows) {
|
||||
if (w == ignoreWindow || !w->m_bIsMapped || !w->m_pWorkspace || w->isHidden() || (!w->isFullscreen() && !w->m_bIsFloating) || !w->m_pWorkspace->isVisible())
|
||||
if (w == pWindow || !w->m_bIsMapped || !w->m_pWorkspace || w->isHidden() || (!w->isFullscreen() && !w->m_bIsFloating) || !w->m_pWorkspace->isVisible())
|
||||
continue;
|
||||
|
||||
if (pWorkspace->m_pMonitor == w->m_pMonitor && pWorkspace != w->m_pWorkspace)
|
||||
if (pWindow->m_pMonitor == w->m_pMonitor && pWindow->m_pWorkspace != w->m_pWorkspace)
|
||||
continue;
|
||||
|
||||
if (pWorkspace->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen)
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen)
|
||||
continue;
|
||||
|
||||
if (!*PMONITORFALLBACK && pWorkspace->m_pMonitor != w->m_pMonitor)
|
||||
if (!*PMONITORFALLBACK && pWindow->m_pMonitor != w->m_pMonitor)
|
||||
continue;
|
||||
|
||||
const auto DIST = w->middle().distance(box.middle());
|
||||
const auto ANGLE = vectorAngles(Vector2D{w->middle() - box.middle()}, VECTORS.at(dir));
|
||||
const auto DIST = w->middle().distance(pWindow->middle());
|
||||
const auto ANGLE = vectorAngles(Vector2D{w->middle() - pWindow->middle()}, VECTORS.at(dir));
|
||||
|
||||
if (ANGLE > M_PI_2)
|
||||
continue; // if the angle is over 90 degrees, ignore. Wrong direction entirely.
|
||||
@@ -1644,8 +1607,8 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks
|
||||
}
|
||||
}
|
||||
|
||||
if (!leaderWindow && pWorkspace->m_bHasFullscreenWindow)
|
||||
leaderWindow = pWorkspace->getFullscreenWindow();
|
||||
if (!leaderWindow && PWORKSPACE->m_bHasFullscreenWindow)
|
||||
leaderWindow = PWORKSPACE->getFullscreenWindow();
|
||||
}
|
||||
|
||||
if (leaderValue != -1)
|
||||
@@ -1654,37 +1617,62 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating, bool visible) {
|
||||
auto it = std::ranges::find(m_vWindows, pWindow);
|
||||
const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(pWindow, w, focusableOnly, floating, visible); };
|
||||
const auto IN_RIGHT = std::find_if(it, m_vWindows.end(), FINDER);
|
||||
if (IN_RIGHT != m_vWindows.end())
|
||||
return *IN_RIGHT;
|
||||
const auto IN_LEFT = std::find_if(m_vWindows.begin(), it, FINDER);
|
||||
return *IN_LEFT;
|
||||
PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
|
||||
bool gotToWindow = false;
|
||||
for (auto const& w : m_vWindows) {
|
||||
if (w != pWindow && !gotToWindow)
|
||||
continue;
|
||||
|
||||
if (w == pWindow) {
|
||||
gotToWindow = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating, bool visible) {
|
||||
auto it = std::ranges::find(std::ranges::reverse_view(m_vWindows), pWindow);
|
||||
const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(pWindow, w, focusableOnly, floating, visible); };
|
||||
const auto IN_LEFT = std::find_if(it, m_vWindows.rend(), FINDER);
|
||||
if (IN_LEFT != m_vWindows.rend())
|
||||
return *IN_LEFT;
|
||||
const auto IN_RIGHT = std::find_if(m_vWindows.rbegin(), it, FINDER);
|
||||
return *IN_RIGHT;
|
||||
if (floating.has_value() && w->m_bIsFloating != floating.value())
|
||||
continue;
|
||||
|
||||
if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()))
|
||||
return w;
|
||||
}
|
||||
|
||||
inline static bool isWorkspaceMatches(PHLWINDOW pWindow, const PHLWINDOW w, bool anyWorkspace) {
|
||||
return anyWorkspace ? w->m_pWorkspace && w->m_pWorkspace->isVisible() : w->m_pWorkspace == pWindow->m_pWorkspace;
|
||||
for (auto const& w : m_vWindows) {
|
||||
if (floating.has_value() && w->m_bIsFloating != floating.value())
|
||||
continue;
|
||||
|
||||
if (w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()))
|
||||
return w;
|
||||
}
|
||||
|
||||
inline static bool isFloatingMatches(PHLWINDOW w, std::optional<bool> floating) {
|
||||
return !floating.has_value() || w->m_bIsFloating == floating.value();
|
||||
};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CCompositor::isWindowAvailableForCycle(PHLWINDOW pWindow, const PHLWINDOW w, bool focusableOnly, std::optional<bool> floating, bool anyWorkspace) {
|
||||
return isFloatingMatches(w, floating) && w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_bIsMapped && !w->isHidden() &&
|
||||
(!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault());
|
||||
PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating) {
|
||||
bool gotToWindow = false;
|
||||
for (auto const& w : m_vWindows | std::views::reverse) {
|
||||
if (w != pWindow && !gotToWindow)
|
||||
continue;
|
||||
|
||||
if (w == pWindow) {
|
||||
gotToWindow = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (floating.has_value() && w->m_bIsFloating != floating.value())
|
||||
continue;
|
||||
|
||||
if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()))
|
||||
return w;
|
||||
}
|
||||
|
||||
for (auto const& w : m_vWindows | std::views::reverse) {
|
||||
if (floating.has_value() && w->m_bIsFloating != floating.value())
|
||||
continue;
|
||||
|
||||
if (w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()))
|
||||
return w;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() {
|
||||
@@ -1719,8 +1707,12 @@ PHLWORKSPACE CCompositor::getWorkspaceByString(const std::string& str) {
|
||||
}
|
||||
|
||||
bool CCompositor::isPointOnAnyMonitor(const Vector2D& point) {
|
||||
return std::ranges::any_of(
|
||||
m_vMonitors, [&](const PHLMONITOR& m) { return VECINRECT(point, m->vecPosition.x, m->vecPosition.y, m->vecSize.x + m->vecPosition.x, m->vecSize.y + m->vecPosition.y); });
|
||||
for (auto const& m : m_vMonitors) {
|
||||
if (VECINRECT(point, m->vecPosition.x, m->vecPosition.y, m->vecSize.x + m->vecPosition.x, m->vecSize.y + m->vecPosition.y))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCompositor::isPointOnReservedArea(const Vector2D& point, const PHLMONITOR pMonitor) {
|
||||
@@ -1842,8 +1834,8 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) {
|
||||
|
||||
pWindow->m_cRealBorderColorPrevious = pWindow->m_cRealBorderColor;
|
||||
pWindow->m_cRealBorderColor = grad;
|
||||
pWindow->m_fBorderFadeAnimationProgress->setValueAndWarp(0.f);
|
||||
*pWindow->m_fBorderFadeAnimationProgress = 1.f;
|
||||
pWindow->m_fBorderFadeAnimationProgress.setValueAndWarp(0.f);
|
||||
pWindow->m_fBorderFadeAnimationProgress = 1.f;
|
||||
};
|
||||
|
||||
const bool IS_SHADOWED_BY_MODAL = pWindow->m_pXDGSurface && pWindow->m_pXDGSurface->toplevel && pWindow->m_pXDGSurface->toplevel->anyChildModal();
|
||||
@@ -1865,15 +1857,19 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
// tick angle if it's not running (aka dead)
|
||||
if (!pWindow->m_fBorderAngleAnimationProgress.isBeingAnimated())
|
||||
pWindow->m_fBorderAngleAnimationProgress.setValueAndWarp(0.f);
|
||||
|
||||
// opacity
|
||||
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
||||
if (pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) {
|
||||
*pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alphaFullscreen.valueOrDefault().applyAlpha(*PFULLSCREENALPHA);
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alphaFullscreen.valueOrDefault().applyAlpha(*PFULLSCREENALPHA);
|
||||
} else {
|
||||
if (pWindow == m_pLastWindow)
|
||||
*pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alpha.valueOrDefault().applyAlpha(*PACTIVEALPHA);
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alpha.valueOrDefault().applyAlpha(*PACTIVEALPHA);
|
||||
else
|
||||
*pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alphaInactive.valueOrDefault().applyAlpha(*PINACTIVEALPHA);
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alphaInactive.valueOrDefault().applyAlpha(*PINACTIVEALPHA);
|
||||
}
|
||||
|
||||
// dim
|
||||
@@ -1886,16 +1882,16 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) {
|
||||
if (IS_SHADOWED_BY_MODAL)
|
||||
goalDim += (1.F - goalDim) / 2.F;
|
||||
|
||||
*pWindow->m_fDimPercent = goalDim;
|
||||
pWindow->m_fDimPercent = goalDim;
|
||||
|
||||
// shadow
|
||||
if (!pWindow->isX11OverrideRedirect() && !pWindow->m_bX11DoesntWantBorders) {
|
||||
if (pWindow == m_pLastWindow)
|
||||
*pWindow->m_cRealShadowColor = CHyprColor(*PSHADOWCOL);
|
||||
pWindow->m_cRealShadowColor = CHyprColor(*PSHADOWCOL);
|
||||
else
|
||||
*pWindow->m_cRealShadowColor = CHyprColor(*PSHADOWCOLINACTIVE != INT64_MAX ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
|
||||
pWindow->m_cRealShadowColor = CHyprColor(*PSHADOWCOLINACTIVE != INT64_MAX ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
|
||||
} else {
|
||||
pWindow->m_cRealShadowColor->setValueAndWarp(CHyprColor(0, 0, 0, 0)); // no shadow
|
||||
pWindow->m_cRealShadowColor.setValueAndWarp(CHyprColor(0, 0, 0, 0)); // no shadow
|
||||
}
|
||||
|
||||
pWindow->updateWindowDecos();
|
||||
@@ -1939,11 +1935,11 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
|
||||
|
||||
// additionally, move floating and fs windows manually
|
||||
if (w->m_bIsFloating)
|
||||
*w->m_vRealPosition = w->m_vRealPosition->goal() - pMonitorA->vecPosition + pMonitorB->vecPosition;
|
||||
w->m_vRealPosition = w->m_vRealPosition.goal() - pMonitorA->vecPosition + pMonitorB->vecPosition;
|
||||
|
||||
if (w->isFullscreen()) {
|
||||
*w->m_vRealPosition = pMonitorB->vecPosition;
|
||||
*w->m_vRealSize = pMonitorB->vecSize;
|
||||
w->m_vRealPosition = pMonitorB->vecPosition;
|
||||
w->m_vRealSize = pMonitorB->vecSize;
|
||||
}
|
||||
|
||||
w->updateToplevel();
|
||||
@@ -1964,11 +1960,11 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
|
||||
|
||||
// additionally, move floating and fs windows manually
|
||||
if (w->m_bIsFloating)
|
||||
*w->m_vRealPosition = w->m_vRealPosition->goal() - pMonitorB->vecPosition + pMonitorA->vecPosition;
|
||||
w->m_vRealPosition = w->m_vRealPosition.goal() - pMonitorB->vecPosition + pMonitorA->vecPosition;
|
||||
|
||||
if (w->isFullscreen()) {
|
||||
*w->m_vRealPosition = pMonitorA->vecPosition;
|
||||
*w->m_vRealSize = pMonitorA->vecSize;
|
||||
w->m_vRealPosition = pMonitorA->vecPosition;
|
||||
w->m_vRealSize = pMonitorA->vecSize;
|
||||
}
|
||||
|
||||
w->updateToplevel();
|
||||
@@ -2083,8 +2079,7 @@ PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
|
||||
|
||||
void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMonitor, bool noWarpCursor) {
|
||||
|
||||
if (!pWorkspace || !pMonitor)
|
||||
return;
|
||||
// We trust the monitor to be correct.
|
||||
|
||||
if (pWorkspace->m_pMonitor == pMonitor)
|
||||
return;
|
||||
@@ -2142,14 +2137,14 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
|
||||
if (w->m_bIsMapped && !w->isHidden()) {
|
||||
if (POLDMON) {
|
||||
if (w->m_bIsFloating)
|
||||
*w->m_vRealPosition = w->m_vRealPosition->goal() - POLDMON->vecPosition + pMonitor->vecPosition;
|
||||
w->m_vRealPosition = w->m_vRealPosition.goal() - POLDMON->vecPosition + pMonitor->vecPosition;
|
||||
|
||||
if (w->isFullscreen()) {
|
||||
*w->m_vRealPosition = pMonitor->vecPosition;
|
||||
*w->m_vRealSize = pMonitor->vecSize;
|
||||
w->m_vRealPosition = pMonitor->vecPosition;
|
||||
w->m_vRealSize = pMonitor->vecSize;
|
||||
}
|
||||
} else {
|
||||
*w->m_vRealPosition = Vector2D{(int)w->m_vRealPosition->goal().x % (int)pMonitor->vecSize.x, (int)w->m_vRealPosition->goal().y % (int)pMonitor->vecSize.y};
|
||||
w->m_vRealPosition = Vector2D{(int)w->m_vRealPosition.goal().x % (int)pMonitor->vecSize.x, (int)w->m_vRealPosition.goal().y % (int)pMonitor->vecSize.y};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2223,9 +2218,9 @@ void CCompositor::updateFullscreenFadeOnWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
continue;
|
||||
|
||||
if (!FULLSCREEN)
|
||||
*w->m_fAlpha = 1.f;
|
||||
w->m_fAlpha = 1.f;
|
||||
else if (!w->isFullscreen())
|
||||
*w->m_fAlpha = !w->m_bCreatedOverFullscreen ? 0.f : 1.f;
|
||||
w->m_fAlpha = !w->m_bCreatedOverFullscreen ? 0.f : 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2234,11 +2229,16 @@ void CCompositor::updateFullscreenFadeOnWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
if (pWorkspace->m_iID == PMONITOR->activeWorkspaceID() || pWorkspace->m_iID == PMONITOR->activeSpecialWorkspaceID()) {
|
||||
for (auto const& ls : PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
if (!ls->fadingOut)
|
||||
*ls->alpha = FULLSCREEN && pWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f;
|
||||
ls->alpha = FULLSCREEN && pWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::changeWindowFullscreenModeInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON) {
|
||||
setWindowFullscreenInternal(
|
||||
PWINDOW, (eFullscreenMode)(ON ? (uint8_t)PWINDOW->m_sFullscreenState.internal | (uint8_t)MODE : ((uint8_t)PWINDOW->m_sFullscreenState.internal & (uint8_t)~MODE)));
|
||||
}
|
||||
|
||||
void CCompositor::changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON) {
|
||||
setWindowFullscreenClient(PWINDOW,
|
||||
(eFullscreenMode)(ON ? (uint8_t)PWINDOW->m_sFullscreenState.client | (uint8_t)MODE : ((uint8_t)PWINDOW->m_sFullscreenState.client & (uint8_t)~MODE)));
|
||||
@@ -2324,7 +2324,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS
|
||||
|
||||
updateFullscreenFadeOnWorkspace(PWORKSPACE);
|
||||
|
||||
PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true);
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal(), true);
|
||||
|
||||
PWORKSPACE->forceReportSizesToWindows();
|
||||
|
||||
@@ -2407,9 +2407,6 @@ PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp_) {
|
||||
} else if (regexp.starts_with("initialtitle:")) {
|
||||
mode = MODE_INITIAL_TITLE_REGEX;
|
||||
regexCheck = regexp.substr(13);
|
||||
} else if (regexp.starts_with("tag:")) {
|
||||
mode = MODE_TAG_REGEX;
|
||||
regexCheck = regexp.substr(4);
|
||||
} else if (regexp.starts_with("address:")) {
|
||||
mode = MODE_ADDRESS;
|
||||
matchCheck = regexp.substr(8);
|
||||
@@ -2447,18 +2444,6 @@ PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp_) {
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
case MODE_TAG_REGEX: {
|
||||
bool tagMatched = false;
|
||||
for (auto const& t : w->m_tags.getTags()) {
|
||||
if (RE2::FullMatch(t, regexCheck)) {
|
||||
tagMatched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!tagMatched)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
case MODE_ADDRESS: {
|
||||
std::string addr = std::format("0x{:x}", (uintptr_t)w.get());
|
||||
if (matchCheck != addr)
|
||||
@@ -2518,13 +2503,13 @@ PHLLS CCompositor::getLayerSurfaceFromSurface(SP<CWLSurfaceResource> pSurface) {
|
||||
continue;
|
||||
|
||||
ls->layerSurface->surface->breadthfirst(
|
||||
[&result](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) {
|
||||
if (surf == result.first) {
|
||||
result.second = true;
|
||||
[](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) {
|
||||
if (surf == ((std::pair<SP<CWLSurfaceResource>, bool>*)data)->first) {
|
||||
*(bool*)data = true;
|
||||
return;
|
||||
}
|
||||
},
|
||||
nullptr);
|
||||
&result);
|
||||
|
||||
if (result.second)
|
||||
return ls;
|
||||
@@ -2595,7 +2580,7 @@ PHLWORKSPACE CCompositor::createNewWorkspace(const WORKSPACEID& id, const MONITO
|
||||
|
||||
const auto PWORKSPACE = m_vWorkspaces.emplace_back(CWorkspace::create(id, getMonitorFromID(monID), NAME, SPECIAL, isEmpty));
|
||||
|
||||
PWORKSPACE->m_fAlpha->setValueAndWarp(0);
|
||||
PWORKSPACE->m_fAlpha.setValueAndWarp(0);
|
||||
|
||||
return PWORKSPACE;
|
||||
}
|
||||
@@ -2611,12 +2596,7 @@ void CCompositor::setActiveMonitor(PHLMONITOR pMonitor) {
|
||||
|
||||
const auto PWORKSPACE = pMonitor->activeWorkspace;
|
||||
|
||||
const auto WORKSPACE_ID = PWORKSPACE ? std::to_string(PWORKSPACE->m_iID) : std::to_string(WORKSPACE_INVALID);
|
||||
const auto WORKSPACE_NAME = PWORKSPACE ? PWORKSPACE->m_szName : "?";
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", pMonitor->szName + "," + WORKSPACE_NAME});
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"focusedmonv2", pMonitor->szName + "," + WORKSPACE_ID});
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", pMonitor->szName + "," + (PWORKSPACE ? PWORKSPACE->m_szName : "?")});
|
||||
EMIT_HOOK_EVENT("focusedMon", pMonitor);
|
||||
m_pLastMonitor = pMonitor->self;
|
||||
}
|
||||
@@ -2651,7 +2631,7 @@ void CCompositor::performUserChecks() {
|
||||
}
|
||||
|
||||
if (!*PNOCHECKQTUTILS) {
|
||||
if (!NFsUtils::executableExistsInPath("hyprland-dialog")) {
|
||||
if (!executableExistsInPath("hyprland-dialog")) {
|
||||
g_pHyprNotificationOverlay->addNotification(
|
||||
"Your system does not have hyprland-qtutils installed. This is a runtime dependency for some dialogs. Consider installing it.", CHyprColor{}, 15000, ICON_WARNING);
|
||||
}
|
||||
@@ -2673,7 +2653,6 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor
|
||||
|
||||
const bool FULLSCREEN = pWindow->isFullscreen();
|
||||
const auto FULLSCREENMODE = pWindow->m_sFullscreenState.internal;
|
||||
const bool WASVISIBLE = pWindow->m_pWorkspace && pWindow->m_pWorkspace->isVisible();
|
||||
|
||||
if (FULLSCREEN)
|
||||
setWindowFullscreenInternal(pWindow, FSMODE_NONE);
|
||||
@@ -2681,7 +2660,7 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor
|
||||
const PHLWINDOW pFirstWindowOnWorkspace = pWorkspace->getFirstWindow();
|
||||
const int visibleWindowsOnWorkspace = pWorkspace->getWindows(std::nullopt, true);
|
||||
const auto PWINDOWMONITOR = pWindow->m_pMonitor.lock();
|
||||
const auto POSTOMON = pWindow->m_vRealPosition->goal() - PWINDOWMONITOR->vecPosition;
|
||||
const auto POSTOMON = pWindow->m_vRealPosition.goal() - PWINDOWMONITOR->vecPosition;
|
||||
const auto PWORKSPACEMONITOR = pWorkspace->m_pMonitor.lock();
|
||||
|
||||
if (!pWindow->m_bIsFloating)
|
||||
@@ -2711,14 +2690,14 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
|
||||
|
||||
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
|
||||
pWindow->addWindowDeco(makeUnique<CHyprGroupBarDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||
|
||||
} else {
|
||||
if (!pWindow->m_bIsFloating)
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow);
|
||||
|
||||
if (pWindow->m_bIsFloating)
|
||||
*pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition;
|
||||
pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition;
|
||||
}
|
||||
|
||||
pWindow->updateToplevel();
|
||||
@@ -2741,11 +2720,6 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor
|
||||
if (pWindow->m_pWorkspace)
|
||||
pWindow->m_pWorkspace->updateWindows();
|
||||
g_pCompositor->updateSuspendedStates();
|
||||
|
||||
if (!WASVISIBLE && pWindow->m_pWorkspace && pWindow->m_pWorkspace->isVisible()) {
|
||||
pWindow->m_fMovingFromWorkspaceAlpha->setValueAndWarp(0.F);
|
||||
*pWindow->m_fMovingFromWorkspaceAlpha = 1.F;
|
||||
}
|
||||
}
|
||||
|
||||
PHLWINDOW CCompositor::getForceFocus() {
|
||||
@@ -2765,9 +2739,11 @@ PHLWINDOW CCompositor::getForceFocus() {
|
||||
void CCompositor::arrangeMonitors() {
|
||||
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling");
|
||||
|
||||
std::vector<PHLMONITOR> toArrange(m_vMonitors.begin(), m_vMonitors.end());
|
||||
std::vector<PHLMONITOR> toArrange;
|
||||
std::vector<PHLMONITOR> arranged;
|
||||
arranged.reserve(toArrange.size());
|
||||
|
||||
for (auto const& m : m_vMonitors)
|
||||
toArrange.push_back(m);
|
||||
|
||||
Debug::log(LOG, "arrangeMonitors: {} to arrange", toArrange.size());
|
||||
|
||||
@@ -2928,6 +2904,17 @@ void CCompositor::updateSuspendedStates() {
|
||||
}
|
||||
}
|
||||
|
||||
PHLWINDOW CCompositor::windowForCPointer(CWindow* pWindow) {
|
||||
for (auto const& w : m_vWindows) {
|
||||
if (w.get() != pWindow)
|
||||
continue;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
static void checkDefaultCursorWarp(PHLMONITOR monitor) {
|
||||
static auto PCURSORMONITOR = CConfigValue<std::string>("cursor:default_monitor");
|
||||
static bool cursorDefaultDone = false;
|
||||
@@ -3005,65 +2992,4 @@ void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
|
||||
|
||||
g_pHyprRenderer->damageMonitor(PNEWMONITOR);
|
||||
PNEWMONITOR->onMonitorFrame();
|
||||
|
||||
if (PROTO::colorManagement && shouldChangePreferredImageDescription())
|
||||
PROTO::colorManagement->onImagePreferredChanged();
|
||||
}
|
||||
|
||||
SImageDescription CCompositor::getPreferredImageDescription() {
|
||||
if (!PROTO::colorManagement) {
|
||||
Debug::log(ERR, "FIXME: color management protocol is not enabled, returning empty image description");
|
||||
return SImageDescription{};
|
||||
}
|
||||
Debug::log(WARN, "FIXME: color management protocol is enabled, determine correct preferred image description");
|
||||
// should determine some common settings to avoid unnecessary transformations while keeping maximum displayable precision
|
||||
return SImageDescription{.primaries = NColorPrimaries::BT709};
|
||||
}
|
||||
|
||||
bool CCompositor::shouldChangePreferredImageDescription() {
|
||||
Debug::log(WARN, "FIXME: color management protocol is enabled and outputs changed, check preferred image description changes");
|
||||
return false;
|
||||
}
|
||||
|
||||
void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspaceRule>& rules) {
|
||||
for (const auto& rule : rules) {
|
||||
if (!rule.isPersistent)
|
||||
continue;
|
||||
|
||||
const auto PMONITOR = getMonitorFromString(rule.monitor);
|
||||
|
||||
if (!PMONITOR) {
|
||||
Debug::log(ERR, "ensurePersistentWorkspacesPresent: couldn't resolve monitor for {}, skipping", rule.monitor);
|
||||
continue;
|
||||
}
|
||||
|
||||
WORKSPACEID id = rule.workspaceId;
|
||||
std::string wsname = rule.workspaceName;
|
||||
if (id == WORKSPACE_INVALID) {
|
||||
const auto R = getWorkspaceIDNameFromString(rule.workspaceString);
|
||||
id = R.id;
|
||||
wsname = R.name;
|
||||
}
|
||||
|
||||
if (id == WORKSPACE_INVALID) {
|
||||
Debug::log(ERR, "ensurePersistentWorkspacesPresent: couldn't resolve id for workspace {}", rule.workspaceString);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (const auto PWORKSPACE = getWorkspaceByID(id); PWORKSPACE) {
|
||||
if (PWORKSPACE->m_pMonitor == PMONITOR) {
|
||||
Debug::log(LOG, "ensurePersistentWorkspacesPresent: workspace persistent {} already on {}", rule.workspaceString, PMONITOR->szName);
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "ensurePersistentWorkspacesPresent: workspace persistent {} not on {}, moving", rule.workspaceString, PMONITOR->szName);
|
||||
moveWorkspaceToMonitor(PWORKSPACE, PMONITOR);
|
||||
continue;
|
||||
}
|
||||
|
||||
createNewWorkspace(id, PMONITOR ? PMONITOR : m_pLastMonitor.lock(), wsname, false);
|
||||
}
|
||||
|
||||
// cleanup old
|
||||
sanityCheckWorkspaces();
|
||||
}
|
||||
|
@@ -1,21 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "defines.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "events/Events.hpp"
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "managers/ThreadManager.hpp"
|
||||
#include "managers/XWaylandManager.hpp"
|
||||
#include "managers/input/InputManager.hpp"
|
||||
#include "managers/LayoutManager.hpp"
|
||||
#include "managers/KeybindManager.hpp"
|
||||
#include "managers/AnimationManager.hpp"
|
||||
#include "managers/EventManager.hpp"
|
||||
#include "managers/ProtocolManager.hpp"
|
||||
#include "managers/SessionLockManager.hpp"
|
||||
#include "managers/HookSystemManager.hpp"
|
||||
#include "debug/HyprDebugOverlay.hpp"
|
||||
#include "debug/HyprNotificationOverlay.hpp"
|
||||
#include "helpers/Monitor.hpp"
|
||||
#include "desktop/Workspace.hpp"
|
||||
#include "desktop/Window.hpp"
|
||||
#include "protocols/types/ColorManagement.hpp"
|
||||
#include "helpers/memory/Memory.hpp"
|
||||
#include "render/Renderer.hpp"
|
||||
#include "render/OpenGL.hpp"
|
||||
#include "hyprerror/HyprError.hpp"
|
||||
#include "plugins/PluginSystem.hpp"
|
||||
#include "helpers/Watchdog.hpp"
|
||||
|
||||
#include <aquamarine/backend/Backend.hpp>
|
||||
#include <aquamarine/output/Output.hpp>
|
||||
|
||||
class CWLSurfaceResource;
|
||||
struct SWorkspaceRule;
|
||||
|
||||
enum eManagersInitStage : uint8_t {
|
||||
STAGE_PRIORITY = 0,
|
||||
@@ -25,7 +42,7 @@ enum eManagersInitStage : uint8_t {
|
||||
|
||||
class CCompositor {
|
||||
public:
|
||||
CCompositor(bool onlyConfig = false);
|
||||
CCompositor();
|
||||
~CCompositor();
|
||||
|
||||
wl_display* m_sWLDisplay;
|
||||
@@ -75,8 +92,7 @@ class CCompositor {
|
||||
bool m_bIsShuttingDown = false;
|
||||
bool m_bFinalRequests = false;
|
||||
bool m_bDesktopEnvSet = false;
|
||||
bool m_bWantsXwayland = true;
|
||||
bool m_bOnlyConfigVerification = false;
|
||||
bool m_bEnableXwayland = true;
|
||||
|
||||
// ------------------------------------------------- //
|
||||
|
||||
@@ -107,9 +123,8 @@ class CCompositor {
|
||||
void changeWindowZOrder(PHLWINDOW, bool);
|
||||
void cleanupFadingOut(const MONITORID& monid);
|
||||
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
|
||||
PHLWINDOW getWindowInDirection(const CBox& box, PHLWORKSPACE pWorkspace, char dir, PHLWINDOW ignoreWindow = nullptr, bool useVectorAngles = false);
|
||||
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {}, bool visible = false);
|
||||
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {}, bool visible = false);
|
||||
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
||||
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);
|
||||
@@ -125,6 +140,7 @@ class CCompositor {
|
||||
void setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||
void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||
void setWindowFullscreenState(const PHLWINDOW PWINDOW, const SFullscreenState state);
|
||||
void changeWindowFullscreenModeInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON);
|
||||
void changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON);
|
||||
void updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
|
||||
PHLWINDOW getX11Parent(PHLWINDOW);
|
||||
@@ -151,11 +167,8 @@ class CCompositor {
|
||||
void setPreferredScaleForSurface(SP<CWLSurfaceResource> pSurface, double scale);
|
||||
void setPreferredTransformForSurface(SP<CWLSurfaceResource> pSurface, wl_output_transform transform);
|
||||
void updateSuspendedStates();
|
||||
PHLWINDOW windowForCPointer(CWindow*);
|
||||
void onNewMonitor(SP<Aquamarine::IOutput> output);
|
||||
void ensurePersistentWorkspacesPresent(const std::vector<SWorkspaceRule>& rules);
|
||||
|
||||
SImageDescription getPreferredImageDescription();
|
||||
bool shouldChangePreferredImageDescription();
|
||||
|
||||
std::string explicitConfigPath;
|
||||
|
||||
@@ -166,11 +179,10 @@ class CCompositor {
|
||||
void setRandomSplash();
|
||||
void initManagers(eManagersInitStage stage);
|
||||
void prepareFallbackOutput();
|
||||
bool isWindowAvailableForCycle(PHLWINDOW pWindow, PHLWINDOW w, bool focusableOnly, std::optional<bool> floating, bool anyWorkspace = false);
|
||||
|
||||
uint64_t m_iHyprlandPID = 0;
|
||||
wl_event_source* m_critSigSource = nullptr;
|
||||
rlimit m_sOriginalNofile = {0};
|
||||
};
|
||||
|
||||
inline UP<CCompositor> g_pCompositor;
|
||||
inline std::unique_ptr<CCompositor> g_pCompositor;
|
||||
|
@@ -3,8 +3,6 @@
|
||||
#include "helpers/math/Math.hpp"
|
||||
#include <functional>
|
||||
#include <any>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <hyprutils/math/Box.hpp>
|
||||
|
||||
enum eIcons : uint8_t {
|
||||
@@ -52,12 +50,6 @@ struct SHyprCtlCommand {
|
||||
std::function<std::string(eHyprCtlOutputFormat, std::string)> fn;
|
||||
};
|
||||
|
||||
struct SDispatchResult {
|
||||
bool passEvent = false;
|
||||
bool success = true;
|
||||
std::string error;
|
||||
};
|
||||
|
||||
typedef int64_t WINDOWID;
|
||||
typedef int64_t MONITORID;
|
||||
typedef int64_t WORKSPACEID;
|
||||
|
@@ -139,12 +139,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{0, 0, 20},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:rounding_power",
|
||||
.description = "rouding power of corners (2 is a circle)",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{2, 2, 10},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:active_opacity",
|
||||
.description = "opacity of active windows. [0.0 - 1.0]",
|
||||
@@ -1295,30 +1289,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "render:expand_undersized_textures",
|
||||
.description = "Whether to expand textures that have not yet resized to be larger, or to just stretch them instead.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "render:xp_mode",
|
||||
.description = "Disable back buffer and bottom layer rendering.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "render:ctm_animation",
|
||||
.description = "Whether to enable a fade animation for CTM changes (hyprsunset). 2 means 'auto' (Yes on everything but Nvidia).",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{2, 0, 2},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "render:allow_early_buffer_release",
|
||||
.description = "Allow early buffer release event. Fixes stuttering and missing frames for some apps. May cause graphical glitches and memory leaks in others",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
|
||||
/*
|
||||
* cursor:
|
||||
@@ -1633,16 +1603,10 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:slave_count_for_center_master",
|
||||
.description = "when using orientation=center, make the master window centered only when at least this many slave windows are open. (Set 0 to always_center_master)",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{2, 0, 10}, //##TODO RANGE?
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:center_master_slaves_on_right",
|
||||
.description = "set if the slaves should appear on right of master when slave_count_for_center_master > 2",
|
||||
.value = "master:always_center_master",
|
||||
.description = "when using orientation=center, keep the master window centered, even when it is the only window in the workspace.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:center_ignores_reserved",
|
||||
@@ -1664,22 +1628,4 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "experimental:wide_color_gamut",
|
||||
.description = "force wide color gamut for all supported outputs",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "experimental:hdr",
|
||||
.description = "force static hdr for all supported outputs",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "experimental:xx_color_management_v4",
|
||||
.description = "enable color management protocol",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
};
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#include <re2/re2.h>
|
||||
|
||||
#include "ConfigManager.hpp"
|
||||
#include "ConfigWatcher.hpp"
|
||||
#include "../managers/KeybindManager.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
@@ -12,20 +11,7 @@
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../xwayland/XWayland.hpp"
|
||||
#include "../protocols/OutputManagement.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "defaultConfig.hpp"
|
||||
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../hyprerror/HyprError.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/eventLoop/EventLoopManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../debug/HyprNotificationOverlay.hpp"
|
||||
#include "../plugins/PluginSystem.hpp"
|
||||
|
||||
#include "managers/HookSystemManager.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <hyprutils/path/Path.hpp>
|
||||
@@ -45,9 +31,7 @@
|
||||
#include <unordered_set>
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
using namespace Hyprutils::String;
|
||||
using namespace Hyprutils::Animation;
|
||||
|
||||
//NOLINTNEXTLINE
|
||||
extern "C" char** environ;
|
||||
@@ -144,18 +128,6 @@ static void configHandleGapDestroy(void** data) {
|
||||
delete reinterpret_cast<CCssGapData*>(*data);
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleExec(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
|
||||
const auto RESULT = g_pConfigManager->handleExec(COMMAND, VALUE);
|
||||
|
||||
Hyprlang::CParseResult result;
|
||||
if (RESULT.has_value())
|
||||
result.setError(RESULT.value().c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleRawExec(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
@@ -180,18 +152,6 @@ static Hyprlang::CParseResult handleExecOnce(const char* c, const char* v) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleExecRawOnce(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
|
||||
const auto RESULT = g_pConfigManager->handleExecRawOnce(COMMAND, VALUE);
|
||||
|
||||
Hyprlang::CParseResult result;
|
||||
if (RESULT.has_value())
|
||||
result.setError(RESULT.value().c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleExecShutdown(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
@@ -375,8 +335,8 @@ static Hyprlang::CParseResult handlePlugin(const char* c, const char* v) {
|
||||
CConfigManager::CConfigManager() {
|
||||
const auto ERR = verifyConfigExists();
|
||||
|
||||
m_configPaths.emplace_back(getMainConfigPath());
|
||||
m_pConfig = makeUnique<Hyprlang::CConfig>(m_configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true});
|
||||
configPaths.emplace_back(getMainConfigPath());
|
||||
m_pConfig = std::make_unique<Hyprlang::CConfig>(configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true});
|
||||
|
||||
m_pConfig->addConfigValue("general:border_size", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("general:no_border_on_floating", Hyprlang::INT{0});
|
||||
@@ -453,7 +413,6 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("debug:log_damage", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("debug:overlay", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("debug:damage_blink", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("debug:pass", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("debug:disable_logs", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("debug:disable_time", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("debug:enable_stdout_logs", Hyprlang::INT{0});
|
||||
@@ -467,7 +426,6 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("debug:colored_stdout_logs", Hyprlang::INT{1});
|
||||
|
||||
m_pConfig->addConfigValue("decoration:rounding", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("decoration:rounding_power", {2.F});
|
||||
m_pConfig->addConfigValue("decoration:blur:enabled", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("decoration:blur:size", Hyprlang::INT{8});
|
||||
m_pConfig->addConfigValue("decoration:blur:passes", Hyprlang::INT{1});
|
||||
@@ -518,8 +476,7 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("master:special_scale_factor", {1.f});
|
||||
m_pConfig->addConfigValue("master:mfact", {0.55f});
|
||||
m_pConfig->addConfigValue("master:new_status", {"slave"});
|
||||
m_pConfig->addConfigValue("master:slave_count_for_center_master", Hyprlang::INT{2});
|
||||
m_pConfig->addConfigValue("master:center_master_slaves_on_right", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("master:always_center_master", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("master:center_ignores_reserved", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("master:new_on_active", {"none"});
|
||||
m_pConfig->addConfigValue("master:new_on_top", Hyprlang::INT{0});
|
||||
@@ -614,9 +571,9 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("xwayland:force_zero_scaling", Hyprlang::INT{0});
|
||||
|
||||
m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("opengl:force_introspection", Hyprlang::INT{1}); // TODO: remove this. I don't think it does us any good to disable intro.
|
||||
m_pConfig->addConfigValue("opengl:force_introspection", Hyprlang::INT{2});
|
||||
|
||||
m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{2});
|
||||
m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24});
|
||||
m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0});
|
||||
@@ -631,7 +588,7 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addConfigValue("cursor:sync_gsettings_theme", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("cursor:hide_on_key_press", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("cursor:hide_on_touch", Hyprlang::INT{1});
|
||||
m_pConfig->addConfigValue("cursor:use_cpu_buffer", Hyprlang::INT{2});
|
||||
m_pConfig->addConfigValue("cursor:use_cpu_buffer", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("cursor:warp_back_after_non_mouse_input", Hyprlang::INT{0});
|
||||
|
||||
m_pConfig->addConfigValue("autogenerated", Hyprlang::INT{0});
|
||||
@@ -655,16 +612,8 @@ CConfigManager::CConfigManager() {
|
||||
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});
|
||||
m_pConfig->addConfigValue("render:xp_mode", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("render:ctm_animation", Hyprlang::INT{2});
|
||||
m_pConfig->addConfigValue("render:allow_early_buffer_release", Hyprlang::INT{1});
|
||||
|
||||
m_pConfig->addConfigValue("ecosystem:no_update_news", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("ecosystem:no_donation_nag", Hyprlang::INT{0});
|
||||
|
||||
m_pConfig->addConfigValue("experimental:wide_color_gamut", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("experimental:hdr", Hyprlang::INT{0});
|
||||
m_pConfig->addConfigValue("experimental:xx_color_management_v4", Hyprlang::INT{0});
|
||||
|
||||
// devices
|
||||
m_pConfig->addSpecialCategory("device", {"name"});
|
||||
@@ -704,10 +653,8 @@ CConfigManager::CConfigManager() {
|
||||
m_pConfig->addSpecialConfigValue("device", "active_area_size", Hyprlang::VEC2{0, 0}); // only for tablets
|
||||
|
||||
// keywords
|
||||
m_pConfig->registerHandler(&::handleExec, "exec", {false});
|
||||
m_pConfig->registerHandler(&::handleRawExec, "execr", {false});
|
||||
m_pConfig->registerHandler(&::handleRawExec, "exec", {false});
|
||||
m_pConfig->registerHandler(&::handleExecOnce, "exec-once", {false});
|
||||
m_pConfig->registerHandler(&::handleExecRawOnce, "execr-once", {false});
|
||||
m_pConfig->registerHandler(&::handleExecShutdown, "exec-shutdown", {false});
|
||||
m_pConfig->registerHandler(&::handleMonitor, "monitor", {false});
|
||||
m_pConfig->registerHandler(&::handleBind, "bind", {true});
|
||||
@@ -729,20 +676,18 @@ CConfigManager::CConfigManager() {
|
||||
|
||||
m_pConfig->commence();
|
||||
|
||||
setDefaultAnimationVars();
|
||||
resetHLConfig();
|
||||
|
||||
if (!g_pCompositor->m_bOnlyConfigVerification) {
|
||||
Debug::log(
|
||||
INFO,
|
||||
Debug::log(INFO,
|
||||
"!!!!HEY YOU, YES YOU!!!!: further logs to stdout / logfile are disabled by default. BEFORE SENDING THIS LOG, ENABLE THEM. Use debug:disable_logs = false to do so: "
|
||||
"https://wiki.hyprland.org/Configuring/Variables/#debug");
|
||||
}
|
||||
|
||||
Debug::disableLogs = reinterpret_cast<int64_t* const*>(m_pConfig->getConfigValuePtr("debug:disable_logs")->getDataStaticPtr());
|
||||
Debug::disableTime = reinterpret_cast<int64_t* const*>(m_pConfig->getConfigValuePtr("debug:disable_time")->getDataStaticPtr());
|
||||
|
||||
if (g_pEventLoopManager && ERR.has_value())
|
||||
g_pEventLoopManager->doLater([ERR] { g_pHyprError->queueCreate(ERR.value(), CHyprColor{1.0, 0.1, 0.1, 1.0}); });
|
||||
if (ERR.has_value())
|
||||
g_pHyprError->queueCreate(ERR.value(), CHyprColor{1.0, 0.1, 0.1, 1.0});
|
||||
}
|
||||
|
||||
std::optional<std::string> CConfigManager::generateConfig(std::string configPath) {
|
||||
@@ -768,7 +713,6 @@ std::optional<std::string> CConfigManager::generateConfig(std::string configPath
|
||||
}
|
||||
|
||||
std::string CConfigManager::getMainConfigPath() {
|
||||
static std::string CONFIG_PATH = [this]() -> std::string {
|
||||
if (!g_pCompositor->explicitConfigPath.empty())
|
||||
return g_pCompositor->explicitConfigPath;
|
||||
|
||||
@@ -783,9 +727,6 @@ std::string CConfigManager::getMainConfigPath() {
|
||||
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.");
|
||||
}();
|
||||
|
||||
return CONFIG_PATH;
|
||||
}
|
||||
|
||||
std::optional<std::string> CConfigManager::verifyConfigExists() {
|
||||
@@ -801,7 +742,7 @@ std::string CConfigManager::getConfigString() {
|
||||
std::string configString;
|
||||
std::string currFileContent;
|
||||
|
||||
for (const auto& path : m_configPaths) {
|
||||
for (const auto& path : configPaths) {
|
||||
std::ifstream configFile(path);
|
||||
configString += ("\n\nConfig File: " + path + ": ");
|
||||
if (!configFile.is_open()) {
|
||||
@@ -826,63 +767,76 @@ void CConfigManager::reload() {
|
||||
resetHLConfig();
|
||||
configCurrentPath = getMainConfigPath();
|
||||
const auto ERR = m_pConfig->parse();
|
||||
m_bLastConfigVerificationWasSuccessful = !ERR.error;
|
||||
postConfigReload(ERR);
|
||||
}
|
||||
|
||||
std::string CConfigManager::verify() {
|
||||
setDefaultAnimationVars();
|
||||
resetHLConfig();
|
||||
configCurrentPath = getMainConfigPath();
|
||||
const auto ERR = m_pConfig->parse();
|
||||
m_bLastConfigVerificationWasSuccessful = !ERR.error;
|
||||
if (ERR.error)
|
||||
return ERR.getError();
|
||||
return "config ok";
|
||||
}
|
||||
|
||||
void CConfigManager::setDefaultAnimationVars() {
|
||||
m_AnimationTree.createNode("__internal_fadeCTM");
|
||||
m_AnimationTree.createNode("global");
|
||||
|
||||
// global
|
||||
m_AnimationTree.createNode("windows", "global");
|
||||
m_AnimationTree.createNode("layers", "global");
|
||||
m_AnimationTree.createNode("fade", "global");
|
||||
m_AnimationTree.createNode("border", "global");
|
||||
m_AnimationTree.createNode("borderangle", "global");
|
||||
m_AnimationTree.createNode("workspaces", "global");
|
||||
|
||||
// layer
|
||||
m_AnimationTree.createNode("layersIn", "layers");
|
||||
m_AnimationTree.createNode("layersOut", "layers");
|
||||
if (isFirstLaunch) {
|
||||
INITANIMCFG("global");
|
||||
INITANIMCFG("windows");
|
||||
INITANIMCFG("layers");
|
||||
INITANIMCFG("fade");
|
||||
INITANIMCFG("border");
|
||||
INITANIMCFG("borderangle");
|
||||
|
||||
// windows
|
||||
m_AnimationTree.createNode("windowsIn", "windows");
|
||||
m_AnimationTree.createNode("windowsOut", "windows");
|
||||
m_AnimationTree.createNode("windowsMove", "windows");
|
||||
INITANIMCFG("windowsIn");
|
||||
INITANIMCFG("windowsOut");
|
||||
INITANIMCFG("windowsMove");
|
||||
|
||||
// layers
|
||||
INITANIMCFG("layersIn");
|
||||
INITANIMCFG("layersOut");
|
||||
|
||||
// fade
|
||||
m_AnimationTree.createNode("fadeIn", "fade");
|
||||
m_AnimationTree.createNode("fadeOut", "fade");
|
||||
m_AnimationTree.createNode("fadeSwitch", "fade");
|
||||
m_AnimationTree.createNode("fadeShadow", "fade");
|
||||
m_AnimationTree.createNode("fadeDim", "fade");
|
||||
m_AnimationTree.createNode("fadeLayers", "fade");
|
||||
m_AnimationTree.createNode("fadeLayersIn", "fadeLayers");
|
||||
m_AnimationTree.createNode("fadeLayersOut", "fadeLayers");
|
||||
INITANIMCFG("fadeIn");
|
||||
INITANIMCFG("fadeOut");
|
||||
INITANIMCFG("fadeSwitch");
|
||||
INITANIMCFG("fadeShadow");
|
||||
INITANIMCFG("fadeDim");
|
||||
|
||||
// border
|
||||
|
||||
// workspaces
|
||||
m_AnimationTree.createNode("workspacesIn", "workspaces");
|
||||
m_AnimationTree.createNode("workspacesOut", "workspaces");
|
||||
m_AnimationTree.createNode("specialWorkspace", "workspaces");
|
||||
m_AnimationTree.createNode("specialWorkspaceIn", "specialWorkspace");
|
||||
m_AnimationTree.createNode("specialWorkspaceOut", "specialWorkspace");
|
||||
INITANIMCFG("workspaces");
|
||||
INITANIMCFG("workspacesIn");
|
||||
INITANIMCFG("workspacesOut");
|
||||
INITANIMCFG("specialWorkspace");
|
||||
INITANIMCFG("specialWorkspaceIn");
|
||||
INITANIMCFG("specialWorkspaceOut");
|
||||
}
|
||||
|
||||
// init the root nodes
|
||||
m_AnimationTree.setConfigForNode("global", 1, 8.f, "", "default");
|
||||
m_AnimationTree.setConfigForNode("__internal_fadeCTM", 1, 5.f, "", "linear");
|
||||
m_AnimationTree.setConfigForNode("borderangle", 0, 0.f, "", "default");
|
||||
// init the values
|
||||
animationConfig["global"] = {false, "default", "", 8.f, 1, &animationConfig["general"], nullptr};
|
||||
|
||||
CREATEANIMCFG("windows", "global");
|
||||
CREATEANIMCFG("layers", "global");
|
||||
CREATEANIMCFG("fade", "global");
|
||||
CREATEANIMCFG("border", "global");
|
||||
CREATEANIMCFG("borderangle", "global");
|
||||
CREATEANIMCFG("workspaces", "global");
|
||||
|
||||
CREATEANIMCFG("layersIn", "layers");
|
||||
CREATEANIMCFG("layersOut", "layers");
|
||||
|
||||
CREATEANIMCFG("windowsIn", "windows");
|
||||
CREATEANIMCFG("windowsOut", "windows");
|
||||
CREATEANIMCFG("windowsMove", "windows");
|
||||
|
||||
CREATEANIMCFG("fadeIn", "fade");
|
||||
CREATEANIMCFG("fadeOut", "fade");
|
||||
CREATEANIMCFG("fadeSwitch", "fade");
|
||||
CREATEANIMCFG("fadeShadow", "fade");
|
||||
CREATEANIMCFG("fadeDim", "fade");
|
||||
CREATEANIMCFG("fadeLayers", "fade");
|
||||
CREATEANIMCFG("fadeLayersIn", "fadeLayers");
|
||||
CREATEANIMCFG("fadeLayersOut", "fadeLayers");
|
||||
|
||||
CREATEANIMCFG("workspacesIn", "workspaces");
|
||||
CREATEANIMCFG("workspacesOut", "workspaces");
|
||||
CREATEANIMCFG("specialWorkspace", "workspaces");
|
||||
CREATEANIMCFG("specialWorkspaceIn", "specialWorkspace");
|
||||
CREATEANIMCFG("specialWorkspaceOut", "specialWorkspace");
|
||||
}
|
||||
|
||||
std::optional<std::string> CConfigManager::resetHLConfig() {
|
||||
@@ -890,8 +844,6 @@ std::optional<std::string> CConfigManager::resetHLConfig() {
|
||||
m_vWindowRules.clear();
|
||||
g_pKeybindManager->clearKeybinds();
|
||||
g_pAnimationManager->removeAllBeziers();
|
||||
g_pAnimationManager->addBezierWithName("linear", Vector2D(0.0, 0.0), Vector2D(1.0, 1.0));
|
||||
|
||||
m_mAdditionalReservedAreas.clear();
|
||||
m_dBlurLSNamespaces.clear();
|
||||
m_vWorkspaceRules.clear();
|
||||
@@ -902,27 +854,20 @@ std::optional<std::string> CConfigManager::resetHLConfig() {
|
||||
finalExecRequests.clear();
|
||||
|
||||
// paths
|
||||
m_configPaths.clear();
|
||||
configPaths.clear();
|
||||
std::string mainConfigPath = getMainConfigPath();
|
||||
Debug::log(LOG, "Using config: {}", mainConfigPath);
|
||||
m_configPaths.emplace_back(mainConfigPath);
|
||||
configPaths.push_back(mainConfigPath);
|
||||
|
||||
const auto RET = verifyConfigExists();
|
||||
|
||||
return RET;
|
||||
}
|
||||
|
||||
void CConfigManager::updateWatcher() {
|
||||
static const auto PDISABLEAUTORELOAD = CConfigValue<Hyprlang::INT>("misc:disable_autoreload");
|
||||
g_pConfigWatcher->setWatchList(*PDISABLEAUTORELOAD ? std::vector<std::string>{} : m_configPaths);
|
||||
}
|
||||
|
||||
void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||
static const auto PENABLEEXPLICIT = CConfigValue<Hyprlang::INT>("render:explicit_sync");
|
||||
static int prevEnabledExplicit = *PENABLEEXPLICIT;
|
||||
|
||||
updateWatcher();
|
||||
|
||||
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||
w->uncacheWindowDecos();
|
||||
}
|
||||
@@ -936,12 +881,11 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||
g_pInputManager->setPointerConfigs();
|
||||
g_pInputManager->setTouchDeviceConfigs();
|
||||
g_pInputManager->setTabletConfigs();
|
||||
|
||||
g_pHyprOpenGL->m_bReloadScreenShader = true;
|
||||
|
||||
g_pHyprOpenGL->ensureBackgroundTexturePresence();
|
||||
}
|
||||
|
||||
if (!isFirstLaunch)
|
||||
g_pHyprOpenGL->m_bReloadScreenShader = true;
|
||||
|
||||
// parseError will be displayed next frame
|
||||
|
||||
if (result.error)
|
||||
@@ -953,7 +897,7 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||
g_pHyprError->queueCreate(result.getError(), CHyprColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0));
|
||||
else if (std::any_cast<Hyprlang::INT>(m_pConfig->getConfigValue("autogenerated")) == 1)
|
||||
g_pHyprError->queueCreate(
|
||||
"Warning: You're using an autogenerated config! Edit the config file to get rid of this message. (config file: " + getMainConfigPath() +
|
||||
"Warning: You're using an autogenerated config! (config file: " + getMainConfigPath() +
|
||||
" )\nSUPER+Q -> kitty (if it doesn't launch, make sure it's installed or choose a different terminal in the config)\nSUPER+M -> exit Hyprland",
|
||||
CHyprColor(1.0, 1.0, 70.0 / 255.0, 1.0));
|
||||
else if (*PENABLEEXPLICIT != prevEnabledExplicit)
|
||||
@@ -974,15 +918,25 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||
|
||||
#ifndef NO_XWAYLAND
|
||||
const auto PENABLEXWAYLAND = std::any_cast<Hyprlang::INT>(m_pConfig->getConfigValue("xwayland:enabled"));
|
||||
g_pCompositor->m_bWantsXwayland = PENABLEXWAYLAND;
|
||||
// enable/disable xwayland usage
|
||||
if (!isFirstLaunch &&
|
||||
g_pXWayland /* XWayland has to be initialized by CCompositor::initManagers for this to make sense, and it doesn't have to be (e.g. very early plugin load) */) {
|
||||
bool prevEnabledXwayland = g_pXWayland->enabled();
|
||||
if (g_pCompositor->m_bWantsXwayland != prevEnabledXwayland)
|
||||
g_pXWayland = makeUnique<CXWayland>(g_pCompositor->m_bWantsXwayland);
|
||||
if (!isFirstLaunch) {
|
||||
bool prevEnabledXwayland = g_pCompositor->m_bEnableXwayland;
|
||||
if (PENABLEXWAYLAND != prevEnabledXwayland) {
|
||||
g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND;
|
||||
if (PENABLEXWAYLAND) {
|
||||
Debug::log(LOG, "xwayland has been enabled");
|
||||
} else {
|
||||
Debug::log(LOG, "xwayland has been disabled, cleaning up...");
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_pXDGSurface || !w->m_bIsX11)
|
||||
continue;
|
||||
g_pCompositor->closeWindow(w);
|
||||
}
|
||||
}
|
||||
g_pXWayland = std::make_unique<CXWayland>(g_pCompositor->m_bEnableXwayland);
|
||||
}
|
||||
} else
|
||||
g_pCompositor->m_bWantsXwayland = PENABLEXWAYLAND;
|
||||
g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND;
|
||||
#endif
|
||||
|
||||
if (!isFirstLaunch && !g_pCompositor->m_bUnsafeState)
|
||||
@@ -1038,10 +992,6 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||
// update plugins
|
||||
handlePluginLoads();
|
||||
|
||||
// update persistent workspaces
|
||||
if (!isFirstLaunch)
|
||||
ensurePersistentWorkspacesPresent();
|
||||
|
||||
EMIT_HOOK_EVENT("configReloaded", nullptr);
|
||||
if (g_pEventManager)
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"configreloaded", ""});
|
||||
@@ -1049,14 +999,17 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||
|
||||
void CConfigManager::init() {
|
||||
|
||||
g_pConfigWatcher->setOnChange([this](const CConfigWatcher::SConfigWatchEvent& e) {
|
||||
Debug::log(LOG, "CConfigManager: file {} modified, reloading", e.file);
|
||||
reload();
|
||||
});
|
||||
|
||||
const std::string CONFIGPATH = getMainConfigPath();
|
||||
reload();
|
||||
|
||||
struct stat fileStat;
|
||||
int err = stat(CONFIGPATH.c_str(), &fileStat);
|
||||
if (err != 0) {
|
||||
Debug::log(WARN, "Error at statting config, error {}", errno);
|
||||
}
|
||||
|
||||
configModifyTimes[CONFIGPATH] = fileStat.st_mtime;
|
||||
|
||||
isFirstLaunch = false;
|
||||
}
|
||||
|
||||
@@ -1097,6 +1050,37 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
||||
return RET.error ? RET.getError() : "";
|
||||
}
|
||||
|
||||
void CConfigManager::tick() {
|
||||
std::string CONFIGPATH = getMainConfigPath();
|
||||
if (!std::filesystem::exists(CONFIGPATH)) {
|
||||
Debug::log(ERR, "Config doesn't exist??");
|
||||
return;
|
||||
}
|
||||
|
||||
bool parse = false;
|
||||
|
||||
for (auto const& cf : configPaths) {
|
||||
struct stat fileStat;
|
||||
int err = stat(cf.c_str(), &fileStat);
|
||||
if (err != 0) {
|
||||
Debug::log(WARN, "Error at ticking config at {}, error {}: {}", cf, err, strerror(err));
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if we need to reload cfg
|
||||
if (fileStat.st_mtime != configModifyTimes[cf] || m_bForceReload) {
|
||||
parse = true;
|
||||
configModifyTimes[cf] = fileStat.st_mtime;
|
||||
}
|
||||
}
|
||||
|
||||
if (parse) {
|
||||
m_bForceReload = false;
|
||||
|
||||
reload();
|
||||
}
|
||||
}
|
||||
|
||||
Hyprlang::CConfigValue* CConfigManager::getConfigValueSafeDevice(const std::string& dev, const std::string& val, const std::string& fallback) {
|
||||
|
||||
const auto VAL = m_pConfig->getSpecialConfigValuePtr("device", val.c_str(), dev.c_str());
|
||||
@@ -1274,10 +1258,10 @@ std::vector<SP<CWindowRule>> CConfigManager::getMatchingRules(PHLWINDOW pWindow,
|
||||
if (rule->szValue.starts_with("tag:") && !tags.isTagged(rule->szValue.substr(4)))
|
||||
continue;
|
||||
|
||||
if (rule->szValue.starts_with("title:") && !rule->rV1Regex.passes(pWindow->m_szTitle))
|
||||
if (rule->szValue.starts_with("title:") && !RE2::FullMatch(pWindow->m_szTitle, rule->szValue.substr(6)))
|
||||
continue;
|
||||
|
||||
if (!rule->rV1Regex.passes(pWindow->m_szClass))
|
||||
if (!RE2::FullMatch(pWindow->m_szClass, rule->szValue))
|
||||
continue;
|
||||
|
||||
} catch (...) {
|
||||
@@ -1367,16 +1351,16 @@ std::vector<SP<CWindowRule>> CConfigManager::getMatchingRules(PHLWINDOW pWindow,
|
||||
if (!rule->szTag.empty() && !tags.isTagged(rule->szTag))
|
||||
continue;
|
||||
|
||||
if (!rule->szClass.empty() && !rule->rClass.passes(pWindow->m_szClass))
|
||||
if (!rule->szClass.empty() && !RE2::FullMatch(pWindow->m_szClass, rule->szClass))
|
||||
continue;
|
||||
|
||||
if (!rule->szTitle.empty() && !rule->rTitle.passes(pWindow->m_szTitle))
|
||||
if (!rule->szTitle.empty() && !RE2::FullMatch(pWindow->m_szTitle, rule->szTitle))
|
||||
continue;
|
||||
|
||||
if (!rule->szInitialTitle.empty() && !rule->rInitialTitle.passes(pWindow->m_szInitialTitle))
|
||||
if (!rule->szInitialTitle.empty() && !RE2::FullMatch(pWindow->m_szInitialTitle, rule->szInitialTitle))
|
||||
continue;
|
||||
|
||||
if (!rule->szInitialClass.empty() && !rule->rInitialClass.passes(pWindow->m_szInitialClass))
|
||||
if (!rule->szInitialClass.empty() && !RE2::FullMatch(pWindow->m_szInitialClass, rule->szInitialClass))
|
||||
continue;
|
||||
|
||||
} catch (std::exception& e) {
|
||||
@@ -1435,7 +1419,7 @@ std::vector<SP<CLayerRule>> CConfigManager::getMatchingRules(PHLLS pLS) {
|
||||
if (lr->targetNamespace.starts_with("address:0x")) {
|
||||
if (std::format("address:0x{:x}", (uintptr_t)pLS.get()) != lr->targetNamespace)
|
||||
continue;
|
||||
} else if (!lr->targetNamespaceRegex.passes(pLS->layerSurface->layerNamespace))
|
||||
} else if (!RE2::FullMatch(pLS->layerSurface->layerNamespace, lr->targetNamespace))
|
||||
continue;
|
||||
|
||||
// hit
|
||||
@@ -1465,7 +1449,7 @@ void CConfigManager::dispatchExecOnce() {
|
||||
isLaunchingExecOnce = true;
|
||||
|
||||
for (auto const& c : firstExecRequests) {
|
||||
c.withRules ? handleExec("", c.exec) : handleRawExec("", c.exec);
|
||||
handleRawExec("", c);
|
||||
}
|
||||
|
||||
firstExecRequests.clear(); // free some kb of memory :P
|
||||
@@ -1499,6 +1483,22 @@ void CConfigManager::dispatchExecShutdown() {
|
||||
handleExecShutdown("", "hyprctl dispatch exit");
|
||||
}
|
||||
|
||||
void CConfigManager::appendMonitorRule(const SMonitorRule& r) {
|
||||
m_vMonitorRules.emplace_back(r);
|
||||
}
|
||||
|
||||
bool CConfigManager::replaceMonitorRule(const SMonitorRule& newrule) {
|
||||
// Looks for an existing monitor rule (compared by name).
|
||||
// If the rule exists, it is replaced with the input rule.
|
||||
for (auto& r : m_vMonitorRules) {
|
||||
if (r.name == newrule.name) {
|
||||
r = newrule;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CConfigManager::performMonitorReload() {
|
||||
|
||||
bool overAgain = false;
|
||||
@@ -1509,7 +1509,7 @@ void CConfigManager::performMonitorReload() {
|
||||
|
||||
auto rule = getMonitorRuleFor(m);
|
||||
|
||||
if (!m->applyMonitorRule(&rule)) {
|
||||
if (!g_pHyprRenderer->applyMonitorRule(m, &rule)) {
|
||||
overAgain = true;
|
||||
break;
|
||||
}
|
||||
@@ -1567,7 +1567,7 @@ void CConfigManager::ensureMonitorStatus() {
|
||||
auto rule = getMonitorRuleFor(rm);
|
||||
|
||||
if (rule.disabled == rm->m_bEnabled)
|
||||
rm->applyMonitorRule(&rule);
|
||||
g_pHyprRenderer->applyMonitorRule(rm, &rule);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1650,8 +1650,8 @@ void CConfigManager::ensureVRR(PHLMONITOR pMonitor) {
|
||||
}
|
||||
}
|
||||
|
||||
SP<SAnimationPropertyConfig> CConfigManager::getAnimationPropertyConfig(const std::string& name) {
|
||||
return m_AnimationTree.getConfig(name);
|
||||
SAnimationPropertyConfig* CConfigManager::getAnimationPropertyConfig(const std::string& name) {
|
||||
return &animationConfig[name];
|
||||
}
|
||||
|
||||
void CConfigManager::addParseError(const std::string& err) {
|
||||
@@ -1686,7 +1686,7 @@ void CConfigManager::addExecRule(const SExecRequestedRule& rule) {
|
||||
}
|
||||
|
||||
void CConfigManager::handlePluginLoads() {
|
||||
if (!g_pPluginSystem)
|
||||
if (g_pPluginSystem == nullptr)
|
||||
return;
|
||||
|
||||
bool pluginsChanged = false;
|
||||
@@ -1705,7 +1705,8 @@ void CConfigManager::handlePluginLoads() {
|
||||
|
||||
if (pluginsChanged) {
|
||||
g_pHyprError->destroy();
|
||||
reload();
|
||||
m_bForceReload = true;
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1713,8 +1714,12 @@ ICustomConfigValueData::~ICustomConfigValueData() {
|
||||
; // empty
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, SP<SAnimationPropertyConfig>>& CConfigManager::getAnimationConfig() {
|
||||
return m_AnimationTree.getFullConfig();
|
||||
std::unordered_map<std::string, SAnimationPropertyConfig> CConfigManager::getAnimationConfig() {
|
||||
return animationConfig;
|
||||
}
|
||||
|
||||
void onPluginLoadUnload(const std::string& name, bool load) {
|
||||
//
|
||||
}
|
||||
|
||||
void CConfigManager::addPluginConfigVar(HANDLE handle, const std::string& name, const Hyprlang::CConfigValue& value) {
|
||||
@@ -1767,17 +1772,7 @@ std::string CConfigManager::getDefaultWorkspaceFor(const std::string& name) {
|
||||
|
||||
std::optional<std::string> CConfigManager::handleRawExec(const std::string& command, const std::string& args) {
|
||||
if (isFirstLaunch) {
|
||||
firstExecRequests.push_back({args, false});
|
||||
return {};
|
||||
}
|
||||
|
||||
g_pKeybindManager->spawnRaw(args);
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<std::string> CConfigManager::handleExec(const std::string& command, const std::string& args) {
|
||||
if (isFirstLaunch) {
|
||||
firstExecRequests.push_back({args, true});
|
||||
firstExecRequests.push_back(args);
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -1787,14 +1782,7 @@ std::optional<std::string> CConfigManager::handleExec(const std::string& command
|
||||
|
||||
std::optional<std::string> CConfigManager::handleExecOnce(const std::string& command, const std::string& args) {
|
||||
if (isFirstLaunch)
|
||||
firstExecRequests.push_back({args, true});
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<std::string> CConfigManager::handleExecRawOnce(const std::string& command, const std::string& args) {
|
||||
if (isFirstLaunch)
|
||||
firstExecRequests.push_back({args, false});
|
||||
firstExecRequests.push_back(args);
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -2077,6 +2065,17 @@ std::optional<std::string> CConfigManager::handleBezier(const std::string& comma
|
||||
return {};
|
||||
}
|
||||
|
||||
void CConfigManager::setAnimForChildren(SAnimationPropertyConfig* const ANIM) {
|
||||
for (auto& [name, anim] : animationConfig) {
|
||||
if (anim.pParentAnimation == ANIM && !anim.overridden) {
|
||||
// if a child isnt overridden, set the values of the parent
|
||||
anim.pValues = ANIM->pValues;
|
||||
|
||||
setAnimForChildren(&anim);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::optional<std::string> CConfigManager::handleAnimation(const std::string& command, const std::string& args) {
|
||||
const auto ARGS = CVarList(args);
|
||||
|
||||
@@ -2085,9 +2084,14 @@ std::optional<std::string> CConfigManager::handleAnimation(const std::string& co
|
||||
// anim name
|
||||
const auto ANIMNAME = ARGS[0];
|
||||
|
||||
if (!m_AnimationTree.nodeExists(ANIMNAME))
|
||||
const auto PANIM = animationConfig.find(ANIMNAME);
|
||||
|
||||
if (PANIM == animationConfig.end())
|
||||
return "no such animation";
|
||||
|
||||
PANIM->second.overridden = true;
|
||||
PANIM->second.pValues = &PANIM->second;
|
||||
|
||||
// This helper casts strings like "1", "true", "off", "yes"... to int.
|
||||
int64_t enabledInt = configStringToInt(ARGS[1]).value_or(0) == 1;
|
||||
|
||||
@@ -2095,41 +2099,43 @@ std::optional<std::string> CConfigManager::handleAnimation(const std::string& co
|
||||
if (enabledInt != 0 && enabledInt != 1)
|
||||
return "invalid animation on/off state";
|
||||
|
||||
if (!enabledInt) {
|
||||
m_AnimationTree.setConfigForNode(ANIMNAME, enabledInt, 1, "default");
|
||||
return {};
|
||||
}
|
||||
|
||||
float speed = -1;
|
||||
PANIM->second.internalEnabled = configStringToInt(ARGS[1]).value_or(0) == 1;
|
||||
|
||||
if (PANIM->second.internalEnabled) {
|
||||
// speed
|
||||
if (isNumber(ARGS[2], true)) {
|
||||
speed = std::stof(ARGS[2]);
|
||||
PANIM->second.internalSpeed = std::stof(ARGS[2]);
|
||||
|
||||
if (speed <= 0) {
|
||||
speed = 1.f;
|
||||
if (PANIM->second.internalSpeed <= 0) {
|
||||
PANIM->second.internalSpeed = 1.f;
|
||||
return "invalid speed";
|
||||
}
|
||||
} else {
|
||||
speed = 10.f;
|
||||
PANIM->second.internalSpeed = 10.f;
|
||||
return "invalid speed";
|
||||
}
|
||||
|
||||
std::string bezierName = ARGS[3];
|
||||
m_AnimationTree.setConfigForNode(ANIMNAME, enabledInt, speed, ARGS[3], ARGS[4]);
|
||||
// curve
|
||||
PANIM->second.internalBezier = ARGS[3];
|
||||
|
||||
if (!g_pAnimationManager->bezierExists(bezierName)) {
|
||||
const auto PANIMNODE = m_AnimationTree.getConfig(ANIMNAME);
|
||||
PANIMNODE->internalBezier = "default";
|
||||
if (!g_pAnimationManager->bezierExists(ARGS[3])) {
|
||||
PANIM->second.internalBezier = "default";
|
||||
return "no such bezier";
|
||||
}
|
||||
|
||||
// style
|
||||
PANIM->second.internalStyle = ARGS[4];
|
||||
|
||||
if (ARGS[4] != "") {
|
||||
auto ERR = g_pAnimationManager->styleValidInConfigVar(ANIMNAME, ARGS[4]);
|
||||
|
||||
if (ERR != "")
|
||||
return ERR;
|
||||
}
|
||||
}
|
||||
|
||||
// now, check for children, recursively
|
||||
setAnimForChildren(&PANIM->second);
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -2295,8 +2301,6 @@ std::optional<std::string> CConfigManager::handleWindowRule(const std::string& c
|
||||
return "Invalid rule: " + RULE;
|
||||
}
|
||||
|
||||
newRule->rV1Regex = {VALUE.starts_with("title:") ? VALUE.substr(6) : VALUE};
|
||||
|
||||
if (RULE.starts_with("size") || RULE.starts_with("maxsize") || RULE.starts_with("minsize"))
|
||||
m_vWindowRules.insert(m_vWindowRules.begin(), newRule);
|
||||
else
|
||||
@@ -2325,8 +2329,6 @@ std::optional<std::string> CConfigManager::handleLayerRule(const std::string& co
|
||||
return "Invalid rule found: " + RULE;
|
||||
}
|
||||
|
||||
rule->targetNamespaceRegex = {VALUE};
|
||||
|
||||
m_vLayerRules.emplace_back(rule);
|
||||
|
||||
for (auto const& m : g_pCompositor->m_vMonitors)
|
||||
@@ -2425,25 +2427,17 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
||||
if (TAGPOS != std::string::npos)
|
||||
rule->szTag = extract(TAGPOS + 4);
|
||||
|
||||
if (CLASSPOS != std::string::npos) {
|
||||
if (CLASSPOS != std::string::npos)
|
||||
rule->szClass = extract(CLASSPOS + 6);
|
||||
rule->rClass = {rule->szClass};
|
||||
}
|
||||
|
||||
if (TITLEPOS != std::string::npos) {
|
||||
if (TITLEPOS != std::string::npos)
|
||||
rule->szTitle = extract(TITLEPOS + 6);
|
||||
rule->rTitle = {rule->szTitle};
|
||||
}
|
||||
|
||||
if (INITIALCLASSPOS != std::string::npos) {
|
||||
if (INITIALCLASSPOS != std::string::npos)
|
||||
rule->szInitialClass = extract(INITIALCLASSPOS + 13);
|
||||
rule->rInitialClass = {rule->szInitialClass};
|
||||
}
|
||||
|
||||
if (INITIALTITLEPOS != std::string::npos) {
|
||||
if (INITIALTITLEPOS != std::string::npos)
|
||||
rule->szInitialTitle = extract(INITIALTITLEPOS + 13);
|
||||
rule->rInitialTitle = {rule->szInitialTitle};
|
||||
}
|
||||
|
||||
if (X11POS != std::string::npos)
|
||||
rule->bX11 = extract(X11POS + 9) == "1" ? 1 : 0;
|
||||
@@ -2694,14 +2688,8 @@ std::optional<std::string> CConfigManager::handleSource(const std::string& comma
|
||||
Debug::log(ERR, "source= path garbage");
|
||||
return "source= path " + rawpath + " bogus!";
|
||||
}
|
||||
|
||||
std::unique_ptr<glob_t, void (*)(glob_t*)> glob_buf{static_cast<glob_t*>(calloc(1, sizeof(glob_t))), // allocate and zero-initialize
|
||||
[](glob_t* g) {
|
||||
if (g) {
|
||||
globfree(g); // free internal resources allocated by glob()
|
||||
free(g); // free the memory for the glob_t structure
|
||||
}
|
||||
}};
|
||||
std::unique_ptr<glob_t, void (*)(glob_t*)> glob_buf{new glob_t, [](glob_t* g) { globfree(g); }};
|
||||
memset(glob_buf.get(), 0, sizeof(glob_t));
|
||||
|
||||
if (auto r = glob(absolutePath(rawpath, configCurrentPath).c_str(), GLOB_TILDE, nullptr, glob_buf.get()); r != 0) {
|
||||
std::string err = std::format("source= globbing error: {}", r == GLOB_NOMATCH ? "found no match" : GLOB_ABORTED ? "read error" : "out of memory");
|
||||
@@ -2723,8 +2711,16 @@ std::optional<std::string> CConfigManager::handleSource(const std::string& comma
|
||||
Debug::log(ERR, "source= file doesn't exist: {}", value);
|
||||
return "source= file " + value + " doesn't exist!";
|
||||
}
|
||||
m_configPaths.emplace_back(value);
|
||||
configPaths.push_back(value);
|
||||
|
||||
struct stat fileStat;
|
||||
int err = stat(value.c_str(), &fileStat);
|
||||
if (err != 0) {
|
||||
Debug::log(WARN, "Error at ticking config at {}, error {}: {}", value, err, strerror(err));
|
||||
return {};
|
||||
}
|
||||
|
||||
configModifyTimes[value] = fileStat.st_mtime;
|
||||
auto configCurrentPathBackup = configCurrentPath;
|
||||
configCurrentPath = value;
|
||||
|
||||
@@ -2786,7 +2782,7 @@ bool CConfigManager::shouldUseSoftwareCursors() {
|
||||
switch (*PNOHW) {
|
||||
case 0: return false;
|
||||
case 1: return true;
|
||||
default: break;
|
||||
default: return g_pHyprRenderer->isNvidia();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2844,7 +2840,3 @@ std::string SConfigOptionDescription::jsonify() const {
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
void CConfigManager::ensurePersistentWorkspacesPresent() {
|
||||
g_pCompositor->ensurePersistentWorkspacesPresent(m_vWorkspaceRules);
|
||||
}
|
||||
|
@@ -1,30 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <hyprutils/animation/AnimationConfig.hpp>
|
||||
#define CONFIG_MANAGER_H
|
||||
|
||||
#include <map>
|
||||
#include "../debug/Log.hpp"
|
||||
#include <unordered_map>
|
||||
#include "../defines.hpp"
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
#include <xf86drmMode.h>
|
||||
#include "../helpers/WLClasses.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
#include "../helpers/varlist/VarList.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include "../desktop/LayerRule.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
|
||||
#include "defaultConfig.hpp"
|
||||
#include "ConfigDataValues.hpp"
|
||||
#include "../SharedDefs.hpp"
|
||||
#include "../helpers/Color.hpp"
|
||||
#include "../desktop/DesktopTypes.hpp"
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
#include "../desktop/WindowRule.hpp"
|
||||
#include "../managers/XWaylandManager.hpp"
|
||||
|
||||
#include <hyprlang.hpp>
|
||||
|
||||
#define INITANIMCFG(name) animationConfig[name] = {}
|
||||
#define CREATEANIMCFG(name, parent) animationConfig[name] = {false, "", "", 0.f, -1, &animationConfig["global"], &animationConfig[parent]}
|
||||
|
||||
#define HANDLE void*
|
||||
|
||||
struct SWorkspaceRule {
|
||||
@@ -53,6 +54,18 @@ struct SMonitorAdditionalReservedArea {
|
||||
int right = 0;
|
||||
};
|
||||
|
||||
struct SAnimationPropertyConfig {
|
||||
bool overridden = true;
|
||||
|
||||
std::string internalBezier = "";
|
||||
std::string internalStyle = "";
|
||||
float internalSpeed = 0.f;
|
||||
int internalEnabled = -1;
|
||||
|
||||
SAnimationPropertyConfig* pValues = nullptr;
|
||||
SAnimationPropertyConfig* pParentAnimation = nullptr;
|
||||
};
|
||||
|
||||
struct SPluginKeyword {
|
||||
HANDLE handle = nullptr;
|
||||
std::string name = "";
|
||||
@@ -133,18 +146,12 @@ struct SConfigOptionDescription {
|
||||
std::variant<SBoolData, SRangeData, SFloatData, SStringData, SColorData, SChoiceData, SGradientData, SVectorData> data;
|
||||
};
|
||||
|
||||
struct SFirstExecRequest {
|
||||
std::string exec = "";
|
||||
bool withRules = false;
|
||||
};
|
||||
|
||||
class CConfigManager {
|
||||
public:
|
||||
CConfigManager();
|
||||
|
||||
void tick();
|
||||
void init();
|
||||
void reload();
|
||||
std::string verify();
|
||||
|
||||
int getDeviceInt(const std::string&, const std::string&, const std::string& fallback = "");
|
||||
float getDeviceFloat(const std::string&, const std::string&, const std::string& fallback = "");
|
||||
@@ -156,7 +163,8 @@ class CConfigManager {
|
||||
|
||||
void* const* getConfigValuePtr(const std::string&);
|
||||
Hyprlang::CConfigValue* getHyprlangConfigValuePtr(const std::string& name, const std::string& specialCat = "");
|
||||
std::string getMainConfigPath();
|
||||
void onPluginLoadUnload(const std::string& name, bool load);
|
||||
static std::string getMainConfigPath();
|
||||
std::string getConfigString();
|
||||
|
||||
SMonitorRule getMonitorRuleFor(const PHLMONITOR);
|
||||
@@ -169,13 +177,12 @@ class CConfigManager {
|
||||
|
||||
std::vector<SP<CWindowRule>> getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false);
|
||||
std::vector<SP<CLayerRule>> getMatchingRules(PHLLS);
|
||||
void ensurePersistentWorkspacesPresent();
|
||||
|
||||
const std::vector<SConfigOptionDescription>& getAllDescriptions();
|
||||
|
||||
std::unordered_map<std::string, SMonitorAdditionalReservedArea> m_mAdditionalReservedAreas;
|
||||
|
||||
const std::unordered_map<std::string, SP<Hyprutils::Animation::SAnimationPropertyConfig>>& getAnimationConfig();
|
||||
std::unordered_map<std::string, SAnimationPropertyConfig> getAnimationConfig();
|
||||
|
||||
void addPluginConfigVar(HANDLE handle, const std::string& name, const Hyprlang::CConfigValue& value);
|
||||
void addPluginKeyword(HANDLE handle, const std::string& name, Hyprlang::PCONFIGHANDLERFUNC fun, Hyprlang::SHandlerOptions opts = {});
|
||||
@@ -186,17 +193,18 @@ class CConfigManager {
|
||||
void dispatchExecShutdown();
|
||||
|
||||
void performMonitorReload();
|
||||
void appendMonitorRule(const SMonitorRule&);
|
||||
bool replaceMonitorRule(const SMonitorRule&);
|
||||
void ensureMonitorStatus();
|
||||
void ensureVRR(PHLMONITOR pMonitor = nullptr);
|
||||
|
||||
bool shouldUseSoftwareCursors();
|
||||
void updateWatcher();
|
||||
|
||||
std::string parseKeyword(const std::string&, const std::string&);
|
||||
|
||||
void addParseError(const std::string&);
|
||||
|
||||
SP<Hyprutils::Animation::SAnimationPropertyConfig> getAnimationPropertyConfig(const std::string&);
|
||||
SAnimationPropertyConfig* getAnimationPropertyConfig(const std::string&);
|
||||
|
||||
void addExecRule(const SExecRequestedRule&);
|
||||
|
||||
@@ -205,9 +213,7 @@ class CConfigManager {
|
||||
|
||||
// keywords
|
||||
std::optional<std::string> handleRawExec(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExec(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExecOnce(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExecRawOnce(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExecShutdown(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleMonitor(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleBind(const std::string&, const std::string&);
|
||||
@@ -256,21 +262,21 @@ class CConfigManager {
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, std::function<CWindowOverridableVar<float>*(PHLWINDOW)>> mfWindowProperties = {
|
||||
{"roundingpower", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.roundingPower; }},
|
||||
{"scrollmouse", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollMouse; }},
|
||||
{"scrolltouchpad", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollTouchpad; }}};
|
||||
|
||||
bool m_bWantsMonitorReload = false;
|
||||
bool m_bForceReload = false;
|
||||
bool m_bNoMonitorReload = false;
|
||||
bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking
|
||||
bool m_bLastConfigVerificationWasSuccessful = true;
|
||||
|
||||
private:
|
||||
UP<Hyprlang::CConfig> m_pConfig;
|
||||
std::unique_ptr<Hyprlang::CConfig> m_pConfig;
|
||||
|
||||
std::vector<std::string> m_configPaths;
|
||||
std::vector<std::string> configPaths; // stores all the config paths
|
||||
std::unordered_map<std::string, time_t> configModifyTimes; // stores modify times
|
||||
|
||||
Hyprutils::Animation::CAnimationConfigTree m_AnimationTree;
|
||||
std::unordered_map<std::string, SAnimationPropertyConfig> animationConfig; // stores all the animations with their set values
|
||||
|
||||
std::string m_szCurrentSubmap = ""; // For storing the current keybind submap
|
||||
|
||||
@@ -290,21 +296,22 @@ class CConfigManager {
|
||||
|
||||
bool firstExecDispatched = false;
|
||||
bool m_bManualCrashInitiated = false;
|
||||
|
||||
std::vector<SFirstExecRequest> firstExecRequests; // bool is for if with rules
|
||||
std::vector<std::string> firstExecRequests;
|
||||
std::vector<std::string> finalExecRequests;
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins
|
||||
std::string m_szConfigErrors = "";
|
||||
|
||||
// internal methods
|
||||
void setAnimForChildren(SAnimationPropertyConfig* const);
|
||||
void updateBlurredLS(const std::string&, const bool);
|
||||
void setDefaultAnimationVars();
|
||||
std::optional<std::string> resetHLConfig();
|
||||
std::optional<std::string> generateConfig(std::string configPath);
|
||||
std::optional<std::string> verifyConfigExists();
|
||||
static std::optional<std::string> generateConfig(std::string configPath);
|
||||
static std::optional<std::string> verifyConfigExists();
|
||||
void postConfigReload(const Hyprlang::CParseResult& result);
|
||||
void reload();
|
||||
SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&);
|
||||
};
|
||||
|
||||
inline UP<CConfigManager> g_pConfigManager;
|
||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include <string>
|
||||
#include <typeindex>
|
||||
#include <hyprlang.hpp>
|
||||
#include "../debug/Log.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "ConfigManager.hpp"
|
||||
|
||||
|
@@ -1,73 +0,0 @@
|
||||
#include "ConfigWatcher.hpp"
|
||||
#include <sys/inotify.h>
|
||||
#include "../debug/Log.hpp"
|
||||
#include <ranges>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
CConfigWatcher::CConfigWatcher() : m_inotifyFd(inotify_init()) {
|
||||
if (m_inotifyFd < 0) {
|
||||
Debug::log(ERR, "CConfigWatcher couldn't open an inotify node. Config will not be automatically reloaded");
|
||||
return;
|
||||
}
|
||||
|
||||
const int FLAGS = fcntl(m_inotifyFd, F_GETFL, 0);
|
||||
if (fcntl(m_inotifyFd, F_SETFL, FLAGS | O_NONBLOCK) < 0) {
|
||||
Debug::log(ERR, "CConfigWatcher couldn't non-block inotify node. Config will not be automatically reloaded");
|
||||
close(m_inotifyFd);
|
||||
m_inotifyFd = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CConfigWatcher::~CConfigWatcher() {
|
||||
if (m_inotifyFd >= 0)
|
||||
close(m_inotifyFd);
|
||||
}
|
||||
|
||||
int CConfigWatcher::getInotifyFD() {
|
||||
return m_inotifyFd;
|
||||
}
|
||||
|
||||
void CConfigWatcher::setWatchList(const std::vector<std::string>& paths) {
|
||||
|
||||
// we clear all watches first, because whichever fired is now invalid
|
||||
// or that is at least what it seems to be.
|
||||
// since we don't know which fired,
|
||||
// plus it doesn't matter that much, these ops are done rarely and fast anyways.
|
||||
|
||||
// cleanup old paths
|
||||
for (auto& watch : m_watches) {
|
||||
inotify_rm_watch(m_inotifyFd, watch.wd);
|
||||
}
|
||||
|
||||
m_watches.clear();
|
||||
|
||||
// add new paths
|
||||
for (const auto& path : paths) {
|
||||
m_watches.emplace_back(SInotifyWatch{
|
||||
.wd = inotify_add_watch(m_inotifyFd, path.c_str(), IN_MODIFY),
|
||||
.file = path,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigWatcher::setOnChange(const std::function<void(const SConfigWatchEvent&)>& fn) {
|
||||
m_watchCallback = fn;
|
||||
}
|
||||
|
||||
void CConfigWatcher::onInotifyEvent() {
|
||||
inotify_event ev;
|
||||
while (read(m_inotifyFd, &ev, sizeof(ev)) > 0) {
|
||||
const auto WD = std::ranges::find_if(m_watches.begin(), m_watches.end(), [wd = ev.wd](const auto& e) { return e.wd == wd; });
|
||||
|
||||
if (WD == m_watches.end()) {
|
||||
Debug::log(ERR, "CConfigWatcher: got an event for wd {} which we don't have?!", ev.wd);
|
||||
return;
|
||||
}
|
||||
|
||||
m_watchCallback(SConfigWatchEvent{
|
||||
.file = WD->file,
|
||||
});
|
||||
}
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
class CConfigWatcher {
|
||||
public:
|
||||
CConfigWatcher();
|
||||
~CConfigWatcher();
|
||||
|
||||
struct SConfigWatchEvent {
|
||||
std::string file;
|
||||
};
|
||||
|
||||
int getInotifyFD();
|
||||
void setWatchList(const std::vector<std::string>& paths);
|
||||
void setOnChange(const std::function<void(const SConfigWatchEvent&)>& fn);
|
||||
void onInotifyEvent();
|
||||
|
||||
private:
|
||||
struct SInotifyWatch {
|
||||
int wd = -1;
|
||||
std::string file;
|
||||
};
|
||||
|
||||
std::function<void(const SConfigWatchEvent&)> m_watchCallback;
|
||||
std::vector<SInotifyWatch> m_watches;
|
||||
int m_inotifyFd = -1;
|
||||
};
|
||||
|
||||
inline UP<CConfigWatcher> g_pConfigWatcher = makeUnique<CConfigWatcher>();
|
@@ -94,7 +94,6 @@ general {
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
||||
decoration {
|
||||
rounding = 10
|
||||
rounding_power = 2
|
||||
|
||||
# Change transparency of focused and unfocused windows
|
||||
active_opacity = 1.0
|
||||
|
@@ -6,7 +6,6 @@
|
||||
#include <cerrno>
|
||||
#include <sys/stat.h>
|
||||
#include <filesystem>
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
|
||||
#include "../plugins/PluginSystem.hpp"
|
||||
#include "../signal-safe.hpp"
|
||||
@@ -112,7 +111,7 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
||||
#ifdef LEGACY_RENDERER
|
||||
finalCrashReport += "legacyrenderer\n";
|
||||
#endif
|
||||
#if ISDEBUG
|
||||
#ifndef ISDEBUG
|
||||
finalCrashReport += "debug\n";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
@@ -162,7 +161,7 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
finalCrashReport.writeCmdOutput("pciconf -lv | grep -F -A4 vga");
|
||||
#else
|
||||
finalCrashReport.writeCmdOutput("lspci -vnn | grep -E '(VGA|Display|3D)'");
|
||||
finalCrashReport.writeCmdOutput("lspci -vnn | grep VGA");
|
||||
#endif
|
||||
|
||||
finalCrashReport += "\n\nos-release:\n";
|
||||
|
@@ -39,18 +39,8 @@ using namespace Hyprutils::String;
|
||||
#include "debug/RollingLogFollow.hpp"
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "helpers/MiscFunctions.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "../version.h"
|
||||
|
||||
#include "../Compositor.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/XWaylandManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../plugins/PluginSystem.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../debug/HyprNotificationOverlay.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
|
||||
static void trimTrailingComma(std::string& str) {
|
||||
if (!str.empty() && str.back() == ',')
|
||||
str.pop_back();
|
||||
@@ -152,7 +142,7 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor>
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
auto allMonitors = false;
|
||||
|
||||
@@ -258,8 +248,8 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) {
|
||||
"focusHistoryID": {},
|
||||
"inhibitingIdle": {}
|
||||
}},)#",
|
||||
(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,
|
||||
(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),
|
||||
escapeJSONStrings(w->m_szInitialTitle), w->getPID(), ((int)w->m_bIsX11 == 1 ? "true" : "false"), (w->m_bPinned ? "true" : "false"),
|
||||
@@ -271,16 +261,15 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) {
|
||||
"{}\n\tinitialClass: {}\n\tinitialTitle: {}\n\tpid: "
|
||||
"{}\n\txwayland: {}\n\tpinned: "
|
||||
"{}\n\tfullscreen: {}\n\tfullscreenClient: {}\n\tgrouped: {}\n\ttags: {}\n\tswallowing: {:x}\n\tfocusHistoryID: {}\n\tinhibitingIdle: {}\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_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),
|
||||
(int)g_pInputManager->isWindowInhibiting(w, false));
|
||||
(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_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), (int)g_pInputManager->isWindowInhibiting(w, false));
|
||||
}
|
||||
}
|
||||
|
||||
static std::string clientsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string clientsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string result = "";
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
result += "[";
|
||||
@@ -379,8 +368,7 @@ static std::string getWorkspaceRuleData(const SWorkspaceRule& r, eHyprCtlOutputF
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
static std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
if (!g_pCompositor->m_pLastMonitor)
|
||||
return "unsafe state";
|
||||
|
||||
@@ -393,7 +381,7 @@ static std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::stri
|
||||
return CHyprCtl::getWorkspaceData(w, format);
|
||||
}
|
||||
|
||||
static std::string workspacesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string workspacesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string result = "";
|
||||
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
@@ -414,7 +402,7 @@ static std::string workspacesRequest(eHyprCtlOutputFormat format, std::string re
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string result = "";
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
result += "[";
|
||||
@@ -434,7 +422,7 @@ static std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::strin
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string activeWindowRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string activeWindowRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
const auto PWINDOW = g_pCompositor->m_pLastWindow.lock();
|
||||
|
||||
if (!validMapped(PWINDOW))
|
||||
@@ -448,7 +436,7 @@ static std::string activeWindowRequest(eHyprCtlOutputFormat format, std::string
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string layersRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string layersRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string result = "";
|
||||
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
@@ -522,7 +510,7 @@ static std::string layersRequest(eHyprCtlOutputFormat format, std::string reques
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string layoutsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string layoutsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string result = "";
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
result += "[";
|
||||
@@ -544,7 +532,7 @@ static std::string layoutsRequest(eHyprCtlOutputFormat format, std::string reque
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string configErrorsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string configErrorsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string result = "";
|
||||
std::string currErrors = g_pConfigManager->getErrors();
|
||||
CVarList errLines(currErrors, 0, '\n');
|
||||
@@ -567,7 +555,7 @@ static std::string configErrorsRequest(eHyprCtlOutputFormat format, std::string
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string devicesRequest(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 {
|
||||
@@ -737,14 +725,14 @@ static std::string devicesRequest(eHyprCtlOutputFormat format, std::string reque
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string animationsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string animationsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string ret = "";
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||
ret += "animations:\n";
|
||||
|
||||
for (auto const& ac : g_pConfigManager->getAnimationConfig()) {
|
||||
ret += std::format("\n\tname: {}\n\t\toverriden: {}\n\t\tbezier: {}\n\t\tenabled: {}\n\t\tspeed: {:.2f}\n\t\tstyle: {}\n", ac.first, (int)ac.second->overridden,
|
||||
ac.second->internalBezier, ac.second->internalEnabled, ac.second->internalSpeed, ac.second->internalStyle);
|
||||
ret += std::format("\n\tname: {}\n\t\toverriden: {}\n\t\tbezier: {}\n\t\tenabled: {}\n\t\tspeed: {:.2f}\n\t\tstyle: {}\n", ac.first, (int)ac.second.overridden,
|
||||
ac.second.internalBezier, ac.second.internalEnabled, ac.second.internalSpeed, ac.second.internalStyle);
|
||||
}
|
||||
|
||||
ret += "beziers:\n";
|
||||
@@ -766,8 +754,8 @@ static std::string animationsRequest(eHyprCtlOutputFormat format, std::string re
|
||||
"speed": {:.2f},
|
||||
"style": "{}"
|
||||
}},)#",
|
||||
ac.first, ac.second->overridden ? "true" : "false", escapeJSONStrings(ac.second->internalBezier), ac.second->internalEnabled ? "true" : "false",
|
||||
ac.second->internalSpeed, escapeJSONStrings(ac.second->internalStyle));
|
||||
ac.first, ac.second.overridden ? "true" : "false", escapeJSONStrings(ac.second.internalBezier), ac.second.internalEnabled ? "true" : "false",
|
||||
ac.second.internalSpeed, escapeJSONStrings(ac.second.internalStyle));
|
||||
}
|
||||
|
||||
ret[ret.length() - 1] = ']';
|
||||
@@ -790,7 +778,7 @@ static std::string animationsRequest(eHyprCtlOutputFormat format, std::string re
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::string rollinglogRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string rollinglogRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string result = "";
|
||||
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
@@ -804,7 +792,7 @@ static std::string rollinglogRequest(eHyprCtlOutputFormat format, std::string re
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string globalShortcutsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string globalShortcutsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string ret = "";
|
||||
const auto SHORTCUTS = PROTO::globalShortcuts->getAllShortcuts();
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||
@@ -827,7 +815,7 @@ static std::string globalShortcutsRequest(eHyprCtlOutputFormat format, std::stri
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string ret = "";
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||
for (auto const& kb : g_pKeybindManager->m_vKeybinds) {
|
||||
@@ -895,14 +883,14 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
HYPRLAND_VERSION, GIT_BRANCH, GIT_COMMIT_HASH, GIT_DIRTY, commitMsg, GIT_COMMIT_DATE, GIT_TAG, GIT_COMMITS, AQUAMARINE_VERSION,
|
||||
HYPRLANG_VERSION, HYPRUTILS_VERSION, HYPRCURSOR_VERSION, HYPRGRAPHICS_VERSION);
|
||||
|
||||
#if (!defined(LEGACY_RENDERER) && !ISDEBUG && !defined(NO_XWAYLAND))
|
||||
#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
|
||||
#if ISDEBUG
|
||||
#ifdef ISDEBUG
|
||||
result += "debug\n";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
@@ -933,7 +921,7 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
#ifdef LEGACY_RENDERER
|
||||
result += "\"legacyrenderer\",";
|
||||
#endif
|
||||
#if ISDEBUG
|
||||
#ifdef ISDEBUG
|
||||
result += "\"debug\",";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
@@ -988,7 +976,7 @@ std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request)
|
||||
}
|
||||
} catch (...) { GPUINFO = "error"; }
|
||||
#else
|
||||
const std::string GPUINFO = execAndGet("lspci -vnn | grep -E '(VGA|Display|3D)'");
|
||||
const std::string GPUINFO = execAndGet("lspci -vnn | grep VGA");
|
||||
#endif
|
||||
result += "GPU information: \n" + GPUINFO;
|
||||
if (GPUINFO.contains("NVIDIA") && std::filesystem::exists("/proc/driver/nvidia/version")) {
|
||||
@@ -1030,7 +1018,7 @@ std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request)
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string dispatchRequest(eHyprCtlOutputFormat format, std::string in) {
|
||||
std::string dispatchRequest(eHyprCtlOutputFormat format, std::string in) {
|
||||
// get rid of the dispatch keyword
|
||||
in = in.substr(in.find_first_of(' ') + 1);
|
||||
|
||||
@@ -1051,7 +1039,7 @@ static std::string dispatchRequest(eHyprCtlOutputFormat format, std::string in)
|
||||
return res.success ? "ok" : res.error;
|
||||
}
|
||||
|
||||
static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) {
|
||||
std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) {
|
||||
// Find the first space to strip the keyword keyword
|
||||
auto const firstSpacePos = in.find_first_of(' ');
|
||||
if (firstSpacePos == std::string::npos) // Handle the case where there's no space found (invalid input)
|
||||
@@ -1100,9 +1088,6 @@ static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in)
|
||||
}
|
||||
}
|
||||
|
||||
if (COMMAND.contains("misc:disable_autoreload"))
|
||||
g_pConfigManager->updateWatcher();
|
||||
|
||||
// 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")) {
|
||||
@@ -1120,29 +1105,32 @@ static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static std::string reloadRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string reloadRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
|
||||
const auto REQMODE = request.substr(request.find_last_of(' ') + 1);
|
||||
|
||||
if (REQMODE == "config-only")
|
||||
g_pConfigManager->m_bNoMonitorReload = true;
|
||||
g_pConfigManager->m_bForceReload = true;
|
||||
|
||||
g_pConfigManager->reload();
|
||||
if (REQMODE == "config-only") {
|
||||
g_pConfigManager->m_bNoMonitorReload = true;
|
||||
}
|
||||
|
||||
g_pConfigManager->tick();
|
||||
|
||||
return "ok";
|
||||
}
|
||||
|
||||
static std::string killRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string killRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
g_pInputManager->setClickMode(CLICKMODE_KILL);
|
||||
|
||||
return "ok";
|
||||
}
|
||||
|
||||
static std::string splashRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string splashRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
return g_pCompositor->m_szCurrentSplash;
|
||||
}
|
||||
|
||||
static std::string cursorPosRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string cursorPosRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal().floor();
|
||||
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||
@@ -1160,33 +1148,41 @@ static std::string cursorPosRequest(eHyprCtlOutputFormat format, std::string req
|
||||
return "error";
|
||||
}
|
||||
|
||||
static std::string dispatchBatch(eHyprCtlOutputFormat format, std::string request) {
|
||||
// split by ; ignores ; inside [] and adds ; on last command
|
||||
std::string dispatchBatch(eHyprCtlOutputFormat format, std::string request) {
|
||||
// split by ;
|
||||
|
||||
request = request.substr(9);
|
||||
std::string curitem = "";
|
||||
std::string reply = "";
|
||||
const std::string DELIMITER = "\n\n\n";
|
||||
int bracket = 0;
|
||||
size_t idx = 0;
|
||||
|
||||
for (size_t i = 0; i <= request.size(); ++i) {
|
||||
char ch = (i < request.size()) ? request[i] : ';';
|
||||
if (ch == '[')
|
||||
++bracket;
|
||||
else if (ch == ']')
|
||||
--bracket;
|
||||
else if (ch == ';' && bracket == 0) {
|
||||
if (idx < i)
|
||||
reply += g_pHyprCtl->getReply(trim(request.substr(idx, i - idx))).append(DELIMITER);
|
||||
idx = i + 1;
|
||||
continue;
|
||||
auto nextItem = [&]() {
|
||||
auto idx = request.find_first_of(';');
|
||||
|
||||
if (idx != std::string::npos) {
|
||||
curitem = request.substr(0, idx);
|
||||
request = request.substr(idx + 1);
|
||||
} else {
|
||||
curitem = request;
|
||||
request = "";
|
||||
}
|
||||
|
||||
curitem = trim(curitem);
|
||||
};
|
||||
|
||||
nextItem();
|
||||
|
||||
const std::string DELIMITER = "\n\n\n";
|
||||
|
||||
while (curitem != "" || request != "") {
|
||||
reply += g_pHyprCtl->getReply(curitem) + DELIMITER;
|
||||
|
||||
nextItem();
|
||||
}
|
||||
|
||||
return reply.substr(0, std::max(static_cast<int>(reply.size() - DELIMITER.size()), 0));
|
||||
}
|
||||
|
||||
static std::string dispatchSetCursor(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string dispatchSetCursor(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
|
||||
const auto SIZESTR = vars[vars.size() - 1];
|
||||
@@ -1210,7 +1206,7 @@ static std::string dispatchSetCursor(eHyprCtlOutputFormat format, std::string re
|
||||
return "ok";
|
||||
}
|
||||
|
||||
static std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
|
||||
const auto KB = vars[1];
|
||||
@@ -1285,7 +1281,7 @@ static std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::stri
|
||||
return "ok";
|
||||
}
|
||||
|
||||
static std::string dispatchSeterror(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string dispatchSeterror(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
|
||||
std::string errorMessage = "";
|
||||
@@ -1314,12 +1310,12 @@ static std::string dispatchSeterror(eHyprCtlOutputFormat format, std::string req
|
||||
return "ok";
|
||||
}
|
||||
|
||||
static std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) {
|
||||
auto result = g_pKeybindManager->m_mDispatchers["setprop"](request.substr(request.find_first_of(' ') + 1));
|
||||
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);
|
||||
}
|
||||
|
||||
static std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string curitem = "";
|
||||
|
||||
auto nextItem = [&]() {
|
||||
@@ -1375,7 +1371,7 @@ static std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string re
|
||||
return "invalid type (internal error)";
|
||||
}
|
||||
|
||||
static std::string decorationRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string decorationRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[1]);
|
||||
|
||||
@@ -1401,7 +1397,7 @@ static std::string decorationRequest(eHyprCtlOutputFormat format, std::string re
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string dispatchOutput(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string dispatchOutput(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
|
||||
if (vars.size() < 2)
|
||||
@@ -1456,7 +1452,7 @@ static std::string dispatchOutput(eHyprCtlOutputFormat format, std::string reque
|
||||
return "ok";
|
||||
}
|
||||
|
||||
static std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
|
||||
if (vars.size() < 2)
|
||||
@@ -1525,7 +1521,7 @@ static std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string reque
|
||||
return "ok";
|
||||
}
|
||||
|
||||
static std::string dispatchNotify(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string dispatchNotify(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
|
||||
if (vars.size() < 5)
|
||||
@@ -1580,7 +1576,7 @@ static std::string dispatchNotify(eHyprCtlOutputFormat format, std::string reque
|
||||
return "ok";
|
||||
}
|
||||
|
||||
static std::string dispatchDismissNotify(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string dispatchDismissNotify(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
|
||||
int amount = -1;
|
||||
@@ -1600,7 +1596,7 @@ static std::string dispatchDismissNotify(eHyprCtlOutputFormat format, std::strin
|
||||
return "ok";
|
||||
}
|
||||
|
||||
static std::string getIsLocked(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string getIsLocked(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string lockedStr = g_pSessionLockManager->isSessionLocked() ? "true" : "false";
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON)
|
||||
lockedStr = std::format(R"#(
|
||||
@@ -1612,7 +1608,7 @@ static std::string getIsLocked(eHyprCtlOutputFormat format, std::string request)
|
||||
return lockedStr;
|
||||
}
|
||||
|
||||
static std::string getDescriptions(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string getDescriptions(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string json = "{";
|
||||
const auto& DESCS = g_pConfigManager->getAllDescriptions();
|
||||
|
||||
@@ -1627,7 +1623,7 @@ static std::string getDescriptions(eHyprCtlOutputFormat format, std::string requ
|
||||
return json;
|
||||
}
|
||||
|
||||
static std::string submapRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string submapRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string submap = g_pKeybindManager->getCurrentSubmap();
|
||||
if (submap.empty())
|
||||
submap = "default";
|
||||
@@ -1796,7 +1792,7 @@ std::string CHyprCtl::makeDynamicCall(const std::string& input) {
|
||||
return getReply(input);
|
||||
}
|
||||
|
||||
static bool successWrite(int fd, const std::string& data, bool needLog = true) {
|
||||
bool successWrite(int fd, const std::string& data, bool needLog = true) {
|
||||
if (write(fd, data.c_str(), data.length()) > 0)
|
||||
return true;
|
||||
|
||||
@@ -1809,7 +1805,7 @@ static bool successWrite(int fd, const std::string& data, bool needLog = true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void runWritingDebugLogThread(const int conn) {
|
||||
void runWritingDebugLogThread(const int conn) {
|
||||
using namespace std::chrono_literals;
|
||||
Debug::log(LOG, "In followlog thread, got connection, start writing: {}", conn);
|
||||
//will be finished, when reading side close connection
|
||||
@@ -1832,11 +1828,11 @@ static void runWritingDebugLogThread(const int conn) {
|
||||
}).detach();
|
||||
}
|
||||
|
||||
static bool isFollowUpRollingLogRequest(const std::string& request) {
|
||||
bool isFollowUpRollingLogRequest(const std::string& request) {
|
||||
return request.contains("rollinglog") && request.contains("f");
|
||||
}
|
||||
|
||||
static int hyprCtlFDTick(int fd, uint32_t mask, void* data) {
|
||||
int hyprCtlFDTick(int fd, uint32_t mask, void* data) {
|
||||
if (mask & WL_EVENT_ERROR || mask & WL_EVENT_HANGUP)
|
||||
return 0;
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Compositor.hpp"
|
||||
#include <fstream>
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include <functional>
|
||||
|
||||
// exposed for main.cpp
|
||||
@@ -38,4 +38,4 @@ class CHyprCtl {
|
||||
std::string m_socketPath;
|
||||
};
|
||||
|
||||
inline UP<CHyprCtl> g_pHyprCtl;
|
||||
inline std::unique_ptr<CHyprCtl> g_pHyprCtl;
|
||||
|
@@ -2,9 +2,6 @@
|
||||
#include "HyprDebugOverlay.hpp"
|
||||
#include "config/ConfigValue.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../render/pass/TexPassElement.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
|
||||
CHyprDebugOverlay::CHyprDebugOverlay() {
|
||||
m_pTexture = makeShared<CTexture>();
|
||||
@@ -198,10 +195,10 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||
double posX = 0, posY = 0;
|
||||
cairo_get_current_point(cr, &posX, &posY);
|
||||
|
||||
g_pHyprRenderer->damageBox(m_wbLastDrawnBox);
|
||||
g_pHyprRenderer->damageBox(&m_wbLastDrawnBox);
|
||||
m_wbLastDrawnBox = {(int)g_pCompositor->m_vMonitors.front()->vecPosition.x + MARGIN_LEFT - 1, (int)g_pCompositor->m_vMonitors.front()->vecPosition.y + offset + MARGIN_TOP - 1,
|
||||
(int)maxTextW + 2, posY - offset - MARGIN_TOP + 2};
|
||||
g_pHyprRenderer->damageBox(m_wbLastDrawnBox);
|
||||
g_pHyprRenderer->damageBox(&m_wbLastDrawnBox);
|
||||
|
||||
return posY - offset;
|
||||
}
|
||||
@@ -271,8 +268,6 @@ void CHyprDebugOverlay::draw() {
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
CTexPassElement::SRenderData data;
|
||||
data.tex = m_pTexture;
|
||||
data.box = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
||||
g_pHyprRenderer->m_sRenderPass.add(makeShared<CTexPassElement>(data));
|
||||
CBox pMonBox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
||||
g_pHyprOpenGL->renderTexture(m_pTexture, &pMonBox, 1.f);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
#include "../render/Texture.hpp"
|
||||
#include <cairo/cairo.h>
|
||||
#include <map>
|
||||
@@ -48,4 +49,4 @@ class CHyprDebugOverlay {
|
||||
friend class CHyprRenderer;
|
||||
};
|
||||
|
||||
inline UP<CHyprDebugOverlay> g_pDebugOverlay;
|
||||
inline std::unique_ptr<CHyprDebugOverlay> g_pDebugOverlay;
|
@@ -3,13 +3,8 @@
|
||||
#include "HyprNotificationOverlay.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../render/pass/TexPassElement.hpp"
|
||||
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
|
||||
static inline auto iconBackendFromLayout(PangoLayout* layout) {
|
||||
inline auto iconBackendFromLayout(PangoLayout* layout) {
|
||||
// preference: Nerd > FontAwesome > text
|
||||
auto eIconBackendChecks = std::array<eIconBackend, 2>{ICONS_BACKEND_NF, ICONS_BACKEND_FA};
|
||||
for (auto iconID : eIconBackendChecks) {
|
||||
@@ -26,7 +21,7 @@ CHyprNotificationOverlay::CHyprNotificationOverlay() {
|
||||
if (m_vNotifications.size() == 0)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageBox(m_bLastDamage);
|
||||
g_pHyprRenderer->damageBox(&m_bLastDamage);
|
||||
});
|
||||
|
||||
m_pTexture = makeShared<CTexture>();
|
||||
@@ -40,7 +35,7 @@ CHyprNotificationOverlay::~CHyprNotificationOverlay() {
|
||||
}
|
||||
|
||||
void CHyprNotificationOverlay::addNotification(const std::string& text, const CHyprColor& color, const float timeMs, const eIcons icon, const float fontSize) {
|
||||
const auto PNOTIF = m_vNotifications.emplace_back(makeUnique<SNotification>()).get();
|
||||
const auto PNOTIF = m_vNotifications.emplace_back(std::make_unique<SNotification>()).get();
|
||||
|
||||
PNOTIF->text = icon != eIcons::ICON_NONE ? " " + text /* tiny bit of padding otherwise icon touches text */ : text;
|
||||
PNOTIF->color = color == CHyprColor(0) ? ICONS_COLORS[icon] : color;
|
||||
@@ -225,8 +220,8 @@ void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) {
|
||||
|
||||
CBox damage = drawNotifications(pMonitor);
|
||||
|
||||
g_pHyprRenderer->damageBox(damage);
|
||||
g_pHyprRenderer->damageBox(m_bLastDamage);
|
||||
g_pHyprRenderer->damageBox(&damage);
|
||||
g_pHyprRenderer->damageBox(&m_bLastDamage);
|
||||
|
||||
g_pCompositor->scheduleFrameForMonitor(pMonitor);
|
||||
|
||||
@@ -246,12 +241,8 @@ void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) {
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MONSIZE.x, MONSIZE.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
CTexPassElement::SRenderData data;
|
||||
data.tex = m_pTexture;
|
||||
data.box = {0, 0, MONSIZE.x, MONSIZE.y};
|
||||
data.a = 1.F;
|
||||
|
||||
g_pHyprRenderer->m_sRenderPass.add(makeShared<CTexPassElement>(data));
|
||||
CBox pMonBox = {0, 0, MONSIZE.x, MONSIZE.y};
|
||||
g_pHyprOpenGL->renderTexture(m_pTexture, &pMonBox, 1.f);
|
||||
}
|
||||
|
||||
bool CHyprNotificationOverlay::hasAny() {
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "../helpers/Timer.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
#include "../render/Texture.hpp"
|
||||
#include "../SharedDefs.hpp"
|
||||
|
||||
@@ -49,7 +50,7 @@ class CHyprNotificationOverlay {
|
||||
CBox drawNotifications(PHLMONITOR pMonitor);
|
||||
CBox m_bLastDamage;
|
||||
|
||||
std::vector<UP<SNotification>> m_vNotifications;
|
||||
std::vector<std::unique_ptr<SNotification>> m_vNotifications;
|
||||
|
||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||
cairo_t* m_pCairo = nullptr;
|
||||
@@ -60,4 +61,4 @@ class CHyprNotificationOverlay {
|
||||
SP<CTexture> m_pTexture;
|
||||
};
|
||||
|
||||
inline UP<CHyprNotificationOverlay> g_pHyprNotificationOverlay;
|
||||
inline std::unique_ptr<CHyprNotificationOverlay> g_pHyprNotificationOverlay;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include "Log.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "RollingLogFollow.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
@@ -5,6 +5,8 @@
|
||||
#include <fstream>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include "../includes.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
|
||||
#define LOGMESSAGESIZE 1024
|
||||
#define ROLLING_LOG_SIZE 4096
|
||||
|
@@ -1,5 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "includes.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "helpers/Color.hpp"
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
#include "../macros.hpp"
|
||||
class CWorkspace;
|
||||
class CWindow;
|
||||
class CLayerSurface;
|
||||
|
@@ -1,4 +1,3 @@
|
||||
#include <re2/re2.h>
|
||||
#include "LayerRule.hpp"
|
||||
#include <unordered_set>
|
||||
#include <algorithm>
|
||||
|
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include "Rule.hpp"
|
||||
|
||||
class CLayerRule {
|
||||
public:
|
||||
@@ -26,6 +25,4 @@ class CLayerRule {
|
||||
|
||||
const std::string targetNamespace;
|
||||
const std::string rule;
|
||||
|
||||
CRuleRegexContainer targetNamespaceRegex;
|
||||
};
|
@@ -4,13 +4,6 @@
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
|
||||
PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
|
||||
@@ -32,20 +25,22 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
pLS->szNamespace = resource->layerNamespace;
|
||||
|
||||
pLS->layer = resource->current.layer;
|
||||
pLS->popupHead = makeUnique<CPopup>(pLS);
|
||||
pLS->popupHead->m_pSelf = pLS->popupHead;
|
||||
pLS->popupHead = std::make_unique<CPopup>(pLS);
|
||||
pLS->monitor = pMonitor;
|
||||
pMonitor->m_aLayerSurfaceLayers[resource->current.layer].emplace_back(pLS);
|
||||
|
||||
pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace);
|
||||
|
||||
g_pAnimationManager->createAnimation(0.f, pLS->alpha, g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pLS->realPosition, g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pLS->realSize, g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
pLS->alpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
pLS->realPosition.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
pLS->realSize.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
pLS->alpha.registerVar();
|
||||
pLS->realPosition.registerVar();
|
||||
pLS->realSize.registerVar();
|
||||
|
||||
pLS->registerCallbacks();
|
||||
|
||||
pLS->alpha->setValueAndWarp(0.f);
|
||||
pLS->alpha.setValueAndWarp(0.f);
|
||||
|
||||
Debug::log(LOG, "LayerSurface {:x} (namespace {} layer {}) created on monitor {}", (uintptr_t)resource.get(), resource->layerNamespace, (int)pLS->layer, pMonitor->szName);
|
||||
|
||||
@@ -53,7 +48,7 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
}
|
||||
|
||||
void CLayerSurface::registerCallbacks() {
|
||||
alpha->setUpdateCallback([this](auto) {
|
||||
alpha.setUpdateCallback([this](void*) {
|
||||
if (dimAround)
|
||||
g_pHyprRenderer->damageMonitor(monitor.lock());
|
||||
});
|
||||
@@ -98,7 +93,7 @@ void CLayerSurface::onDestroy() {
|
||||
onUnmap();
|
||||
} else {
|
||||
Debug::log(LOG, "Removing LayerSurface that wasn't mapped.");
|
||||
alpha->setValueAndWarp(0.f);
|
||||
alpha.setValueAndWarp(0.f);
|
||||
fadingOut = true;
|
||||
g_pCompositor->addToFadingOutSafe(self.lock());
|
||||
}
|
||||
@@ -115,7 +110,7 @@ void CLayerSurface::onDestroy() {
|
||||
|
||||
// and damage
|
||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
}
|
||||
|
||||
readyToDelete = true;
|
||||
@@ -179,7 +174,7 @@ void CLayerSurface::onMap() {
|
||||
position = Vector2D(geometry.x, geometry.y);
|
||||
|
||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
const bool FULLSCREEN = PMONITOR->activeWorkspace && PMONITOR->activeWorkspace->m_bHasFullscreenWindow && PMONITOR->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN;
|
||||
|
||||
startAnimation(!(layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS));
|
||||
@@ -215,7 +210,7 @@ void CLayerSurface::onUnmap() {
|
||||
}
|
||||
|
||||
// make a snapshot and start fade
|
||||
g_pHyprRenderer->makeLayerSnapshot(self.lock());
|
||||
g_pHyprOpenGL->makeLayerSnapshot(self.lock());
|
||||
|
||||
startAnimation(false);
|
||||
|
||||
@@ -240,13 +235,13 @@ void CLayerSurface::onUnmap() {
|
||||
g_pSeatManager->setKeyboardFocus(g_pCompositor->m_pLastFocus.lock());
|
||||
|
||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
|
||||
geomFixed = {geometry.x + (int)PMONITOR->vecPosition.x, geometry.y + (int)PMONITOR->vecPosition.y, (int)layerSurface->surface->current.size.x,
|
||||
(int)layerSurface->surface->current.size.y};
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
g_pInputManager->sendMotionEventsToFocused();
|
||||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||
}
|
||||
@@ -275,7 +270,7 @@ void CLayerSurface::onCommit() {
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd
|
||||
|
||||
CBox geomFixed = {geometry.x, geometry.y, geometry.width, geometry.height};
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
|
||||
if (layerSurface->current.committed != 0) {
|
||||
if (layerSurface->current.committed & CLayerShellResource::eCommittedState::STATE_LAYER) {
|
||||
@@ -312,17 +307,17 @@ void CLayerSurface::onCommit() {
|
||||
}
|
||||
}
|
||||
|
||||
if (realPosition->goal() != geometry.pos()) {
|
||||
if (realPosition->isBeingAnimated())
|
||||
*realPosition = geometry.pos();
|
||||
if (realPosition.goal() != geometry.pos()) {
|
||||
if (realPosition.isBeingAnimated())
|
||||
realPosition = geometry.pos();
|
||||
else
|
||||
realPosition->setValueAndWarp(geometry.pos());
|
||||
realPosition.setValueAndWarp(geometry.pos());
|
||||
}
|
||||
if (realSize->goal() != geometry.size()) {
|
||||
if (realSize->isBeingAnimated())
|
||||
*realSize = geometry.size();
|
||||
if (realSize.goal() != geometry.size()) {
|
||||
if (realSize.isBeingAnimated())
|
||||
realSize = geometry.size();
|
||||
else
|
||||
realSize->setValueAndWarp(geometry.size());
|
||||
realSize.setValueAndWarp(geometry.size());
|
||||
}
|
||||
|
||||
if (mapped && (layerSurface->current.committed & CLayerShellResource::eCommittedState::STATE_INTERACTIVITY)) {
|
||||
@@ -332,7 +327,7 @@ void CLayerSurface::onCommit() {
|
||||
nullptr);
|
||||
if (!WASLASTFOCUS && popupHead) {
|
||||
popupHead->breadthfirst(
|
||||
[&WASLASTFOCUS](WP<CPopup> popup, void* data) {
|
||||
[&WASLASTFOCUS](CPopup* popup, void* data) {
|
||||
WASLASTFOCUS = WASLASTFOCUS || (popup->m_pWLSurface && g_pSeatManager->state.keyboardFocus == popup->m_pWLSurface->resource());
|
||||
},
|
||||
nullptr);
|
||||
@@ -439,17 +434,17 @@ void CLayerSurface::applyRules() {
|
||||
}
|
||||
|
||||
void CLayerSurface::startAnimation(bool in, bool instant) {
|
||||
const auto ANIMSTYLE = animationStyle.value_or(realPosition.m_pConfig->pValues->internalStyle);
|
||||
if (in) {
|
||||
realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn"));
|
||||
realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn"));
|
||||
alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"));
|
||||
realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn");
|
||||
realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn");
|
||||
alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn");
|
||||
} else {
|
||||
realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut"));
|
||||
realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut"));
|
||||
alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut"));
|
||||
realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut");
|
||||
realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut");
|
||||
alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut");
|
||||
}
|
||||
|
||||
const auto ANIMSTYLE = animationStyle.value_or(realPosition->getStyle());
|
||||
if (ANIMSTYLE.starts_with("slide")) {
|
||||
// get closest edge
|
||||
const auto MIDDLE = geometry.middle();
|
||||
@@ -490,9 +485,9 @@ void CLayerSurface::startAnimation(bool in, bool instant) {
|
||||
}
|
||||
}
|
||||
|
||||
realSize->setValueAndWarp(geometry.size());
|
||||
alpha->setValueAndWarp(in ? 0.f : 1.f);
|
||||
*alpha = in ? 1.f : 0.f;
|
||||
realSize.setValueAndWarp(geometry.size());
|
||||
alpha.setValueAndWarp(in ? 0.f : 1.f);
|
||||
alpha = in ? 1.f : 0.f;
|
||||
|
||||
Vector2D prePos;
|
||||
|
||||
@@ -517,11 +512,11 @@ void CLayerSurface::startAnimation(bool in, bool instant) {
|
||||
}
|
||||
|
||||
if (in) {
|
||||
realPosition->setValueAndWarp(prePos);
|
||||
*realPosition = geometry.pos();
|
||||
realPosition.setValueAndWarp(prePos);
|
||||
realPosition = geometry.pos();
|
||||
} else {
|
||||
realPosition->setValueAndWarp(geometry.pos());
|
||||
*realPosition = prePos;
|
||||
realPosition.setValueAndWarp(geometry.pos());
|
||||
realPosition = prePos;
|
||||
}
|
||||
|
||||
} else if (ANIMSTYLE.starts_with("popin")) {
|
||||
@@ -540,25 +535,25 @@ void CLayerSurface::startAnimation(bool in, bool instant) {
|
||||
const auto GOALSIZE = (geometry.size() * minPerc).clamp({5, 5});
|
||||
const auto GOALPOS = geometry.pos() + (geometry.size() - GOALSIZE) / 2.f;
|
||||
|
||||
alpha->setValueAndWarp(in ? 0.f : 1.f);
|
||||
*alpha = in ? 1.f : 0.f;
|
||||
alpha.setValueAndWarp(in ? 0.f : 1.f);
|
||||
alpha = in ? 1.f : 0.f;
|
||||
|
||||
if (in) {
|
||||
realSize->setValueAndWarp(GOALSIZE);
|
||||
realPosition->setValueAndWarp(GOALPOS);
|
||||
*realSize = geometry.size();
|
||||
*realPosition = geometry.pos();
|
||||
realSize.setValueAndWarp(GOALSIZE);
|
||||
realPosition.setValueAndWarp(GOALPOS);
|
||||
realSize = geometry.size();
|
||||
realPosition = geometry.pos();
|
||||
} else {
|
||||
realSize->setValueAndWarp(geometry.size());
|
||||
realPosition->setValueAndWarp(geometry.pos());
|
||||
*realSize = GOALSIZE;
|
||||
*realPosition = GOALPOS;
|
||||
realSize.setValueAndWarp(geometry.size());
|
||||
realPosition.setValueAndWarp(geometry.pos());
|
||||
realSize = GOALSIZE;
|
||||
realPosition = GOALPOS;
|
||||
}
|
||||
} else {
|
||||
// fade
|
||||
realPosition->setValueAndWarp(geometry.pos());
|
||||
realSize->setValueAndWarp(geometry.size());
|
||||
*alpha = in ? 1.f : 0.f;
|
||||
realPosition.setValueAndWarp(geometry.pos());
|
||||
realSize.setValueAndWarp(geometry.size());
|
||||
alpha = in ? 1.f : 0.f;
|
||||
}
|
||||
|
||||
if (!in)
|
||||
@@ -569,7 +564,7 @@ bool CLayerSurface::isFadedOut() {
|
||||
if (!fadingOut)
|
||||
return false;
|
||||
|
||||
return !realPosition->isBeingAnimated() && !realSize->isBeingAnimated() && !alpha->isBeingAnimated();
|
||||
return !realPosition.isBeingAnimated() && !realSize.isBeingAnimated() && !alpha.isBeingAnimated();
|
||||
}
|
||||
|
||||
int CLayerSurface::popupsCount() {
|
||||
@@ -577,7 +572,7 @@ int CLayerSurface::popupsCount() {
|
||||
return 0;
|
||||
|
||||
int no = -1; // we have one dummy
|
||||
popupHead->breadthfirst([](WP<CPopup> p, void* data) { *(int*)data += 1; }, &no);
|
||||
popupHead->breadthfirst([](CPopup* p, void* data) { *(int*)data += 1; }, &no);
|
||||
return no;
|
||||
}
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include "../defines.hpp"
|
||||
#include "WLSurface.hpp"
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
#include "LayerRule.hpp"
|
||||
|
||||
class CLayerShellResource;
|
||||
|
||||
@@ -22,9 +23,9 @@ class CLayerSurface {
|
||||
bool isFadedOut();
|
||||
int popupsCount();
|
||||
|
||||
PHLANIMVAR<Vector2D> realPosition;
|
||||
PHLANIMVAR<Vector2D> realSize;
|
||||
PHLANIMVAR<float> alpha;
|
||||
CAnimatedVariable<Vector2D> realPosition;
|
||||
CAnimatedVariable<Vector2D> realSize;
|
||||
CAnimatedVariable<float> alpha;
|
||||
|
||||
WP<CLayerShellResource> layerSurface;
|
||||
wl_list link;
|
||||
@@ -59,7 +60,7 @@ class CLayerSurface {
|
||||
CBox geometry = {0, 0, 0, 0};
|
||||
Vector2D position;
|
||||
std::string szNamespace = "";
|
||||
UP<CPopup> popupHead;
|
||||
std::unique_ptr<CPopup> popupHead;
|
||||
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
|
@@ -6,10 +6,6 @@
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "../managers/eventLoop/EventLoopManager.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../render/OpenGL.hpp"
|
||||
#include <ranges>
|
||||
|
||||
CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) {
|
||||
@@ -20,8 +16,7 @@ CPopup::CPopup(PHLLS pOwner) : m_pLayerOwner(pOwner) {
|
||||
initAllSignals();
|
||||
}
|
||||
|
||||
CPopup::CPopup(SP<CXDGPopupResource> popup, WP<CPopup> pOwner) :
|
||||
m_pWindowOwner(pOwner->m_pWindowOwner), m_pLayerOwner(pOwner->m_pLayerOwner), m_pParent(pOwner), m_pResource(popup) {
|
||||
CPopup::CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner) : m_pWindowOwner(pOwner->m_pWindowOwner), m_pLayerOwner(pOwner->m_pLayerOwner), m_pParent(pOwner), m_pResource(popup) {
|
||||
m_pWLSurface = CWLSurface::create();
|
||||
m_pWLSurface->assign(popup->surface->surface.lock(), this);
|
||||
|
||||
@@ -59,8 +54,7 @@ void CPopup::initAllSignals() {
|
||||
}
|
||||
|
||||
void CPopup::onNewPopup(SP<CXDGPopupResource> popup) {
|
||||
const auto& POPUP = m_vChildren.emplace_back(makeShared<CPopup>(popup, m_pSelf));
|
||||
POPUP->m_pSelf = POPUP;
|
||||
const auto POPUP = m_vChildren.emplace_back(makeShared<CPopup>(popup, this)).get();
|
||||
Debug::log(LOG, "New popup at {:x}", (uintptr_t)POPUP);
|
||||
}
|
||||
|
||||
@@ -85,14 +79,13 @@ void CPopup::onMap() {
|
||||
|
||||
CBox box = m_pWLSurface->resource()->extends();
|
||||
box.translate(COORDS).expand(4);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
|
||||
m_vLastPos = coordsRelativeToParent();
|
||||
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
|
||||
m_pSubsurfaceHead = makeUnique<CSubsurface>(m_pSelf);
|
||||
m_pSubsurfaceHead->m_pSelf = m_pSubsurfaceHead;
|
||||
m_pSubsurfaceHead = std::make_unique<CSubsurface>(this);
|
||||
|
||||
//unconstrain();
|
||||
sendScale();
|
||||
@@ -120,7 +113,7 @@ void CPopup::onUnmap() {
|
||||
|
||||
CBox box = m_pWLSurface->resource()->extends();
|
||||
box.translate(COORDS).expand(4);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
|
||||
m_pSubsurfaceHead.reset();
|
||||
|
||||
@@ -129,20 +122,19 @@ void CPopup::onUnmap() {
|
||||
|
||||
// damage all children
|
||||
breadthfirst(
|
||||
[](WP<CPopup> p, void* data) {
|
||||
[](CPopup* p, void* data) {
|
||||
if (!p->m_pResource)
|
||||
return;
|
||||
|
||||
auto box = CBox{p->coordsGlobal(), p->size()};
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
},
|
||||
nullptr);
|
||||
|
||||
// TODO: probably refocus, but without a motion event?
|
||||
// const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == m_pWLSurface->resource() || g_pSeatManager->state.pointerFocus == m_pWLSurface->resource();
|
||||
const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == m_pWLSurface->resource() || g_pSeatManager->state.pointerFocus == m_pWLSurface->resource();
|
||||
|
||||
// if (WASLASTFOCUS)
|
||||
// g_pInputManager->simulateMouseMovement();
|
||||
if (WASLASTFOCUS)
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
}
|
||||
|
||||
void CPopup::onCommit(bool ignoreSiblings) {
|
||||
@@ -174,10 +166,10 @@ void CPopup::onCommit(bool ignoreSiblings) {
|
||||
|
||||
if (m_vLastSize != m_pResource->surface->surface->current.size || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) {
|
||||
CBox box = {localToGlobal(m_vLastPos), m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
m_vLastSize = m_pResource->surface->surface->current.size;
|
||||
box = {COORDS, m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
|
||||
m_vLastPos = COORDSLOCAL;
|
||||
}
|
||||
@@ -227,7 +219,7 @@ Vector2D CPopup::coordsRelativeToParent() {
|
||||
if (!m_pResource)
|
||||
return {};
|
||||
|
||||
WP<CPopup> current = m_pSelf;
|
||||
CPopup* current = this;
|
||||
offset -= current->m_pResource->surface->current.geometry.pos();
|
||||
|
||||
while (current->m_pParent && current->m_pResource) {
|
||||
@@ -251,16 +243,16 @@ Vector2D CPopup::localToGlobal(const Vector2D& rel) {
|
||||
|
||||
Vector2D CPopup::t1ParentCoords() {
|
||||
if (!m_pWindowOwner.expired())
|
||||
return m_pWindowOwner->m_vRealPosition->value();
|
||||
return m_pWindowOwner->m_vRealPosition.value();
|
||||
if (!m_pLayerOwner.expired())
|
||||
return m_pLayerOwner->realPosition->value();
|
||||
return m_pLayerOwner->realPosition.value();
|
||||
|
||||
ASSERT(false);
|
||||
return {};
|
||||
}
|
||||
|
||||
void CPopup::recheckTree() {
|
||||
WP<CPopup> curr = m_pSelf;
|
||||
CPopup* curr = this;
|
||||
while (curr->m_pParent) {
|
||||
curr = curr->m_pParent;
|
||||
}
|
||||
@@ -300,17 +292,17 @@ bool CPopup::visible() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPopup::bfHelper(std::vector<WP<CPopup>> const& nodes, std::function<void(WP<CPopup>, void*)> fn, void* data) {
|
||||
void CPopup::bfHelper(std::vector<CPopup*> const& nodes, std::function<void(CPopup*, void*)> fn, void* data) {
|
||||
for (auto const& n : nodes) {
|
||||
fn(n, data);
|
||||
}
|
||||
|
||||
std::vector<WP<CPopup>> nodes2;
|
||||
std::vector<CPopup*> nodes2;
|
||||
nodes2.reserve(nodes.size() * 2);
|
||||
|
||||
for (auto const& n : nodes) {
|
||||
for (auto const& c : n->m_vChildren) {
|
||||
nodes2.push_back(c->m_pSelf);
|
||||
nodes2.push_back(c.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,15 +310,15 @@ void CPopup::bfHelper(std::vector<WP<CPopup>> const& nodes, std::function<void(W
|
||||
bfHelper(nodes2, fn, data);
|
||||
}
|
||||
|
||||
void CPopup::breadthfirst(std::function<void(WP<CPopup>, void*)> fn, void* data) {
|
||||
std::vector<WP<CPopup>> popups;
|
||||
popups.push_back(m_pSelf);
|
||||
void CPopup::breadthfirst(std::function<void(CPopup*, void*)> fn, void* data) {
|
||||
std::vector<CPopup*> popups;
|
||||
popups.push_back(this);
|
||||
bfHelper(popups, fn, data);
|
||||
}
|
||||
|
||||
WP<CPopup> CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||
std::vector<WP<CPopup>> popups;
|
||||
breadthfirst([](WP<CPopup> popup, void* data) { ((std::vector<WP<CPopup>>*)data)->push_back(popup); }, &popups);
|
||||
CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||
std::vector<CPopup*> popups;
|
||||
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)
|
||||
@@ -348,5 +340,5 @@ WP<CPopup> CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "Subsurface.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
|
||||
class CXDGPopupResource;
|
||||
|
||||
@@ -14,7 +14,7 @@ class CPopup {
|
||||
CPopup(PHLLS pOwner);
|
||||
|
||||
// real nodes
|
||||
CPopup(SP<CXDGPopupResource> popup, WP<CPopup> pOwner);
|
||||
CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner);
|
||||
|
||||
~CPopup();
|
||||
|
||||
@@ -36,12 +36,11 @@ class CPopup {
|
||||
bool visible();
|
||||
|
||||
// will also loop over this node
|
||||
void breadthfirst(std::function<void(WP<CPopup>, void*)> fn, void* data);
|
||||
WP<CPopup> at(const Vector2D& globalCoords, bool allowsInput = false);
|
||||
void breadthfirst(std::function<void(CPopup*, void*)> fn, void* data);
|
||||
CPopup* at(const Vector2D& globalCoords, bool allowsInput = false);
|
||||
|
||||
//
|
||||
SP<CWLSurface> m_pWLSurface;
|
||||
WP<CPopup> m_pSelf;
|
||||
bool m_bMapped = false;
|
||||
|
||||
private:
|
||||
@@ -50,7 +49,7 @@ class CPopup {
|
||||
PHLLSREF m_pLayerOwner;
|
||||
|
||||
// T2 owners
|
||||
WP<CPopup> m_pParent;
|
||||
CPopup* m_pParent = nullptr;
|
||||
|
||||
WP<CXDGPopupResource> m_pResource;
|
||||
|
||||
@@ -63,7 +62,7 @@ class CPopup {
|
||||
|
||||
//
|
||||
std::vector<SP<CPopup>> m_vChildren;
|
||||
UP<CSubsurface> m_pSubsurfaceHead;
|
||||
std::unique_ptr<CSubsurface> m_pSubsurfaceHead;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener newPopup;
|
||||
@@ -82,5 +81,5 @@ class CPopup {
|
||||
|
||||
Vector2D localToGlobal(const Vector2D& rel);
|
||||
Vector2D t1ParentCoords();
|
||||
static void bfHelper(std::vector<WP<CPopup>> const& nodes, std::function<void(WP<CPopup>, void*)> fn, void* data);
|
||||
static void bfHelper(std::vector<CPopup*> const& nodes, std::function<void(CPopup*, void*)> fn, void* data);
|
||||
};
|
||||
|
@@ -1,22 +0,0 @@
|
||||
#include <re2/re2.h>
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
#include "Rule.hpp"
|
||||
#include "../debug/Log.hpp"
|
||||
|
||||
CRuleRegexContainer::CRuleRegexContainer(const std::string& regex_) {
|
||||
const bool NEGATIVE = regex_.starts_with("negative:");
|
||||
|
||||
negative = NEGATIVE;
|
||||
regex = makeUnique<RE2>(NEGATIVE ? regex_.substr(9) : regex_);
|
||||
|
||||
// TODO: maybe pop an error?
|
||||
if (!regex->ok())
|
||||
Debug::log(ERR, "RuleRegexContainer: regex {} failed to parse!", regex_);
|
||||
}
|
||||
|
||||
bool CRuleRegexContainer::passes(const std::string& str) const {
|
||||
if (!regex)
|
||||
return false;
|
||||
|
||||
return RE2::FullMatch(str, *regex) != negative;
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hyprutils/memory/UniquePtr.hpp>
|
||||
|
||||
//NOLINTNEXTLINE
|
||||
namespace re2 {
|
||||
class RE2;
|
||||
};
|
||||
|
||||
class CRuleRegexContainer {
|
||||
public:
|
||||
CRuleRegexContainer() = default;
|
||||
|
||||
CRuleRegexContainer(const std::string& regex);
|
||||
|
||||
bool passes(const std::string& str) const;
|
||||
|
||||
private:
|
||||
Hyprutils::Memory::CUniquePointer<re2::RE2> regex;
|
||||
bool negative = false;
|
||||
};
|
@@ -4,15 +4,13 @@
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../protocols/core/Subcompositor.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
|
||||
CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) {
|
||||
initSignals();
|
||||
initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
|
||||
}
|
||||
|
||||
CSubsurface::CSubsurface(WP<CPopup> pOwner) : m_pPopupParent(pOwner) {
|
||||
CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) {
|
||||
initSignals();
|
||||
initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
|
||||
}
|
||||
@@ -24,7 +22,7 @@ CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner
|
||||
initExistingSubsurfaces(pSubsurface->surface.lock());
|
||||
}
|
||||
|
||||
CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
|
||||
CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
|
||||
m_pWLSurface = CWLSurface::create();
|
||||
m_pWLSurface->assign(pSubsurface->surface.lock(), this);
|
||||
initSignals();
|
||||
@@ -101,20 +99,11 @@ void CSubsurface::onCommit() {
|
||||
checkSiblingDamage();
|
||||
|
||||
if (m_vLastSize != m_pWLSurface->resource()->current.size) {
|
||||
// TODO: fix this
|
||||
// CBox box{COORDS, m_vLastSize};
|
||||
// g_pHyprRenderer->damageBox(box);
|
||||
// m_vLastSize = m_pWLSurface->resource()->current.size;
|
||||
// box = {COORDS, m_vLastSize};
|
||||
// g_pHyprRenderer->damageBox(box);
|
||||
|
||||
CBox box;
|
||||
if (m_pPopupParent)
|
||||
box = m_pPopupParent->m_pWLSurface->getSurfaceBoxGlobal().value_or(CBox{});
|
||||
else if (m_pWindowParent)
|
||||
box = m_pWindowParent->getWindowMainSurfaceBox();
|
||||
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
CBox box{COORDS, m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
m_vLastSize = m_pWLSurface->resource()->current.size;
|
||||
box = {COORDS, m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,18 +121,16 @@ void CSubsurface::onDestroy() {
|
||||
}
|
||||
|
||||
void CSubsurface::onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface) {
|
||||
WP<CSubsurface> PSUBSURFACE;
|
||||
CSubsurface* PSUBSURFACE = nullptr;
|
||||
|
||||
if (!m_pWindowParent.expired())
|
||||
PSUBSURFACE = m_vChildren.emplace_back(makeUnique<CSubsurface>(pSubsurface, m_pWindowParent.lock()));
|
||||
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent.lock())).get();
|
||||
else if (m_pPopupParent)
|
||||
PSUBSURFACE = m_vChildren.emplace_back(makeUnique<CSubsurface>(pSubsurface, m_pPopupParent));
|
||||
|
||||
PSUBSURFACE->m_pSelf = PSUBSURFACE;
|
||||
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pPopupParent)).get();
|
||||
|
||||
ASSERT(PSUBSURFACE);
|
||||
|
||||
PSUBSURFACE->m_pParent = m_pSelf;
|
||||
PSUBSURFACE->m_pParent = this;
|
||||
}
|
||||
|
||||
void CSubsurface::onMap() {
|
||||
@@ -152,7 +139,7 @@ void CSubsurface::onMap() {
|
||||
const auto COORDS = coordsGlobal();
|
||||
CBox box{COORDS, m_vLastSize};
|
||||
box.expand(4);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
|
||||
if (!m_pWindowParent.expired())
|
||||
m_pWindowParent->updateSurfaceScaleTransformDetails();
|
||||
@@ -162,7 +149,7 @@ void CSubsurface::onUnmap() {
|
||||
const auto COORDS = coordsGlobal();
|
||||
CBox box{COORDS, m_vLastSize};
|
||||
box.expand(4);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
|
||||
if (m_pWLSurface->resource() == g_pCompositor->m_pLastFocus)
|
||||
g_pInputManager->releaseAllMouseButtons();
|
||||
@@ -182,7 +169,7 @@ Vector2D CSubsurface::coordsGlobal() {
|
||||
Vector2D coords = coordsRelativeToParent();
|
||||
|
||||
if (!m_pWindowParent.expired())
|
||||
coords += m_pWindowParent->m_vRealPosition->value();
|
||||
coords += m_pWindowParent->m_vRealPosition.value();
|
||||
else if (m_pPopupParent)
|
||||
coords += m_pPopupParent->coordsGlobal();
|
||||
|
||||
|
@@ -11,11 +11,11 @@ class CSubsurface {
|
||||
public:
|
||||
// root dummy nodes
|
||||
CSubsurface(PHLWINDOW pOwner);
|
||||
CSubsurface(WP<CPopup> pOwner);
|
||||
CSubsurface(CPopup* pOwner);
|
||||
|
||||
// real nodes
|
||||
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner);
|
||||
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner);
|
||||
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner);
|
||||
|
||||
~CSubsurface();
|
||||
|
||||
@@ -34,8 +34,6 @@ class CSubsurface {
|
||||
|
||||
void recheckDamageForSubsurfaces();
|
||||
|
||||
WP<CSubsurface> m_pSelf;
|
||||
|
||||
private:
|
||||
struct {
|
||||
CHyprSignalListener destroySubsurface;
|
||||
@@ -50,12 +48,12 @@ class CSubsurface {
|
||||
Vector2D m_vLastSize = {};
|
||||
|
||||
// if nullptr, means it's a dummy node
|
||||
WP<CSubsurface> m_pParent;
|
||||
CSubsurface* m_pParent = nullptr;
|
||||
|
||||
PHLWINDOWREF m_pWindowParent;
|
||||
WP<CPopup> m_pPopupParent;
|
||||
CPopup* m_pPopupParent = nullptr;
|
||||
|
||||
std::vector<UP<CSubsurface>> m_vChildren;
|
||||
std::vector<std::unique_ptr<CSubsurface>> m_vChildren;
|
||||
|
||||
bool m_bInert = false;
|
||||
|
||||
|
@@ -1,9 +1,7 @@
|
||||
#include "WLSurface.hpp"
|
||||
#include "LayerSurface.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface) {
|
||||
m_pResource = pSurface;
|
||||
@@ -74,7 +72,7 @@ Vector2D CWLSurface::correctSmallVec() const {
|
||||
const auto SIZE = getViewporterCorrectedSize();
|
||||
const auto O = m_pWindowOwner.lock();
|
||||
|
||||
return Vector2D{(O->m_vReportedSize.x - SIZE.x) / 2, (O->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_vRealSize->value() / O->m_vReportedSize);
|
||||
return Vector2D{(O->m_vReportedSize.x - SIZE.x) / 2, (O->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_vRealSize.value() / O->m_vReportedSize);
|
||||
}
|
||||
|
||||
Vector2D CWLSurface::correctSmallVecBuf() const {
|
||||
|
@@ -84,11 +84,7 @@ class CWLSurface {
|
||||
static SP<CWLSurface> fromResource(SP<CWLSurfaceResource> pSurface);
|
||||
|
||||
// used by the alpha-modifier protocol
|
||||
float m_fAlphaModifier = 1.F;
|
||||
|
||||
// used by the hyprland-surface protocol
|
||||
float m_fOverallOpacity = 1.F;
|
||||
CRegion m_visibleRegion;
|
||||
float m_pAlphaModifier = 1.F;
|
||||
|
||||
struct {
|
||||
CSignal destroy;
|
||||
@@ -120,5 +116,4 @@ class CWLSurface {
|
||||
} listeners;
|
||||
|
||||
friend class CPointerConstraint;
|
||||
friend class CXxColorManagerV4;
|
||||
};
|
@@ -1,4 +1,3 @@
|
||||
#include <hyprutils/animation/AnimatedVariable.hpp>
|
||||
#include <re2/re2.h>
|
||||
|
||||
#include <any>
|
||||
@@ -12,23 +11,12 @@
|
||||
#include "../render/decorations/CHyprBorderDecoration.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../managers/TokenManager.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../xwayland/XWayland.hpp"
|
||||
#include "../helpers/Color.hpp"
|
||||
#include "../events/Events.hpp"
|
||||
#include "../managers/XWaylandManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
|
||||
using namespace Hyprutils::String;
|
||||
using namespace Hyprutils::Animation;
|
||||
|
||||
PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
|
||||
PHLWINDOW pWindow = SP<CWindow>(new CWindow(surface));
|
||||
@@ -36,19 +24,18 @@ PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
|
||||
pWindow->m_pSelf = pWindow;
|
||||
pWindow->m_bIsX11 = true;
|
||||
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_vRealPosition, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_vRealSize, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(0.f, pWindow->m_fBorderFadeAnimationProgress, g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER);
|
||||
g_pAnimationManager->createAnimation(0.f, pWindow->m_fBorderAngleAnimationProgress, g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER);
|
||||
g_pAnimationManager->createAnimation(1.f, pWindow->m_fAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(1.f, pWindow->m_fActiveInactiveAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(CHyprColor(), pWindow->m_cRealShadowColor, g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW);
|
||||
g_pAnimationManager->createAnimation(0.f, pWindow->m_fDimPercent, g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingToWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingFromWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER);
|
||||
pWindow->m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER);
|
||||
pWindow->m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW);
|
||||
pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_fMovingToWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
|
||||
pWindow->addWindowDeco(makeUnique<CHyprDropShadowDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(makeUnique<CHyprBorderDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow));
|
||||
|
||||
return pWindow;
|
||||
}
|
||||
@@ -59,19 +46,18 @@ PHLWINDOW CWindow::create(SP<CXDGSurfaceResource> resource) {
|
||||
pWindow->m_pSelf = pWindow;
|
||||
resource->toplevel->window = pWindow;
|
||||
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_vRealPosition, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_vRealSize, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(0.f, pWindow->m_fBorderFadeAnimationProgress, g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER);
|
||||
g_pAnimationManager->createAnimation(0.f, pWindow->m_fBorderAngleAnimationProgress, g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER);
|
||||
g_pAnimationManager->createAnimation(1.f, pWindow->m_fAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(1.f, pWindow->m_fActiveInactiveAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(CHyprColor(), pWindow->m_cRealShadowColor, g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW);
|
||||
g_pAnimationManager->createAnimation(0.f, pWindow->m_fDimPercent, g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingToWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingFromWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER);
|
||||
pWindow->m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER);
|
||||
pWindow->m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW);
|
||||
pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
pWindow->m_fMovingToWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
|
||||
pWindow->addWindowDeco(makeUnique<CHyprDropShadowDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(makeUnique<CHyprBorderDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow));
|
||||
|
||||
pWindow->m_pWLSurface->assign(pWindow->m_pXDGSurface->surface.lock(), pWindow);
|
||||
|
||||
@@ -130,8 +116,8 @@ SBoxExtents CWindow::getFullWindowExtents() {
|
||||
|
||||
if (m_sWindowData.dimAround.valueOrDefault()) {
|
||||
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR)
|
||||
return {{m_vRealPosition->value().x - PMONITOR->vecPosition.x, m_vRealPosition->value().y - PMONITOR->vecPosition.y},
|
||||
{PMONITOR->vecSize.x - (m_vRealPosition->value().x - PMONITOR->vecPosition.x), PMONITOR->vecSize.y - (m_vRealPosition->value().y - PMONITOR->vecPosition.y)}};
|
||||
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)}};
|
||||
}
|
||||
|
||||
SBoxExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}};
|
||||
@@ -154,7 +140,7 @@ SBoxExtents CWindow::getFullWindowExtents() {
|
||||
CBox surfaceExtents = {0, 0, 0, 0};
|
||||
// TODO: this could be better, perhaps make a getFullWindowRegion?
|
||||
m_pPopupHead->breadthfirst(
|
||||
[](WP<CPopup> popup, void* data) {
|
||||
[](CPopup* popup, void* data) {
|
||||
if (!popup->m_pWLSurface || !popup->m_pWLSurface->resource())
|
||||
return;
|
||||
|
||||
@@ -195,8 +181,8 @@ CBox CWindow::getFullWindowBoundingBox() {
|
||||
|
||||
auto maxExtents = getFullWindowExtents();
|
||||
|
||||
CBox finalBox = {m_vRealPosition->value().x - maxExtents.topLeft.x, m_vRealPosition->value().y - maxExtents.topLeft.y,
|
||||
m_vRealSize->value().x + maxExtents.topLeft.x + maxExtents.bottomRight.x, m_vRealSize->value().y + maxExtents.topLeft.y + maxExtents.bottomRight.y};
|
||||
CBox finalBox = {m_vRealPosition.value().x - maxExtents.topLeft.x, m_vRealPosition.value().y - maxExtents.topLeft.y,
|
||||
m_vRealSize.value().x + maxExtents.topLeft.x + maxExtents.bottomRight.x, m_vRealSize.value().y + maxExtents.topLeft.y + maxExtents.bottomRight.y};
|
||||
|
||||
return finalBox;
|
||||
}
|
||||
@@ -250,7 +236,7 @@ CBox CWindow::getWindowBoxUnified(uint64_t properties) {
|
||||
if (properties & FULL_EXTENTS)
|
||||
EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(m_pSelf.lock(), false));
|
||||
|
||||
CBox box = {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y};
|
||||
CBox box = {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y};
|
||||
box.addExtents(EXTENTS);
|
||||
|
||||
return box;
|
||||
@@ -282,8 +268,6 @@ void CWindow::updateWindowDecos() {
|
||||
|
||||
// make a copy because updateWindow can remove decos.
|
||||
std::vector<IHyprWindowDecoration*> decos;
|
||||
// reserve to avoid reallocations
|
||||
decos.reserve(m_dWindowDecorations.size());
|
||||
|
||||
for (auto const& wd : m_dWindowDecorations) {
|
||||
decos.push_back(wd.get());
|
||||
@@ -296,7 +280,7 @@ void CWindow::updateWindowDecos() {
|
||||
}
|
||||
}
|
||||
|
||||
void CWindow::addWindowDeco(UP<IHyprWindowDecoration> deco) {
|
||||
void CWindow::addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco) {
|
||||
m_dWindowDecorations.emplace_back(std::move(deco));
|
||||
g_pDecorationPositioner->forceRecalcFor(m_pSelf.lock());
|
||||
updateWindowDecos();
|
||||
@@ -422,12 +406,10 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
|
||||
const auto OLDWORKSPACE = m_pWorkspace;
|
||||
|
||||
if (OLDWORKSPACE->isVisible()) {
|
||||
m_fMovingToWorkspaceAlpha->setValueAndWarp(1.F);
|
||||
*m_fMovingToWorkspaceAlpha = 0.F;
|
||||
m_fMovingToWorkspaceAlpha->setCallbackOnEnd([this](auto) { m_iMonitorMovedFrom = -1; });
|
||||
m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->monitorID() : -1;
|
||||
}
|
||||
m_fMovingToWorkspaceAlpha.setValueAndWarp(1.F);
|
||||
m_fMovingToWorkspaceAlpha = 0.F;
|
||||
m_fMovingToWorkspaceAlpha.setCallbackOnEnd([this](void* thisptr) { m_iMonitorMovedFrom = -1; });
|
||||
|
||||
m_pWorkspace = pWorkspace;
|
||||
|
||||
@@ -455,7 +437,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
}
|
||||
|
||||
// update xwayland coords
|
||||
sendWindowSize(m_vRealSize->goal());
|
||||
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.value());
|
||||
|
||||
if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_iID) && OLDWORKSPACE->getWindows() == 0 && *PCLOSEONLASTSPECIAL) {
|
||||
if (const auto PMONITOR = OLDWORKSPACE->m_pMonitor.lock(); PMONITOR)
|
||||
@@ -491,6 +473,19 @@ PHLWINDOW CWindow::x11TransientFor() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CWindow::removeDecorationByType(eDecorationType type) {
|
||||
for (auto const& wd : m_dWindowDecorations) {
|
||||
if (wd->getDecorationType() == type)
|
||||
m_vDecosToRemove.push_back(wd.get());
|
||||
}
|
||||
|
||||
updateWindowDecos();
|
||||
}
|
||||
|
||||
void unregisterVar(void* ptr) {
|
||||
((CBaseAnimatedVariable*)ptr)->unregister();
|
||||
}
|
||||
|
||||
void CWindow::onUnmap() {
|
||||
static auto PCLOSEONLASTSPECIAL = CConfigValue<Hyprlang::INT>("misc:close_special_on_empty");
|
||||
static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
|
||||
@@ -509,6 +504,18 @@ void CWindow::onUnmap() {
|
||||
|
||||
m_iLastWorkspace = m_pWorkspace->m_iID;
|
||||
|
||||
m_vRealPosition.setCallbackOnEnd(unregisterVar);
|
||||
m_vRealSize.setCallbackOnEnd(unregisterVar);
|
||||
m_fBorderFadeAnimationProgress.setCallbackOnEnd(unregisterVar);
|
||||
m_fBorderAngleAnimationProgress.setCallbackOnEnd(unregisterVar);
|
||||
m_fActiveInactiveAlpha.setCallbackOnEnd(unregisterVar);
|
||||
m_fAlpha.setCallbackOnEnd(unregisterVar);
|
||||
m_cRealShadowColor.setCallbackOnEnd(unregisterVar);
|
||||
m_fDimPercent.setCallbackOnEnd(unregisterVar);
|
||||
m_fMovingToWorkspaceAlpha.setCallbackOnEnd(unregisterVar);
|
||||
|
||||
m_vRealSize.setCallbackOnBegin(nullptr);
|
||||
|
||||
std::erase_if(g_pCompositor->m_vWindowFocusHistory, [&](const auto& other) { return other.expired() || other.lock().get() == this; });
|
||||
|
||||
if (*PCLOSEONLASTSPECIAL && m_pWorkspace && m_pWorkspace->getWindows() == 0 && onSpecialWorkspace()) {
|
||||
@@ -540,26 +547,30 @@ void CWindow::onUnmap() {
|
||||
|
||||
void CWindow::onMap() {
|
||||
// JIC, reset the callbacks. If any are set, we'll make sure they are cleared so we don't accidentally unset them. (In case a window got remapped)
|
||||
m_vRealPosition->resetAllCallbacks();
|
||||
m_vRealSize->resetAllCallbacks();
|
||||
m_fBorderFadeAnimationProgress->resetAllCallbacks();
|
||||
m_fBorderAngleAnimationProgress->resetAllCallbacks();
|
||||
m_fActiveInactiveAlpha->resetAllCallbacks();
|
||||
m_fAlpha->resetAllCallbacks();
|
||||
m_cRealShadowColor->resetAllCallbacks();
|
||||
m_fDimPercent->resetAllCallbacks();
|
||||
m_fMovingToWorkspaceAlpha->resetAllCallbacks();
|
||||
m_fMovingFromWorkspaceAlpha->resetAllCallbacks();
|
||||
m_vRealPosition.resetAllCallbacks();
|
||||
m_vRealSize.resetAllCallbacks();
|
||||
m_fBorderFadeAnimationProgress.resetAllCallbacks();
|
||||
m_fBorderAngleAnimationProgress.resetAllCallbacks();
|
||||
m_fActiveInactiveAlpha.resetAllCallbacks();
|
||||
m_fAlpha.resetAllCallbacks();
|
||||
m_cRealShadowColor.resetAllCallbacks();
|
||||
m_fDimPercent.resetAllCallbacks();
|
||||
m_fMovingToWorkspaceAlpha.resetAllCallbacks();
|
||||
|
||||
m_fMovingFromWorkspaceAlpha->setValueAndWarp(1.F);
|
||||
m_vRealPosition.registerVar();
|
||||
m_vRealSize.registerVar();
|
||||
m_fBorderFadeAnimationProgress.registerVar();
|
||||
m_fBorderAngleAnimationProgress.registerVar();
|
||||
m_fActiveInactiveAlpha.registerVar();
|
||||
m_fAlpha.registerVar();
|
||||
m_cRealShadowColor.registerVar();
|
||||
m_fDimPercent.registerVar();
|
||||
m_fMovingToWorkspaceAlpha.registerVar();
|
||||
|
||||
if (m_fBorderAngleAnimationProgress->enabled()) {
|
||||
m_fBorderAngleAnimationProgress->setValueAndWarp(0.f);
|
||||
m_fBorderAngleAnimationProgress->setCallbackOnEnd([&](WP<CBaseAnimatedVariable> p) { onBorderAngleAnimEnd(p); }, false);
|
||||
*m_fBorderAngleAnimationProgress = 1.f;
|
||||
}
|
||||
m_fBorderAngleAnimationProgress.setCallbackOnEnd([&](void* ptr) { onBorderAngleAnimEnd(ptr); }, false);
|
||||
|
||||
m_fMovingFromWorkspaceAlpha->setValueAndWarp(1.F);
|
||||
m_fBorderAngleAnimationProgress.setValueAndWarp(0.f);
|
||||
m_fBorderAngleAnimationProgress = 1.f;
|
||||
|
||||
g_pCompositor->m_vWindowFocusHistory.push_back(m_pSelf);
|
||||
|
||||
@@ -571,28 +582,24 @@ void CWindow::onMap() {
|
||||
if (m_bIsX11)
|
||||
return;
|
||||
|
||||
m_pSubsurfaceHead = makeUnique<CSubsurface>(m_pSelf.lock());
|
||||
m_pSubsurfaceHead->m_pSelf = m_pSubsurfaceHead;
|
||||
m_pPopupHead = makeUnique<CPopup>(m_pSelf.lock());
|
||||
m_pPopupHead->m_pSelf = m_pPopupHead;
|
||||
m_pSubsurfaceHead = std::make_unique<CSubsurface>(m_pSelf.lock());
|
||||
m_pPopupHead = std::make_unique<CPopup>(m_pSelf.lock());
|
||||
}
|
||||
|
||||
void CWindow::onBorderAngleAnimEnd(WP<CBaseAnimatedVariable> pav) {
|
||||
const auto PAV = pav.lock();
|
||||
if (!PAV)
|
||||
return;
|
||||
void CWindow::onBorderAngleAnimEnd(void* ptr) {
|
||||
const auto PANIMVAR = (CAnimatedVariable<float>*)ptr;
|
||||
|
||||
if (PAV->getStyle() != "loop" || !PAV->enabled())
|
||||
return;
|
||||
const std::string STYLE = PANIMVAR->getConfig()->pValues->internalStyle;
|
||||
|
||||
const auto PANIMVAR = dynamic_cast<CAnimatedVariable<float>*>(PAV.get());
|
||||
if (STYLE != "loop" || !PANIMVAR->getConfig()->pValues->internalEnabled)
|
||||
return;
|
||||
|
||||
PANIMVAR->setCallbackOnEnd(nullptr); // we remove the callback here because otherwise setvalueandwarp will recurse this
|
||||
|
||||
PANIMVAR->setValueAndWarp(0);
|
||||
*PANIMVAR = 1.f;
|
||||
|
||||
PANIMVAR->setCallbackOnEnd([&](WP<CBaseAnimatedVariable> pav) { onBorderAngleAnimEnd(pav); }, false);
|
||||
PANIMVAR->setCallbackOnEnd([&](void* ptr) { onBorderAngleAnimEnd(ptr); }, false);
|
||||
}
|
||||
|
||||
void CWindow::setHidden(bool hidden) {
|
||||
@@ -820,27 +827,26 @@ void CWindow::updateDynamicRules() {
|
||||
// otherwise behaviour is undefined
|
||||
bool CWindow::isInCurvedCorner(double x, double y) {
|
||||
const int ROUNDING = rounding();
|
||||
const int ROUNDINGPOWER = roundingPower();
|
||||
if (getRealBorderSize() >= ROUNDING)
|
||||
return false;
|
||||
|
||||
// (x0, y0), (x0, y1), ... are the center point of rounding at each corner
|
||||
double x0 = m_vRealPosition->value().x + ROUNDING;
|
||||
double y0 = m_vRealPosition->value().y + ROUNDING;
|
||||
double x1 = m_vRealPosition->value().x + m_vRealSize->value().x - ROUNDING;
|
||||
double y1 = m_vRealPosition->value().y + m_vRealSize->value().y - ROUNDING;
|
||||
double x0 = m_vRealPosition.value().x + ROUNDING;
|
||||
double y0 = m_vRealPosition.value().y + ROUNDING;
|
||||
double x1 = m_vRealPosition.value().x + m_vRealSize.value().x - ROUNDING;
|
||||
double y1 = m_vRealPosition.value().y + m_vRealSize.value().y - ROUNDING;
|
||||
|
||||
if (x < x0 && y < y0) {
|
||||
return std::pow(x0 - x, ROUNDINGPOWER) + std::pow(y0 - y, ROUNDINGPOWER) > std::pow((double)ROUNDING, ROUNDINGPOWER);
|
||||
return Vector2D{x0, y0}.distance(Vector2D{x, y}) > (double)ROUNDING;
|
||||
}
|
||||
if (x > x1 && y < y0) {
|
||||
return std::pow(x - x1, ROUNDINGPOWER) + std::pow(y0 - y, ROUNDINGPOWER) > std::pow((double)ROUNDING, ROUNDINGPOWER);
|
||||
return Vector2D{x1, y0}.distance(Vector2D{x, y}) > (double)ROUNDING;
|
||||
}
|
||||
if (x < x0 && y > y1) {
|
||||
return std::pow(x0 - x, ROUNDINGPOWER) + std::pow(y - y1, ROUNDINGPOWER) > std::pow((double)ROUNDING, ROUNDINGPOWER);
|
||||
return Vector2D{x0, y1}.distance(Vector2D{x, y}) > (double)ROUNDING;
|
||||
}
|
||||
if (x > x1 && y > y1) {
|
||||
return std::pow(x - x1, ROUNDINGPOWER) + std::pow(y - y1, ROUNDINGPOWER) > std::pow((double)ROUNDING, ROUNDINGPOWER);
|
||||
return Vector2D{x1, y1}.distance(Vector2D{x, y}) > (double)ROUNDING;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -851,7 +857,7 @@ bool CWindow::hasPopupAt(const Vector2D& pos) {
|
||||
if (m_bIsX11)
|
||||
return false;
|
||||
|
||||
auto popup = m_pPopupHead->at(pos);
|
||||
CPopup* popup = m_pPopupHead->at(pos);
|
||||
|
||||
return popup && popup->m_pWLSurface->resource();
|
||||
}
|
||||
@@ -876,7 +882,7 @@ void CWindow::createGroup() {
|
||||
m_sGroupData.locked = false;
|
||||
m_sGroupData.deny = false;
|
||||
|
||||
addWindowDeco(makeUnique<CHyprGroupBarDecoration>(m_pSelf.lock()));
|
||||
addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(m_pSelf.lock()));
|
||||
|
||||
if (m_pWorkspace) {
|
||||
m_pWorkspace->updateWindows();
|
||||
@@ -1022,22 +1028,22 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) {
|
||||
const auto WORKSPACE = PCURRENT->m_pWorkspace;
|
||||
const auto MODE = PCURRENT->m_sFullscreenState.internal;
|
||||
|
||||
const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goal();
|
||||
const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goal();
|
||||
|
||||
const auto CURRENTISFOCUS = PCURRENT == g_pCompositor->m_pLastWindow.lock();
|
||||
|
||||
if (FULLSCREEN)
|
||||
g_pCompositor->setWindowFullscreenInternal(PCURRENT, FSMODE_NONE);
|
||||
|
||||
const auto PWINDOWSIZE = PCURRENT->m_vRealSize->goal();
|
||||
const auto PWINDOWPOS = PCURRENT->m_vRealPosition->goal();
|
||||
|
||||
PCURRENT->setHidden(true);
|
||||
pWindow->setHidden(false); // can remove m_pLastWindow
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->replaceWindowDataWith(PCURRENT, pWindow);
|
||||
|
||||
if (PCURRENT->m_bIsFloating) {
|
||||
pWindow->m_vRealPosition->setValueAndWarp(PWINDOWPOS);
|
||||
pWindow->m_vRealSize->setValueAndWarp(PWINDOWSIZE);
|
||||
pWindow->m_vRealPosition.setValueAndWarp(PWINDOWPOS);
|
||||
pWindow->m_vRealSize.setValueAndWarp(PWINDOWSIZE);
|
||||
}
|
||||
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
@@ -1058,7 +1064,7 @@ void CWindow::insertWindowToGroup(PHLWINDOW pWindow) {
|
||||
const auto ENDAT = m_sGroupData.pNextWindow.lock();
|
||||
|
||||
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
|
||||
pWindow->addWindowDeco(makeUnique<CHyprGroupBarDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||
|
||||
if (!pWindow->m_sGroupData.pNextWindow.lock()) {
|
||||
BEGINAT->m_sGroupData.pNextWindow = pWindow;
|
||||
@@ -1119,22 +1125,22 @@ void CWindow::updateGroupOutputs() {
|
||||
curr->m_pMonitor = m_pMonitor;
|
||||
curr->moveToWorkspace(WS);
|
||||
|
||||
*curr->m_vRealPosition = m_vRealPosition->goal();
|
||||
*curr->m_vRealSize = m_vRealSize->goal();
|
||||
curr->m_vRealPosition = m_vRealPosition.goal();
|
||||
curr->m_vRealSize = m_vRealSize.goal();
|
||||
|
||||
curr = curr->m_sGroupData.pNextWindow.lock();
|
||||
}
|
||||
}
|
||||
|
||||
Vector2D CWindow::middle() {
|
||||
return m_vRealPosition->goal() + m_vRealSize->goal() / 2.f;
|
||||
return m_vRealPosition.goal() + m_vRealSize.goal() / 2.f;
|
||||
}
|
||||
|
||||
bool CWindow::opaque() {
|
||||
if (m_fAlpha->value() != 1.f || m_fActiveInactiveAlpha->value() != 1.f)
|
||||
if (m_fAlpha.value() != 1.f || m_fActiveInactiveAlpha.value() != 1.f)
|
||||
return false;
|
||||
|
||||
if (m_vRealSize->goal().floor() != m_vReportedSize)
|
||||
if (m_vRealSize.goal().floor() != m_vReportedSize)
|
||||
return false;
|
||||
|
||||
const auto PWORKSPACE = m_pWorkspace;
|
||||
@@ -1142,7 +1148,7 @@ bool CWindow::opaque() {
|
||||
if (m_pWLSurface->small() && !m_pWLSurface->m_bFillIgnoreSmall)
|
||||
return false;
|
||||
|
||||
if (PWORKSPACE->m_fAlpha->value() != 1.f)
|
||||
if (PWORKSPACE->m_fAlpha.value() != 1.f)
|
||||
return false;
|
||||
|
||||
if (m_bIsX11 && m_pXWaylandSurface && m_pXWaylandSurface->surface && m_pXWaylandSurface->surface->current.texture)
|
||||
@@ -1161,20 +1167,12 @@ bool CWindow::opaque() {
|
||||
|
||||
float CWindow::rounding() {
|
||||
static auto PROUNDING = CConfigValue<Hyprlang::INT>("decoration:rounding");
|
||||
static auto PROUNDINGPOWER = CConfigValue<Hyprlang::FLOAT>("decoration:rounding_power");
|
||||
|
||||
float roundingPower = m_sWindowData.roundingPower.valueOr(*PROUNDINGPOWER);
|
||||
float rounding = m_sWindowData.rounding.valueOr(*PROUNDING) * (roundingPower / 2.0); /* Make perceived roundness consistent. */
|
||||
float rounding = m_sWindowData.rounding.valueOr(*PROUNDING);
|
||||
|
||||
return m_sWindowData.noRounding.valueOrDefault() ? 0 : rounding;
|
||||
}
|
||||
|
||||
float CWindow::roundingPower() {
|
||||
static auto PROUNDINGPOWER = CConfigValue<Hyprlang::FLOAT>("decoration:rounding_power");
|
||||
|
||||
return m_sWindowData.roundingPower.valueOr(*PROUNDINGPOWER);
|
||||
}
|
||||
|
||||
void CWindow::updateWindowData() {
|
||||
const auto PWORKSPACE = m_pWorkspace;
|
||||
const auto WORKSPACERULE = PWORKSPACE ? g_pConfigManager->getWorkspaceRuleFor(PWORKSPACE) : SWorkspaceRule{};
|
||||
@@ -1232,13 +1230,15 @@ void CWindow::setSuspended(bool suspend) {
|
||||
}
|
||||
|
||||
bool CWindow::visibleOnMonitor(PHLMONITOR pMonitor) {
|
||||
CBox wbox = {m_vRealPosition->value(), m_vRealSize->value()};
|
||||
CBox wbox = {m_vRealPosition.value(), m_vRealSize.value()};
|
||||
|
||||
return !wbox.intersection({pMonitor->vecPosition, pMonitor->vecSize}).empty();
|
||||
}
|
||||
|
||||
void CWindow::setAnimationsToMove() {
|
||||
m_vRealPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove"));
|
||||
auto* const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove");
|
||||
m_vRealPosition.setConfig(PANIMCFG);
|
||||
m_vRealSize.setConfig(PANIMCFG);
|
||||
m_bAnimatingIn = false;
|
||||
}
|
||||
|
||||
@@ -1259,16 +1259,16 @@ void CWindow::onWorkspaceAnimUpdate() {
|
||||
return;
|
||||
|
||||
const auto WINBB = getFullWindowBoundingBox();
|
||||
if (PWORKSPACE->m_vRenderOffset->value().x != 0) {
|
||||
const auto PROGRESS = PWORKSPACE->m_vRenderOffset->value().x / PWSMON->vecSize.x;
|
||||
if (PWORKSPACE->m_vRenderOffset.value().x != 0) {
|
||||
const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().x / PWSMON->vecSize.x;
|
||||
|
||||
if (WINBB.x < PWSMON->vecPosition.x)
|
||||
offset.x += (PWSMON->vecPosition.x - WINBB.x) * PROGRESS;
|
||||
|
||||
if (WINBB.x + WINBB.width > PWSMON->vecPosition.x + PWSMON->vecSize.x)
|
||||
offset.x += (WINBB.x + WINBB.width - PWSMON->vecPosition.x - PWSMON->vecSize.x) * PROGRESS;
|
||||
} else if (PWORKSPACE->m_vRenderOffset->value().y != 0) {
|
||||
const auto PROGRESS = PWORKSPACE->m_vRenderOffset->value().y / PWSMON->vecSize.y;
|
||||
} else if (PWORKSPACE->m_vRenderOffset.value().y != 0) {
|
||||
const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().y / PWSMON->vecSize.y;
|
||||
|
||||
if (WINBB.y < PWSMON->vecPosition.y)
|
||||
offset.y += (PWSMON->vecPosition.y - WINBB.y) * PROGRESS;
|
||||
@@ -1280,20 +1280,12 @@ void CWindow::onWorkspaceAnimUpdate() {
|
||||
m_vFloatingOffset = offset;
|
||||
}
|
||||
|
||||
void CWindow::onFocusAnimUpdate() {
|
||||
// borderangle once
|
||||
if (m_fBorderAngleAnimationProgress->enabled() && !m_fBorderAngleAnimationProgress->isBeingAnimated()) {
|
||||
m_fBorderAngleAnimationProgress->setValueAndWarp(0.f);
|
||||
*m_fBorderAngleAnimationProgress = 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
int CWindow::popupsCount() {
|
||||
if (m_bIsX11)
|
||||
return 0;
|
||||
|
||||
int no = -1;
|
||||
m_pPopupHead->breadthfirst([](WP<CPopup> p, void* d) { *((int*)d) += 1; }, &no);
|
||||
m_pPopupHead->breadthfirst([](CPopup* p, void* d) { *((int*)d) += 1; }, &no);
|
||||
return no;
|
||||
}
|
||||
|
||||
@@ -1307,13 +1299,13 @@ int CWindow::surfacesCount() {
|
||||
}
|
||||
|
||||
void CWindow::clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize) {
|
||||
const Vector2D REALSIZE = m_vRealSize->goal();
|
||||
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;
|
||||
sendWindowSize(NEWSIZE);
|
||||
m_vRealPosition = m_vRealPosition.goal() + DELTA / 2.0;
|
||||
m_vRealSize = NEWSIZE;
|
||||
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), NEWSIZE);
|
||||
}
|
||||
|
||||
bool CWindow::isFullscreen() {
|
||||
@@ -1406,24 +1398,13 @@ void CWindow::activate(bool force) {
|
||||
|
||||
void CWindow::onUpdateState() {
|
||||
std::optional<bool> requestsFS = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsFullscreen : m_pXWaylandSurface->state.requestsFullscreen;
|
||||
std::optional<MONITORID> requestsID = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsFullscreenMonitor : MONITOR_INVALID;
|
||||
std::optional<bool> requestsMX = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsMaximize : m_pXWaylandSurface->state.requestsMaximize;
|
||||
|
||||
if (requestsFS.has_value() && !(m_eSuppressedEvents & SUPPRESS_FULLSCREEN)) {
|
||||
if (requestsID.has_value() && (requestsID.value() != MONITOR_INVALID) && !(m_eSuppressedEvents & SUPPRESS_FULLSCREEN_OUTPUT)) {
|
||||
if (m_bIsMapped) {
|
||||
const auto monitor = g_pCompositor->getMonitorFromID(requestsID.value());
|
||||
g_pCompositor->moveWindowToWorkspaceSafe(m_pSelf.lock(), monitor->activeWorkspace);
|
||||
g_pCompositor->setActiveMonitor(monitor);
|
||||
}
|
||||
|
||||
if (!m_bIsMapped)
|
||||
m_iWantsInitialFullscreenMonitor = requestsID.value();
|
||||
}
|
||||
|
||||
bool fs = requestsFS.value();
|
||||
if (m_bIsMapped)
|
||||
if (m_bIsMapped) {
|
||||
g_pCompositor->changeWindowFullscreenModeClient(m_pSelf.lock(), FSMODE_FULLSCREEN, requestsFS.value());
|
||||
}
|
||||
|
||||
if (!m_bIsMapped)
|
||||
m_bWantsInitialFullscreen = fs;
|
||||
@@ -1537,7 +1518,7 @@ void CWindow::onX11Configure(CBox box) {
|
||||
g_pHyprRenderer->damageWindow(m_pSelf.lock());
|
||||
|
||||
if (!m_bIsFloating || isFullscreen() || g_pInputManager->currentlyDraggedWindow == m_pSelf) {
|
||||
sendWindowSize(m_vRealSize->goal(), true);
|
||||
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal(), true);
|
||||
g_pInputManager->refocus();
|
||||
g_pHyprRenderer->damageWindow(m_pSelf.lock());
|
||||
return;
|
||||
@@ -1550,21 +1531,21 @@ void CWindow::onX11Configure(CBox box) {
|
||||
|
||||
const auto LOGICALPOS = g_pXWaylandManager->xwaylandToWaylandCoords(box.pos());
|
||||
|
||||
m_vRealPosition->setValueAndWarp(LOGICALPOS);
|
||||
m_vRealSize->setValueAndWarp(box.size());
|
||||
m_vRealPosition.setValueAndWarp(LOGICALPOS);
|
||||
m_vRealSize.setValueAndWarp(box.size());
|
||||
|
||||
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
|
||||
if (*PXWLFORCESCALEZERO) {
|
||||
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR) {
|
||||
m_vRealSize->setValueAndWarp(m_vRealSize->goal() / PMONITOR->scale);
|
||||
m_vRealSize.setValueAndWarp(m_vRealSize.goal() / PMONITOR->scale);
|
||||
m_fX11SurfaceScaledBy = PMONITOR->scale;
|
||||
}
|
||||
}
|
||||
|
||||
m_vPosition = m_vRealPosition->goal();
|
||||
m_vSize = m_vRealSize->goal();
|
||||
m_vPosition = m_vRealPosition.value();
|
||||
m_vSize = m_vRealSize.value();
|
||||
|
||||
sendWindowSize(box.size(), true);
|
||||
m_pXWaylandSurface->configure(box);
|
||||
|
||||
m_vPendingReportedSize = box.size();
|
||||
m_vReportedSize = box.size();
|
||||
@@ -1574,7 +1555,7 @@ void CWindow::onX11Configure(CBox box) {
|
||||
if (!m_pWorkspace || !m_pWorkspace->isVisible())
|
||||
return; // further things are only for visible windows
|
||||
|
||||
m_pWorkspace = g_pCompositor->getMonitorFromVector(m_vRealPosition->goal() + m_vRealSize->goal() / 2.f)->activeWorkspace;
|
||||
m_pWorkspace = g_pCompositor->getMonitorFromVector(m_vRealPosition.value() + m_vRealSize.value() / 2.f)->activeWorkspace;
|
||||
|
||||
g_pCompositor->changeWindowZOrder(m_pSelf.lock(), true);
|
||||
|
||||
@@ -1694,38 +1675,3 @@ Vector2D CWindow::requestedMaxSize() {
|
||||
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
void CWindow::sendWindowSize(Vector2D size, bool force, std::optional<Vector2D> overridePos) {
|
||||
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
|
||||
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
|
||||
size = size.clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
|
||||
|
||||
// calculate pos
|
||||
// TODO: this should be decoupled from setWindowSize IMO
|
||||
Vector2D windowPos = overridePos.value_or(m_vRealPosition->goal());
|
||||
|
||||
if (m_bIsX11) {
|
||||
if (const auto XWAYLANDPOS = g_pXWaylandManager->waylandToXWaylandCoords(windowPos); XWAYLANDPOS != Vector2D{})
|
||||
windowPos = XWAYLANDPOS;
|
||||
}
|
||||
|
||||
if (!force && m_vPendingReportedSize == size && (windowPos == m_vReportedPosition || !m_bIsX11))
|
||||
return;
|
||||
|
||||
m_vReportedPosition = windowPos;
|
||||
m_vPendingReportedSize = size;
|
||||
|
||||
m_fX11SurfaceScaledBy = 1.0f;
|
||||
|
||||
if (*PXWLFORCESCALEZERO && m_bIsX11 && PMONITOR) {
|
||||
size *= PMONITOR->scale;
|
||||
m_fX11SurfaceScaledBy = PMONITOR->scale;
|
||||
}
|
||||
|
||||
if (m_bIsX11 && m_pXWaylandSurface)
|
||||
m_pXWaylandSurface->configure({windowPos, size});
|
||||
else if (m_pXDGSurface && m_pXDGSurface->toplevel)
|
||||
m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(size), size.floor());
|
||||
}
|
||||
|
@@ -2,9 +2,9 @@
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
#include "../config/ConfigDataValues.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
#include "../helpers/math/Math.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "../macros.hpp"
|
||||
#include "../managers/XWaylandManager.hpp"
|
||||
#include "../render/decorations/IHyprWindowDecoration.hpp"
|
||||
#include "../render/Transformer.hpp"
|
||||
#include "DesktopTypes.hpp"
|
||||
#include "Popup.hpp"
|
||||
#include "Subsurface.hpp"
|
||||
@@ -58,7 +57,6 @@ enum eSuppressEvents : uint8_t {
|
||||
SUPPRESS_MAXIMIZE = 1 << 1,
|
||||
SUPPRESS_ACTIVATE = 1 << 2,
|
||||
SUPPRESS_ACTIVATE_FOCUSONLY = 1 << 3,
|
||||
SUPPRESS_FULLSCREEN_OUTPUT = 1 << 4,
|
||||
};
|
||||
|
||||
class IWindowTransformer;
|
||||
@@ -185,7 +183,6 @@ struct SWindowData {
|
||||
CWindowOverridableVar<bool> renderUnfocused = false;
|
||||
|
||||
CWindowOverridableVar<int> rounding;
|
||||
CWindowOverridableVar<float> roundingPower;
|
||||
CWindowOverridableVar<int> borderSize;
|
||||
|
||||
CWindowOverridableVar<float> scrollMouse;
|
||||
@@ -235,8 +232,8 @@ class CWindow {
|
||||
Vector2D m_vSize = Vector2D(0, 0);
|
||||
|
||||
// this is the real position and size used to draw the thing
|
||||
PHLANIMVAR<Vector2D> m_vRealPosition;
|
||||
PHLANIMVAR<Vector2D> m_vRealSize;
|
||||
CAnimatedVariable<Vector2D> m_vRealPosition;
|
||||
CAnimatedVariable<Vector2D> m_vRealSize;
|
||||
|
||||
// for not spamming the protocols
|
||||
Vector2D m_vReportedPosition;
|
||||
@@ -291,23 +288,22 @@ class CWindow {
|
||||
|
||||
// Fullscreen and Maximize
|
||||
bool m_bWantsInitialFullscreen = false;
|
||||
MONITORID m_iWantsInitialFullscreenMonitor = MONITOR_INVALID;
|
||||
|
||||
// bitfield eSuppressEvents
|
||||
uint64_t m_eSuppressedEvents = SUPPRESS_NONE;
|
||||
|
||||
// desktop components
|
||||
UP<CSubsurface> m_pSubsurfaceHead;
|
||||
UP<CPopup> m_pPopupHead;
|
||||
std::unique_ptr<CSubsurface> m_pSubsurfaceHead;
|
||||
std::unique_ptr<CPopup> m_pPopupHead;
|
||||
|
||||
// Animated border
|
||||
CGradientValueData m_cRealBorderColor = {0};
|
||||
CGradientValueData m_cRealBorderColorPrevious = {0};
|
||||
PHLANIMVAR<float> m_fBorderFadeAnimationProgress;
|
||||
PHLANIMVAR<float> m_fBorderAngleAnimationProgress;
|
||||
CAnimatedVariable<float> m_fBorderFadeAnimationProgress;
|
||||
CAnimatedVariable<float> m_fBorderAngleAnimationProgress;
|
||||
|
||||
// Fade in-out
|
||||
PHLANIMVAR<float> m_fAlpha;
|
||||
CAnimatedVariable<float> m_fAlpha;
|
||||
bool m_bFadingOut = false;
|
||||
bool m_bReadyToDelete = false;
|
||||
Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in
|
||||
@@ -329,28 +325,27 @@ class CWindow {
|
||||
|
||||
// Window decorations
|
||||
// TODO: make this a SP.
|
||||
std::vector<UP<IHyprWindowDecoration>> m_dWindowDecorations;
|
||||
std::vector<std::unique_ptr<IHyprWindowDecoration>> m_dWindowDecorations;
|
||||
std::vector<IHyprWindowDecoration*> m_vDecosToRemove;
|
||||
|
||||
// Special render data, rules, etc
|
||||
SWindowData m_sWindowData;
|
||||
|
||||
// Transformers
|
||||
std::vector<UP<IWindowTransformer>> m_vTransformers;
|
||||
std::vector<std::unique_ptr<IWindowTransformer>> m_vTransformers;
|
||||
|
||||
// for alpha
|
||||
PHLANIMVAR<float> m_fActiveInactiveAlpha;
|
||||
PHLANIMVAR<float> m_fMovingFromWorkspaceAlpha;
|
||||
CAnimatedVariable<float> m_fActiveInactiveAlpha;
|
||||
|
||||
// animated shadow color
|
||||
PHLANIMVAR<CHyprColor> m_cRealShadowColor;
|
||||
CAnimatedVariable<CHyprColor> m_cRealShadowColor;
|
||||
|
||||
// animated tint
|
||||
PHLANIMVAR<float> m_fDimPercent;
|
||||
CAnimatedVariable<float> m_fDimPercent;
|
||||
|
||||
// animate moving to an invisible workspace
|
||||
int m_iMonitorMovedFrom = -1; // -1 means not moving
|
||||
PHLANIMVAR<float> m_fMovingToWorkspaceAlpha;
|
||||
CAnimatedVariable<float> m_fMovingToWorkspaceAlpha;
|
||||
|
||||
// swallowing
|
||||
PHLWINDOWREF m_pSwallowed;
|
||||
@@ -397,13 +392,14 @@ class CWindow {
|
||||
SBoxExtents getFullWindowExtents();
|
||||
CBox getWindowBoxUnified(uint64_t props);
|
||||
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
||||
void addWindowDeco(UP<IHyprWindowDecoration> deco);
|
||||
void addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco);
|
||||
void updateWindowDecos();
|
||||
void removeWindowDeco(IHyprWindowDecoration* deco);
|
||||
void uncacheWindowDecos();
|
||||
bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {});
|
||||
pid_t getPID();
|
||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||
void removeDecorationByType(eDecorationType);
|
||||
void updateToplevel();
|
||||
void updateSurfaceScaleTransformDetails(bool force = false);
|
||||
void moveToWorkspace(PHLWORKSPACE);
|
||||
@@ -418,7 +414,6 @@ class CWindow {
|
||||
Vector2D middle();
|
||||
bool opaque();
|
||||
float rounding();
|
||||
float roundingPower();
|
||||
bool canBeTorn();
|
||||
void setSuspended(bool suspend);
|
||||
bool visibleOnMonitor(PHLMONITOR pMonitor);
|
||||
@@ -435,7 +430,7 @@ class CWindow {
|
||||
float getScrollTouchpad();
|
||||
void updateWindowData();
|
||||
void updateWindowData(const struct SWorkspaceRule&);
|
||||
void onBorderAngleAnimEnd(WP<Hyprutils::Animation::CBaseAnimatedVariable> pav);
|
||||
void onBorderAngleAnimEnd(void* ptr);
|
||||
bool isInCurvedCorner(double x, double y);
|
||||
bool hasPopupAt(const Vector2D& pos);
|
||||
int popupsCount();
|
||||
@@ -455,7 +450,6 @@ class CWindow {
|
||||
void switchWithWindowInGroup(PHLWINDOW pWindow);
|
||||
void setAnimationsToMove();
|
||||
void onWorkspaceAnimUpdate();
|
||||
void onFocusAnimUpdate();
|
||||
void onUpdateState();
|
||||
void onUpdateMeta();
|
||||
void onX11Configure(CBox box);
|
||||
@@ -469,10 +463,9 @@ class CWindow {
|
||||
bool isModal();
|
||||
Vector2D requestedMinSize();
|
||||
Vector2D requestedMaxSize();
|
||||
void sendWindowSize(Vector2D size, bool force = false, std::optional<Vector2D> overridePos = std::nullopt);
|
||||
|
||||
CBox getWindowMainSurfaceBox() const {
|
||||
return {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y};
|
||||
return {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y};
|
||||
}
|
||||
|
||||
// listeners
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#include "WindowRule.hpp"
|
||||
#include <unordered_set>
|
||||
#include <algorithm>
|
||||
#include <re2/re2.h>
|
||||
#include "../config/ConfigManager.hpp"
|
||||
|
||||
static const auto RULES = std::unordered_set<std::string>{
|
||||
@@ -9,7 +8,7 @@ static const auto RULES = std::unordered_set<std::string>{
|
||||
};
|
||||
static const auto RULES_PREFIX = std::unordered_set<std::string>{
|
||||
"animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor", "move", "opacity",
|
||||
"plugin:", "prop", "pseudo", "rounding", "roundingpower", "scrollmouse", "scrolltouchpad", "size", "suppressevent", "tag", "workspace", "xray",
|
||||
"plugin:", "prop", "pseudo", "rounding", "scrollmouse", "scrolltouchpad", "size", "suppressevent", "tag", "workspace", "xray",
|
||||
};
|
||||
|
||||
CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool isV2, bool isExecRule) : szValue(value), szRule(rule), v2(isV2), execRule(isExecRule) {
|
||||
|
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include "Rule.hpp"
|
||||
|
||||
class CWindowRule {
|
||||
public:
|
||||
@@ -58,11 +57,4 @@ class CWindowRule {
|
||||
std::string szFullscreenState = ""; // empty means any
|
||||
std::string szOnWorkspace = ""; // empty means any
|
||||
std::string szWorkspace = ""; // empty means any
|
||||
|
||||
// precompiled regexes
|
||||
CRuleRegexContainer rTitle;
|
||||
CRuleRegexContainer rClass;
|
||||
CRuleRegexContainer rInitialTitle;
|
||||
CRuleRegexContainer rInitialClass;
|
||||
CRuleRegexContainer rV1Regex;
|
||||
};
|
@@ -1,12 +1,7 @@
|
||||
#include "Workspace.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "managers/AnimationManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
|
||||
#include <hyprutils/animation/AnimatedVariable.hpp>
|
||||
#include <hyprutils/string/String.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
|
||||
@@ -24,10 +19,16 @@ CWorkspace::CWorkspace(WORKSPACEID id, PHLMONITOR monitor, std::string name, boo
|
||||
void CWorkspace::init(PHLWORKSPACE self) {
|
||||
m_pSelf = self;
|
||||
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), m_vRenderOffset,
|
||||
g_pConfigManager->getAnimationPropertyConfig(m_bIsSpecialWorkspace ? "specialWorkspaceIn" : "workspacesIn"), self, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(1.f, m_fAlpha, g_pConfigManager->getAnimationPropertyConfig(m_bIsSpecialWorkspace ? "specialWorkspaceIn" : "workspacesIn"), self,
|
||||
m_vRenderOffset.create(m_bIsSpecialWorkspace ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspaceIn") :
|
||||
g_pConfigManager->getAnimationPropertyConfig("workspacesIn"),
|
||||
self, AVARDAMAGE_ENTIRE);
|
||||
m_fAlpha.create(AVARTYPE_FLOAT,
|
||||
m_bIsSpecialWorkspace ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspaceIn") : g_pConfigManager->getAnimationPropertyConfig("workspacesIn"), self,
|
||||
AVARDAMAGE_ENTIRE);
|
||||
m_fAlpha.setValueAndWarp(1.f);
|
||||
|
||||
m_vRenderOffset.registerVar();
|
||||
m_fAlpha.registerVar();
|
||||
|
||||
const auto RULEFORTHIS = g_pConfigManager->getWorkspaceRuleFor(self);
|
||||
if (RULEFORTHIS.defaultName.has_value())
|
||||
@@ -54,11 +55,16 @@ void CWorkspace::init(PHLWORKSPACE self) {
|
||||
EMIT_HOOK_EVENT("createWorkspace", this);
|
||||
}
|
||||
|
||||
SWorkspaceIDName CWorkspace::getPrevWorkspaceIDName() const {
|
||||
SWorkspaceIDName CWorkspace::getPrevWorkspaceIDName(bool perMonitor) const {
|
||||
if (perMonitor)
|
||||
return m_sPrevWorkspacePerMonitor;
|
||||
|
||||
return m_sPrevWorkspace;
|
||||
}
|
||||
|
||||
CWorkspace::~CWorkspace() {
|
||||
m_vRenderOffset.unregister();
|
||||
|
||||
Debug::log(LOG, "Destroying workspace ID {}", m_iID);
|
||||
|
||||
// check if g_pHookSystem and g_pEventManager exist, they might be destroyed as in when the compositor is closing.
|
||||
@@ -76,15 +82,15 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
if (!instant) {
|
||||
const std::string ANIMNAME = std::format("{}{}", m_bIsSpecialWorkspace ? "specialWorkspace" : "workspaces", in ? "In" : "Out");
|
||||
|
||||
m_fAlpha->setConfig(g_pConfigManager->getAnimationPropertyConfig(ANIMNAME));
|
||||
m_vRenderOffset->setConfig(g_pConfigManager->getAnimationPropertyConfig(ANIMNAME));
|
||||
m_fAlpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig(ANIMNAME);
|
||||
m_vRenderOffset.m_pConfig = g_pConfigManager->getAnimationPropertyConfig(ANIMNAME);
|
||||
}
|
||||
|
||||
const auto ANIMSTYLE = m_fAlpha->getStyle();
|
||||
const auto ANIMSTYLE = m_fAlpha.m_pConfig->pValues->internalStyle;
|
||||
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
||||
|
||||
// set floating windows offset callbacks
|
||||
m_vRenderOffset->setUpdateCallback([&](auto) {
|
||||
m_vRenderOffset.setUpdateCallback([&](void*) {
|
||||
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||
if (!validMapped(w) || w->workspaceID() != m_iID)
|
||||
continue;
|
||||
@@ -104,84 +110,84 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
} catch (std::exception& e) { Debug::log(ERR, "Error in startAnim: invalid percentage"); }
|
||||
}
|
||||
|
||||
m_fAlpha->setValueAndWarp(1.f);
|
||||
m_vRenderOffset->setValueAndWarp(Vector2D(0, 0));
|
||||
m_fAlpha.setValueAndWarp(1.f);
|
||||
m_vRenderOffset.setValueAndWarp(Vector2D(0, 0));
|
||||
|
||||
if (ANIMSTYLE.starts_with("slidefadevert")) {
|
||||
if (in) {
|
||||
m_fAlpha->setValueAndWarp(0.f);
|
||||
m_vRenderOffset->setValueAndWarp(Vector2D(0.0, (left ? PMONITOR->vecSize.y : -PMONITOR->vecSize.y) * (movePerc / 100.f)));
|
||||
*m_fAlpha = 1.f;
|
||||
*m_vRenderOffset = Vector2D(0, 0);
|
||||
m_fAlpha.setValueAndWarp(0.f);
|
||||
m_vRenderOffset.setValueAndWarp(Vector2D(0.0, (left ? PMONITOR->vecSize.y : -PMONITOR->vecSize.y) * (movePerc / 100.f)));
|
||||
m_fAlpha = 1.f;
|
||||
m_vRenderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
m_fAlpha->setValueAndWarp(1.f);
|
||||
*m_fAlpha = 0.f;
|
||||
*m_vRenderOffset = Vector2D(0.0, (left ? -PMONITOR->vecSize.y : PMONITOR->vecSize.y) * (movePerc / 100.f));
|
||||
m_fAlpha.setValueAndWarp(1.f);
|
||||
m_fAlpha = 0.f;
|
||||
m_vRenderOffset = Vector2D(0.0, (left ? -PMONITOR->vecSize.y : PMONITOR->vecSize.y) * (movePerc / 100.f));
|
||||
}
|
||||
} else {
|
||||
if (in) {
|
||||
m_fAlpha->setValueAndWarp(0.f);
|
||||
m_vRenderOffset->setValueAndWarp(Vector2D((left ? PMONITOR->vecSize.x : -PMONITOR->vecSize.x) * (movePerc / 100.f), 0.0));
|
||||
*m_fAlpha = 1.f;
|
||||
*m_vRenderOffset = Vector2D(0, 0);
|
||||
m_fAlpha.setValueAndWarp(0.f);
|
||||
m_vRenderOffset.setValueAndWarp(Vector2D((left ? PMONITOR->vecSize.x : -PMONITOR->vecSize.x) * (movePerc / 100.f), 0.0));
|
||||
m_fAlpha = 1.f;
|
||||
m_vRenderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
m_fAlpha->setValueAndWarp(1.f);
|
||||
*m_fAlpha = 0.f;
|
||||
*m_vRenderOffset = Vector2D((left ? -PMONITOR->vecSize.x : PMONITOR->vecSize.x) * (movePerc / 100.f), 0.0);
|
||||
m_fAlpha.setValueAndWarp(1.f);
|
||||
m_fAlpha = 0.f;
|
||||
m_vRenderOffset = Vector2D((left ? -PMONITOR->vecSize.x : PMONITOR->vecSize.x) * (movePerc / 100.f), 0.0);
|
||||
}
|
||||
}
|
||||
} else if (ANIMSTYLE == "fade") {
|
||||
m_vRenderOffset->setValueAndWarp(Vector2D(0, 0)); // fix a bug, if switching from slide -> fade.
|
||||
m_vRenderOffset.setValueAndWarp(Vector2D(0, 0)); // fix a bug, if switching from slide -> fade.
|
||||
|
||||
if (in) {
|
||||
m_fAlpha->setValueAndWarp(0.f);
|
||||
*m_fAlpha = 1.f;
|
||||
m_fAlpha.setValueAndWarp(0.f);
|
||||
m_fAlpha = 1.f;
|
||||
} else {
|
||||
m_fAlpha->setValueAndWarp(1.f);
|
||||
*m_fAlpha = 0.f;
|
||||
m_fAlpha.setValueAndWarp(1.f);
|
||||
m_fAlpha = 0.f;
|
||||
}
|
||||
} else if (ANIMSTYLE == "slidevert") {
|
||||
// fallback is slide
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
const auto YDISTANCE = PMONITOR->vecSize.y + *PWORKSPACEGAP;
|
||||
|
||||
m_fAlpha->setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
|
||||
m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
|
||||
|
||||
if (in) {
|
||||
m_vRenderOffset->setValueAndWarp(Vector2D(0.0, left ? YDISTANCE : -YDISTANCE));
|
||||
*m_vRenderOffset = Vector2D(0, 0);
|
||||
m_vRenderOffset.setValueAndWarp(Vector2D(0.0, left ? YDISTANCE : -YDISTANCE));
|
||||
m_vRenderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
*m_vRenderOffset = Vector2D(0.0, left ? -YDISTANCE : YDISTANCE);
|
||||
m_vRenderOffset = Vector2D(0.0, left ? -YDISTANCE : YDISTANCE);
|
||||
}
|
||||
} else {
|
||||
// fallback is slide
|
||||
const auto PMONITOR = m_pMonitor.lock();
|
||||
const auto XDISTANCE = PMONITOR->vecSize.x + *PWORKSPACEGAP;
|
||||
|
||||
m_fAlpha->setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
|
||||
m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
|
||||
|
||||
if (in) {
|
||||
m_vRenderOffset->setValueAndWarp(Vector2D(left ? XDISTANCE : -XDISTANCE, 0.0));
|
||||
*m_vRenderOffset = Vector2D(0, 0);
|
||||
m_vRenderOffset.setValueAndWarp(Vector2D(left ? XDISTANCE : -XDISTANCE, 0.0));
|
||||
m_vRenderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
*m_vRenderOffset = Vector2D(left ? -XDISTANCE : XDISTANCE, 0.0);
|
||||
m_vRenderOffset = Vector2D(left ? -XDISTANCE : XDISTANCE, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bIsSpecialWorkspace) {
|
||||
// required for open/close animations
|
||||
if (in) {
|
||||
m_fAlpha->setValueAndWarp(0.f);
|
||||
*m_fAlpha = 1.f;
|
||||
m_fAlpha.setValueAndWarp(0.f);
|
||||
m_fAlpha = 1.f;
|
||||
} else {
|
||||
m_fAlpha->setValueAndWarp(1.f);
|
||||
*m_fAlpha = 0.f;
|
||||
m_fAlpha.setValueAndWarp(1.f);
|
||||
m_fAlpha = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
if (instant) {
|
||||
m_vRenderOffset->warp();
|
||||
m_fAlpha->warp();
|
||||
m_vRenderOffset.warp();
|
||||
m_fAlpha.warp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +221,10 @@ void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) {
|
||||
m_sPrevWorkspace.id = prev->m_iID;
|
||||
m_sPrevWorkspace.name = prev->m_szName;
|
||||
|
||||
prev->m_pMonitor->addPrevWorkspaceID(prev->m_iID);
|
||||
if (prev->m_pMonitor == m_pMonitor) {
|
||||
m_sPrevWorkspacePerMonitor.id = prev->m_iID;
|
||||
m_sPrevWorkspacePerMonitor.name = prev->m_szName;
|
||||
}
|
||||
}
|
||||
|
||||
std::string CWorkspace::getConfigName() {
|
||||
@@ -624,7 +633,7 @@ void CWorkspace::forceReportSizesToWindows() {
|
||||
if (w->m_pWorkspace != m_pSelf || !w->m_bIsMapped || w->isHidden())
|
||||
continue;
|
||||
|
||||
w->sendWindowSize(w->m_vRealSize->goal(), true);
|
||||
g_pXWaylandManager->setWindowSize(w, w->m_vRealSize.value(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -27,6 +27,9 @@ class CWorkspace {
|
||||
WORKSPACEID m_iID = WORKSPACE_INVALID;
|
||||
std::string m_szName = "";
|
||||
PHLMONITORREF m_pMonitor;
|
||||
// Previous workspace ID and name is stored during a workspace change, allowing travel
|
||||
// to the previous workspace.
|
||||
SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor;
|
||||
|
||||
bool m_bHasFullscreenWindow = false;
|
||||
eFullscreenMode m_efFullscreenMode = FSMODE_NONE;
|
||||
@@ -34,8 +37,8 @@ class CWorkspace {
|
||||
wl_array m_wlrCoordinateArr;
|
||||
|
||||
// for animations
|
||||
PHLANIMVAR<Vector2D> m_vRenderOffset;
|
||||
PHLANIMVAR<float> m_fAlpha;
|
||||
CAnimatedVariable<Vector2D> m_vRenderOffset;
|
||||
CAnimatedVariable<float> m_fAlpha;
|
||||
bool m_bForceRendering = false;
|
||||
|
||||
// allows damage to propagate.
|
||||
@@ -69,7 +72,7 @@ class CWorkspace {
|
||||
std::string getConfigName();
|
||||
bool matchesStaticSelector(const std::string& selector);
|
||||
void markInert();
|
||||
SWorkspaceIDName getPrevWorkspaceIDName() const;
|
||||
SWorkspaceIDName getPrevWorkspaceIDName(bool perMonitor) const;
|
||||
void updateWindowDecos();
|
||||
void updateWindowData();
|
||||
int getWindows(std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
||||
@@ -86,9 +89,6 @@ class CWorkspace {
|
||||
|
||||
private:
|
||||
void init(PHLWORKSPACE self);
|
||||
// Previous workspace ID and name is stored during a workspace change, allowing travel
|
||||
// to the previous workspace.
|
||||
SWorkspaceIDName m_sPrevWorkspace;
|
||||
|
||||
SP<HOOK_CALLBACK_FN> m_pFocusedWindowHook;
|
||||
bool m_bInert = true;
|
||||
|
@@ -44,10 +44,6 @@ void IKeyboard::clearManuallyAllocd() {
|
||||
if (xkbKeymapFD >= 0)
|
||||
close(xkbKeymapFD);
|
||||
|
||||
if (xkbSymState)
|
||||
xkb_state_unref(xkbSymState);
|
||||
|
||||
xkbSymState = nullptr;
|
||||
xkbKeymap = nullptr;
|
||||
xkbState = nullptr;
|
||||
xkbStaticState = nullptr;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include "Keyboard.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
#include <aquamarine/input/Input.hpp>
|
||||
|
||||
|
@@ -11,7 +11,7 @@ SP<CVirtualPointer> CVirtualPointer::create(SP<CVirtualPointerV1Resource> resour
|
||||
}
|
||||
|
||||
CVirtualPointer::CVirtualPointer(SP<CVirtualPointerV1Resource> resource) : pointer(resource) {
|
||||
if UNLIKELY (!resource->good())
|
||||
if (!resource->good())
|
||||
return;
|
||||
|
||||
listeners.destroy = pointer->events.destroy.registerListener([this](std::any d) {
|
||||
|
@@ -12,17 +12,10 @@
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../protocols/ToplevelExport.hpp"
|
||||
#include "../xwayland/XSurface.hpp"
|
||||
#include "managers/AnimationManager.hpp"
|
||||
#include "managers/PointerManager.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
using namespace Hyprutils::Animation;
|
||||
|
||||
// ------------------------------------------------------------ //
|
||||
// __ _______ _ _ _____ ______ _______ //
|
||||
@@ -34,17 +27,15 @@ using namespace Hyprutils::Animation;
|
||||
// //
|
||||
// ------------------------------------------------------------ //
|
||||
|
||||
static void setVector2DAnimToMove(WP<CBaseAnimatedVariable> pav) {
|
||||
const auto PAV = pav.lock();
|
||||
if (!PAV)
|
||||
return;
|
||||
void setAnimToMove(void* data) {
|
||||
auto* const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove");
|
||||
|
||||
CAnimatedVariable<Vector2D>* animvar = dynamic_cast<CAnimatedVariable<Vector2D>*>(PAV.get());
|
||||
animvar->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove"));
|
||||
CBaseAnimatedVariable* animvar = (CBaseAnimatedVariable*)data;
|
||||
|
||||
const auto PHLWINDOW = animvar->m_Context.pWindow.lock();
|
||||
if (PHLWINDOW)
|
||||
PHLWINDOW->m_bAnimatingIn = false;
|
||||
animvar->setConfig(PANIMCFG);
|
||||
|
||||
if (animvar->getWindow() && !animvar->getWindow()->m_vRealPosition.isBeingAnimated() && !animvar->getWindow()->m_vRealSize.isBeingAnimated())
|
||||
animvar->getWindow()->m_bAnimatingIn = false;
|
||||
}
|
||||
|
||||
void Events::listener_mapWindow(void* owner, void* data) {
|
||||
@@ -130,13 +121,22 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
PWINDOW->m_bX11ShouldntFocus = PWINDOW->m_bX11ShouldntFocus || (PWINDOW->m_bIsX11 && PWINDOW->isX11OverrideRedirect() && !PWINDOW->m_pXWaylandSurface->wantsFocus());
|
||||
|
||||
if (PWORKSPACE->m_bDefaultFloating)
|
||||
PWINDOW->m_bIsFloating = true;
|
||||
|
||||
if (PWORKSPACE->m_bDefaultPseudo) {
|
||||
PWINDOW->m_bIsPseudotiled = true;
|
||||
CBox desiredGeometry = {0};
|
||||
g_pXWaylandManager->getGeometryForWindow(PWINDOW, &desiredGeometry);
|
||||
PWINDOW->m_vPseudoSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
|
||||
}
|
||||
|
||||
// window rules
|
||||
PWINDOW->m_vMatchedRules = g_pConfigManager->getMatchingRules(PWINDOW, false);
|
||||
std::optional<eFullscreenMode> requestedInternalFSMode, requestedClientFSMode;
|
||||
std::optional<SFullscreenState> requestedFSState;
|
||||
if (PWINDOW->m_bWantsInitialFullscreen || (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface->fullscreen))
|
||||
requestedClientFSMode = FSMODE_FULLSCREEN;
|
||||
MONITORID requestedFSMonitor = PWINDOW->m_iWantsInitialFullscreenMonitor;
|
||||
|
||||
for (auto const& r : PWINDOW->m_vMatchedRules) {
|
||||
switch (r->ruleType) {
|
||||
@@ -171,10 +171,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PMONITOR = PMONITORFROMID;
|
||||
}
|
||||
PWINDOW->m_pWorkspace = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace;
|
||||
PWORKSPACE = PWINDOW->m_pWorkspace;
|
||||
|
||||
Debug::log(LOG, "Rule monitor, applying to {:mw}", PWINDOW);
|
||||
requestedFSMonitor = MONITOR_INVALID;
|
||||
} catch (std::exception& e) { Debug::log(ERR, "Rule monitor failed, rule: {} -> {} | err: {}", r->szRule, r->szValue, e.what()); }
|
||||
break;
|
||||
}
|
||||
@@ -182,10 +180,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
// check if it isnt unset
|
||||
const auto WORKSPACERQ = r->szRule.substr(r->szRule.find_first_of(' ') + 1);
|
||||
|
||||
if (WORKSPACERQ == "unset")
|
||||
if (WORKSPACERQ == "unset") {
|
||||
requestedWorkspace = "";
|
||||
else
|
||||
} else {
|
||||
requestedWorkspace = WORKSPACERQ;
|
||||
}
|
||||
|
||||
const auto JUSTWORKSPACE = WORKSPACERQ.contains(' ') ? WORKSPACERQ.substr(0, WORKSPACERQ.find_first_of(' ')) : WORKSPACERQ;
|
||||
|
||||
@@ -193,7 +192,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
requestedWorkspace = "";
|
||||
|
||||
Debug::log(LOG, "Rule workspace matched by {}, {} applied.", PWINDOW, r->szValue);
|
||||
requestedFSMonitor = MONITOR_INVALID;
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_FLOAT: {
|
||||
@@ -235,8 +233,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_eSuppressedEvents |= SUPPRESS_ACTIVATE;
|
||||
else if (vars[i] == "activatefocus")
|
||||
PWINDOW->m_eSuppressedEvents |= SUPPRESS_ACTIVATE_FOCUSONLY;
|
||||
else if (vars[i] == "fullscreenoutput")
|
||||
PWINDOW->m_eSuppressedEvents |= SUPPRESS_FULLSCREEN_OUTPUT;
|
||||
else
|
||||
Debug::log(ERR, "Error while parsing suppressevent windowrule: unknown event type {}", vars[i]);
|
||||
}
|
||||
@@ -347,39 +343,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
PMONITOR = g_pCompositor->m_pLastMonitor.lock();
|
||||
}
|
||||
|
||||
requestedFSMonitor = MONITOR_INVALID;
|
||||
} else
|
||||
workspaceSilent = false;
|
||||
}
|
||||
|
||||
if (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN_OUTPUT)
|
||||
requestedFSMonitor = MONITOR_INVALID;
|
||||
else if (requestedFSMonitor != MONITOR_INVALID) {
|
||||
if (const auto PM = g_pCompositor->getMonitorFromID(requestedFSMonitor); PM)
|
||||
PWINDOW->m_pMonitor = PM;
|
||||
|
||||
const auto PMONITORFROMID = PWINDOW->m_pMonitor.lock();
|
||||
|
||||
if (PWINDOW->m_pMonitor != PMONITOR) {
|
||||
g_pKeybindManager->m_mDispatchers["focusmonitor"](std::to_string(PWINDOW->monitorID()));
|
||||
PMONITOR = PMONITORFROMID;
|
||||
}
|
||||
PWINDOW->m_pWorkspace = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace;
|
||||
PWORKSPACE = PWINDOW->m_pWorkspace;
|
||||
|
||||
Debug::log(LOG, "Requested monitor, applying to {:mw}", PWINDOW);
|
||||
}
|
||||
|
||||
if (PWORKSPACE->m_bDefaultFloating)
|
||||
PWINDOW->m_bIsFloating = true;
|
||||
|
||||
if (PWORKSPACE->m_bDefaultPseudo) {
|
||||
PWINDOW->m_bIsPseudotiled = true;
|
||||
CBox desiredGeometry = g_pXWaylandManager->getGeometryForWindow(PWINDOW);
|
||||
PWINDOW->m_vPseudoSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
|
||||
}
|
||||
|
||||
PWINDOW->updateWindowData();
|
||||
|
||||
// Verify window swallowing. Get the swallower before calling onWindowCreated(PWINDOW) because getSwallower() wouldn't get it after if PWINDOW gets auto grouped.
|
||||
@@ -411,10 +378,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
const auto MAXSIZE = PWINDOW->requestedMaxSize();
|
||||
|
||||
const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, PMONITOR->vecSize.x) :
|
||||
stringToFloatClamp(SIZEXSTR, PWINDOW->m_vRealSize->goal().x, PMONITOR->vecSize.x);
|
||||
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);
|
||||
stringToFloatClamp(SIZEYSTR, PWINDOW->m_vRealSize.goal().y, PMONITOR->vecSize.y);
|
||||
|
||||
Debug::log(LOG, "Rule size, applying to {}", PWINDOW);
|
||||
|
||||
@@ -451,7 +418,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
(!POSXRAW.contains('%') ? std::stoi(POSXRAW) : std::stof(POSXRAW.substr(0, POSXRAW.length() - 1)) * 0.01 * PMONITOR->vecSize.x);
|
||||
|
||||
if (subtractWindow)
|
||||
posX -= PWINDOW->m_vRealSize->goal().x;
|
||||
posX -= PWINDOW->m_vRealSize.goal().x;
|
||||
|
||||
if (CURSOR)
|
||||
Debug::log(ERR, "Cursor is not compatible with 100%-, ignoring cursor!");
|
||||
@@ -463,7 +430,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
posX = g_pInputManager->getMouseCoordsInternal().x - PMONITOR->vecPosition.x;
|
||||
} else {
|
||||
posX = g_pInputManager->getMouseCoordsInternal().x - PMONITOR->vecPosition.x +
|
||||
(!POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stof(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize->goal().x);
|
||||
(!POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stof(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize.goal().x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +441,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
(!POSYRAW.contains('%') ? std::stoi(POSYRAW) : std::stof(POSYRAW.substr(0, POSYRAW.length() - 1)) * 0.01 * PMONITOR->vecSize.y);
|
||||
|
||||
if (subtractWindow)
|
||||
posY -= PWINDOW->m_vRealSize->goal().y;
|
||||
posY -= PWINDOW->m_vRealSize.goal().y;
|
||||
|
||||
if (CURSOR)
|
||||
Debug::log(ERR, "Cursor is not compatible with 100%-, ignoring cursor!");
|
||||
@@ -486,7 +453,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
posY = g_pInputManager->getMouseCoordsInternal().y - PMONITOR->vecPosition.y;
|
||||
} else {
|
||||
posY = g_pInputManager->getMouseCoordsInternal().y - PMONITOR->vecPosition.y +
|
||||
(!POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stof(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize->goal().y);
|
||||
(!POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stof(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize.goal().y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,15 +461,15 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
int borderSize = PWINDOW->getRealBorderSize();
|
||||
|
||||
posX = std::clamp(posX, (int)(PMONITOR->vecReservedTopLeft.x + borderSize),
|
||||
(int)(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PWINDOW->m_vRealSize->goal().x - borderSize));
|
||||
(int)(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PWINDOW->m_vRealSize.goal().x - borderSize));
|
||||
|
||||
posY = std::clamp(posY, (int)(PMONITOR->vecReservedTopLeft.y + borderSize),
|
||||
(int)(PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PWINDOW->m_vRealSize->goal().y - borderSize));
|
||||
(int)(PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PWINDOW->m_vRealSize.goal().y - borderSize));
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Rule move, applying to {}", PWINDOW);
|
||||
|
||||
*PWINDOW->m_vRealPosition = Vector2D(posX, posY) + PMONITOR->vecPosition;
|
||||
PWINDOW->m_vRealPosition = Vector2D(posX, posY) + PMONITOR->vecPosition;
|
||||
|
||||
PWINDOW->setHidden(false);
|
||||
} catch (...) { Debug::log(LOG, "Rule move failed, rule: {} -> {}", r->szRule, r->szValue); }
|
||||
@@ -514,7 +481,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
if (ARGS[1] == "1")
|
||||
RESERVEDOFFSET = (PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight) / 2.f;
|
||||
|
||||
*PWINDOW->m_vRealPosition = PMONITOR->middle() - PWINDOW->m_vRealSize->goal() / 2.f + RESERVEDOFFSET;
|
||||
PWINDOW->m_vRealPosition = PMONITOR->middle() - PWINDOW->m_vRealSize.goal() / 2.f + RESERVEDOFFSET;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -524,7 +491,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
// set the pseudo size to the GOAL of our current size
|
||||
// because the windows are animated on RealSize
|
||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize->goal();
|
||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal();
|
||||
|
||||
g_pCompositor->changeWindowZOrder(PWINDOW, true);
|
||||
} else {
|
||||
@@ -557,7 +524,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
}
|
||||
|
||||
if (!setPseudo)
|
||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize->goal() - Vector2D(10, 10);
|
||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal() - Vector2D(10, 10);
|
||||
}
|
||||
|
||||
const auto PFOCUSEDWINDOWPREV = g_pCompositor->m_pLastWindow.lock();
|
||||
@@ -587,11 +554,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
(!PWINDOW->isX11OverrideRedirect() || (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface->wantsFocus())) && !workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW) &&
|
||||
!g_pInputManager->isConstrained()) {
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
PWINDOW->m_fActiveInactiveAlpha->setValueAndWarp(*PACTIVEALPHA);
|
||||
PWINDOW->m_fDimPercent->setValueAndWarp(PWINDOW->m_sWindowData.noDim.valueOrDefault() ? 0.f : *PDIMSTRENGTH);
|
||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
|
||||
PWINDOW->m_fDimPercent.setValueAndWarp(PWINDOW->m_sWindowData.noDim.valueOrDefault() ? 0.f : *PDIMSTRENGTH);
|
||||
} else {
|
||||
PWINDOW->m_fActiveInactiveAlpha->setValueAndWarp(*PINACTIVEALPHA);
|
||||
PWINDOW->m_fDimPercent->setValueAndWarp(0);
|
||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PINACTIVEALPHA);
|
||||
PWINDOW->m_fDimPercent.setValueAndWarp(0);
|
||||
}
|
||||
|
||||
if (requestedClientFSMode.has_value() && (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN))
|
||||
@@ -604,8 +571,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
if (PWINDOW->m_pWorkspace->m_bHasFullscreenWindow)
|
||||
g_pCompositor->setWindowFullscreenInternal(PWINDOW->m_pWorkspace->getFullscreenWindow(), FSMODE_NONE);
|
||||
|
||||
PWINDOW->m_vRealPosition->warp();
|
||||
PWINDOW->m_vRealSize->warp();
|
||||
PWINDOW->m_vRealPosition.warp();
|
||||
PWINDOW->m_vRealSize.warp();
|
||||
if (requestedFSState.has_value()) {
|
||||
PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(false, PRIORITY_WINDOW_RULE);
|
||||
g_pCompositor->setWindowFullscreenState(PWINDOW, requestedFSState.value());
|
||||
@@ -640,7 +607,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
PWINDOW->m_bFirstMap = false;
|
||||
|
||||
Debug::log(LOG, "Map request dispatched, monitor {}, window pos: {:5j}, window size: {:5j}", PMONITOR->szName, PWINDOW->m_vRealPosition->goal(), PWINDOW->m_vRealSize->goal());
|
||||
Debug::log(LOG, "Map request dispatched, monitor {}, window pos: {:5j}, window size: {:5j}", PMONITOR->szName, PWINDOW->m_vRealPosition.goal(), PWINDOW->m_vRealSize.goal());
|
||||
|
||||
auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName;
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"openwindow", std::format("{:x},{},{},{}", PWINDOW, workspaceID, PWINDOW->m_szClass, PWINDOW->m_szTitle)});
|
||||
@@ -653,17 +620,17 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
// do animations
|
||||
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, false);
|
||||
PWINDOW->m_fAlpha->setValueAndWarp(0.f);
|
||||
*PWINDOW->m_fAlpha = 1.f;
|
||||
PWINDOW->m_fAlpha.setValueAndWarp(0.f);
|
||||
PWINDOW->m_fAlpha = 1.f;
|
||||
|
||||
PWINDOW->m_vRealPosition->setCallbackOnEnd(setVector2DAnimToMove);
|
||||
PWINDOW->m_vRealSize->setCallbackOnEnd(setVector2DAnimToMove);
|
||||
PWINDOW->m_vRealPosition.setCallbackOnEnd(setAnimToMove);
|
||||
PWINDOW->m_vRealSize.setCallbackOnEnd(setAnimToMove);
|
||||
|
||||
// recalc the values for this window
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW);
|
||||
// avoid this window being visible
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !PWINDOW->isFullscreen() && !PWINDOW->m_bIsFloating)
|
||||
PWINDOW->m_fAlpha->setValueAndWarp(0.f);
|
||||
PWINDOW->m_fAlpha.setValueAndWarp(0.f);
|
||||
|
||||
g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface->resource(), PMONITOR->scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface->resource(), PMONITOR->transform);
|
||||
@@ -679,13 +646,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
if (PMONITOR && PWINDOW->isX11OverrideRedirect())
|
||||
PWINDOW->m_fX11SurfaceScaledBy = PMONITOR->scale;
|
||||
|
||||
// Fix some X11 popups being invisible / having incorrect size on open.
|
||||
// What the ACTUAL FUCK is going on?????? I HATE X11
|
||||
if (!PWINDOW->isX11OverrideRedirect() && PWINDOW->m_bIsX11 && PWINDOW->m_bIsFloating) {
|
||||
PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true, PWINDOW->m_vRealPosition->goal() - Vector2D{1, 1});
|
||||
PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
@@ -706,8 +666,8 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
|
||||
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
if (PMONITOR) {
|
||||
PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition->value() - PMONITOR->vecPosition;
|
||||
PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize->value();
|
||||
PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.value() - PMONITOR->vecPosition;
|
||||
PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.value();
|
||||
PWINDOW->m_eOriginalClosedExtents = PWINDOW->getFullWindowExtents();
|
||||
}
|
||||
|
||||
@@ -720,7 +680,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
g_pCompositor->setWindowFullscreenInternal(PWINDOW, FSMODE_NONE);
|
||||
|
||||
// Allow the renderer to catch the last frame.
|
||||
g_pHyprRenderer->makeWindowSnapshot(PWINDOW);
|
||||
g_pHyprOpenGL->makeWindowSnapshot(PWINDOW);
|
||||
|
||||
// swallowing
|
||||
if (valid(PWINDOW->m_pSwallowed)) {
|
||||
@@ -798,11 +758,11 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
g_pCompositor->addToFadingOutSafe(PWINDOW);
|
||||
|
||||
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
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.value() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it
|
||||
|
||||
// anims
|
||||
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, true);
|
||||
*PWINDOW->m_fAlpha = 0.f;
|
||||
PWINDOW->m_fAlpha = 0.f;
|
||||
|
||||
// recheck idle inhibitors
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
@@ -852,7 +812,7 @@ void Events::listener_commitWindow(void* owner, void* data) {
|
||||
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,
|
||||
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) {
|
||||
@@ -912,6 +872,15 @@ void Events::listener_destroyWindow(void* owner, void* data) {
|
||||
PWINDOW->listeners.commit.reset();
|
||||
}
|
||||
|
||||
void Events::listener_setTitleWindow(void* owner, void* data) {
|
||||
PHLWINDOW PWINDOW = ((CWindow*)owner)->m_pSelf.lock();
|
||||
|
||||
if (!validMapped(PWINDOW))
|
||||
return;
|
||||
|
||||
PWINDOW->onUpdateMeta();
|
||||
}
|
||||
|
||||
void Events::listener_activateX11(void* owner, void* data) {
|
||||
PHLWINDOW PWINDOW = ((CWindow*)owner)->m_pSelf.lock();
|
||||
|
||||
@@ -943,8 +912,8 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
if (!PWINDOW->m_bIsMapped || !PWINDOW->m_pXWaylandSurface || !PWINDOW->m_pXWaylandSurface->overrideRedirect)
|
||||
return;
|
||||
|
||||
const auto POS = PWINDOW->m_vRealPosition->goal();
|
||||
const auto SIZ = PWINDOW->m_vRealSize->goal();
|
||||
const auto POS = PWINDOW->m_vRealPosition.goal();
|
||||
const auto SIZ = PWINDOW->m_vRealSize.goal();
|
||||
|
||||
if (PWINDOW->m_pXWaylandSurface->geometry.size() > Vector2D{1, 1})
|
||||
PWINDOW->setHidden(false);
|
||||
@@ -952,7 +921,7 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
PWINDOW->setHidden(true);
|
||||
|
||||
if (PWINDOW->isFullscreen() || !PWINDOW->m_bIsFloating) {
|
||||
PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true);
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal(), true);
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
return;
|
||||
}
|
||||
@@ -966,27 +935,27 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
Debug::log(LOG, "Unmanaged window {} requests geometry update to {:j} {:j}", PWINDOW, LOGICALPOS, PWINDOW->m_pXWaylandSurface->geometry.size());
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
PWINDOW->m_vRealPosition->setValueAndWarp(Vector2D(LOGICALPOS.x, LOGICALPOS.y));
|
||||
PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(LOGICALPOS.x, LOGICALPOS.y));
|
||||
|
||||
if (abs(std::floor(SIZ.x) - PWINDOW->m_pXWaylandSurface->geometry.w) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_pXWaylandSurface->geometry.h) > 2)
|
||||
PWINDOW->m_vRealSize->setValueAndWarp(PWINDOW->m_pXWaylandSurface->geometry.size());
|
||||
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_pXWaylandSurface->geometry.size());
|
||||
|
||||
if (*PXWLFORCESCALEZERO) {
|
||||
if (const auto PMONITOR = PWINDOW->m_pMonitor.lock(); PMONITOR) {
|
||||
PWINDOW->m_vRealSize->setValueAndWarp(PWINDOW->m_vRealSize->goal() / PMONITOR->scale);
|
||||
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goal() / PMONITOR->scale);
|
||||
}
|
||||
}
|
||||
|
||||
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition->goal();
|
||||
PWINDOW->m_vSize = PWINDOW->m_vRealSize->goal();
|
||||
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goal();
|
||||
PWINDOW->m_vSize = PWINDOW->m_vRealSize.goal();
|
||||
|
||||
PWINDOW->m_pWorkspace = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition->value() + PWINDOW->m_vRealSize->value() / 2.f)->activeWorkspace;
|
||||
PWINDOW->m_pWorkspace = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.value() + PWINDOW->m_vRealSize.value() / 2.f)->activeWorkspace;
|
||||
|
||||
g_pCompositor->changeWindowZOrder(PWINDOW, true);
|
||||
PWINDOW->updateWindowDecos();
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
|
||||
PWINDOW->m_vReportedPosition = PWINDOW->m_vRealPosition->goal();
|
||||
PWINDOW->m_vPendingReportedSize = PWINDOW->m_vRealSize->goal();
|
||||
PWINDOW->m_vReportedPosition = PWINDOW->m_vRealPosition.goal();
|
||||
PWINDOW->m_vPendingReportedSize = PWINDOW->m_vRealSize.goal();
|
||||
}
|
||||
}
|
||||
|
92
src/helpers/AnimatedVariable.cpp
Normal file
92
src/helpers/AnimatedVariable.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "AnimatedVariable.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
|
||||
CBaseAnimatedVariable::CBaseAnimatedVariable(eAnimatedVarType type) : m_Type(type) {
|
||||
; // dummy var
|
||||
}
|
||||
|
||||
void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy) {
|
||||
m_eDamagePolicy = policy;
|
||||
m_pConfig = pAnimConfig;
|
||||
m_pWindow = pWindow;
|
||||
|
||||
m_bDummy = false;
|
||||
}
|
||||
|
||||
void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, eAVarDamagePolicy policy) {
|
||||
m_eDamagePolicy = policy;
|
||||
m_pConfig = pAnimConfig;
|
||||
m_pLayer = pLayer;
|
||||
|
||||
m_bDummy = false;
|
||||
}
|
||||
|
||||
void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy) {
|
||||
m_eDamagePolicy = policy;
|
||||
m_pConfig = pAnimConfig;
|
||||
m_pWorkspace = pWorkspace;
|
||||
|
||||
m_bDummy = false;
|
||||
}
|
||||
|
||||
void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, eAVarDamagePolicy policy) {
|
||||
m_eDamagePolicy = policy;
|
||||
m_pConfig = pAnimConfig;
|
||||
|
||||
m_bDummy = false;
|
||||
}
|
||||
|
||||
CBaseAnimatedVariable::~CBaseAnimatedVariable() {
|
||||
unregister();
|
||||
}
|
||||
|
||||
void CBaseAnimatedVariable::unregister() {
|
||||
if (!g_pAnimationManager)
|
||||
return;
|
||||
std::erase_if(g_pAnimationManager->m_vAnimatedVariables, [&](const auto& other) { return other == this; });
|
||||
m_bIsRegistered = false;
|
||||
disconnectFromActive();
|
||||
}
|
||||
|
||||
void CBaseAnimatedVariable::registerVar() {
|
||||
if (!m_bIsRegistered)
|
||||
g_pAnimationManager->m_vAnimatedVariables.push_back(this);
|
||||
m_bIsRegistered = true;
|
||||
}
|
||||
|
||||
int CBaseAnimatedVariable::getDurationLeftMs() {
|
||||
return std::max(
|
||||
(int)(m_pConfig->pValues->internalSpeed * 100) - (int)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - animationBegin).count(), 0);
|
||||
}
|
||||
|
||||
float CBaseAnimatedVariable::getPercent() {
|
||||
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - animationBegin).count();
|
||||
return std::clamp((DURATIONPASSED / 100.f) / m_pConfig->pValues->internalSpeed, 0.f, 1.f);
|
||||
}
|
||||
|
||||
float CBaseAnimatedVariable::getCurveValue() {
|
||||
if (!m_bIsBeingAnimated)
|
||||
return 1.f;
|
||||
|
||||
const auto SPENT = getPercent();
|
||||
|
||||
if (SPENT >= 1.f)
|
||||
return 1.f;
|
||||
|
||||
return g_pAnimationManager->getBezier(m_pConfig->pValues->internalBezier)->getYForPoint(SPENT);
|
||||
}
|
||||
|
||||
void CBaseAnimatedVariable::connectToActive() {
|
||||
g_pAnimationManager->scheduleTick(); // otherwise the animation manager will never pick this up
|
||||
|
||||
if (!m_bIsConnectedToActive)
|
||||
g_pAnimationManager->m_vActiveAnimatedVariables.push_back(this);
|
||||
|
||||
m_bIsConnectedToActive = true;
|
||||
}
|
||||
|
||||
void CBaseAnimatedVariable::disconnectFromActive() {
|
||||
std::erase_if(g_pAnimationManager->m_vActiveAnimatedVariables, [&](const auto& other) { return other == this; });
|
||||
m_bIsConnectedToActive = false;
|
||||
}
|
@@ -1,18 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <hyprutils/animation/AnimatedVariable.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <any>
|
||||
#include <chrono>
|
||||
#include <type_traits>
|
||||
#include "math/Math.hpp"
|
||||
#include "Color.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../debug/Log.hpp"
|
||||
#include "../desktop/DesktopTypes.hpp"
|
||||
|
||||
enum eAVarDamagePolicy : int8_t {
|
||||
AVARDAMAGE_NONE = -1,
|
||||
AVARDAMAGE_ENTIRE = 0,
|
||||
AVARDAMAGE_BORDER,
|
||||
AVARDAMAGE_SHADOW
|
||||
};
|
||||
|
||||
enum eAnimatedVarType : int8_t {
|
||||
AVARTYPE_INVALID = -1,
|
||||
AVARTYPE_FLOAT,
|
||||
@@ -45,6 +42,20 @@ struct STypeToAnimatedVarType_t<CHyprColor> {
|
||||
template <class T>
|
||||
inline constexpr eAnimatedVarType typeToeAnimatedVarType = STypeToAnimatedVarType_t<T>::value;
|
||||
|
||||
enum eAVarDamagePolicy : int8_t {
|
||||
AVARDAMAGE_NONE = -1,
|
||||
AVARDAMAGE_ENTIRE = 0,
|
||||
AVARDAMAGE_BORDER,
|
||||
AVARDAMAGE_SHADOW
|
||||
};
|
||||
|
||||
class CAnimationManager;
|
||||
struct SAnimationPropertyConfig;
|
||||
class CHyprRenderer;
|
||||
class CWindow;
|
||||
class CWorkspace;
|
||||
class CLayerSurface;
|
||||
|
||||
// Utility to define a concept as a list of possible type
|
||||
template <class T, class... U>
|
||||
concept OneOf = (... or std::same_as<T, U>);
|
||||
@@ -55,19 +66,247 @@ concept OneOf = (... or std::same_as<T, U>);
|
||||
template <class T>
|
||||
concept Animable = OneOf<T, Vector2D, float, CHyprColor>;
|
||||
|
||||
struct SAnimationContext {
|
||||
PHLWINDOWREF pWindow;
|
||||
PHLWORKSPACEREF pWorkspace;
|
||||
PHLLSREF pLayer;
|
||||
class CBaseAnimatedVariable {
|
||||
public:
|
||||
CBaseAnimatedVariable(eAnimatedVarType type);
|
||||
void create(SAnimationPropertyConfig* pAnimConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy);
|
||||
void create(SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, eAVarDamagePolicy policy);
|
||||
void create(SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy);
|
||||
void create(SAnimationPropertyConfig* pAnimConfig, eAVarDamagePolicy policy);
|
||||
|
||||
eAVarDamagePolicy eDamagePolicy = AVARDAMAGE_NONE;
|
||||
CBaseAnimatedVariable(const CBaseAnimatedVariable&) = delete;
|
||||
CBaseAnimatedVariable(CBaseAnimatedVariable&&) = delete;
|
||||
CBaseAnimatedVariable& operator=(const CBaseAnimatedVariable&) = delete;
|
||||
CBaseAnimatedVariable& operator=(CBaseAnimatedVariable&&) = delete;
|
||||
|
||||
virtual ~CBaseAnimatedVariable();
|
||||
|
||||
void unregister();
|
||||
void registerVar();
|
||||
|
||||
virtual void warp(bool endCallback = true) = 0;
|
||||
|
||||
//
|
||||
void setConfig(SAnimationPropertyConfig* pConfig) {
|
||||
m_pConfig = pConfig;
|
||||
}
|
||||
|
||||
SAnimationPropertyConfig* getConfig() {
|
||||
return m_pConfig;
|
||||
}
|
||||
|
||||
int getDurationLeftMs();
|
||||
|
||||
/* returns the spent (completion) % */
|
||||
float getPercent();
|
||||
|
||||
/* returns the current curve value */
|
||||
float getCurveValue();
|
||||
|
||||
// checks if an animation is in progress
|
||||
bool isBeingAnimated() const {
|
||||
return m_bIsBeingAnimated;
|
||||
}
|
||||
|
||||
/* sets a function to be ran when the animation finishes.
|
||||
if an animation is not running, runs instantly.
|
||||
if "remove" is set to true, will remove the callback when ran. */
|
||||
void setCallbackOnEnd(std::function<void(void* thisptr)> func, bool remove = true) {
|
||||
m_fEndCallback = std::move(func);
|
||||
m_bRemoveEndAfterRan = remove;
|
||||
|
||||
if (!isBeingAnimated())
|
||||
onAnimationEnd();
|
||||
}
|
||||
|
||||
/* sets a function to be ran when an animation is started.
|
||||
if "remove" is set to true, will remove the callback when ran. */
|
||||
void setCallbackOnBegin(std::function<void(void* thisptr)> func, bool remove = true) {
|
||||
m_fBeginCallback = std::move(func);
|
||||
m_bRemoveBeginAfterRan = remove;
|
||||
}
|
||||
|
||||
/* Sets the update callback, called every time the value is animated and a step is done
|
||||
Warning: calling unregisterVar/registerVar in this handler will cause UB */
|
||||
void setUpdateCallback(std::function<void(void* thisptr)> func) {
|
||||
m_fUpdateCallback = std::move(func);
|
||||
}
|
||||
|
||||
/* resets all callbacks. Does not call any. */
|
||||
void resetAllCallbacks() {
|
||||
m_fBeginCallback = nullptr;
|
||||
m_fEndCallback = nullptr;
|
||||
m_fUpdateCallback = nullptr;
|
||||
m_bRemoveBeginAfterRan = false;
|
||||
m_bRemoveEndAfterRan = false;
|
||||
}
|
||||
|
||||
PHLWINDOW getWindow() {
|
||||
return m_pWindow.lock();
|
||||
}
|
||||
|
||||
protected:
|
||||
PHLWINDOWREF m_pWindow;
|
||||
PHLWORKSPACEREF m_pWorkspace;
|
||||
PHLLSREF m_pLayer;
|
||||
|
||||
SAnimationPropertyConfig* m_pConfig = nullptr;
|
||||
|
||||
bool m_bDummy = true;
|
||||
bool m_bIsRegistered = false;
|
||||
bool m_bIsBeingAnimated = false;
|
||||
|
||||
std::chrono::steady_clock::time_point animationBegin;
|
||||
|
||||
eAVarDamagePolicy m_eDamagePolicy = AVARDAMAGE_NONE;
|
||||
eAnimatedVarType m_Type;
|
||||
|
||||
bool m_bRemoveEndAfterRan = true;
|
||||
bool m_bRemoveBeginAfterRan = true;
|
||||
std::function<void(void* thisptr)> m_fEndCallback;
|
||||
std::function<void(void* thisptr)> m_fBeginCallback;
|
||||
std::function<void(void* thisptr)> m_fUpdateCallback;
|
||||
|
||||
bool m_bIsConnectedToActive = false;
|
||||
|
||||
void connectToActive();
|
||||
|
||||
void disconnectFromActive();
|
||||
|
||||
// methods
|
||||
void onAnimationEnd() {
|
||||
m_bIsBeingAnimated = false;
|
||||
disconnectFromActive();
|
||||
|
||||
if (m_fEndCallback) {
|
||||
// loading m_bRemoveEndAfterRan before calling the callback allows the callback to delete this animation safely if it is false.
|
||||
auto removeEndCallback = m_bRemoveEndAfterRan;
|
||||
m_fEndCallback(this);
|
||||
if (removeEndCallback)
|
||||
m_fEndCallback = nullptr; // reset
|
||||
}
|
||||
}
|
||||
|
||||
void onAnimationBegin() {
|
||||
m_bIsBeingAnimated = true;
|
||||
connectToActive();
|
||||
|
||||
if (m_fBeginCallback) {
|
||||
m_fBeginCallback(this);
|
||||
if (m_bRemoveBeginAfterRan)
|
||||
m_fBeginCallback = nullptr; // reset
|
||||
}
|
||||
}
|
||||
|
||||
friend class CAnimationManager;
|
||||
friend class CWorkspace;
|
||||
friend class CLayerSurface;
|
||||
friend class CHyprRenderer;
|
||||
};
|
||||
|
||||
template <Animable VarType>
|
||||
using CAnimatedVariable = Hyprutils::Animation::CGenericAnimatedVariable<VarType, SAnimationContext>;
|
||||
class CAnimatedVariable : public CBaseAnimatedVariable {
|
||||
public:
|
||||
CAnimatedVariable() : CBaseAnimatedVariable(typeToeAnimatedVarType<VarType>) {
|
||||
;
|
||||
} // dummy var
|
||||
|
||||
template <Animable VarType>
|
||||
using PHLANIMVAR = SP<CAnimatedVariable<VarType>>;
|
||||
void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy) {
|
||||
create(pAnimConfig, pWindow, policy);
|
||||
m_Value = value;
|
||||
m_Goal = value;
|
||||
}
|
||||
void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, eAVarDamagePolicy policy) {
|
||||
create(pAnimConfig, pLayer, policy);
|
||||
m_Value = value;
|
||||
m_Goal = value;
|
||||
}
|
||||
void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy) {
|
||||
create(pAnimConfig, pWorkspace, policy);
|
||||
m_Value = value;
|
||||
m_Goal = value;
|
||||
}
|
||||
void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, eAVarDamagePolicy policy) {
|
||||
create(pAnimConfig, policy);
|
||||
m_Value = value;
|
||||
m_Goal = value;
|
||||
}
|
||||
|
||||
template <Animable VarType>
|
||||
using PHLANIMVARREF = WP<CAnimatedVariable<VarType>>;
|
||||
using CBaseAnimatedVariable::create;
|
||||
|
||||
CAnimatedVariable(const CAnimatedVariable&) = delete;
|
||||
CAnimatedVariable(CAnimatedVariable&&) = delete;
|
||||
CAnimatedVariable& operator=(const CAnimatedVariable&) = delete;
|
||||
CAnimatedVariable& operator=(CAnimatedVariable&&) = delete;
|
||||
|
||||
~CAnimatedVariable() = default;
|
||||
|
||||
// gets the current vector value (real time)
|
||||
const VarType& value() const {
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
// gets the goal vector value
|
||||
const VarType& goal() const {
|
||||
return m_Goal;
|
||||
}
|
||||
|
||||
CAnimatedVariable& operator=(const VarType& v) {
|
||||
if (v == m_Goal)
|
||||
return *this;
|
||||
|
||||
m_Goal = v;
|
||||
animationBegin = std::chrono::steady_clock::now();
|
||||
m_Begun = m_Value;
|
||||
|
||||
onAnimationBegin();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Sets the actual stored value, without affecting the goal, but resets the timer
|
||||
void setValue(const VarType& v) {
|
||||
if (v == m_Value)
|
||||
return;
|
||||
|
||||
m_Value = v;
|
||||
animationBegin = std::chrono::steady_clock::now();
|
||||
m_Begun = m_Value;
|
||||
|
||||
onAnimationBegin();
|
||||
}
|
||||
|
||||
// Sets the actual value and goal
|
||||
void setValueAndWarp(const VarType& v) {
|
||||
m_Goal = v;
|
||||
m_bIsBeingAnimated = true;
|
||||
warp();
|
||||
}
|
||||
|
||||
void warp(bool endCallback = true) override {
|
||||
if (!m_bIsBeingAnimated)
|
||||
return;
|
||||
|
||||
m_Value = m_Goal;
|
||||
|
||||
m_bIsBeingAnimated = false;
|
||||
|
||||
if (m_fUpdateCallback)
|
||||
m_fUpdateCallback(this);
|
||||
|
||||
if (endCallback)
|
||||
onAnimationEnd();
|
||||
}
|
||||
|
||||
private:
|
||||
VarType m_Value{};
|
||||
VarType m_Goal{};
|
||||
VarType m_Begun{};
|
||||
|
||||
// owners
|
||||
|
||||
friend class CAnimationManager;
|
||||
friend class CWorkspace;
|
||||
friend class CLayerSurface;
|
||||
friend class CHyprRenderer;
|
||||
};
|
||||
|
90
src/helpers/BezierCurve.cpp
Normal file
90
src/helpers/BezierCurve.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#include "BezierCurve.hpp"
|
||||
#include "../debug/Log.hpp"
|
||||
#include "../macros.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <algorithm>
|
||||
|
||||
void CBezierCurve::setup(std::vector<Vector2D>* pVec) {
|
||||
const auto BEGIN = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// Avoid reallocations by reserving enough memory upfront
|
||||
m_vPoints.resize(pVec->size() + 2);
|
||||
m_vPoints[0] = Vector2D(0, 0); // Start point
|
||||
size_t index = 1; // Start after the first element
|
||||
for (const auto& vec : *pVec) {
|
||||
if (index < m_vPoints.size() - 1) { // Bounds check to ensure safety
|
||||
m_vPoints[index] = vec;
|
||||
++index;
|
||||
}
|
||||
}
|
||||
m_vPoints.back() = Vector2D(1, 1); // End point
|
||||
|
||||
RASSERT(m_vPoints.size() == 4, "CBezierCurve only supports cubic beziers! (points num: {})", m_vPoints.size());
|
||||
|
||||
// bake BAKEDPOINTS points for faster lookups
|
||||
// T -> X ( / BAKEDPOINTS )
|
||||
for (int i = 0; i < BAKEDPOINTS; ++i) {
|
||||
float const t = (i + 1) / (float)BAKEDPOINTS;
|
||||
m_aPointsBaked[i] = Vector2D(getXForT(t), getYForT(t));
|
||||
}
|
||||
|
||||
const auto ELAPSEDUS = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - BEGIN).count() / 1000.f;
|
||||
const auto POINTSSIZE = m_aPointsBaked.size() * sizeof(m_aPointsBaked[0]) / 1000.f;
|
||||
|
||||
const auto BEGINCALC = std::chrono::high_resolution_clock::now();
|
||||
for (int j = 1; j < 10; ++j) {
|
||||
float i = j / 10.0f;
|
||||
getYForPoint(i);
|
||||
}
|
||||
const auto ELAPSEDCALCAVG = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - BEGINCALC).count() / 1000.f / 10.f;
|
||||
|
||||
Debug::log(LOG, "Created a bezier curve, baked {} points, mem usage: {:.2f}kB, time to bake: {:.2f}µs. Estimated average calc time: {:.2f}µs.", BAKEDPOINTS, POINTSSIZE,
|
||||
ELAPSEDUS, ELAPSEDCALCAVG);
|
||||
}
|
||||
|
||||
float CBezierCurve::getXForT(float const& t) const {
|
||||
float t2 = t * t;
|
||||
float t3 = t2 * t;
|
||||
|
||||
return 3 * t * (1 - t) * (1 - t) * m_vPoints[1].x + 3 * t2 * (1 - t) * m_vPoints[2].x + t3 * m_vPoints[3].x;
|
||||
}
|
||||
|
||||
float CBezierCurve::getYForT(float const& t) const {
|
||||
float t2 = t * t;
|
||||
float t3 = t2 * t;
|
||||
|
||||
return 3 * t * (1 - t) * (1 - t) * m_vPoints[1].y + 3 * t2 * (1 - t) * m_vPoints[2].y + t3 * m_vPoints[3].y;
|
||||
}
|
||||
|
||||
// Todo: this probably can be done better and faster
|
||||
float CBezierCurve::getYForPoint(float const& x) const {
|
||||
if (x >= 1.f)
|
||||
return 1.f;
|
||||
if (x <= 0.f)
|
||||
return 0.f;
|
||||
|
||||
int index = 0;
|
||||
bool below = true;
|
||||
for (int step = (BAKEDPOINTS + 1) / 2; step > 0; step /= 2) {
|
||||
if (below)
|
||||
index += step;
|
||||
else
|
||||
index -= step;
|
||||
|
||||
below = m_aPointsBaked[index].x < x;
|
||||
}
|
||||
|
||||
int lowerIndex = index - (!below || index == BAKEDPOINTS - 1);
|
||||
|
||||
// in the name of performance i shall make a hack
|
||||
const auto LOWERPOINT = &m_aPointsBaked[lowerIndex];
|
||||
const auto UPPERPOINT = &m_aPointsBaked[lowerIndex + 1];
|
||||
|
||||
const auto PERCINDELTA = (x - LOWERPOINT->x) / (UPPERPOINT->x - LOWERPOINT->x);
|
||||
|
||||
if (std::isnan(PERCINDELTA) || std::isinf(PERCINDELTA)) // can sometimes happen for VERY small x
|
||||
return 0.f;
|
||||
|
||||
return LOWERPOINT->y + (UPPERPOINT->y - LOWERPOINT->y) * PERCINDELTA;
|
||||
}
|
28
src/helpers/BezierCurve.hpp
Normal file
28
src/helpers/BezierCurve.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include "math/Math.hpp"
|
||||
|
||||
constexpr int BAKEDPOINTS = 255;
|
||||
constexpr float INVBAKEDPOINTS = 1.f / BAKEDPOINTS;
|
||||
|
||||
// an implementation of a cubic bezier curve
|
||||
// might do better later
|
||||
class CBezierCurve {
|
||||
public:
|
||||
// sets up the bezier curve.
|
||||
// this EXCLUDES the 0,0 and 1,1 points,
|
||||
void setup(std::vector<Vector2D>* points);
|
||||
|
||||
float getYForT(float const& t) const;
|
||||
float getXForT(float const& t) const;
|
||||
float getYForPoint(float const& x) const;
|
||||
|
||||
private:
|
||||
// this INCLUDES the 0,0 and 1,1 points.
|
||||
std::vector<Vector2D> m_vPoints;
|
||||
|
||||
std::array<Vector2D, BAKEDPOINTS> m_aPointsBaked;
|
||||
};
|
@@ -43,7 +43,3 @@ Hyprgraphics::CColor::SHSL CHyprColor::asHSL() const {
|
||||
CHyprColor CHyprColor::stripA() const {
|
||||
return {r, g, b, 1.F};
|
||||
}
|
||||
|
||||
CHyprColor CHyprColor::modifyA(float newa) const {
|
||||
return {r, g, b, newa};
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <hyprgraphics/color/Color.hpp>
|
||||
#include "../debug/Log.hpp"
|
||||
#include "../macros.hpp"
|
||||
|
||||
class CHyprColor {
|
||||
@@ -17,7 +18,6 @@ class CHyprColor {
|
||||
Hyprgraphics::CColor::SOkLab asOkLab() const;
|
||||
Hyprgraphics::CColor::SHSL asHSL() const;
|
||||
CHyprColor stripA() const;
|
||||
CHyprColor modifyA(float newa) const;
|
||||
|
||||
//
|
||||
bool operator==(const CHyprColor& c2) const {
|
||||
@@ -45,18 +45,3 @@ class CHyprColor {
|
||||
private:
|
||||
Hyprgraphics::CColor::SOkLab okLab; // cache for the OkLab representation
|
||||
};
|
||||
|
||||
//NOLINTNEXTLINE
|
||||
namespace Colors {
|
||||
static const CHyprColor WHITE = CHyprColor(1.F, 1.F, 1.F, 1.F);
|
||||
static const CHyprColor GREEN = CHyprColor(0.F, 1.F, 0.F, 1.F);
|
||||
static const CHyprColor BLUE = CHyprColor(0.F, 0.F, 1.F, 1.F);
|
||||
static const CHyprColor RED = CHyprColor(1.F, 0.F, 0.F, 1.F);
|
||||
static const CHyprColor ORANGE = CHyprColor(1.F, 0.5F, 0.F, 1.F);
|
||||
static const CHyprColor YELLOW = CHyprColor(1.F, 1.F, 0.F, 1.F);
|
||||
static const CHyprColor MAGENTA = CHyprColor(1.F, 0.F, 1.F, 1.F);
|
||||
static const CHyprColor PURPLE = CHyprColor(0.5F, 0.F, 0.5F, 1.F);
|
||||
static const CHyprColor LIME = CHyprColor(0.5F, 1.F, 0.1F, 1.F);
|
||||
static const CHyprColor LIGHT_BLUE = CHyprColor(0.1F, 1.F, 1.F, 1.F);
|
||||
static const CHyprColor BLACK = CHyprColor(0.F, 0.F, 0.F, 1.F);
|
||||
};
|
||||
|
@@ -3,9 +3,6 @@
|
||||
#include <algorithm>
|
||||
#include "../Compositor.hpp"
|
||||
#include "../managers/TokenManager.hpp"
|
||||
#include "Monitor.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "fs/FsUtils.hpp"
|
||||
#include <optional>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
@@ -164,6 +161,26 @@ std::string absolutePath(const std::string& rawpath, const std::string& currentP
|
||||
return value;
|
||||
}
|
||||
|
||||
void addWLSignal(wl_signal* pSignal, wl_listener* pListener, void* pOwner, const std::string& ownerString) {
|
||||
ASSERT(pSignal);
|
||||
ASSERT(pListener);
|
||||
|
||||
wl_signal_add(pSignal, pListener);
|
||||
|
||||
Debug::log(LOG, "Registered signal for owner {:x}: {:x} -> {:x} (owner: {})", (uintptr_t)pOwner, (uintptr_t)pSignal, (uintptr_t)pListener, ownerString);
|
||||
}
|
||||
|
||||
void removeWLSignal(wl_listener* pListener) {
|
||||
wl_list_remove(&pListener->link);
|
||||
wl_list_init(&pListener->link);
|
||||
|
||||
Debug::log(LOG, "Removed listener {:x}", (uintptr_t)pListener);
|
||||
}
|
||||
|
||||
void handleNoop(struct wl_listener* listener, void* data) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
std::string escapeJSONStrings(const std::string& str) {
|
||||
std::ostringstream oss;
|
||||
for (auto const& c : str) {
|
||||
@@ -261,7 +278,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||
if (!valid(PWORKSPACE))
|
||||
return {WORKSPACE_INVALID};
|
||||
|
||||
const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->getPrevWorkspaceIDName().id);
|
||||
const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->m_sPrevWorkspace.id);
|
||||
|
||||
if (!PLASTWORKSPACE)
|
||||
return {WORKSPACE_INVALID};
|
||||
@@ -611,7 +628,7 @@ void logSystemInfo() {
|
||||
}
|
||||
} catch (...) { GPUINFO = "error"; }
|
||||
#else
|
||||
const std::string GPUINFO = execAndGet("lspci -vnn | grep -E '(VGA|Display|3D)'");
|
||||
const std::string GPUINFO = execAndGet("lspci -vnn | grep VGA");
|
||||
#endif
|
||||
Debug::log(LOG, "GPU information:\n{}\n", GPUINFO);
|
||||
|
||||
@@ -622,7 +639,7 @@ void logSystemInfo() {
|
||||
// log etc
|
||||
Debug::log(LOG, "os-release:");
|
||||
|
||||
Debug::log(NONE, "{}", NFsUtils::readFileAsString("/etc/os-release").value_or("error"));
|
||||
Debug::log(NONE, "{}", execAndGet("cat /etc/os-release"));
|
||||
}
|
||||
|
||||
int64_t getPPIDof(int64_t pid) {
|
||||
@@ -914,3 +931,30 @@ float stringToPercentage(const std::string& VALUE, const float REL) {
|
||||
else
|
||||
return std::stof(VALUE);
|
||||
}
|
||||
|
||||
bool executableExistsInPath(const std::string& exe) {
|
||||
if (!getenv("PATH"))
|
||||
return false;
|
||||
|
||||
static CVarList paths(getenv("PATH"), 0, ':', true);
|
||||
|
||||
for (auto& p : paths) {
|
||||
std::string path = p + std::string{"/"} + exe;
|
||||
std::error_code ec;
|
||||
if (!std::filesystem::exists(path, ec) || ec)
|
||||
continue;
|
||||
|
||||
if (!std::filesystem::is_regular_file(path, ec) || ec)
|
||||
continue;
|
||||
|
||||
auto stat = std::filesystem::status(path, ec);
|
||||
if (ec)
|
||||
continue;
|
||||
|
||||
auto perms = stat.permissions();
|
||||
|
||||
return std::filesystem::perms::none != (perms & std::filesystem::perms::others_exec);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <wayland-server.h>
|
||||
#include "math/Math.hpp"
|
||||
#include <vector>
|
||||
#include <format>
|
||||
#include <expected>
|
||||
@@ -19,6 +21,8 @@ struct SWorkspaceIDName {
|
||||
};
|
||||
|
||||
std::string absolutePath(const std::string&, const std::string&);
|
||||
void addWLSignal(wl_signal*, wl_listener*, void* pOwner, const std::string& ownerString);
|
||||
void removeWLSignal(wl_listener*);
|
||||
std::string escapeJSONStrings(const std::string& str);
|
||||
bool isDirection(const std::string&);
|
||||
bool isDirection(const char&);
|
||||
@@ -38,6 +42,7 @@ 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);
|
||||
bool executableExistsInPath(const std::string& exe);
|
||||
|
||||
template <typename... Args>
|
||||
[[deprecated("use std::format instead")]] std::string getFormat(std::format_string<Args...> fmt, Args&&... args) {
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#include "Monitor.hpp"
|
||||
#include "MiscFunctions.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "math/Math.hpp"
|
||||
#include "sync/SyncReleaser.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
@@ -17,23 +16,15 @@
|
||||
#include "../managers/PointerManager.hpp"
|
||||
#include "../managers/eventLoop/EventLoopManager.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "sync/SyncTimeline.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include <aquamarine/output/Output.hpp>
|
||||
#include "debug/Log.hpp"
|
||||
#include "debug/HyprNotificationOverlay.hpp"
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <hyprutils/utils/ScopeGuard.hpp>
|
||||
#include <cstring>
|
||||
#include <ranges>
|
||||
using namespace Hyprutils::String;
|
||||
using namespace Hyprutils::Utils;
|
||||
|
||||
static int ratHandler(void* data) {
|
||||
int ratHandler(void* data) {
|
||||
g_pHyprRenderer->renderMonitor(((CMonitor*)data)->self.lock());
|
||||
|
||||
return 1;
|
||||
@@ -51,8 +42,6 @@ void CMonitor::onConnect(bool noRule) {
|
||||
EMIT_HOOK_EVENT("preMonitorAdded", self.lock());
|
||||
CScopeGuard x = {[]() { g_pCompositor->arrangeMonitors(); }};
|
||||
|
||||
g_pEventLoopManager->doLater([] { g_pConfigManager->ensurePersistentWorkspacesPresent(); });
|
||||
|
||||
if (output->supportsExplicit) {
|
||||
inTimeline = CSyncTimeline::create(output->getBackend()->drmFD());
|
||||
outTimeline = CSyncTimeline::create(output->getBackend()->drmFD());
|
||||
@@ -96,7 +85,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
return;
|
||||
|
||||
Debug::log(LOG, "Reapplying monitor rule for {} from a state request", szName);
|
||||
applyMonitorRule(&activeMonitorRule, true);
|
||||
g_pHyprRenderer->applyMonitorRule(self.lock(), &activeMonitorRule, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -110,7 +99,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
SMonitorRule rule = activeMonitorRule;
|
||||
rule.resolution = SIZE;
|
||||
|
||||
applyMonitorRule(&rule);
|
||||
g_pHyprRenderer->applyMonitorRule(self.lock(), &rule);
|
||||
});
|
||||
|
||||
tearingState.canTear = output->getBackend()->type() == Aquamarine::AQ_BACKEND_DRM;
|
||||
@@ -183,7 +172,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
|
||||
// set mode, also applies
|
||||
if (!noRule)
|
||||
applyMonitorRule(&monitorRule, true);
|
||||
g_pHyprRenderer->applyMonitorRule(self.lock(), &monitorRule, true);
|
||||
|
||||
if (!state.commit())
|
||||
Debug::log(WARN, "state.commit() failed in CMonitor::onCommit");
|
||||
@@ -372,392 +361,6 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||
std::erase_if(g_pCompositor->m_vMonitors, [&](PHLMONITOR& el) { return el.get() == this; });
|
||||
}
|
||||
|
||||
bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
|
||||
|
||||
static auto PDISABLESCALECHECKS = CConfigValue<Hyprlang::INT>("debug:disable_scale_checks");
|
||||
|
||||
Debug::log(LOG, "Applying monitor rule for {}", szName);
|
||||
|
||||
activeMonitorRule = *pMonitorRule;
|
||||
|
||||
if (forceSize.has_value())
|
||||
activeMonitorRule.resolution = forceSize.value();
|
||||
|
||||
const auto RULE = &activeMonitorRule;
|
||||
|
||||
// if it's disabled, disable and ignore
|
||||
if (RULE->disabled) {
|
||||
if (m_bEnabled)
|
||||
onDisconnect();
|
||||
|
||||
events.modeChanged.emit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// don't touch VR headsets
|
||||
if (output->nonDesktop)
|
||||
return true;
|
||||
|
||||
if (!m_bEnabled) {
|
||||
onConnect(true); // enable it.
|
||||
Debug::log(LOG, "Monitor {} is disabled but is requested to be enabled", szName);
|
||||
force = true;
|
||||
}
|
||||
|
||||
// Check if the rule isn't already applied
|
||||
// TODO: clean this up lol
|
||||
if (!force && DELTALESSTHAN(vecPixelSize.x, RULE->resolution.x, 1) && DELTALESSTHAN(vecPixelSize.y, RULE->resolution.y, 1) &&
|
||||
DELTALESSTHAN(refreshRate, RULE->refreshRate, 1) && setScale == RULE->scale &&
|
||||
((DELTALESSTHAN(vecPosition.x, RULE->offset.x, 1) && DELTALESSTHAN(vecPosition.y, RULE->offset.y, 1)) || RULE->offset == Vector2D(-INT32_MAX, -INT32_MAX)) &&
|
||||
transform == RULE->transform && RULE->enable10bit == enabled10bit && !std::memcmp(&customDrmMode, &RULE->drmMode, sizeof(customDrmMode))) {
|
||||
|
||||
Debug::log(LOG, "Not applying a new rule to {} because it's already applied!", szName);
|
||||
|
||||
setMirror(RULE->mirrorOf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool autoScale = false;
|
||||
|
||||
if (RULE->scale > 0.1) {
|
||||
scale = RULE->scale;
|
||||
} else {
|
||||
autoScale = true;
|
||||
const auto DEFAULTSCALE = getDefaultScale();
|
||||
scale = DEFAULTSCALE;
|
||||
}
|
||||
|
||||
setScale = scale;
|
||||
transform = RULE->transform;
|
||||
|
||||
// accumulate requested modes in reverse order (cause inesrting at front is inefficient)
|
||||
std::vector<SP<Aquamarine::SOutputMode>> requestedModes;
|
||||
std::string requestedStr = "preferred";
|
||||
|
||||
// use sortFunc, add best 3 to requestedModes in reverse, since we test in reverse
|
||||
auto addBest3Modes = [&](auto const& sortFunc) {
|
||||
auto sortedModes = output->modes;
|
||||
std::ranges::sort(sortedModes, sortFunc);
|
||||
if (sortedModes.size() > 3)
|
||||
sortedModes.erase(sortedModes.begin() + 3, sortedModes.end());
|
||||
requestedModes.insert(requestedModes.end(), sortedModes.rbegin(), sortedModes.rend());
|
||||
};
|
||||
|
||||
// last fallback is preferred mode, btw this covers resolution == Vector2D()
|
||||
if (!output->preferredMode())
|
||||
Debug::log(ERR, "Monitor {} has NO PREFERRED MODE", output->name);
|
||||
else
|
||||
requestedModes.push_back(output->preferredMode());
|
||||
|
||||
if (RULE->resolution == Vector2D(-1, -1)) {
|
||||
requestedStr = "highrr";
|
||||
|
||||
// sort prioritizing refresh rate 1st and resolution 2nd, then add best 3
|
||||
addBest3Modes([](auto const& a, auto const& b) {
|
||||
if (std::round(a->refreshRate) > std::round(b->refreshRate))
|
||||
return true;
|
||||
else if (DELTALESSTHAN((float)a->refreshRate, (float)b->refreshRate, 1.F) && a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y)
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
} else if (RULE->resolution == Vector2D(-1, -2)) {
|
||||
requestedStr = "highres";
|
||||
|
||||
// sort prioritizing resultion 1st and refresh rate 2nd, then add best 3
|
||||
addBest3Modes([](auto const& a, auto const& b) {
|
||||
if (a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y)
|
||||
return true;
|
||||
else if (DELTALESSTHAN(a->pixelSize.x, b->pixelSize.x, 1) && DELTALESSTHAN(a->pixelSize.y, b->pixelSize.y, 1) &&
|
||||
std::round(a->refreshRate) > std::round(b->refreshRate))
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
} else if (RULE->resolution != Vector2D()) {
|
||||
// user requested mode
|
||||
requestedStr = std::format("{:X0}@{:.2f}Hz", RULE->resolution, RULE->refreshRate);
|
||||
|
||||
// sort by closeness to requested, then add best 3
|
||||
addBest3Modes([&](auto const& a, auto const& b) {
|
||||
if (abs(a->pixelSize.x - RULE->resolution.x) < abs(b->pixelSize.x - RULE->resolution.x))
|
||||
return true;
|
||||
if (a->pixelSize.x == b->pixelSize.x && abs(a->pixelSize.y - RULE->resolution.y) < abs(b->pixelSize.y - RULE->resolution.y))
|
||||
return true;
|
||||
if (a->pixelSize == b->pixelSize && abs((a->refreshRate / 1000.f) - RULE->refreshRate) < abs((b->refreshRate / 1000.f) - RULE->refreshRate))
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
// if the best mode isnt close to requested, then try requested as custom mode first
|
||||
if (!requestedModes.empty()) {
|
||||
auto bestMode = requestedModes.back();
|
||||
if (!DELTALESSTHAN(bestMode->pixelSize.x, RULE->resolution.x, 1) || !DELTALESSTHAN(bestMode->pixelSize.y, RULE->resolution.y, 1) ||
|
||||
!DELTALESSTHAN(bestMode->refreshRate / 1000.f, RULE->refreshRate, 1))
|
||||
requestedModes.push_back(makeShared<Aquamarine::SOutputMode>(Aquamarine::SOutputMode{.pixelSize = RULE->resolution, .refreshRate = RULE->refreshRate * 1000.f}));
|
||||
}
|
||||
|
||||
// then if requested is custom, try custom mode first
|
||||
if (RULE->drmMode.type == DRM_MODE_TYPE_USERDEF) {
|
||||
if (output->getBackend()->type() != Aquamarine::eBackendType::AQ_BACKEND_DRM)
|
||||
Debug::log(ERR, "Tried to set custom modeline on non-DRM output");
|
||||
else
|
||||
requestedModes.push_back(makeShared<Aquamarine::SOutputMode>(
|
||||
Aquamarine::SOutputMode{.pixelSize = {RULE->drmMode.hdisplay, RULE->drmMode.vdisplay}, .refreshRate = RULE->drmMode.vrefresh, .modeInfo = RULE->drmMode}));
|
||||
}
|
||||
}
|
||||
|
||||
const auto WAS10B = enabled10bit;
|
||||
const auto OLDRES = vecPixelSize;
|
||||
bool success = false;
|
||||
|
||||
// Needed in case we are switching from a custom modeline to a standard mode
|
||||
customDrmMode = {};
|
||||
currentMode = nullptr;
|
||||
|
||||
output->state->setFormat(DRM_FORMAT_XRGB8888);
|
||||
prevDrmFormat = drmFormat;
|
||||
drmFormat = DRM_FORMAT_XRGB8888;
|
||||
output->state->resetExplicitFences();
|
||||
|
||||
if (Debug::trace) {
|
||||
Debug::log(TRACE, "Monitor {} requested modes:", szName);
|
||||
if (requestedModes.empty())
|
||||
Debug::log(TRACE, "| None");
|
||||
else {
|
||||
for (auto const& mode : requestedModes | std::views::reverse) {
|
||||
Debug::log(TRACE, "| {:X0}@{:.2f}Hz", mode->pixelSize, mode->refreshRate / 1000.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& mode : requestedModes | std::views::reverse) {
|
||||
std::string modeStr = std::format("{:X0}@{:.2f}Hz", mode->pixelSize, mode->refreshRate / 1000.f);
|
||||
|
||||
if (mode->modeInfo.has_value() && mode->modeInfo->type == DRM_MODE_TYPE_USERDEF) {
|
||||
output->state->setCustomMode(mode);
|
||||
|
||||
if (!state.test()) {
|
||||
Debug::log(ERR, "Monitor {}: REJECTED custom mode {}!", szName, modeStr);
|
||||
continue;
|
||||
}
|
||||
|
||||
customDrmMode = mode->modeInfo.value();
|
||||
} else {
|
||||
output->state->setMode(mode);
|
||||
|
||||
if (!state.test()) {
|
||||
Debug::log(ERR, "Monitor {}: REJECTED available mode {}!", szName, modeStr);
|
||||
if (mode->preferred)
|
||||
Debug::log(ERR, "Monitor {}: REJECTED preferred mode!!!", szName);
|
||||
continue;
|
||||
}
|
||||
|
||||
customDrmMode = {};
|
||||
}
|
||||
|
||||
refreshRate = mode->refreshRate / 1000.f;
|
||||
vecSize = mode->pixelSize;
|
||||
currentMode = mode;
|
||||
|
||||
success = true;
|
||||
|
||||
if (mode->preferred)
|
||||
Debug::log(LOG, "Monitor {}: requested {}, using preferred mode {}", szName, requestedStr, modeStr);
|
||||
else if (mode->modeInfo.has_value() && mode->modeInfo->type == DRM_MODE_TYPE_USERDEF)
|
||||
Debug::log(LOG, "Monitor {}: requested {}, using custom mode {}", szName, requestedStr, modeStr);
|
||||
else
|
||||
Debug::log(LOG, "Monitor {}: requested {}, using available mode {}", szName, requestedStr, modeStr);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// try requested as custom mode jic it works
|
||||
if (!success && RULE->resolution != Vector2D() && RULE->resolution != Vector2D(-1, -1) && RULE->resolution != Vector2D(-1, -2)) {
|
||||
auto refreshRate = output->getBackend()->type() == Aquamarine::eBackendType::AQ_BACKEND_DRM ? RULE->refreshRate * 1000 : 0;
|
||||
auto mode = makeShared<Aquamarine::SOutputMode>(Aquamarine::SOutputMode{.pixelSize = RULE->resolution, .refreshRate = refreshRate});
|
||||
std::string modeStr = std::format("{:X0}@{:.2f}Hz", mode->pixelSize, mode->refreshRate / 1000.f);
|
||||
|
||||
output->state->setCustomMode(mode);
|
||||
|
||||
if (state.test()) {
|
||||
Debug::log(LOG, "Monitor {}: requested {}, using custom mode {}", szName, requestedStr, modeStr);
|
||||
|
||||
refreshRate = mode->refreshRate / 1000.f;
|
||||
vecSize = mode->pixelSize;
|
||||
currentMode = mode;
|
||||
customDrmMode = {};
|
||||
|
||||
success = true;
|
||||
} else
|
||||
Debug::log(ERR, "Monitor {}: REJECTED custom mode {}!", szName, modeStr);
|
||||
}
|
||||
|
||||
// try any of the modes if none of the above work
|
||||
if (!success) {
|
||||
for (auto const& mode : output->modes) {
|
||||
output->state->setMode(mode);
|
||||
|
||||
if (!state.test())
|
||||
continue;
|
||||
|
||||
auto errorMessage =
|
||||
std::format("Monitor {} failed to set any requested modes, falling back to mode {:X0}@{:.2f}Hz", szName, mode->pixelSize, mode->refreshRate / 1000.f);
|
||||
Debug::log(WARN, errorMessage);
|
||||
g_pHyprNotificationOverlay->addNotification(errorMessage, CHyprColor(0xff0000ff), 5000, ICON_WARNING);
|
||||
|
||||
refreshRate = mode->refreshRate / 1000.f;
|
||||
vecSize = mode->pixelSize;
|
||||
currentMode = mode;
|
||||
customDrmMode = {};
|
||||
|
||||
success = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
Debug::log(ERR, "Monitor {} has NO FALLBACK MODES, and an INVALID one was requested: {:X0}@{:.2f}Hz", szName, RULE->resolution, RULE->refreshRate);
|
||||
return true;
|
||||
}
|
||||
|
||||
vrrActive = output->state->state().adaptiveSync // disabled here, will be tested in CConfigManager::ensureVRR()
|
||||
|| createdByUser; // wayland backend doesn't allow for disabling adaptive_sync
|
||||
|
||||
vecPixelSize = vecSize;
|
||||
|
||||
// clang-format off
|
||||
static const std::array<std::vector<std::pair<std::string, uint32_t>>, 2> formats{
|
||||
std::vector<std::pair<std::string, uint32_t>>{ /* 10-bit */
|
||||
{"DRM_FORMAT_XRGB2101010", DRM_FORMAT_XRGB2101010}, {"DRM_FORMAT_XBGR2101010", DRM_FORMAT_XBGR2101010}, {"DRM_FORMAT_XRGB8888", DRM_FORMAT_XRGB8888}, {"DRM_FORMAT_XBGR8888", DRM_FORMAT_XBGR8888}
|
||||
},
|
||||
std::vector<std::pair<std::string, uint32_t>>{ /* 8-bit */
|
||||
{"DRM_FORMAT_XRGB8888", DRM_FORMAT_XRGB8888}, {"DRM_FORMAT_XBGR8888", DRM_FORMAT_XBGR8888}
|
||||
}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
bool set10bit = false;
|
||||
|
||||
for (auto const& fmt : formats[(int)!RULE->enable10bit]) {
|
||||
output->state->setFormat(fmt.second);
|
||||
prevDrmFormat = drmFormat;
|
||||
drmFormat = fmt.second;
|
||||
|
||||
if (!state.test()) {
|
||||
Debug::log(ERR, "output {} failed basic test on format {}", szName, fmt.first);
|
||||
} else {
|
||||
Debug::log(LOG, "output {} succeeded basic test on format {}", szName, fmt.first);
|
||||
if (RULE->enable10bit && fmt.first.contains("101010"))
|
||||
set10bit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enabled10bit = set10bit;
|
||||
|
||||
Vector2D logicalSize = vecPixelSize / scale;
|
||||
if (!*PDISABLESCALECHECKS && (logicalSize.x != std::round(logicalSize.x) || logicalSize.y != std::round(logicalSize.y))) {
|
||||
// invalid scale, will produce fractional pixels.
|
||||
// find the nearest valid.
|
||||
|
||||
float searchScale = std::round(scale * 120.0);
|
||||
bool found = false;
|
||||
|
||||
double scaleZero = searchScale / 120.0;
|
||||
|
||||
Vector2D logicalZero = vecPixelSize / scaleZero;
|
||||
if (logicalZero == logicalZero.round())
|
||||
scale = scaleZero;
|
||||
else {
|
||||
for (size_t i = 1; i < 90; ++i) {
|
||||
double scaleUp = (searchScale + i) / 120.0;
|
||||
double scaleDown = (searchScale - i) / 120.0;
|
||||
|
||||
Vector2D logicalUp = vecPixelSize / scaleUp;
|
||||
Vector2D logicalDown = vecPixelSize / scaleDown;
|
||||
|
||||
if (logicalUp == logicalUp.round()) {
|
||||
found = true;
|
||||
searchScale = scaleUp;
|
||||
break;
|
||||
}
|
||||
if (logicalDown == logicalDown.round()) {
|
||||
found = true;
|
||||
searchScale = scaleDown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (autoScale)
|
||||
scale = std::round(scaleZero);
|
||||
else {
|
||||
Debug::log(ERR, "Invalid scale passed to monitor, {} failed to find a clean divisor", scale);
|
||||
g_pConfigManager->addParseError("Invalid scale passed to monitor " + szName + ", failed to find a clean divisor");
|
||||
scale = getDefaultScale();
|
||||
}
|
||||
} else {
|
||||
if (!autoScale) {
|
||||
Debug::log(ERR, "Invalid scale passed to monitor, {} found suggestion {}", scale, searchScale);
|
||||
g_pConfigManager->addParseError(
|
||||
std::format("Invalid scale passed to monitor {}, failed to find a clean divisor. Suggested nearest scale: {:5f}", szName, searchScale));
|
||||
scale = getDefaultScale();
|
||||
} else
|
||||
scale = searchScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output->scheduleFrame();
|
||||
|
||||
if (!state.commit())
|
||||
Debug::log(ERR, "Couldn't commit output named {}", output->name);
|
||||
|
||||
Vector2D xfmd = transform % 2 == 1 ? Vector2D{vecPixelSize.y, vecPixelSize.x} : vecPixelSize;
|
||||
vecSize = (xfmd / scale).round();
|
||||
vecTransformedSize = xfmd;
|
||||
|
||||
if (createdByUser) {
|
||||
CBox transformedBox = {0, 0, vecTransformedSize.x, vecTransformedSize.y};
|
||||
transformedBox.transform(wlTransformToHyprutils(invertTransform(transform)), vecTransformedSize.x, vecTransformedSize.y);
|
||||
|
||||
vecPixelSize = Vector2D(transformedBox.width, transformedBox.height);
|
||||
}
|
||||
|
||||
updateMatrix();
|
||||
|
||||
if (WAS10B != enabled10bit || OLDRES != vecPixelSize)
|
||||
g_pHyprOpenGL->destroyMonitorResources(self.lock());
|
||||
|
||||
g_pCompositor->arrangeMonitors();
|
||||
|
||||
damage.setSize(vecTransformedSize);
|
||||
|
||||
// Set scale for all surfaces on this monitor, needed for some clients
|
||||
// but not on unsafe state to avoid crashes
|
||||
if (!g_pCompositor->m_bUnsafeState) {
|
||||
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||
w->updateSurfaceScaleTransformDetails();
|
||||
}
|
||||
}
|
||||
// updato us
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(ID);
|
||||
|
||||
// reload to fix mirrors
|
||||
g_pConfigManager->m_bWantsMonitorReload = true;
|
||||
|
||||
Debug::log(LOG, "Monitor {} data dump: res {:X}@{:.2f}Hz, scale {:.2f}, transform {}, pos {:X}, 10b {}", szName, vecPixelSize, refreshRate, scale, (int)transform, vecPosition,
|
||||
(int)enabled10bit);
|
||||
|
||||
EMIT_HOOK_EVENT("monitorLayoutChanged", nullptr);
|
||||
|
||||
events.modeChanged.emit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -767,18 +370,18 @@ void CMonitor::addDamage(const pixman_region32_t* rg) {
|
||||
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
}
|
||||
|
||||
void CMonitor::addDamage(const CRegion& rg) {
|
||||
addDamage(const_cast<CRegion*>(&rg)->pixman());
|
||||
void CMonitor::addDamage(const CRegion* rg) {
|
||||
addDamage(const_cast<CRegion*>(rg)->pixman());
|
||||
}
|
||||
|
||||
void CMonitor::addDamage(const CBox& box) {
|
||||
void CMonitor::addDamage(const CBox* box) {
|
||||
static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
|
||||
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == self) {
|
||||
damage.damageEntire();
|
||||
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
}
|
||||
|
||||
if (damage.damage(box))
|
||||
if (damage.damage(*box))
|
||||
g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE);
|
||||
}
|
||||
|
||||
@@ -809,7 +412,7 @@ bool CMonitor::matchesStaticSelector(const std::string& selector) const {
|
||||
// match by description
|
||||
const auto DESCRIPTIONSELECTOR = selector.substr(5);
|
||||
|
||||
return szDescription.starts_with(DESCRIPTIONSELECTOR) || szShortDescription.starts_with(DESCRIPTIONSELECTOR);
|
||||
return DESCRIPTIONSELECTOR == szShortDescription || DESCRIPTIONSELECTOR == szDescription;
|
||||
} else {
|
||||
// match by selector
|
||||
return szName == selector;
|
||||
@@ -927,7 +530,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||
|
||||
setupDefaultWS(RULE);
|
||||
|
||||
applyMonitorRule((SMonitorRule*)&RULE, true); // will apply the offset and stuff
|
||||
g_pHyprRenderer->applyMonitorRule(self.lock(), (SMonitorRule*)&RULE, true); // will apply the offset and stuff
|
||||
} else {
|
||||
PHLMONITOR BACKUPMON = nullptr;
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
@@ -1137,15 +740,15 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
if (w->m_bIsFloating && !VECINRECT(MIDDLE, vecPosition.x, vecPosition.y, vecPosition.x + vecSize.x, vecPosition.y + vecSize.y) && !w->isX11OverrideRedirect()) {
|
||||
// if it's floating and the middle isnt on the current mon, move it to the center
|
||||
const auto PMONFROMMIDDLE = g_pCompositor->getMonitorFromVector(MIDDLE);
|
||||
Vector2D pos = w->m_vRealPosition->goal();
|
||||
Vector2D pos = w->m_vRealPosition.goal();
|
||||
if (!VECINRECT(MIDDLE, PMONFROMMIDDLE->vecPosition.x, PMONFROMMIDDLE->vecPosition.y, PMONFROMMIDDLE->vecPosition.x + PMONFROMMIDDLE->vecSize.x,
|
||||
PMONFROMMIDDLE->vecPosition.y + PMONFROMMIDDLE->vecSize.y)) {
|
||||
// not on any monitor, center
|
||||
pos = middle() / 2.f - w->m_vRealSize->goal() / 2.f;
|
||||
pos = middle() / 2.f - w->m_vRealSize.goal() / 2.f;
|
||||
} else
|
||||
pos = pos - PMONFROMMIDDLE->vecPosition + vecPosition;
|
||||
|
||||
*w->m_vRealPosition = pos;
|
||||
w->m_vRealPosition = pos;
|
||||
w->m_vPosition = pos;
|
||||
}
|
||||
}
|
||||
@@ -1179,29 +782,6 @@ void CMonitor::moveTo(const Vector2D& pos) {
|
||||
vecPosition = pos;
|
||||
}
|
||||
|
||||
SWorkspaceIDName CMonitor::getPrevWorkspaceIDName(const WORKSPACEID id) {
|
||||
while (!prevWorkSpaces.empty()) {
|
||||
const int PREVID = prevWorkSpaces.top();
|
||||
prevWorkSpaces.pop();
|
||||
if (PREVID == id) // skip same workspace
|
||||
continue;
|
||||
|
||||
// recheck if previous workspace's was moved to another monitor
|
||||
const auto ws = g_pCompositor->getWorkspaceByID(PREVID);
|
||||
if (ws && ws->monitorID() == ID)
|
||||
return {.id = PREVID, .name = ws->m_szName};
|
||||
}
|
||||
|
||||
return {.id = WORKSPACE_INVALID};
|
||||
}
|
||||
|
||||
void CMonitor::addPrevWorkspaceID(const WORKSPACEID id) {
|
||||
if (!prevWorkSpaces.empty() && prevWorkSpaces.top() == id)
|
||||
return;
|
||||
|
||||
prevWorkSpaces.emplace(id);
|
||||
}
|
||||
|
||||
Vector2D CMonitor::middle() {
|
||||
return vecPosition + vecSize / 2.f;
|
||||
}
|
||||
|
@@ -1,14 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include "../SharedDefs.hpp"
|
||||
#include "MiscFunctions.hpp"
|
||||
#include "WLClasses.hpp"
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
#include <memory>
|
||||
#include <xf86drmMode.h>
|
||||
#include "Timer.hpp"
|
||||
#include "math/Math.hpp"
|
||||
@@ -33,7 +30,7 @@ struct SMonitorRule {
|
||||
Vector2D resolution = Vector2D(1280, 720);
|
||||
Vector2D offset = Vector2D(0, 0);
|
||||
float scale = 1;
|
||||
float refreshRate = 60; // Hz
|
||||
float refreshRate = 60;
|
||||
bool disabled = false;
|
||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
std::string mirrorOf = "";
|
||||
@@ -92,8 +89,10 @@ class CMonitor {
|
||||
CDamageRing damage;
|
||||
|
||||
SP<Aquamarine::IOutput> output;
|
||||
float refreshRate = 60; // Hz
|
||||
float refreshRate = 60;
|
||||
int framesToSkip = 0;
|
||||
int forceFullFrames = 0;
|
||||
bool noFrameSchedule = false;
|
||||
bool scheduledRecalc = false;
|
||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
float xwaylandScale = 1.f;
|
||||
@@ -164,10 +163,9 @@ class CMonitor {
|
||||
// methods
|
||||
void onConnect(bool noRule);
|
||||
void onDisconnect(bool destroy = false);
|
||||
bool applyMonitorRule(SMonitorRule* pMonitorRule, bool force = false);
|
||||
void addDamage(const pixman_region32_t* rg);
|
||||
void addDamage(const CRegion& rg);
|
||||
void addDamage(const CBox& box);
|
||||
void addDamage(const CRegion* rg);
|
||||
void addDamage(const CBox* box);
|
||||
bool shouldSkipScheduleFrameOnMouseEvent();
|
||||
void setMirror(const std::string&);
|
||||
bool isMirror();
|
||||
@@ -192,7 +190,6 @@ class CMonitor {
|
||||
|
||||
bool m_bEnabled = false;
|
||||
bool m_bRenderingInitPassed = false;
|
||||
WP<CWindow> m_previousFSWindow;
|
||||
|
||||
// For the list lookup
|
||||
|
||||
@@ -200,16 +197,11 @@ class CMonitor {
|
||||
return vecPosition == rhs.vecPosition && vecSize == rhs.vecSize && szName == rhs.szName;
|
||||
}
|
||||
|
||||
// workspace previous per monitor functionality
|
||||
SWorkspaceIDName getPrevWorkspaceIDName(const WORKSPACEID id);
|
||||
void addPrevWorkspaceID(const WORKSPACEID id);
|
||||
|
||||
private:
|
||||
void setupDefaultWS(const SMonitorRule&);
|
||||
WORKSPACEID findAvailableDefaultWS();
|
||||
|
||||
bool doneScheduled = false;
|
||||
std::stack<WORKSPACEID> prevWorkSpaces;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener frame;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include "SdDaemon.hpp"
|
||||
#include "memory/Memory.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <cerrno>
|
||||
|
@@ -1,13 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "../events/Events.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include "../desktop/Subsurface.hpp"
|
||||
#include "../desktop/Popup.hpp"
|
||||
#include "AnimatedVariable.hpp"
|
||||
#include "../desktop/WLSurface.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "../desktop/DesktopTypes.hpp"
|
||||
#include "memory/Memory.hpp"
|
||||
#include "signal/Signal.hpp"
|
||||
#include "math/Math.hpp"
|
||||
|
||||
class CMonitor;
|
||||
class IPointer;
|
||||
@@ -16,6 +17,47 @@ class CWLSurfaceResource;
|
||||
|
||||
AQUAMARINE_FORWARD(ISwitch);
|
||||
|
||||
struct SRenderData {
|
||||
PHLMONITORREF pMonitor;
|
||||
timespec* when;
|
||||
double x, y;
|
||||
|
||||
// for iters
|
||||
void* data = nullptr;
|
||||
SP<CWLSurfaceResource> surface = nullptr;
|
||||
double w, h;
|
||||
|
||||
// for rounding
|
||||
bool dontRound = true;
|
||||
|
||||
// for fade
|
||||
float fadeAlpha = 1.f;
|
||||
|
||||
// for alpha settings
|
||||
float alpha = 1.f;
|
||||
|
||||
// for decorations (border)
|
||||
bool decorate = false;
|
||||
|
||||
// for custom round values
|
||||
int rounding = -1; // -1 means not set
|
||||
|
||||
// for blurring
|
||||
bool blur = false;
|
||||
bool blockBlurOptimization = false;
|
||||
|
||||
// only for windows, not popups
|
||||
bool squishOversized = true;
|
||||
|
||||
// for calculating UV
|
||||
PHLWINDOW pWindow;
|
||||
|
||||
bool popup = false;
|
||||
|
||||
// counts how many surfaces this pass has rendered
|
||||
int surfaceCounter = 0;
|
||||
};
|
||||
|
||||
struct SSwipeGesture {
|
||||
PHLWORKSPACE pWorkspaceBegin = nullptr;
|
||||
|
||||
|
@@ -14,7 +14,7 @@ CWatchdog::~CWatchdog() {
|
||||
|
||||
CWatchdog::CWatchdog() : m_iMainThreadPID(pthread_self()) {
|
||||
|
||||
m_pWatchdog = makeUnique<std::thread>([this] {
|
||||
m_pWatchdog = std::make_unique<std::thread>([this] {
|
||||
static auto PTIMEOUT = CConfigValue<Hyprlang::INT>("debug:watchdog_timeout");
|
||||
|
||||
m_bWatchdogInitialized = true;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "memory/Memory.hpp"
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
@@ -24,11 +24,11 @@ class CWatchdog {
|
||||
std::atomic<bool> m_bWatching = false;
|
||||
std::atomic<bool> m_bWillWatch = false;
|
||||
|
||||
UP<std::thread> m_pWatchdog;
|
||||
std::unique_ptr<std::thread> m_pWatchdog;
|
||||
std::mutex m_mWatchdogMutex;
|
||||
std::atomic<bool> m_bNotified = false;
|
||||
std::atomic<bool> m_bExitThread = false;
|
||||
std::condition_variable m_cvWatchdogCondition;
|
||||
};
|
||||
|
||||
inline UP<CWatchdog> g_pWatchdog;
|
||||
inline std::unique_ptr<CWatchdog> g_pWatchdog;
|
@@ -1,107 +0,0 @@
|
||||
#include "FsUtils.hpp"
|
||||
#include "../../debug/Log.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <hyprutils/string/VarList.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
|
||||
std::optional<std::string> NFsUtils::getDataHome() {
|
||||
const auto DATA_HOME = getenv("XDG_DATA_HOME");
|
||||
|
||||
std::string dataRoot;
|
||||
|
||||
if (!DATA_HOME) {
|
||||
const auto HOME = getenv("HOME");
|
||||
|
||||
if (!HOME) {
|
||||
Debug::log(ERR, "FsUtils::getDataHome: can't get data home: no $HOME or $XDG_DATA_HOME");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
dataRoot = HOME + std::string{"/.local/share/"};
|
||||
} else
|
||||
dataRoot = DATA_HOME + std::string{"/"};
|
||||
|
||||
std::error_code ec;
|
||||
if (!std::filesystem::exists(dataRoot, ec) || ec) {
|
||||
Debug::log(ERR, "FsUtils::getDataHome: can't get data home: inaccessible / missing");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
dataRoot += "hyprland/";
|
||||
|
||||
if (!std::filesystem::exists(dataRoot, ec) || ec) {
|
||||
Debug::log(LOG, "FsUtils::getDataHome: no hyprland data home, creating.");
|
||||
std::filesystem::create_directory(dataRoot, ec);
|
||||
if (ec) {
|
||||
Debug::log(ERR, "FsUtils::getDataHome: can't create new data home for hyprland");
|
||||
return std::nullopt;
|
||||
}
|
||||
std::filesystem::permissions(dataRoot, std::filesystem::perms::owner_read | std::filesystem::perms::owner_write | std::filesystem::perms::owner_exec, ec);
|
||||
if (ec)
|
||||
Debug::log(WARN, "FsUtils::getDataHome: couldn't set perms on hyprland data store. Proceeding anyways.");
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(dataRoot, ec) || ec) {
|
||||
Debug::log(ERR, "FsUtils::getDataHome: no hyprland data home, failed to create.");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return dataRoot;
|
||||
}
|
||||
|
||||
std::optional<std::string> NFsUtils::readFileAsString(const std::string& path) {
|
||||
std::error_code ec;
|
||||
|
||||
if (!std::filesystem::exists(path, ec) || ec)
|
||||
return std::nullopt;
|
||||
|
||||
std::ifstream file(path);
|
||||
if (!file.good())
|
||||
return std::nullopt;
|
||||
|
||||
return trim(std::string((std::istreambuf_iterator<char>(file)), (std::istreambuf_iterator<char>())));
|
||||
}
|
||||
|
||||
bool NFsUtils::writeToFile(const std::string& path, const std::string& content) {
|
||||
std::ofstream of(path, std::ios::trunc);
|
||||
if (!of.good()) {
|
||||
Debug::log(ERR, "CVersionKeeperManager: couldn't open an ofstream for writing the version file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
of << content;
|
||||
of.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NFsUtils::executableExistsInPath(const std::string& exe) {
|
||||
if (!getenv("PATH"))
|
||||
return false;
|
||||
|
||||
static CVarList paths(getenv("PATH"), 0, ':', true);
|
||||
|
||||
for (auto& p : paths) {
|
||||
std::string path = p + std::string{"/"} + exe;
|
||||
std::error_code ec;
|
||||
if (!std::filesystem::exists(path, ec) || ec)
|
||||
continue;
|
||||
|
||||
if (!std::filesystem::is_regular_file(path, ec) || ec)
|
||||
continue;
|
||||
|
||||
auto stat = std::filesystem::status(path, ec);
|
||||
if (ec)
|
||||
continue;
|
||||
|
||||
auto perms = stat.permissions();
|
||||
|
||||
return std::filesystem::perms::none != (perms & std::filesystem::perms::others_exec);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace NFsUtils {
|
||||
// Returns the path to the hyprland directory in data home.
|
||||
std::optional<std::string> getDataHome();
|
||||
|
||||
std::optional<std::string> readFileAsString(const std::string& path);
|
||||
|
||||
// overwrites the file if exists
|
||||
bool writeToFile(const std::string& path, const std::string& content);
|
||||
|
||||
bool executableExistsInPath(const std::string& exe);
|
||||
};
|
@@ -7,4 +7,4 @@ using namespace Hyprutils::Memory;
|
||||
|
||||
#define SP Hyprutils::Memory::CSharedPointer
|
||||
#define WP Hyprutils::Memory::CWeakPointer
|
||||
#define UP Hyprutils::Memory::CUniquePointer
|
||||
#define UP std::unique_ptr
|
||||
|
@@ -2,16 +2,13 @@
|
||||
#include "HyprError.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../render/pass/TexPassElement.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
|
||||
#include <hyprutils/utils/ScopeGuard.hpp>
|
||||
using namespace Hyprutils::Animation;
|
||||
using namespace Hyprutils::Utils;
|
||||
|
||||
CHyprError::CHyprError() {
|
||||
g_pAnimationManager->createAnimation(0.f, m_fFadeOpacity, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), AVARDAMAGE_NONE);
|
||||
m_fFadeOpacity.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), AVARDAMAGE_NONE);
|
||||
m_fFadeOpacity.registerVar();
|
||||
|
||||
static auto P = g_pHookSystem->hookDynamic("focusedMon", [&](void* self, SCallbackInfo& info, std::any param) {
|
||||
if (!m_bIsCreated)
|
||||
@@ -25,14 +22,16 @@ CHyprError::CHyprError() {
|
||||
if (!m_bIsCreated)
|
||||
return;
|
||||
|
||||
if (m_fFadeOpacity->isBeingAnimated() || m_bMonitorChanged)
|
||||
g_pHyprRenderer->damageBox(m_bDamageBox);
|
||||
if (m_fFadeOpacity.isBeingAnimated() || m_bMonitorChanged)
|
||||
g_pHyprRenderer->damageBox(&m_bDamageBox);
|
||||
});
|
||||
|
||||
m_pTexture = makeShared<CTexture>();
|
||||
}
|
||||
|
||||
CHyprError::~CHyprError() = default;
|
||||
CHyprError::~CHyprError() {
|
||||
m_fFadeOpacity.unregister();
|
||||
}
|
||||
|
||||
void CHyprError::queueCreate(std::string message, const CHyprColor& color) {
|
||||
m_szQueued = message;
|
||||
@@ -43,10 +42,10 @@ void CHyprError::createQueued() {
|
||||
if (m_bIsCreated)
|
||||
m_pTexture->destroyTexture();
|
||||
|
||||
m_fFadeOpacity->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn"));
|
||||
m_fFadeOpacity.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn"));
|
||||
|
||||
m_fFadeOpacity->setValueAndWarp(0.f);
|
||||
*m_fFadeOpacity = 1.f;
|
||||
m_fFadeOpacity.setValueAndWarp(0.f);
|
||||
m_fFadeOpacity = 1.f;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front();
|
||||
|
||||
@@ -176,8 +175,8 @@ void CHyprError::draw() {
|
||||
}
|
||||
|
||||
if (m_bQueuedDestroy) {
|
||||
if (!m_fFadeOpacity->isBeingAnimated()) {
|
||||
if (m_fFadeOpacity->value() == 0.f) {
|
||||
if (!m_fFadeOpacity.isBeingAnimated()) {
|
||||
if (m_fFadeOpacity.value() == 0.f) {
|
||||
m_bQueuedDestroy = false;
|
||||
m_pTexture->destroyTexture();
|
||||
m_bIsCreated = false;
|
||||
@@ -189,8 +188,8 @@ void CHyprError::draw() {
|
||||
|
||||
return;
|
||||
} else {
|
||||
m_fFadeOpacity->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut"));
|
||||
*m_fFadeOpacity = 0.f;
|
||||
m_fFadeOpacity.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut"));
|
||||
m_fFadeOpacity = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,17 +201,12 @@ void CHyprError::draw() {
|
||||
m_bDamageBox.x = (int)PMONITOR->vecPosition.x;
|
||||
m_bDamageBox.y = (int)PMONITOR->vecPosition.y;
|
||||
|
||||
if (m_fFadeOpacity->isBeingAnimated() || m_bMonitorChanged)
|
||||
g_pHyprRenderer->damageBox(m_bDamageBox);
|
||||
if (m_fFadeOpacity.isBeingAnimated() || m_bMonitorChanged)
|
||||
g_pHyprRenderer->damageBox(&m_bDamageBox);
|
||||
|
||||
m_bMonitorChanged = false;
|
||||
|
||||
CTexPassElement::SRenderData data;
|
||||
data.tex = m_pTexture;
|
||||
data.box = monbox;
|
||||
data.a = m_fFadeOpacity->value();
|
||||
|
||||
g_pHyprRenderer->m_sRenderPass.add(makeShared<CTexPassElement>(data));
|
||||
g_pHyprOpenGL->renderTexture(m_pTexture, &monbox, m_fFadeOpacity.value(), 0);
|
||||
}
|
||||
|
||||
void CHyprError::destroy() {
|
||||
|
@@ -25,11 +25,11 @@ class CHyprError {
|
||||
bool m_bQueuedDestroy = false;
|
||||
bool m_bIsCreated = false;
|
||||
SP<CTexture> m_pTexture;
|
||||
PHLANIMVAR<float> m_fFadeOpacity;
|
||||
CAnimatedVariable<float> m_fFadeOpacity;
|
||||
CBox m_bDamageBox = {0, 0, 0, 0};
|
||||
float m_fLastHeight = 0.F;
|
||||
|
||||
bool m_bMonitorChanged = false;
|
||||
};
|
||||
|
||||
inline UP<CHyprError> g_pHyprError; // This is a full-screen error. Treat it with respect, and there can only be one at a time.
|
||||
inline std::unique_ptr<CHyprError> g_pHyprError; // This is a full-screen error. Treat it with respect, and there can only be one at a time.
|
||||
|
@@ -2,10 +2,6 @@
|
||||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
|
||||
void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverride, bool verticalOverride) {
|
||||
if (children[0]) {
|
||||
@@ -42,6 +38,14 @@ void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverrid
|
||||
}
|
||||
}
|
||||
|
||||
void SDwindleNodeData::getAllChildrenRecursive(std::vector<SDwindleNodeData*>* pVec) {
|
||||
if (children[0]) {
|
||||
children[0]->getAllChildrenRecursive(pVec);
|
||||
children[1]->getAllChildrenRecursive(pVec);
|
||||
} else
|
||||
pVec->push_back(this);
|
||||
}
|
||||
|
||||
int CHyprDwindleLayout::getNodesOnWorkspace(const WORKSPACEID& id) {
|
||||
int no = 0;
|
||||
for (auto const& n : m_lDwindleNodesData) {
|
||||
@@ -105,8 +109,8 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (const auto WS = g_pCompositor->getWorkspaceByID(pNode->workspaceID); WS)
|
||||
PMONITOR = WS->m_pMonitor.lock();
|
||||
} else
|
||||
PMONITOR = g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_pMonitor.lock();
|
||||
|
||||
if (!PMONITOR) {
|
||||
Debug::log(ERR, "Orphaned Node {}!!", pNode);
|
||||
@@ -196,25 +200,25 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
CBox wb = {calcPos + (calcSize - calcSize * *PSCALEFACTOR) / 2.f, calcSize * *PSCALEFACTOR};
|
||||
wb.round(); // avoid rounding mess
|
||||
|
||||
*PWINDOW->m_vRealPosition = wb.pos();
|
||||
*PWINDOW->m_vRealSize = wb.size();
|
||||
PWINDOW->m_vRealPosition = wb.pos();
|
||||
PWINDOW->m_vRealSize = wb.size();
|
||||
|
||||
PWINDOW->sendWindowSize(wb.size());
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, wb.size());
|
||||
} else {
|
||||
CBox wb = {calcPos, calcSize};
|
||||
wb.round(); // avoid rounding mess
|
||||
|
||||
*PWINDOW->m_vRealSize = wb.size();
|
||||
*PWINDOW->m_vRealPosition = wb.pos();
|
||||
PWINDOW->m_vRealSize = wb.size();
|
||||
PWINDOW->m_vRealPosition = wb.pos();
|
||||
|
||||
PWINDOW->sendWindowSize(wb.size());
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, wb.size());
|
||||
}
|
||||
|
||||
if (force) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
|
||||
PWINDOW->m_vRealPosition->warp();
|
||||
PWINDOW->m_vRealSize->warp();
|
||||
PWINDOW->m_vRealPosition.warp();
|
||||
PWINDOW->m_vRealSize.warp();
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
@@ -512,8 +516,8 @@ void CHyprDwindleLayout::calculateWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
const auto PFULLWINDOW = pWorkspace->getFullscreenWindow();
|
||||
|
||||
if (pWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) {
|
||||
*PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition;
|
||||
*PFULLWINDOW->m_vRealSize = PMONITOR->vecSize;
|
||||
PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition;
|
||||
PFULLWINDOW->m_vRealSize = PMONITOR->vecSize;
|
||||
} else if (pWorkspace->m_efFullscreenMode == FSMODE_MAXIMIZED) {
|
||||
SDwindleNodeData fakeNode;
|
||||
fakeNode.pWindow = PFULLWINDOW;
|
||||
@@ -558,8 +562,8 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
|
||||
if (!PNODE) {
|
||||
*PWINDOW->m_vRealSize =
|
||||
(PWINDOW->m_vRealSize->goal() + pixResize)
|
||||
PWINDOW->m_vRealSize =
|
||||
(PWINDOW->m_vRealSize.goal() + pixResize)
|
||||
.clamp(PWINDOW->m_sWindowData.minSize.valueOr(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), PWINDOW->m_sWindowData.maxSize.valueOr(Vector2D{INFINITY, INFINITY}));
|
||||
PWINDOW->updateWindowDecos();
|
||||
return;
|
||||
@@ -579,7 +583,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
|
||||
if (!m_PseudoDragFlags.started) {
|
||||
m_PseudoDragFlags.started = true;
|
||||
|
||||
const auto pseudoSize = PWINDOW->m_vRealSize->goal();
|
||||
const auto pseudoSize = PWINDOW->m_vRealSize.goal();
|
||||
const auto mouseOffset = g_pInputManager->getMouseCoordsInternal() - (PNODE->box.pos() + ((PNODE->box.size() / 2) - (pseudoSize / 2)));
|
||||
|
||||
if (mouseOffset.x > 0 && mouseOffset.x < pseudoSize.x && mouseOffset.y > 0 && mouseOffset.y < pseudoSize.y) {
|
||||
@@ -747,10 +751,10 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFu
|
||||
|
||||
// save position and size if floating
|
||||
if (pWindow->m_bIsFloating && CURRENT_EFFECTIVE_MODE == FSMODE_NONE) {
|
||||
pWindow->m_vLastFloatingSize = pWindow->m_vRealSize->goal();
|
||||
pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition->goal();
|
||||
pWindow->m_vPosition = pWindow->m_vRealPosition->goal();
|
||||
pWindow->m_vSize = pWindow->m_vRealSize->goal();
|
||||
pWindow->m_vLastFloatingSize = pWindow->m_vRealSize.goal();
|
||||
pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition.goal();
|
||||
pWindow->m_vPosition = pWindow->m_vRealPosition.goal();
|
||||
pWindow->m_vSize = pWindow->m_vRealSize.goal();
|
||||
}
|
||||
|
||||
if (EFFECTIVE_MODE == FSMODE_NONE) {
|
||||
@@ -760,8 +764,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFu
|
||||
applyNodeDataToWindow(PNODE);
|
||||
else {
|
||||
// get back its' dimensions from position and size
|
||||
*pWindow->m_vRealPosition = pWindow->m_vLastFloatingPosition;
|
||||
*pWindow->m_vRealSize = pWindow->m_vLastFloatingSize;
|
||||
pWindow->m_vRealPosition = pWindow->m_vLastFloatingPosition;
|
||||
pWindow->m_vRealSize = pWindow->m_vLastFloatingSize;
|
||||
|
||||
pWindow->unsetWindowData(PRIORITY_LAYOUT);
|
||||
pWindow->updateWindowData();
|
||||
@@ -769,8 +773,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFu
|
||||
} else {
|
||||
// apply new pos and size being monitors' box
|
||||
if (EFFECTIVE_MODE == FSMODE_FULLSCREEN) {
|
||||
*pWindow->m_vRealPosition = PMONITOR->vecPosition;
|
||||
*pWindow->m_vRealSize = PMONITOR->vecSize;
|
||||
pWindow->m_vRealPosition = PMONITOR->vecPosition;
|
||||
pWindow->m_vRealSize = PMONITOR->vecSize;
|
||||
} else {
|
||||
// This is a massive hack.
|
||||
// We make a fake "only" node and apply
|
||||
@@ -800,6 +804,15 @@ void CHyprDwindleLayout::recalculateWindow(PHLWINDOW pWindow) {
|
||||
PNODE->recalcSizePosRecursive();
|
||||
}
|
||||
|
||||
static void addToVectorRecursive(std::vector<SDwindleNodeData*>* pVec, std::vector<SDwindleNodeData*>* pParents, SDwindleNodeData* node) {
|
||||
if (node->isNode) {
|
||||
pParents->emplace_back(node);
|
||||
addToVectorRecursive(pVec, pParents, node->children[0]);
|
||||
addToVectorRecursive(pVec, pParents, node->children[1]);
|
||||
} else
|
||||
pVec->emplace_back(node);
|
||||
}
|
||||
|
||||
SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(PHLWINDOW pWindow) {
|
||||
// window should be valid, insallah
|
||||
SWindowRenderLayoutHints hints;
|
||||
@@ -847,15 +860,6 @@ void CHyprDwindleLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
|
||||
pWindow->m_pMonitor = PMONITORFOCAL;
|
||||
}
|
||||
|
||||
pWindow->updateGroupOutputs();
|
||||
if (!pWindow->m_sGroupData.pNextWindow.expired()) {
|
||||
PHLWINDOW next = pWindow->m_sGroupData.pNextWindow.lock();
|
||||
while (next != pWindow) {
|
||||
next->updateToplevel();
|
||||
next = next->m_sGroupData.pNextWindow.lock();
|
||||
}
|
||||
}
|
||||
|
||||
onWindowCreatedTiling(pWindow);
|
||||
|
||||
m_vOverrideFocalPoint.reset();
|
||||
|
@@ -39,6 +39,7 @@ struct SDwindleNodeData {
|
||||
}
|
||||
|
||||
void recalcSizePosRecursive(bool force = false, bool horizontalOverride = false, bool verticalOverride = false);
|
||||
void getAllChildrenRecursive(std::vector<SDwindleNodeData*>*);
|
||||
CHyprDwindleLayout* layout = nullptr;
|
||||
};
|
||||
|
||||
|
@@ -7,14 +7,10 @@
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../xwayland/XSurface.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
|
||||
void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) {
|
||||
CBox desiredGeometry = g_pXWaylandManager->getGeometryForWindow(pWindow);
|
||||
CBox desiredGeometry = {};
|
||||
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
|
||||
|
||||
if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) {
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
@@ -24,6 +20,9 @@ void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) {
|
||||
|
||||
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;
|
||||
@@ -32,9 +31,6 @@ void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) {
|
||||
onWindowCreatedFloating(pWindow);
|
||||
else
|
||||
onWindowCreatedTiling(pWindow, direction);
|
||||
|
||||
if (!g_pXWaylandManager->shouldBeFloated(pWindow)) // do not apply group rules to child windows
|
||||
pWindow->applyGroupRules();
|
||||
}
|
||||
|
||||
void IHyprLayout::onWindowRemoved(PHLWINDOW pWindow) {
|
||||
@@ -90,7 +86,8 @@ void IHyprLayout::onWindowRemovedFloating(PHLWINDOW pWindow) {
|
||||
|
||||
void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
|
||||
|
||||
CBox desiredGeometry = g_pXWaylandManager->getGeometryForWindow(pWindow);
|
||||
CBox desiredGeometry = {0};
|
||||
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
if (pWindow->m_bIsX11) {
|
||||
@@ -109,7 +106,7 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
|
||||
|
||||
if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) {
|
||||
const auto PWINDOWSURFACE = pWindow->m_pWLSurface->resource();
|
||||
*pWindow->m_vRealSize = PWINDOWSURFACE->current.size;
|
||||
pWindow->m_vRealSize = PWINDOWSURFACE->current.size;
|
||||
|
||||
if ((desiredGeometry.width <= 1 || desiredGeometry.height <= 1) && pWindow->m_bIsX11 &&
|
||||
pWindow->isX11OverrideRedirect()) { // XDG windows should be fine. TODO: check for weird atoms?
|
||||
@@ -118,23 +115,23 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
|
||||
}
|
||||
|
||||
// reject any windows with size <= 5x5
|
||||
if (pWindow->m_vRealSize->goal().x <= 5 || pWindow->m_vRealSize->goal().y <= 5)
|
||||
*pWindow->m_vRealSize = PMONITOR->vecSize / 2.f;
|
||||
if (pWindow->m_vRealSize.goal().x <= 5 || pWindow->m_vRealSize.goal().y <= 5)
|
||||
pWindow->m_vRealSize = PMONITOR->vecSize / 2.f;
|
||||
|
||||
if (pWindow->m_bIsX11 && pWindow->isX11OverrideRedirect()) {
|
||||
|
||||
if (pWindow->m_pXWaylandSurface->geometry.x != 0 && pWindow->m_pXWaylandSurface->geometry.y != 0)
|
||||
*pWindow->m_vRealPosition = g_pXWaylandManager->xwaylandToWaylandCoords(pWindow->m_pXWaylandSurface->geometry.pos());
|
||||
pWindow->m_vRealPosition = g_pXWaylandManager->xwaylandToWaylandCoords(pWindow->m_pXWaylandSurface->geometry.pos());
|
||||
else
|
||||
*pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize->goal().x) / 2.f,
|
||||
PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize->goal().y) / 2.f);
|
||||
pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.goal().x) / 2.f,
|
||||
PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.goal().y) / 2.f);
|
||||
} else {
|
||||
*pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize->goal().x) / 2.f,
|
||||
PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize->goal().y) / 2.f);
|
||||
pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.goal().x) / 2.f,
|
||||
PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.goal().y) / 2.f);
|
||||
}
|
||||
} else {
|
||||
// we respect the size.
|
||||
*pWindow->m_vRealSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
|
||||
pWindow->m_vRealSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
|
||||
|
||||
// check if it's on the correct monitor!
|
||||
Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f;
|
||||
@@ -153,35 +150,35 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
|
||||
if ((desiredGeometry.x == 0 && desiredGeometry.y == 0) || !visible || !pWindow->m_bIsX11) {
|
||||
// if the pos isn't set, fall back to the center placement if it's not a child, otherwise middle of parent if available
|
||||
if (!pWindow->m_bIsX11 && pWindow->m_pXDGSurface->toplevel->parent && validMapped(pWindow->m_pXDGSurface->toplevel->parent->window))
|
||||
*pWindow->m_vRealPosition = pWindow->m_pXDGSurface->toplevel->parent->window->m_vRealPosition->goal() +
|
||||
pWindow->m_pXDGSurface->toplevel->parent->window->m_vRealSize->goal() / 2.F - desiredGeometry.size() / 2.F;
|
||||
pWindow->m_vRealPosition = pWindow->m_pXDGSurface->toplevel->parent->window->m_vRealPosition.goal() +
|
||||
pWindow->m_pXDGSurface->toplevel->parent->window->m_vRealSize.goal() / 2.F - desiredGeometry.size() / 2.F;
|
||||
else
|
||||
*pWindow->m_vRealPosition = PMONITOR->vecPosition + PMONITOR->vecSize / 2.F - desiredGeometry.size() / 2.F;
|
||||
pWindow->m_vRealPosition = PMONITOR->vecPosition + PMONITOR->vecSize / 2.F - desiredGeometry.size() / 2.F;
|
||||
} else {
|
||||
// if it is, we respect where it wants to put itself, but apply monitor offset if outside
|
||||
// most of these are popups
|
||||
|
||||
if (const auto POPENMON = g_pCompositor->getMonitorFromVector(middlePoint); POPENMON->ID != PMONITOR->ID)
|
||||
*pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y) - POPENMON->vecPosition + PMONITOR->vecPosition;
|
||||
pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y) - POPENMON->vecPosition + PMONITOR->vecPosition;
|
||||
else
|
||||
*pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y);
|
||||
pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y);
|
||||
}
|
||||
}
|
||||
|
||||
if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11)
|
||||
*pWindow->m_vRealSize = pWindow->m_vRealSize->goal() / PMONITOR->scale;
|
||||
pWindow->m_vRealSize = pWindow->m_vRealSize.goal() / PMONITOR->scale;
|
||||
|
||||
if (pWindow->m_bX11DoesntWantBorders || (pWindow->m_bIsX11 && pWindow->isX11OverrideRedirect())) {
|
||||
pWindow->m_vRealPosition->warp();
|
||||
pWindow->m_vRealSize->warp();
|
||||
pWindow->m_vRealPosition.warp();
|
||||
pWindow->m_vRealSize.warp();
|
||||
}
|
||||
|
||||
if (!pWindow->isX11OverrideRedirect()) {
|
||||
pWindow->sendWindowSize(pWindow->m_vRealSize->goal());
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goal());
|
||||
|
||||
g_pCompositor->changeWindowZOrder(pWindow, true);
|
||||
} else {
|
||||
pWindow->m_vPendingReportedSize = pWindow->m_vRealSize->goal();
|
||||
pWindow->m_vPendingReportedSize = pWindow->m_vRealSize.goal();
|
||||
pWindow->m_vReportedSize = pWindow->m_vPendingReportedSize;
|
||||
}
|
||||
}
|
||||
@@ -208,12 +205,11 @@ bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) {
|
||||
(*USECURRPOS ? OPENINGON : OPENINGON->getGroupTail())->insertWindowToGroup(pWindow);
|
||||
|
||||
OPENINGON->setGroupCurrent(pWindow);
|
||||
pWindow->applyGroupRules();
|
||||
pWindow->updateWindowDecos();
|
||||
recalculateWindow(pWindow);
|
||||
|
||||
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
|
||||
pWindow->addWindowDeco(makeUnique<CHyprGroupBarDecoration>(pWindow));
|
||||
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -253,18 +249,18 @@ void IHyprLayout::onBeginDragWindow() {
|
||||
|
||||
if (!DRAGGINGWINDOW->m_bIsFloating) {
|
||||
if (g_pInputManager->dragMode == MBIND_MOVE) {
|
||||
DRAGGINGWINDOW->m_vLastFloatingSize = (DRAGGINGWINDOW->m_vRealSize->goal() * 0.8489).clamp(Vector2D{5, 5}, Vector2D{}).floor();
|
||||
DRAGGINGWINDOW->m_vLastFloatingSize = (DRAGGINGWINDOW->m_vRealSize.goal() * 0.8489).clamp(Vector2D{5, 5}, Vector2D{}).floor();
|
||||
changeWindowFloatingMode(DRAGGINGWINDOW);
|
||||
DRAGGINGWINDOW->m_bIsFloating = true;
|
||||
DRAGGINGWINDOW->m_bDraggingTiled = true;
|
||||
|
||||
*DRAGGINGWINDOW->m_vRealPosition = g_pInputManager->getMouseCoordsInternal() - DRAGGINGWINDOW->m_vRealSize->goal() / 2.f;
|
||||
DRAGGINGWINDOW->m_vRealPosition = g_pInputManager->getMouseCoordsInternal() - DRAGGINGWINDOW->m_vRealSize.goal() / 2.f;
|
||||
}
|
||||
}
|
||||
|
||||
m_vBeginDragXY = g_pInputManager->getMouseCoordsInternal();
|
||||
m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition->goal();
|
||||
m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize->goal();
|
||||
m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition.goal();
|
||||
m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.goal();
|
||||
m_vLastDragXY = m_vBeginDragXY;
|
||||
|
||||
// get the grab corner
|
||||
@@ -352,8 +348,8 @@ void IHyprLayout::onEndDragWindow() {
|
||||
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->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();
|
||||
}
|
||||
}
|
||||
@@ -363,16 +359,15 @@ void IHyprLayout::onEndDragWindow() {
|
||||
DRAGGINGWINDOW->m_bDraggingTiled = false;
|
||||
|
||||
if (pWindow->m_bIsFloating)
|
||||
DRAGGINGWINDOW->sendWindowSize(DRAGGINGWINDOW->m_vRealSize->goal()); // match the size of the window
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, pWindow->m_vRealSize.goal()); // match the size of the window
|
||||
|
||||
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
|
||||
(*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW);
|
||||
pWindow->setGroupCurrent(DRAGGINGWINDOW);
|
||||
DRAGGINGWINDOW->applyGroupRules();
|
||||
DRAGGINGWINDOW->updateWindowDecos();
|
||||
|
||||
if (!DRAGGINGWINDOW->getDecorationByType(DECORATION_GROUPBAR))
|
||||
DRAGGINGWINDOW->addWindowDeco(makeUnique<CHyprGroupBarDecoration>(DRAGGINGWINDOW));
|
||||
DRAGGINGWINDOW->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(DRAGGINGWINDOW));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,11 +421,9 @@ static void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRA
|
||||
if (*SNAPWINDOWGAP) {
|
||||
const double GAPSIZE = *SNAPWINDOWGAP;
|
||||
const auto WSID = DRAGGINGWINDOW->workspaceID();
|
||||
const bool HASFULLSCREEN = DRAGGINGWINDOW->m_pWorkspace && DRAGGINGWINDOW->m_pWorkspace->m_bHasFullscreenWindow;
|
||||
|
||||
for (auto& other : g_pCompositor->m_vWindows) {
|
||||
if ((HASFULLSCREEN && !other->m_bCreatedOverFullscreen) || other == DRAGGINGWINDOW || other->workspaceID() != WSID || !other->m_bIsMapped || other->m_bFadingOut ||
|
||||
other->isX11OverrideRedirect())
|
||||
if (other == DRAGGINGWINDOW || other->workspaceID() != WSID || !other->m_bIsMapped || other->m_bFadingOut || other->isX11OverrideRedirect())
|
||||
continue;
|
||||
|
||||
const int OTHERBORDERSIZE = other->getRealBorderSize();
|
||||
@@ -462,22 +455,22 @@ static void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRA
|
||||
|
||||
// corner snapping
|
||||
const double BORDERDIFF = OTHERBORDERSIZE - DRAGGINGBORDERSIZE;
|
||||
if (sourceX.start == SURFBX.end || SURFBX.start == sourceX.end) {
|
||||
if (snaps & (SNAP_LEFT | SNAP_RIGHT)) {
|
||||
const SRange SURFY = {SURF.y - BORDERDIFF, SURF.y + SURF.h + BORDERDIFF};
|
||||
if (CORNER & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && !(snaps & SNAP_UP) && canSnap(sourceY.start, SURFY.start, GAPSIZE)) {
|
||||
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) && !(snaps & SNAP_DOWN) && canSnap(sourceY.end, SURFY.end, GAPSIZE)) {
|
||||
} 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) {
|
||||
if (snaps & (SNAP_UP | SNAP_DOWN)) {
|
||||
const SRange SURFX = {SURF.x - BORDERDIFF, SURF.x + SURF.w + BORDERDIFF};
|
||||
if (CORNER & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && !(snaps & SNAP_LEFT) && canSnap(sourceX.start, SURFX.start, GAPSIZE)) {
|
||||
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) && !(snaps & SNAP_RIGHT) && canSnap(sourceX.end, SURFX.end, GAPSIZE)) {
|
||||
} else if (CORNER & (CORNER_TOPRIGHT | CORNER_BOTTOMRIGHT) && canSnap(sourceX.end, SURFX.end, GAPSIZE)) {
|
||||
SNAP(sourceX.end, sourceX.start, SURFX.end);
|
||||
snaps |= SNAP_RIGHT;
|
||||
}
|
||||
@@ -596,7 +589,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
if (g_pInputManager->dragMode == MBIND_MOVE) {
|
||||
|
||||
Vector2D newPos = m_vBeginDragPositionXY + DELTA;
|
||||
Vector2D newSize = DRAGGINGWINDOW->m_vRealSize->goal();
|
||||
Vector2D newSize = DRAGGINGWINDOW->m_vRealSize.goal();
|
||||
|
||||
if (*SNAPENABLED && !DRAGGINGWINDOW->m_bDraggingTiled)
|
||||
performSnap(newPos, newSize, DRAGGINGWINDOW, MBIND_MOVE, -1, m_vBeginDragSizeXY);
|
||||
@@ -605,11 +598,11 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
wb.round();
|
||||
|
||||
if (*PANIMATEMOUSE)
|
||||
*DRAGGINGWINDOW->m_vRealPosition = wb.pos();
|
||||
DRAGGINGWINDOW->m_vRealPosition = wb.pos();
|
||||
else
|
||||
DRAGGINGWINDOW->m_vRealPosition->setValueAndWarp(wb.pos());
|
||||
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos());
|
||||
|
||||
DRAGGINGWINDOW->sendWindowSize(DRAGGINGWINDOW->m_vRealSize->goal());
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goal());
|
||||
} else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) {
|
||||
if (DRAGGINGWINDOW->m_bIsFloating) {
|
||||
|
||||
@@ -674,21 +667,21 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
wb.round();
|
||||
|
||||
if (*PANIMATE) {
|
||||
*DRAGGINGWINDOW->m_vRealSize = wb.size();
|
||||
*DRAGGINGWINDOW->m_vRealPosition = wb.pos();
|
||||
DRAGGINGWINDOW->m_vRealSize = wb.size();
|
||||
DRAGGINGWINDOW->m_vRealPosition = wb.pos();
|
||||
} else {
|
||||
DRAGGINGWINDOW->m_vRealSize->setValueAndWarp(wb.size());
|
||||
DRAGGINGWINDOW->m_vRealPosition->setValueAndWarp(wb.pos());
|
||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(wb.size());
|
||||
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos());
|
||||
}
|
||||
|
||||
DRAGGINGWINDOW->sendWindowSize(DRAGGINGWINDOW->m_vRealSize->goal());
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goal());
|
||||
} else {
|
||||
resizeActiveWindow(TICKDELTA, m_eGrabbedCorner, DRAGGINGWINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
// get middle point
|
||||
Vector2D middle = DRAGGINGWINDOW->m_vRealPosition->value() + DRAGGINGWINDOW->m_vRealSize->value() / 2.f;
|
||||
Vector2D middle = DRAGGINGWINDOW->m_vRealPosition.value() + DRAGGINGWINDOW->m_vRealSize.value() / 2.f;
|
||||
|
||||
// and check its monitor
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle);
|
||||
@@ -715,8 +708,6 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
|
||||
|
||||
pWindow->m_bPinned = false;
|
||||
|
||||
g_pHyprRenderer->damageWindow(pWindow, true);
|
||||
|
||||
const auto TILED = isWindowTiled(pWindow);
|
||||
|
||||
// event
|
||||
@@ -724,7 +715,7 @@ 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);
|
||||
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.value() + pWindow->m_vRealSize.value() / 2.f);
|
||||
pWindow->m_pMonitor = PNEWMON;
|
||||
pWindow->moveToWorkspace(PNEWMON->activeSpecialWorkspace ? PNEWMON->activeSpecialWorkspace : PNEWMON->activeWorkspace);
|
||||
pWindow->updateGroupOutputs();
|
||||
@@ -735,12 +726,12 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
|
||||
g_pCompositor->setWindowFullscreenInternal(PWORKSPACE->getFullscreenWindow(), FSMODE_NONE);
|
||||
|
||||
// save real pos cuz the func applies the default 5,5 mid
|
||||
const auto PSAVEDPOS = pWindow->m_vRealPosition->goal();
|
||||
const auto PSAVEDSIZE = pWindow->m_vRealSize->goal();
|
||||
const auto PSAVEDPOS = pWindow->m_vRealPosition.goal();
|
||||
const auto PSAVEDSIZE = pWindow->m_vRealSize.goal();
|
||||
|
||||
// if the window is pseudo, update its size
|
||||
if (!pWindow->m_bDraggingTiled)
|
||||
pWindow->m_vPseudoSize = pWindow->m_vRealSize->goal();
|
||||
pWindow->m_vPseudoSize = pWindow->m_vRealSize.goal();
|
||||
|
||||
pWindow->m_vLastFloatingSize = PSAVEDSIZE;
|
||||
|
||||
@@ -749,8 +740,8 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
|
||||
|
||||
onWindowCreatedTiling(pWindow);
|
||||
|
||||
pWindow->m_vRealPosition->setValue(PSAVEDPOS);
|
||||
pWindow->m_vRealSize->setValue(PSAVEDSIZE);
|
||||
pWindow->m_vRealPosition.setValue(PSAVEDPOS);
|
||||
pWindow->m_vRealSize.setValue(PSAVEDSIZE);
|
||||
|
||||
// fix pseudo leaving artifacts
|
||||
g_pHyprRenderer->damageMonitor(pWindow->m_pMonitor.lock());
|
||||
@@ -762,16 +753,16 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
|
||||
|
||||
g_pCompositor->changeWindowZOrder(pWindow, true);
|
||||
|
||||
CBox wb = {pWindow->m_vRealPosition->goal() + (pWindow->m_vRealSize->goal() - pWindow->m_vLastFloatingSize) / 2.f, pWindow->m_vLastFloatingSize};
|
||||
CBox wb = {pWindow->m_vRealPosition.goal() + (pWindow->m_vRealSize.goal() - pWindow->m_vLastFloatingSize) / 2.f, pWindow->m_vLastFloatingSize};
|
||||
wb.round();
|
||||
|
||||
if (!(pWindow->m_bIsFloating && pWindow->m_bIsPseudotiled) && DELTALESSTHAN(pWindow->m_vRealSize->value().x, pWindow->m_vLastFloatingSize.x, 10) &&
|
||||
DELTALESSTHAN(pWindow->m_vRealSize->value().y, pWindow->m_vLastFloatingSize.y, 10)) {
|
||||
if (!(pWindow->m_bIsFloating && pWindow->m_bIsPseudotiled) && DELTALESSTHAN(pWindow->m_vRealSize.value().x, pWindow->m_vLastFloatingSize.x, 10) &&
|
||||
DELTALESSTHAN(pWindow->m_vRealSize.value().y, pWindow->m_vLastFloatingSize.y, 10)) {
|
||||
wb = {wb.pos() + Vector2D{10, 10}, wb.size() - Vector2D{20, 20}};
|
||||
}
|
||||
|
||||
*pWindow->m_vRealPosition = wb.pos();
|
||||
*pWindow->m_vRealSize = wb.size();
|
||||
pWindow->m_vRealPosition = wb.pos();
|
||||
pWindow->m_vRealSize = wb.size();
|
||||
|
||||
pWindow->m_vSize = wb.pos();
|
||||
pWindow->m_vPosition = wb.size();
|
||||
@@ -786,9 +777,8 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
|
||||
}
|
||||
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
|
||||
|
||||
pWindow->updateToplevel();
|
||||
pWindow->sendWindowSize(pWindow->m_vRealSize->goal());
|
||||
g_pHyprRenderer->damageWindow(pWindow);
|
||||
}
|
||||
|
||||
void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) {
|
||||
@@ -804,7 +794,7 @@ void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) {
|
||||
|
||||
PWINDOW->setAnimationsToMove();
|
||||
|
||||
*PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition->goal() + delta;
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + delta;
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ class CGradientValueData;
|
||||
|
||||
struct SWindowRenderLayoutHints {
|
||||
bool isBorderGradient = false;
|
||||
CGradientValueData* borderGradient = nullptr;
|
||||
CGradientValueData* borderGradient;
|
||||
};
|
||||
|
||||
struct SLayoutMessageHeader {
|
||||
|
@@ -4,10 +4,6 @@
|
||||
#include "config/ConfigDataValues.hpp"
|
||||
#include <ranges>
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
|
||||
SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(PHLWINDOW pWindow) {
|
||||
for (auto& nd : m_lMasterNodesData) {
|
||||
@@ -305,8 +301,8 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
const auto PFULLWINDOW = pWorkspace->getFullscreenWindow();
|
||||
|
||||
if (pWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) {
|
||||
*PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition;
|
||||
*PFULLWINDOW->m_vRealSize = PMONITOR->vecSize;
|
||||
PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition;
|
||||
PFULLWINDOW->m_vRealSize = PMONITOR->vecSize;
|
||||
} else if (pWorkspace->m_efFullscreenMode == FSMODE_MAXIMIZED) {
|
||||
SMasterNodeData fakeNode;
|
||||
fakeNode.pWindow = PFULLWINDOW;
|
||||
@@ -331,8 +327,7 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
|
||||
eOrientation orientation = getDynamicOrientation(pWorkspace);
|
||||
bool centerMasterWindow = false;
|
||||
static auto SLAVECOUNTFORCENTER = CConfigValue<Hyprlang::INT>("master:slave_count_for_center_master");
|
||||
static auto CMSLAVESONRIGHT = CConfigValue<Hyprlang::INT>("master:center_master_slaves_on_right");
|
||||
static auto ALWAYSCENTER = CConfigValue<Hyprlang::INT>("master:always_center_master");
|
||||
static auto PIGNORERESERVED = CConfigValue<Hyprlang::INT>("master:center_ignores_reserved");
|
||||
static auto PSMARTRESIZING = CConfigValue<Hyprlang::INT>("master:smart_resizing");
|
||||
|
||||
@@ -343,13 +338,10 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
const auto WSPOS = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
||||
|
||||
if (orientation == ORIENTATION_CENTER) {
|
||||
if (STACKWINDOWS >= *SLAVECOUNTFORCENTER) {
|
||||
if (STACKWINDOWS >= 2 || (*ALWAYSCENTER == 1)) {
|
||||
centerMasterWindow = true;
|
||||
} else {
|
||||
if (*CMSLAVESONRIGHT)
|
||||
orientation = ORIENTATION_LEFT;
|
||||
else
|
||||
orientation = ORIENTATION_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,20 +515,15 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
float nextY = 0;
|
||||
float nextYL = 0;
|
||||
float nextYR = 0;
|
||||
bool onRight = *CMSLAVESONRIGHT;
|
||||
int slavesLeftL = 1 + (slavesLeft - 1) / 2;
|
||||
int slavesLeftR = slavesLeft - slavesLeftL;
|
||||
bool onRight = true;
|
||||
|
||||
if (*CMSLAVESONRIGHT) {
|
||||
slavesLeftR = 1 + (slavesLeft - 1) / 2;
|
||||
slavesLeftL = slavesLeft - slavesLeftR;
|
||||
}
|
||||
int slavesLeftR = 1 + (slavesLeft - 1) / 2;
|
||||
int slavesLeftL = slavesLeft - slavesLeftR;
|
||||
|
||||
const float slaveAverageHeightL = WSSIZE.y / slavesLeftL;
|
||||
const float slaveAverageHeightR = WSSIZE.y / slavesLeftR;
|
||||
float slaveAccumulatedHeightL = 0;
|
||||
float slaveAccumulatedHeightR = 0;
|
||||
|
||||
if (*PSMARTRESIZING) {
|
||||
for (auto const& nd : m_lMasterNodesData) {
|
||||
if (nd.workspaceID != pWorkspace->m_iID || nd.isMaster)
|
||||
@@ -549,8 +536,7 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
}
|
||||
onRight = !onRight;
|
||||
}
|
||||
|
||||
onRight = *CMSLAVESONRIGHT;
|
||||
onRight = true;
|
||||
}
|
||||
|
||||
for (auto& nd : m_lMasterNodesData) {
|
||||
@@ -676,25 +662,25 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
CBox wb = {calcPos + (calcSize - calcSize * *PSCALEFACTOR) / 2.f, calcSize * *PSCALEFACTOR};
|
||||
wb.round(); // avoid rounding mess
|
||||
|
||||
*PWINDOW->m_vRealPosition = wb.pos();
|
||||
*PWINDOW->m_vRealSize = wb.size();
|
||||
PWINDOW->m_vRealPosition = wb.pos();
|
||||
PWINDOW->m_vRealSize = wb.size();
|
||||
|
||||
PWINDOW->sendWindowSize(wb.size());
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, wb.size());
|
||||
} else {
|
||||
CBox wb = {calcPos, calcSize};
|
||||
wb.round(); // avoid rounding mess
|
||||
|
||||
*PWINDOW->m_vRealPosition = wb.pos();
|
||||
*PWINDOW->m_vRealSize = wb.size();
|
||||
PWINDOW->m_vRealPosition = wb.pos();
|
||||
PWINDOW->m_vRealSize = wb.size();
|
||||
|
||||
PWINDOW->sendWindowSize(wb.size());
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, wb.size());
|
||||
}
|
||||
|
||||
if (m_bForceWarps && !*PANIMATE) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
|
||||
PWINDOW->m_vRealPosition->warp();
|
||||
PWINDOW->m_vRealSize->warp();
|
||||
PWINDOW->m_vRealPosition.warp();
|
||||
PWINDOW->m_vRealSize.warp();
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
@@ -715,17 +701,21 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
|
||||
if (!PNODE) {
|
||||
*PWINDOW->m_vRealSize =
|
||||
(PWINDOW->m_vRealSize->goal() + pixResize)
|
||||
PWINDOW->m_vRealSize =
|
||||
(PWINDOW->m_vRealSize.goal() + pixResize)
|
||||
.clamp(PWINDOW->m_sWindowData.minSize.valueOr(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), PWINDOW->m_sWindowData.maxSize.valueOr(Vector2D{INFINITY, INFINITY}));
|
||||
PWINDOW->updateWindowDecos();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
static auto SLAVECOUNTFORCENTER = CConfigValue<Hyprlang::INT>("master:slave_count_for_center_master");
|
||||
static auto ALWAYSCENTER = CConfigValue<Hyprlang::INT>("master:always_center_master");
|
||||
static auto PSMARTRESIZING = CConfigValue<Hyprlang::INT>("master:smart_resizing");
|
||||
|
||||
eOrientation orientation = getDynamicOrientation(PWINDOW->m_pWorkspace);
|
||||
bool centered = orientation == ORIENTATION_CENTER && (*ALWAYSCENTER == 1);
|
||||
double delta = 0;
|
||||
|
||||
const bool DISPLAYBOTTOM = STICKS(PWINDOW->m_vPosition.y + PWINDOW->m_vSize.y, PMONITOR->vecPosition.y + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y);
|
||||
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);
|
||||
@@ -739,10 +729,6 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
|
||||
const auto WINDOWS = getNodesOnWorkspace(PNODE->workspaceID);
|
||||
const auto STACKWINDOWS = WINDOWS - MASTERS;
|
||||
|
||||
eOrientation orientation = getDynamicOrientation(PWINDOW->m_pWorkspace);
|
||||
bool centered = orientation == ORIENTATION_CENTER && (STACKWINDOWS >= *SLAVECOUNTFORCENTER);
|
||||
double delta = 0;
|
||||
|
||||
if (getNodesOnWorkspace(PWINDOW->workspaceID()) == 1 && !centered)
|
||||
return;
|
||||
|
||||
@@ -755,7 +741,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
|
||||
case ORIENTATION_TOP: delta = pixResize.y / PMONITOR->vecSize.y; break;
|
||||
case ORIENTATION_CENTER:
|
||||
delta = pixResize.x / PMONITOR->vecSize.x;
|
||||
if (STACKWINDOWS >= *SLAVECOUNTFORCENTER) {
|
||||
if (WINDOWS > 2 || *ALWAYSCENTER) {
|
||||
if (!NONE || !PNODE->isMaster)
|
||||
delta *= 2;
|
||||
if ((!PNODE->isMaster && DISPLAYLEFT) || (PNODE->isMaster && LEFT && *PSMARTRESIZING))
|
||||
@@ -856,10 +842,10 @@ void CHyprMasterLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFul
|
||||
|
||||
// save position and size if floating
|
||||
if (pWindow->m_bIsFloating && CURRENT_EFFECTIVE_MODE == FSMODE_NONE) {
|
||||
pWindow->m_vLastFloatingSize = pWindow->m_vRealSize->goal();
|
||||
pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition->goal();
|
||||
pWindow->m_vPosition = pWindow->m_vRealPosition->goal();
|
||||
pWindow->m_vSize = pWindow->m_vRealSize->goal();
|
||||
pWindow->m_vLastFloatingSize = pWindow->m_vRealSize.goal();
|
||||
pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition.goal();
|
||||
pWindow->m_vPosition = pWindow->m_vRealPosition.goal();
|
||||
pWindow->m_vSize = pWindow->m_vRealSize.goal();
|
||||
}
|
||||
|
||||
if (EFFECTIVE_MODE == FSMODE_NONE) {
|
||||
@@ -869,8 +855,8 @@ void CHyprMasterLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFul
|
||||
applyNodeDataToWindow(PNODE);
|
||||
else {
|
||||
// get back its' dimensions from position and size
|
||||
*pWindow->m_vRealPosition = pWindow->m_vLastFloatingPosition;
|
||||
*pWindow->m_vRealSize = pWindow->m_vLastFloatingSize;
|
||||
pWindow->m_vRealPosition = pWindow->m_vLastFloatingPosition;
|
||||
pWindow->m_vRealSize = pWindow->m_vLastFloatingSize;
|
||||
|
||||
pWindow->unsetWindowData(PRIORITY_LAYOUT);
|
||||
pWindow->updateWindowData();
|
||||
@@ -878,8 +864,8 @@ void CHyprMasterLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFul
|
||||
} else {
|
||||
// apply new pos and size being monitors' box
|
||||
if (EFFECTIVE_MODE == FSMODE_FULLSCREEN) {
|
||||
*pWindow->m_vRealPosition = PMONITOR->vecPosition;
|
||||
*pWindow->m_vRealSize = PMONITOR->vecSize;
|
||||
pWindow->m_vRealPosition = PMONITOR->vecPosition;
|
||||
pWindow->m_vRealSize = PMONITOR->vecSize;
|
||||
} else {
|
||||
// This is a massive hack.
|
||||
// We make a fake "only" node and apply
|
||||
@@ -945,15 +931,6 @@ void CHyprMasterLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
|
||||
if (silent)
|
||||
g_pCompositor->focusWindow(PWINDOW2);
|
||||
}
|
||||
|
||||
pWindow->updateGroupOutputs();
|
||||
if (!pWindow->m_sGroupData.pNextWindow.expired()) {
|
||||
PHLWINDOW next = pWindow->m_sGroupData.pNextWindow.lock();
|
||||
while (next != pWindow) {
|
||||
next->updateToplevel();
|
||||
next = next->m_sGroupData.pNextWindow.lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprMasterLayout::switchWindows(PHLWINDOW pWindow, PHLWINDOW pWindow2) {
|
||||
@@ -1001,7 +978,7 @@ void CHyprMasterLayout::alterSplitRatio(PHLWINDOW pWindow, float ratio, bool exa
|
||||
recalculateMonitor(pWindow->monitorID());
|
||||
}
|
||||
|
||||
PHLWINDOW CHyprMasterLayout::getNextWindow(PHLWINDOW pWindow, bool next, bool loop) {
|
||||
PHLWINDOW CHyprMasterLayout::getNextWindow(PHLWINDOW pWindow, bool next) {
|
||||
if (!isWindowTiled(pWindow))
|
||||
return nullptr;
|
||||
|
||||
@@ -1020,13 +997,6 @@ PHLWINDOW CHyprMasterLayout::getNextWindow(PHLWINDOW pWindow, bool next, bool lo
|
||||
CANDIDATE =
|
||||
std::find_if(nodes.begin(), nodes.end(), [&](const auto& other) { return other != *PNODE && ISMASTER != other.isMaster && other.workspaceID == PNODE->workspaceID; });
|
||||
|
||||
if (CANDIDATE != nodes.end() && !loop) {
|
||||
if (CANDIDATE->isMaster && next)
|
||||
return nullptr;
|
||||
if (!CANDIDATE->isMaster && ISMASTER && !next)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return CANDIDATE == nodes.end() ? nullptr : CANDIDATE->pWindow.lock();
|
||||
}
|
||||
|
||||
@@ -1140,8 +1110,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
if (!PWINDOW)
|
||||
return 0;
|
||||
|
||||
const bool NOLOOP = vars.size() >= 2 && vars[1] == "noloop";
|
||||
const auto PNEXTWINDOW = getNextWindow(PWINDOW, true, !NOLOOP);
|
||||
const auto PNEXTWINDOW = getNextWindow(PWINDOW, true);
|
||||
switchToWindow(PNEXTWINDOW);
|
||||
} else if (command == "cycleprev") {
|
||||
const auto PWINDOW = header.pWindow;
|
||||
@@ -1149,8 +1118,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
if (!PWINDOW)
|
||||
return 0;
|
||||
|
||||
const bool NOLOOP = vars.size() >= 2 && vars[1] == "noloop";
|
||||
const auto PPREVWINDOW = getNextWindow(PWINDOW, false, !NOLOOP);
|
||||
const auto PPREVWINDOW = getNextWindow(PWINDOW, false);
|
||||
switchToWindow(PPREVWINDOW);
|
||||
} else if (command == "swapnext") {
|
||||
if (!validMapped(header.pWindow))
|
||||
@@ -1161,8 +1129,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
return 0;
|
||||
}
|
||||
|
||||
const bool NOLOOP = vars.size() >= 2 && vars[1] == "noloop";
|
||||
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true, !NOLOOP);
|
||||
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true);
|
||||
|
||||
if (PWINDOWTOSWAPWITH) {
|
||||
g_pCompositor->setWindowFullscreenInternal(header.pWindow, FSMODE_NONE);
|
||||
@@ -1178,8 +1145,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
return 0;
|
||||
}
|
||||
|
||||
const bool NOLOOP = vars.size() >= 2 && vars[1] == "noloop";
|
||||
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false, !NOLOOP);
|
||||
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false);
|
||||
|
||||
if (PWINDOWTOSWAPWITH) {
|
||||
g_pCompositor->setWindowFullscreenClient(header.pWindow, FSMODE_NONE);
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "IHyprLayout.hpp"
|
||||
#include "../desktop/DesktopTypes.hpp"
|
||||
#include "../helpers/varlist/VarList.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
@@ -87,7 +87,7 @@ class CHyprMasterLayout : public IHyprLayout {
|
||||
SMasterNodeData* getMasterNodeOnWorkspace(const WORKSPACEID&);
|
||||
SMasterWorkspaceData* getMasterWorkspaceData(const WORKSPACEID&);
|
||||
void calculateWorkspace(PHLWORKSPACE);
|
||||
PHLWINDOW getNextWindow(PHLWINDOW, bool, bool);
|
||||
PHLWINDOW getNextWindow(PHLWINDOW, bool);
|
||||
int getMastersOnWorkspace(const WORKSPACEID&);
|
||||
|
||||
friend struct SMasterNodeData;
|
||||
|
@@ -2,11 +2,9 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <csignal>
|
||||
#include <print>
|
||||
#include <utility>
|
||||
|
||||
#include "helpers/memory/Memory.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef HYPRLAND_DEBUG
|
||||
@@ -51,7 +49,7 @@
|
||||
Debug::log(CRIT, "\n==========================================================================================\nASSERTION FAILED! \n\n{}\n\nat: line {} in {}", \
|
||||
std::format(reason, ##__VA_ARGS__), __LINE__, \
|
||||
([]() constexpr -> std::string { return std::string(__FILE__).substr(std::string(__FILE__).find_last_of('/') + 1); })()); \
|
||||
std::print("Assertion failed! See the log in /tmp/hypr/hyprland.log for more info."); \
|
||||
printf("Assertion failed! See the log in /tmp/hypr/hyprland.log for more info."); \
|
||||
raise(SIGABRT); \
|
||||
}
|
||||
|
||||
@@ -114,6 +112,3 @@
|
||||
namespace Aquamarine { \
|
||||
class name; \
|
||||
}
|
||||
|
||||
#define UNLIKELY(expr) (expr) [[unlikely]]
|
||||
#define LIKELY(expr) (expr) [[likely]]
|
||||
|
19
src/main.cpp
19
src/main.cpp
@@ -18,7 +18,7 @@ using namespace Hyprutils::String;
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
static void help() {
|
||||
void help() {
|
||||
std::println("usage: Hyprland [arg [...]].\n");
|
||||
std::println(R"(Arguments:
|
||||
--help -h - Show this message again
|
||||
@@ -27,7 +27,6 @@ static void help() {
|
||||
--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?)
|
||||
--verify-config - Do not run Hyprland, only print if the config has any errors
|
||||
--version -v - Print this binary's version)");
|
||||
}
|
||||
|
||||
@@ -50,7 +49,7 @@ int main(int argc, char** argv) {
|
||||
std::string configPath;
|
||||
std::string socketName;
|
||||
int socketFd = -1;
|
||||
bool ignoreSudo = false, verifyConfig = false;
|
||||
bool ignoreSudo = false;
|
||||
|
||||
std::vector<std::string> args{argv + 1, argv + argc};
|
||||
|
||||
@@ -125,9 +124,6 @@ int main(int argc, char** argv) {
|
||||
} else if (*it == "--systeminfo") {
|
||||
std::println("{}", systemInfoRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, ""));
|
||||
return 0;
|
||||
} else if (*it == "--verify-config") {
|
||||
verifyConfig = true;
|
||||
continue;
|
||||
} else {
|
||||
std::println(stderr, "[ ERROR ] Unknown option '{}' !", *it);
|
||||
help();
|
||||
@@ -142,8 +138,9 @@ int main(int argc, char** argv) {
|
||||
" Hint: Use the --i-am-really-stupid flag to omit that check.");
|
||||
|
||||
return 1;
|
||||
} else if (ignoreSudo && NInit::isSudo())
|
||||
} else if (ignoreSudo && NInit::isSudo()) {
|
||||
std::println("Superuser privileges check is omitted. I hope you know what you're doing.");
|
||||
}
|
||||
|
||||
if (socketName.empty() ^ (socketFd == -1)) {
|
||||
std::println(stderr,
|
||||
@@ -153,13 +150,12 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!verifyConfig)
|
||||
std::println("Welcome to Hyprland!");
|
||||
|
||||
// let's init the compositor.
|
||||
// it initializes basic Wayland stuff in the constructor.
|
||||
try {
|
||||
g_pCompositor = makeUnique<CCompositor>(verifyConfig);
|
||||
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());
|
||||
@@ -168,9 +164,6 @@ int main(int argc, char** argv) {
|
||||
|
||||
g_pCompositor->initServer(socketName, socketFd);
|
||||
|
||||
if (verifyConfig)
|
||||
return !g_pConfigManager->m_bLastConfigVerificationWasSuccessful;
|
||||
|
||||
if (!envEnabled("HYPRLAND_NO_RT"))
|
||||
NInit::gainRealTime();
|
||||
|
||||
@@ -181,8 +174,6 @@ int main(int argc, char** argv) {
|
||||
|
||||
g_pCompositor->cleanup();
|
||||
|
||||
g_pCompositor.reset();
|
||||
|
||||
Debug::log(LOG, "Hyprland has reached the end.");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
@@ -1,22 +1,16 @@
|
||||
#include "AnimationManager.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "HookSystemManager.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../desktop/DesktopTypes.hpp"
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "macros.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "eventLoop/EventLoopManager.hpp"
|
||||
#include "../helpers/varlist/VarList.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
|
||||
#include <hyprgraphics/color/Color.hpp>
|
||||
#include <hyprutils/animation/AnimatedVariable.hpp>
|
||||
#include <hyprutils/animation/AnimationManager.hpp>
|
||||
|
||||
static int wlTick(SP<CEventLoopTimer> self, void* data) {
|
||||
int wlTick(SP<CEventLoopTimer> self, void* data) {
|
||||
if (g_pAnimationManager)
|
||||
g_pAnimationManager->onTicked();
|
||||
|
||||
@@ -32,77 +26,89 @@ static int wlTick(SP<CEventLoopTimer> self, void* data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CHyprAnimationManager::CHyprAnimationManager() {
|
||||
CAnimationManager::CAnimationManager() {
|
||||
std::vector<Vector2D> points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)};
|
||||
m_mBezierCurves["default"].setup(&points);
|
||||
|
||||
m_pAnimationTimer = SP<CEventLoopTimer>(new CEventLoopTimer(std::chrono::microseconds(500), wlTick, nullptr));
|
||||
if (g_pEventLoopManager) // null in --verify-config mode
|
||||
g_pEventLoopManager->addTimer(m_pAnimationTimer);
|
||||
|
||||
addBezierWithName("linear", Vector2D(0.0, 0.0), Vector2D(1.0, 1.0));
|
||||
}
|
||||
|
||||
template <Animable VarType>
|
||||
static void updateVariable(CAnimatedVariable<VarType>& av, const float POINTY, bool warp = false) {
|
||||
if (warp || av.value() == av.goal()) {
|
||||
av.warp();
|
||||
void CAnimationManager::removeAllBeziers() {
|
||||
m_mBezierCurves.clear();
|
||||
|
||||
// add the default one
|
||||
std::vector<Vector2D> points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)};
|
||||
m_mBezierCurves["default"].setup(&points);
|
||||
}
|
||||
|
||||
void CAnimationManager::addBezierWithName(std::string name, const Vector2D& p1, const Vector2D& p2) {
|
||||
std::vector points = {p1, p2};
|
||||
m_mBezierCurves[name].setup(&points);
|
||||
}
|
||||
|
||||
void CAnimationManager::onTicked() {
|
||||
m_bTickScheduled = false;
|
||||
}
|
||||
|
||||
void CAnimationManager::tick() {
|
||||
static std::chrono::time_point lastTick = std::chrono::high_resolution_clock::now();
|
||||
m_fLastTickTime = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - lastTick).count() / 1000.0;
|
||||
lastTick = std::chrono::high_resolution_clock::now();
|
||||
|
||||
if (m_vActiveAnimatedVariables.empty())
|
||||
return;
|
||||
|
||||
bool animGlobalDisabled = false;
|
||||
|
||||
static auto PANIMENABLED = CConfigValue<Hyprlang::INT>("animations:enabled");
|
||||
|
||||
if (!*PANIMENABLED)
|
||||
animGlobalDisabled = true;
|
||||
|
||||
static auto* const PSHADOWSENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:shadow:enabled");
|
||||
|
||||
const auto DEFAULTBEZIER = m_mBezierCurves.find("default");
|
||||
|
||||
std::vector<CBaseAnimatedVariable*> animationEndedVars;
|
||||
|
||||
for (auto const& av : m_vActiveAnimatedVariables) {
|
||||
|
||||
if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW && !*PSHADOWSENABLED) {
|
||||
av->warp(false);
|
||||
animationEndedVars.push_back(av);
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto DELTA = av.goal() - av.begun();
|
||||
av.value() = av.begun() + DELTA * POINTY;
|
||||
}
|
||||
// get the spent % (0 - 1)
|
||||
const float SPENT = av->getPercent();
|
||||
|
||||
static void updateColorVariable(CAnimatedVariable<CHyprColor>& av, const float POINTY, bool warp) {
|
||||
if (warp || av.value() == av.goal()) {
|
||||
av.warp();
|
||||
return;
|
||||
}
|
||||
|
||||
// convert both to OkLab, then lerp that, and convert back.
|
||||
// This is not as fast as just lerping rgb, but it's WAY more precise...
|
||||
// Use the CHyprColor cache for OkLab
|
||||
|
||||
const auto& L1 = av.begun().asOkLab();
|
||||
const auto& L2 = av.goal().asOkLab();
|
||||
|
||||
static const auto lerp = [](const float one, const float two, const float progress) -> float { return one + (two - one) * progress; };
|
||||
|
||||
const Hyprgraphics::CColor lerped = Hyprgraphics::CColor::SOkLab{
|
||||
.l = lerp(L1.l, L2.l, POINTY),
|
||||
.a = lerp(L1.a, L2.a, POINTY),
|
||||
.b = lerp(L1.b, L2.b, POINTY),
|
||||
};
|
||||
|
||||
av.value() = {lerped, lerp(av.begun().a, av.goal().a, POINTY)};
|
||||
}
|
||||
|
||||
template <Animable VarType>
|
||||
static void handleUpdate(CAnimatedVariable<VarType>& av, bool warp) {
|
||||
PHLWINDOW PWINDOW = av.m_Context.pWindow.lock();
|
||||
PHLWORKSPACE PWORKSPACE = av.m_Context.pWorkspace.lock();
|
||||
PHLLS PLAYER = av.m_Context.pLayer.lock();
|
||||
// window stuff
|
||||
PHLWINDOW PWINDOW = av->m_pWindow.lock();
|
||||
PHLWORKSPACE PWORKSPACE = av->m_pWorkspace.lock();
|
||||
PHLLS PLAYER = av->m_pLayer.lock();
|
||||
PHLMONITOR PMONITOR = nullptr;
|
||||
bool animationsDisabled = warp;
|
||||
bool animationsDisabled = animGlobalDisabled;
|
||||
|
||||
if (PWINDOW) {
|
||||
if (av.m_Context.eDamagePolicy == AVARDAMAGE_ENTIRE)
|
||||
if (av->m_eDamagePolicy == AVARDAMAGE_ENTIRE) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
else if (av.m_Context.eDamagePolicy == AVARDAMAGE_BORDER) {
|
||||
} else if (av->m_eDamagePolicy == AVARDAMAGE_BORDER) {
|
||||
const auto PDECO = PWINDOW->getDecorationByType(DECORATION_BORDER);
|
||||
PDECO->damageEntire();
|
||||
} else if (av.m_Context.eDamagePolicy == AVARDAMAGE_SHADOW) {
|
||||
} else if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW) {
|
||||
const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW);
|
||||
PDECO->damageEntire();
|
||||
}
|
||||
|
||||
PMONITOR = PWINDOW->m_pMonitor.lock();
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
|
||||
continue;
|
||||
animationsDisabled = PWINDOW->m_sWindowData.noAnim.valueOr(animationsDisabled);
|
||||
} else if (PWORKSPACE) {
|
||||
PMONITOR = PWORKSPACE->m_pMonitor.lock();
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
continue;
|
||||
|
||||
// dont damage the whole monitor on workspace change, unless it's a special workspace, because dim/blur etc
|
||||
if (PWORKSPACE->m_bIsSpecialWorkspace)
|
||||
@@ -135,29 +141,113 @@ static void handleUpdate(CAnimatedVariable<VarType>& av, bool warp) {
|
||||
}
|
||||
} else if (PLAYER) {
|
||||
// "some fucking layers miss 1 pixel???" -- vaxry
|
||||
CBox expandBox = CBox{PLAYER->realPosition->value(), PLAYER->realSize->value()};
|
||||
CBox expandBox = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()};
|
||||
expandBox.expand(5);
|
||||
g_pHyprRenderer->damageBox(expandBox);
|
||||
g_pHyprRenderer->damageBox(&expandBox);
|
||||
|
||||
PMONITOR = g_pCompositor->getMonitorFromVector(PLAYER->realPosition->goal() + PLAYER->realSize->goal() / 2.F);
|
||||
PMONITOR = g_pCompositor->getMonitorFromVector(PLAYER->realPosition.goal() + PLAYER->realSize.goal() / 2.F);
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
continue;
|
||||
animationsDisabled = animationsDisabled || PLAYER->noAnimations;
|
||||
}
|
||||
|
||||
const auto SPENT = av.getPercent();
|
||||
const auto PBEZIER = g_pAnimationManager->getBezier(av.getBezierName());
|
||||
const auto POINTY = PBEZIER->getYForPoint(SPENT);
|
||||
const bool WARP = animationsDisabled || SPENT >= 1.f;
|
||||
const bool VISIBLE = PWINDOW && PWINDOW->m_pWorkspace ? PWINDOW->m_pWorkspace->isVisible() : true;
|
||||
|
||||
if constexpr (std::same_as<VarType, CHyprColor>)
|
||||
updateColorVariable(av, POINTY, WARP);
|
||||
// beziers are with a switch unforto
|
||||
// TODO: maybe do something cleaner
|
||||
|
||||
static const auto updateVariable = [this]<Animable T>(CAnimatedVariable<T>& av, const float SPENT, const CBezierCurve& DEFAULTBEZIER, const bool DISABLED) {
|
||||
// for disabled anims just warp
|
||||
if (av.m_pConfig->pValues->internalEnabled == 0 || DISABLED) {
|
||||
av.warp(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SPENT >= 1.f || av.m_Begun == av.m_Goal) {
|
||||
av.warp(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto BEZIER = m_mBezierCurves.find(av.m_pConfig->pValues->internalBezier);
|
||||
const auto POINTY = BEZIER != m_mBezierCurves.end() ? BEZIER->second.getYForPoint(SPENT) : DEFAULTBEZIER.getYForPoint(SPENT);
|
||||
|
||||
const auto DELTA = av.m_Goal - av.m_Begun;
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av.m_Value = av.m_Begun + DELTA * POINTY;
|
||||
else
|
||||
updateVariable<VarType>(av, POINTY, WARP);
|
||||
av.m_Value = av.m_Begun + DELTA * POINTY;
|
||||
};
|
||||
|
||||
av.onUpdate();
|
||||
static const auto updateColorVariable = [this](CAnimatedVariable<CHyprColor>& av, const float SPENT, const CBezierCurve& DEFAULTBEZIER, const bool DISABLED) {
|
||||
// for disabled anims just warp
|
||||
if (av.m_pConfig->pValues->internalEnabled == 0 || DISABLED) {
|
||||
av.warp(false);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (av.m_Context.eDamagePolicy) {
|
||||
if (SPENT >= 1.f || av.m_Begun == av.m_Goal) {
|
||||
av.warp(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto BEZIER = m_mBezierCurves.find(av.m_pConfig->pValues->internalBezier);
|
||||
const auto POINTY = BEZIER != m_mBezierCurves.end() ? BEZIER->second.getYForPoint(SPENT) : DEFAULTBEZIER.getYForPoint(SPENT);
|
||||
|
||||
// convert both to OkLab, then lerp that, and convert back.
|
||||
// This is not as fast as just lerping rgb, but it's WAY more precise...
|
||||
// Use the CHyprColor cache for OkLab
|
||||
|
||||
const auto& L1 = av.m_Begun.asOkLab();
|
||||
const auto& L2 = av.m_Goal.asOkLab();
|
||||
|
||||
static const auto lerp = [](const float one, const float two, const float progress) -> float { return one + (two - one) * progress; };
|
||||
|
||||
const Hyprgraphics::CColor lerped = Hyprgraphics::CColor::SOkLab{
|
||||
.l = lerp(L1.l, L2.l, POINTY),
|
||||
.a = lerp(L1.a, L2.a, POINTY),
|
||||
.b = lerp(L1.b, L2.b, POINTY),
|
||||
};
|
||||
|
||||
av.m_Value = {lerped, lerp(av.m_Begun.a, av.m_Goal.a, POINTY)};
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
switch (av->m_Type) {
|
||||
case AVARTYPE_FLOAT: {
|
||||
auto typedAv = dynamic_cast<CAnimatedVariable<float>*>(av);
|
||||
updateVariable(*typedAv, SPENT, DEFAULTBEZIER->second, animationsDisabled);
|
||||
break;
|
||||
}
|
||||
case AVARTYPE_VECTOR: {
|
||||
auto typedAv = dynamic_cast<CAnimatedVariable<Vector2D>*>(av);
|
||||
updateVariable(*typedAv, SPENT, DEFAULTBEZIER->second, animationsDisabled);
|
||||
break;
|
||||
}
|
||||
case AVARTYPE_COLOR: {
|
||||
auto typedAv = dynamic_cast<CAnimatedVariable<CHyprColor>*>(av);
|
||||
updateColorVariable(*typedAv, SPENT, DEFAULTBEZIER->second, animationsDisabled);
|
||||
break;
|
||||
}
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
// set size and pos if valid, but only if damage policy entire (dont if border for example)
|
||||
if (validMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE && !PWINDOW->isX11OverrideRedirect())
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
|
||||
|
||||
// check if we did not finish animating. If so, trigger onAnimationEnd.
|
||||
if (!av->isBeingAnimated())
|
||||
animationEndedVars.push_back(av);
|
||||
|
||||
// lastly, handle damage, but only if whatever we are animating is visible.
|
||||
if (!VISIBLE)
|
||||
continue;
|
||||
|
||||
if (av->m_fUpdateCallback)
|
||||
av->m_fUpdateCallback(av);
|
||||
|
||||
switch (av->m_eDamagePolicy) {
|
||||
case AVARDAMAGE_ENTIRE: {
|
||||
if (PWINDOW) {
|
||||
PWINDOW->updateWindowDecos();
|
||||
@@ -178,9 +268,9 @@ static void handleUpdate(CAnimatedVariable<VarType>& av, bool warp) {
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR);
|
||||
|
||||
// some fucking layers miss 1 pixel???
|
||||
CBox expandBox = CBox{PLAYER->realPosition->value(), PLAYER->realSize->value()};
|
||||
CBox expandBox = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()};
|
||||
expandBox.expand(5);
|
||||
g_pHyprRenderer->damageBox(expandBox);
|
||||
g_pHyprRenderer->damageBox(&expandBox);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -211,68 +301,43 @@ static void handleUpdate(CAnimatedVariable<VarType>& av, bool warp) {
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_ANIMATION);
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::tick() {
|
||||
static std::chrono::time_point lastTick = std::chrono::high_resolution_clock::now();
|
||||
m_fLastTickTime = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - lastTick).count() / 1000.0;
|
||||
lastTick = std::chrono::high_resolution_clock::now();
|
||||
|
||||
static auto PANIMENABLED = CConfigValue<Hyprlang::INT>("animations:enabled");
|
||||
|
||||
for (size_t i = 0; i < m_vActiveAnimatedVariables.size(); i++) {
|
||||
const auto PAV = m_vActiveAnimatedVariables[i].lock();
|
||||
if (!PAV)
|
||||
continue;
|
||||
|
||||
// for disabled anims just warp
|
||||
bool warp = !*PANIMENABLED || !PAV->enabled();
|
||||
|
||||
switch (PAV->m_Type) {
|
||||
case AVARTYPE_FLOAT: {
|
||||
auto pTypedAV = dynamic_cast<CAnimatedVariable<float>*>(PAV.get());
|
||||
RASSERT(pTypedAV, "Failed to upcast animated float");
|
||||
handleUpdate(*pTypedAV, warp);
|
||||
} break;
|
||||
case AVARTYPE_VECTOR: {
|
||||
auto pTypedAV = dynamic_cast<CAnimatedVariable<Vector2D>*>(PAV.get());
|
||||
RASSERT(pTypedAV, "Failed to upcast animated Vector2D");
|
||||
handleUpdate(*pTypedAV, warp);
|
||||
} break;
|
||||
case AVARTYPE_COLOR: {
|
||||
auto pTypedAV = dynamic_cast<CAnimatedVariable<CHyprColor>*>(PAV.get());
|
||||
RASSERT(pTypedAV, "Failed to upcast animated CHyprColor");
|
||||
handleUpdate(*pTypedAV, warp);
|
||||
} break;
|
||||
default: UNREACHABLE();
|
||||
// do it here, because if this alters the animation vars vec we would be in trouble above.
|
||||
for (auto const& ave : animationEndedVars) {
|
||||
ave->onAnimationEnd();
|
||||
}
|
||||
}
|
||||
|
||||
tickDone();
|
||||
bool CAnimationManager::deltaSmallToFlip(const Vector2D& a, const Vector2D& b) {
|
||||
return std::abs(a.x - b.x) < 0.5f && std::abs(a.y - b.y) < 0.5f;
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::scheduleTick() {
|
||||
if (m_bTickScheduled)
|
||||
return;
|
||||
|
||||
m_bTickScheduled = true;
|
||||
|
||||
const auto PMOSTHZ = g_pHyprRenderer->m_pMostHzMonitor;
|
||||
|
||||
if (!PMOSTHZ) {
|
||||
m_pAnimationTimer->updateTimeout(std::chrono::milliseconds(16));
|
||||
return;
|
||||
bool CAnimationManager::deltaSmallToFlip(const CHyprColor& a, const CHyprColor& b) {
|
||||
return std::abs(a.r - b.r) < 0.5f && std::abs(a.g - b.g) < 0.5f && std::abs(a.b - b.b) < 0.5f && std::abs(a.a - b.a) < 0.5f;
|
||||
}
|
||||
|
||||
float refreshDelayMs = std::floor(1000.f / PMOSTHZ->refreshRate);
|
||||
|
||||
const float SINCEPRES = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - PMOSTHZ->lastPresentationTimer.chrono()).count() / 1000.f;
|
||||
|
||||
const auto TOPRES = std::clamp(refreshDelayMs - SINCEPRES, 1.1f, 1000.f); // we can't send 0, that will disarm it
|
||||
|
||||
m_pAnimationTimer->updateTimeout(std::chrono::milliseconds((int)std::floor(TOPRES)));
|
||||
bool CAnimationManager::deltaSmallToFlip(const float& a, const float& b) {
|
||||
return std::abs(a - b) < 0.5f;
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::onTicked() {
|
||||
m_bTickScheduled = false;
|
||||
bool CAnimationManager::deltazero(const Vector2D& a, const Vector2D& b) {
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
bool CAnimationManager::deltazero(const float& a, const float& b) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
bool CAnimationManager::deltazero(const CHyprColor& a, const CHyprColor& b) {
|
||||
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
|
||||
}
|
||||
|
||||
bool CAnimationManager::bezierExists(const std::string& bezier) {
|
||||
for (auto const& [bc, bz] : m_mBezierCurves) {
|
||||
if (bc == bezier)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -280,24 +345,24 @@ void CHyprAnimationManager::onTicked() {
|
||||
//
|
||||
//
|
||||
|
||||
void CHyprAnimationManager::animationPopin(PHLWINDOW pWindow, bool close, float minPerc) {
|
||||
const auto GOALPOS = pWindow->m_vRealPosition->goal();
|
||||
const auto GOALSIZE = pWindow->m_vRealSize->goal();
|
||||
void CAnimationManager::animationPopin(PHLWINDOW pWindow, bool close, float minPerc) {
|
||||
const auto GOALPOS = pWindow->m_vRealPosition.goal();
|
||||
const auto GOALSIZE = pWindow->m_vRealSize.goal();
|
||||
|
||||
if (!close) {
|
||||
pWindow->m_vRealSize->setValue((GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y}));
|
||||
pWindow->m_vRealPosition->setValue(GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize->value() / 2.f);
|
||||
pWindow->m_vRealSize.setValue((GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y}));
|
||||
pWindow->m_vRealPosition.setValue(GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize.m_Value / 2.f);
|
||||
} else {
|
||||
*pWindow->m_vRealSize = (GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y});
|
||||
*pWindow->m_vRealPosition = GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize->goal() / 2.f;
|
||||
pWindow->m_vRealSize = (GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y});
|
||||
pWindow->m_vRealPosition = GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize.m_Goal / 2.f;
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, bool close) {
|
||||
pWindow->m_vRealSize->warp(false); // size we preserve in slide
|
||||
void CAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, bool close) {
|
||||
pWindow->m_vRealSize.warp(false); // size we preserve in slide
|
||||
|
||||
const auto GOALPOS = pWindow->m_vRealPosition->goal();
|
||||
const auto GOALSIZE = pWindow->m_vRealSize->goal();
|
||||
const auto GOALPOS = pWindow->m_vRealPosition.goal();
|
||||
const auto GOALSIZE = pWindow->m_vRealSize.goal();
|
||||
|
||||
const auto PMONITOR = pWindow->m_pMonitor.lock();
|
||||
|
||||
@@ -317,9 +382,9 @@ void CHyprAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force,
|
||||
posOffset = Vector2D(GOALPOS.x, PMONITOR->vecPosition.y - GOALSIZE.y);
|
||||
|
||||
if (!close)
|
||||
pWindow->m_vRealPosition->setValue(posOffset);
|
||||
pWindow->m_vRealPosition.setValue(posOffset);
|
||||
else
|
||||
*pWindow->m_vRealPosition = posOffset;
|
||||
pWindow->m_vRealPosition = posOffset;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -352,33 +417,33 @@ void CHyprAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force,
|
||||
}
|
||||
|
||||
if (!close)
|
||||
pWindow->m_vRealPosition->setValue(posOffset);
|
||||
pWindow->m_vRealPosition.setValue(posOffset);
|
||||
else
|
||||
*pWindow->m_vRealPosition = posOffset;
|
||||
pWindow->m_vRealPosition = posOffset;
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool close) {
|
||||
void CAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool close) {
|
||||
if (!close) {
|
||||
pWindow->m_vRealPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsIn"));
|
||||
pWindow->m_vRealSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsIn"));
|
||||
pWindow->m_fAlpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn"));
|
||||
pWindow->m_vRealPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsIn");
|
||||
pWindow->m_vRealSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsIn");
|
||||
pWindow->m_fAlpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeIn");
|
||||
} else {
|
||||
pWindow->m_vRealPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsOut"));
|
||||
pWindow->m_vRealSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsOut"));
|
||||
pWindow->m_fAlpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut"));
|
||||
pWindow->m_vRealPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsOut");
|
||||
pWindow->m_vRealSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsOut");
|
||||
pWindow->m_fAlpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeOut");
|
||||
}
|
||||
|
||||
std::string ANIMSTYLE = pWindow->m_vRealPosition->getStyle();
|
||||
auto ANIMSTYLE = pWindow->m_vRealPosition.m_pConfig->pValues->internalStyle;
|
||||
transform(ANIMSTYLE.begin(), ANIMSTYLE.end(), ANIMSTYLE.begin(), ::tolower);
|
||||
|
||||
CVarList animList(ANIMSTYLE, 0, 's');
|
||||
|
||||
// if the window is not being animated, that means the layout set a fixed size for it, don't animate.
|
||||
if (!pWindow->m_vRealPosition->isBeingAnimated() && !pWindow->m_vRealSize->isBeingAnimated())
|
||||
if (!pWindow->m_vRealPosition.isBeingAnimated() && !pWindow->m_vRealSize.isBeingAnimated())
|
||||
return;
|
||||
|
||||
// if the animation is disabled and we are leaving, ignore the anim to prevent the snapshot being fucked
|
||||
if (!pWindow->m_vRealPosition->enabled())
|
||||
if (!pWindow->m_vRealPosition.m_pConfig->pValues->internalEnabled)
|
||||
return;
|
||||
|
||||
if (pWindow->m_sWindowData.animationStyle.hasValue()) {
|
||||
@@ -423,7 +488,7 @@ void CHyprAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool clos
|
||||
}
|
||||
}
|
||||
|
||||
std::string CHyprAnimationManager::styleValidInConfigVar(const std::string& config, const std::string& style) {
|
||||
std::string CAnimationManager::styleValidInConfigVar(const std::string& config, const std::string& style) {
|
||||
if (config.starts_with("window")) {
|
||||
if (style.starts_with("slide"))
|
||||
return "";
|
||||
@@ -497,3 +562,39 @@ std::string CHyprAnimationManager::styleValidInConfigVar(const std::string& conf
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
CBezierCurve* CAnimationManager::getBezier(const std::string& name) {
|
||||
const auto BEZIER = std::find_if(m_mBezierCurves.begin(), m_mBezierCurves.end(), [&](const auto& other) { return other.first == name; });
|
||||
|
||||
return BEZIER == m_mBezierCurves.end() ? &m_mBezierCurves["default"] : &BEZIER->second;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, CBezierCurve> CAnimationManager::getAllBeziers() {
|
||||
return m_mBezierCurves;
|
||||
}
|
||||
|
||||
bool CAnimationManager::shouldTickForNext() {
|
||||
return !m_vActiveAnimatedVariables.empty();
|
||||
}
|
||||
|
||||
void CAnimationManager::scheduleTick() {
|
||||
if (m_bTickScheduled)
|
||||
return;
|
||||
|
||||
m_bTickScheduled = true;
|
||||
|
||||
const auto PMOSTHZ = g_pHyprRenderer->m_pMostHzMonitor;
|
||||
|
||||
if (!PMOSTHZ) {
|
||||
m_pAnimationTimer->updateTimeout(std::chrono::milliseconds(16));
|
||||
return;
|
||||
}
|
||||
|
||||
float refreshDelayMs = std::floor(1000.f / PMOSTHZ->refreshRate);
|
||||
|
||||
const float SINCEPRES = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - PMOSTHZ->lastPresentationTimer.chrono()).count() / 1000.f;
|
||||
|
||||
const auto TOPRES = std::clamp(refreshDelayMs - SINCEPRES, 1.1f, 1000.f); // we can't send 0, that will disarm it
|
||||
|
||||
m_pAnimationTimer->updateTimeout(std::chrono::milliseconds((int)std::floor(TOPRES)));
|
||||
}
|
||||
|
@@ -1,59 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <hyprutils/animation/AnimationManager.hpp>
|
||||
#include <hyprutils/animation/AnimatedVariable.hpp>
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
#include "../desktop/DesktopTypes.hpp"
|
||||
#include "../helpers/BezierCurve.hpp"
|
||||
#include "../helpers/Timer.hpp"
|
||||
#include "eventLoop/EventLoopTimer.hpp"
|
||||
|
||||
class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
||||
class CWindow;
|
||||
|
||||
class CAnimationManager {
|
||||
public:
|
||||
CHyprAnimationManager();
|
||||
CAnimationManager();
|
||||
|
||||
void tick();
|
||||
virtual void scheduleTick();
|
||||
virtual void onTicked();
|
||||
|
||||
using SAnimationPropertyConfig = Hyprutils::Animation::SAnimationPropertyConfig;
|
||||
template <Animable VarType>
|
||||
void createAnimation(const VarType& v, PHLANIMVAR<VarType>& pav, SP<SAnimationPropertyConfig> pConfig, eAVarDamagePolicy policy) {
|
||||
constexpr const eAnimatedVarType EAVTYPE = typeToeAnimatedVarType<VarType>;
|
||||
const auto PAV = makeShared<CAnimatedVariable<VarType>>();
|
||||
|
||||
PAV->create(EAVTYPE, static_cast<Hyprutils::Animation::CAnimationManager*>(this), PAV, v);
|
||||
PAV->setConfig(pConfig);
|
||||
PAV->m_Context.eDamagePolicy = policy;
|
||||
|
||||
pav = std::move(PAV);
|
||||
}
|
||||
|
||||
template <Animable VarType>
|
||||
void createAnimation(const VarType& v, PHLANIMVAR<VarType>& pav, SP<SAnimationPropertyConfig> pConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy) {
|
||||
createAnimation(v, pav, pConfig, policy);
|
||||
pav->m_Context.pWindow = pWindow;
|
||||
}
|
||||
template <Animable VarType>
|
||||
void createAnimation(const VarType& v, PHLANIMVAR<VarType>& pav, SP<SAnimationPropertyConfig> pConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy) {
|
||||
createAnimation(v, pav, pConfig, policy);
|
||||
pav->m_Context.pWorkspace = pWorkspace;
|
||||
}
|
||||
template <Animable VarType>
|
||||
void createAnimation(const VarType& v, PHLANIMVAR<VarType>& pav, SP<SAnimationPropertyConfig> pConfig, PHLLS pLayer, eAVarDamagePolicy policy) {
|
||||
createAnimation(v, pav, pConfig, policy);
|
||||
pav->m_Context.pLayer = pLayer;
|
||||
}
|
||||
bool shouldTickForNext();
|
||||
void onTicked();
|
||||
void scheduleTick();
|
||||
void addBezierWithName(std::string, const Vector2D&, const Vector2D&);
|
||||
void removeAllBeziers();
|
||||
|
||||
void onWindowPostCreateClose(PHLWINDOW, bool close = false);
|
||||
|
||||
bool bezierExists(const std::string&);
|
||||
CBezierCurve* getBezier(const std::string&);
|
||||
|
||||
std::string styleValidInConfigVar(const std::string&, const std::string&);
|
||||
|
||||
std::unordered_map<std::string, CBezierCurve> getAllBeziers();
|
||||
|
||||
std::vector<CBaseAnimatedVariable*> m_vAnimatedVariables;
|
||||
std::vector<CBaseAnimatedVariable*> m_vActiveAnimatedVariables;
|
||||
|
||||
SP<CEventLoopTimer> m_pAnimationTimer;
|
||||
|
||||
float m_fLastTickTime; // in ms
|
||||
|
||||
private:
|
||||
bool deltaSmallToFlip(const Vector2D& a, const Vector2D& b);
|
||||
bool deltaSmallToFlip(const CHyprColor& a, const CHyprColor& b);
|
||||
bool deltaSmallToFlip(const float& a, const float& b);
|
||||
bool deltazero(const Vector2D& a, const Vector2D& b);
|
||||
bool deltazero(const CHyprColor& a, const CHyprColor& b);
|
||||
bool deltazero(const float& a, const float& b);
|
||||
|
||||
std::unordered_map<std::string, CBezierCurve> m_mBezierCurves;
|
||||
|
||||
bool m_bTickScheduled = false;
|
||||
|
||||
// Anim stuff
|
||||
@@ -61,4 +54,4 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
||||
void animationSlide(PHLWINDOW, std::string force = "", bool close = false);
|
||||
};
|
||||
|
||||
inline UP<CHyprAnimationManager> g_pAnimationManager;
|
||||
inline std::unique_ptr<CAnimationManager> g_pAnimationManager;
|
||||
|
@@ -3,7 +3,6 @@
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "PointerManager.hpp"
|
||||
#include "../xwayland/XWayland.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
|
||||
static int cursorAnimTimer(SP<CEventLoopTimer> self, void* data) {
|
||||
const auto cursorMgr = reinterpret_cast<CCursorManager*>(data);
|
||||
@@ -64,8 +63,8 @@ void CCursorBuffer::endDataPtr() {
|
||||
}
|
||||
|
||||
CCursorManager::CCursorManager() {
|
||||
m_pHyprcursor = makeUnique<Hyprcursor::CHyprcursorManager>(m_szTheme.empty() ? nullptr : m_szTheme.c_str(), hcLogger);
|
||||
m_pXcursor = makeUnique<CXCursorManager>();
|
||||
m_pHyprcursor = std::make_unique<Hyprcursor::CHyprcursorManager>(m_szTheme.empty() ? nullptr : m_szTheme.c_str(), hcLogger);
|
||||
m_pXcursor = std::make_unique<CXCursorManager>();
|
||||
static auto PUSEHYPRCURSOR = CConfigValue<Hyprlang::INT>("cursor:enable_hyprcursor");
|
||||
|
||||
if (m_pHyprcursor->valid() && *PUSEHYPRCURSOR) {
|
||||
@@ -323,7 +322,7 @@ bool CCursorManager::changeTheme(const std::string& name, const int size) {
|
||||
m_szTheme = name.empty() ? "" : name;
|
||||
m_iSize = size;
|
||||
|
||||
m_pHyprcursor = makeUnique<Hyprcursor::CHyprcursorManager>(m_szTheme.empty() ? nullptr : m_szTheme.c_str(), options);
|
||||
m_pHyprcursor = std::make_unique<Hyprcursor::CHyprcursorManager>(m_szTheme.empty() ? nullptr : m_szTheme.c_str(), options);
|
||||
if (!m_pHyprcursor->valid()) {
|
||||
Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to XCursor.", m_szTheme);
|
||||
m_pXcursor->loadTheme(m_szTheme.empty() ? xcursor_theme : m_szTheme, m_iSize, m_fCursorScale);
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <hyprcursor/hyprcursor.hpp>
|
||||
#include <memory>
|
||||
#include "../includes.hpp"
|
||||
#include "../helpers/math/Math.hpp"
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
@@ -60,8 +61,8 @@ class CCursorManager {
|
||||
bool m_bOurBufferConnected = false;
|
||||
std::vector<SP<CCursorBuffer>> m_vCursorBuffers;
|
||||
|
||||
UP<Hyprcursor::CHyprcursorManager> m_pHyprcursor;
|
||||
UP<CXCursorManager> m_pXcursor;
|
||||
std::unique_ptr<Hyprcursor::CHyprcursorManager> m_pHyprcursor;
|
||||
std::unique_ptr<CXCursorManager> m_pXcursor;
|
||||
SP<SXCursors> m_currentXcursor;
|
||||
|
||||
std::string m_szTheme = "";
|
||||
@@ -75,4 +76,4 @@ class CCursorManager {
|
||||
Hyprcursor::SCursorShapeData m_sCurrentCursorShapeData;
|
||||
};
|
||||
|
||||
inline UP<CCursorManager> g_pCursorManager;
|
||||
inline std::unique_ptr<CCursorManager> g_pCursorManager;
|
||||
|
@@ -1,114 +0,0 @@
|
||||
#include "DonationNagManager.hpp"
|
||||
#include "../debug/Log.hpp"
|
||||
#include "VersionKeeperManager.hpp"
|
||||
#include "eventLoop/EventLoopManager.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <format>
|
||||
|
||||
#include "../helpers/fs/FsUtils.hpp"
|
||||
|
||||
#include <hyprutils/os/Process.hpp>
|
||||
using namespace Hyprutils::OS;
|
||||
|
||||
constexpr const char* LAST_NAG_FILE_NAME = "lastNag";
|
||||
constexpr uint64_t DAY_IN_SECONDS = 3600ULL * 24;
|
||||
constexpr uint64_t MONTH_IN_SECONDS = DAY_IN_SECONDS * 30;
|
||||
|
||||
struct SNagDatePoint {
|
||||
// Counted from 1, as in Jan 1st is 1, 1
|
||||
// No month-boundaries because I am lazy
|
||||
uint8_t month = 0, dayStart = 0, dayEnd = 0;
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
const std::vector<SNagDatePoint> NAG_DATE_POINTS = {
|
||||
SNagDatePoint {
|
||||
7, 20, 31,
|
||||
},
|
||||
SNagDatePoint {
|
||||
12, 1, 28
|
||||
},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
CDonationNagManager::CDonationNagManager() {
|
||||
static auto PNONAG = CConfigValue<Hyprlang::INT>("ecosystem:no_donation_nag");
|
||||
|
||||
if (g_pVersionKeeperMgr->fired() || *PNONAG)
|
||||
return;
|
||||
|
||||
const auto DATAROOT = NFsUtils::getDataHome();
|
||||
|
||||
if (!DATAROOT)
|
||||
return;
|
||||
|
||||
const auto EPOCH = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
|
||||
const auto LASTNAGSTR = NFsUtils::readFileAsString(*DATAROOT + "/" + LAST_NAG_FILE_NAME);
|
||||
|
||||
if (!LASTNAGSTR) {
|
||||
const auto EPOCHSTR = std::format("{}", EPOCH);
|
||||
NFsUtils::writeToFile(*DATAROOT + "/" + LAST_NAG_FILE_NAME, EPOCHSTR);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t LAST_EPOCH = 0;
|
||||
|
||||
try {
|
||||
LAST_EPOCH = std::stoull(*LASTNAGSTR);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "DonationNag: Last epoch invalid? Failed to parse \"{}\". Setting to today.", *LASTNAGSTR);
|
||||
const auto EPOCHSTR = std::format("{}", EPOCH);
|
||||
NFsUtils::writeToFile(*DATAROOT + "/" + LAST_NAG_FILE_NAME, EPOCHSTR);
|
||||
return;
|
||||
}
|
||||
|
||||
// don't nag if the last nag was less than a month ago. This is
|
||||
// mostly for first-time nags, as other nags happen in specific time frames shorter than a month
|
||||
if (EPOCH - LAST_EPOCH < MONTH_IN_SECONDS) {
|
||||
Debug::log(LOG, "DonationNag: last nag was {} days ago, too early for a nag.", (int)std::round((EPOCH - LAST_EPOCH) / (double)MONTH_IN_SECONDS));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!NFsUtils::executableExistsInPath("hyprland-donate-screen")) {
|
||||
Debug::log(ERR, "DonationNag: executable doesn't exist, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
auto local = *localtime(&tt);
|
||||
|
||||
const auto MONTH = local.tm_mon + 1;
|
||||
const auto DAY = local.tm_mday;
|
||||
|
||||
for (const auto& nagPoint : NAG_DATE_POINTS) {
|
||||
if (MONTH != nagPoint.month)
|
||||
continue;
|
||||
|
||||
if (DAY < nagPoint.dayStart || DAY > nagPoint.dayEnd)
|
||||
continue;
|
||||
|
||||
Debug::log(LOG, "DonationNag: hit nag month {} days {}-{}, it's {} today, nagging", MONTH, nagPoint.dayStart, nagPoint.dayEnd, DAY);
|
||||
|
||||
m_bFired = true;
|
||||
|
||||
const auto EPOCHSTR = std::format("{}", EPOCH);
|
||||
NFsUtils::writeToFile(*DATAROOT + "/" + LAST_NAG_FILE_NAME, EPOCHSTR);
|
||||
|
||||
g_pEventLoopManager->doLater([] {
|
||||
CProcess proc("hyprland-donate-screen", {});
|
||||
proc.runAsync();
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!m_bFired)
|
||||
Debug::log(LOG, "DonationNag: didn't hit any nagging periods");
|
||||
}
|
||||
|
||||
bool CDonationNagManager::fired() {
|
||||
return m_bFired;
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
|
||||
class CDonationNagManager {
|
||||
public:
|
||||
CDonationNagManager();
|
||||
|
||||
// whether the donation nag was shown this boot.
|
||||
bool fired();
|
||||
|
||||
private:
|
||||
bool m_bFired = false;
|
||||
};
|
||||
|
||||
inline UP<CDonationNagManager> g_pDonationNagManager;
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user