Compare commits
6 Commits
v0.47.2
...
scale-work
Author | SHA1 | Date | |
---|---|---|---|
|
85917a40b0 | ||
|
d3e26652d6 | ||
|
276652b44e | ||
|
746f804568 | ||
|
00319c01d4 | ||
|
b509273759 |
101
.clang-tidy
@@ -1,101 +0,0 @@
|
|||||||
WarningsAsErrors: '*'
|
|
||||||
HeaderFilterRegex: '.*\.hpp'
|
|
||||||
FormatStyle: file
|
|
||||||
Checks: >
|
|
||||||
-*,
|
|
||||||
bugprone-*,
|
|
||||||
-bugprone-easily-swappable-parameters,
|
|
||||||
-bugprone-forward-declararion-namespace,
|
|
||||||
-bugprone-forward-declararion-namespace,
|
|
||||||
-bugprone-macro-parentheses,
|
|
||||||
-bugprone-narrowing-conversions,
|
|
||||||
-bugprone-branch-clone,
|
|
||||||
-bugprone-assignment-in-if-condition,
|
|
||||||
concurrency-*,
|
|
||||||
-concurrency-mt-unsafe,
|
|
||||||
cppcoreguidelines-*,
|
|
||||||
-cppcoreguidelines-owning-memory,
|
|
||||||
-cppcoreguidelines-avoid-magic-numbers,
|
|
||||||
-cppcoreguidelines-pro-bounds-constant-array-index,
|
|
||||||
-cppcoreguidelines-avoid-const-or-ref-data-members,
|
|
||||||
-cppcoreguidelines-non-private-member-variables-in-classes,
|
|
||||||
-cppcoreguidelines-avoid-goto,
|
|
||||||
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
|
||||||
-cppcoreguidelines-avoid-do-while,
|
|
||||||
-cppcoreguidelines-avoid-non-const-global-variables,
|
|
||||||
-cppcoreguidelines-special-member-functions,
|
|
||||||
-cppcoreguidelines-explicit-virtual-functions,
|
|
||||||
-cppcoreguidelines-avoid-c-arrays,
|
|
||||||
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
|
|
||||||
-cppcoreguidelines-narrowing-conversions,
|
|
||||||
-cppcoreguidelines-pro-type-union-access,
|
|
||||||
-cppcoreguidelines-pro-type-member-init,
|
|
||||||
-cppcoreguidelines-macro-usage,
|
|
||||||
-cppcoreguidelines-macro-to-enum,
|
|
||||||
-cppcoreguidelines-init-variables,
|
|
||||||
-cppcoreguidelines-pro-type-cstyle-cast,
|
|
||||||
-cppcoreguidelines-pro-type-vararg,
|
|
||||||
-cppcoreguidelines-pro-type-reinterpret-cast,
|
|
||||||
google-global-names-in-headers,
|
|
||||||
-google-readability-casting,
|
|
||||||
google-runtime-operator,
|
|
||||||
misc-*,
|
|
||||||
-misc-unused-parameters,
|
|
||||||
-misc-no-recursion,
|
|
||||||
-misc-non-private-member-variables-in-classes,
|
|
||||||
-misc-include-cleaner,
|
|
||||||
-misc-use-anonymous-namespace,
|
|
||||||
-misc-const-correctness,
|
|
||||||
modernize-*,
|
|
||||||
-modernize-return-braced-init-list,
|
|
||||||
-modernize-use-trailing-return-type,
|
|
||||||
-modernize-use-using,
|
|
||||||
-modernize-use-override,
|
|
||||||
-modernize-avoid-c-arrays,
|
|
||||||
-modernize-macro-to-enum,
|
|
||||||
-modernize-loop-convert,
|
|
||||||
-modernize-use-nodiscard,
|
|
||||||
-modernize-pass-by-value,
|
|
||||||
-modernize-use-auto,
|
|
||||||
performance-*,
|
|
||||||
-performance-avoid-endl,
|
|
||||||
-performance-unnecessary-value-param,
|
|
||||||
portability-std-allocator-const,
|
|
||||||
readability-*,
|
|
||||||
-readability-function-cognitive-complexity,
|
|
||||||
-readability-function-size,
|
|
||||||
-readability-identifier-length,
|
|
||||||
-readability-magic-numbers,
|
|
||||||
-readability-uppercase-literal-suffix,
|
|
||||||
-readability-braces-around-statements,
|
|
||||||
-readability-redundant-access-specifiers,
|
|
||||||
-readability-else-after-return,
|
|
||||||
-readability-container-data-pointer,
|
|
||||||
-readability-implicit-bool-conversion,
|
|
||||||
-readability-avoid-nested-conditional-operator,
|
|
||||||
-readability-redundant-member-init,
|
|
||||||
-readability-redundant-string-init,
|
|
||||||
-readability-avoid-const-params-in-decls,
|
|
||||||
-readability-named-parameter,
|
|
||||||
-readability-convert-member-functions-to-static,
|
|
||||||
-readability-qualified-auto,
|
|
||||||
-readability-make-member-function-const,
|
|
||||||
-readability-isolate-declaration,
|
|
||||||
-readability-inconsistent-declaration-parameter-name,
|
|
||||||
-clang-diagnostic-error,
|
|
||||||
|
|
||||||
CheckOptions:
|
|
||||||
performance-for-range-copy.WarnOnAllAutoCopies: true
|
|
||||||
performance-inefficient-string-concatenation.StrictMode: true
|
|
||||||
readability-braces-around-statements.ShortStatementLines: 0
|
|
||||||
readability-identifier-naming.ClassCase: CamelCase
|
|
||||||
readability-identifier-naming.ClassIgnoredRegexp: I.*
|
|
||||||
readability-identifier-naming.ClassPrefix: C # We can't use regex here?!?!?!?
|
|
||||||
readability-identifier-naming.EnumCase: CamelCase
|
|
||||||
readability-identifier-naming.EnumPrefix: e
|
|
||||||
readability-identifier-naming.EnumConstantCase: UPPER_CASE
|
|
||||||
readability-identifier-naming.FunctionCase: camelBack
|
|
||||||
readability-identifier-naming.NamespaceCase: CamelCase
|
|
||||||
readability-identifier-naming.NamespacePrefix: N
|
|
||||||
readability-identifier-naming.StructPrefix: S
|
|
||||||
readability-identifier-naming.StructCase: CamelCase
|
|
81
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -2,13 +2,12 @@ name: Bug Report
|
|||||||
description: Something is not working right
|
description: Something is not working right
|
||||||
labels: ["bug"]
|
labels: ["bug"]
|
||||||
body:
|
body:
|
||||||
- type: checkboxes
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
label: Already reported ? *
|
value: |
|
||||||
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.
|
## Before opening a new issue, 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
|
|
||||||
|
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
id: type
|
id: type
|
||||||
@@ -19,28 +18,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
|
**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
|
multiple: true
|
||||||
options:
|
options:
|
||||||
- "Definitely a regression - something broke after update (requires bisect)"
|
- "Yes"
|
||||||
- "Probably not a regression / I don't remember it happening before"
|
- "No"
|
||||||
- "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"
|
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: ver
|
id: ver
|
||||||
attributes:
|
attributes:
|
||||||
label: System Info and Hyprland Version
|
label: System Info and Version
|
||||||
description: |
|
description: |
|
||||||
Paste the output of `hyprctl systeminfo` here. If you can't
|
Paste the output of `hyprctl systeminfo -c` here (If you are on a
|
||||||
launch Hyprland, paste the output of `Hyprland --systeminfo`.
|
version that shows you help menu, omit the `-c` and attach config files
|
||||||
|
to the issue). If you have configs outside of the main config shown
|
||||||
|
here, please attach.
|
||||||
value: "<details>
|
value: "<details>
|
||||||
<summary>System/Version info</summary>
|
<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 +60,15 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: How to reproduce
|
label: How to reproduce
|
||||||
description: "How can someone else reproduce the issue?"
|
description: "How can someone else reproduce the issue?"
|
||||||
placeholder: |
|
|
||||||
1. ...
|
|
||||||
2. ...
|
|
||||||
3. ...
|
|
||||||
|
|
||||||
validations:
|
validations:
|
||||||
required: true
|
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
|
- type: textarea
|
||||||
id: logs
|
id: logs
|
||||||
attributes:
|
attributes:
|
||||||
label: Additional info & File uploads
|
label: Crash reports, logs, images, videos
|
||||||
description: |
|
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
|
||||||
|
|
||||||
|
19
.github/actions/setup_base/action.yml
vendored
@@ -33,9 +33,7 @@ runs:
|
|||||||
libfontenc \
|
libfontenc \
|
||||||
libglvnd \
|
libglvnd \
|
||||||
libinput \
|
libinput \
|
||||||
libjxl \
|
|
||||||
libliftoff \
|
libliftoff \
|
||||||
libwebp \
|
|
||||||
libxcursor \
|
libxcursor \
|
||||||
libxcvt \
|
libxcvt \
|
||||||
libxfont2 \
|
libxfont2 \
|
||||||
@@ -60,17 +58,7 @@ runs:
|
|||||||
xcb-util \
|
xcb-util \
|
||||||
xcb-util-image \
|
xcb-util-image \
|
||||||
libzip \
|
libzip \
|
||||||
librsvg \
|
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
|
- name: Get hyprwayland-scanner-git
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -81,11 +69,6 @@ runs:
|
|||||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
cmake --install build
|
cmake --install build
|
||||||
|
|
||||||
- name: Get hyprgraphics-git
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
git clone https://github.com/hyprwm/hyprgraphics && cd hyprgraphics && cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -B build && cmake --build build --target hyprgraphics && cmake --install build
|
|
||||||
|
|
||||||
- name: Get hyprutils-git
|
- name: Get hyprutils-git
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
6
.github/pull_request_template.md
vendored
@@ -1,9 +1,3 @@
|
|||||||
<!--
|
|
||||||
BEFORE you submit your PR, please check out the PR guidelines
|
|
||||||
on our wiki: https://wiki.hyprland.org/Contributing-and-Debugging/PR-Guidelines/
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
#### Describe your PR, what does it fix/add?
|
#### Describe your PR, what does it fix/add?
|
||||||
|
|
||||||
|
|
||||||
|
27
.github/workflows/ci.yaml
vendored
@@ -39,7 +39,7 @@ jobs:
|
|||||||
tar -cvf Hyprland.tar.xz hyprland
|
tar -cvf Hyprland.tar.xz hyprland
|
||||||
|
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: Build archive
|
name: Build archive
|
||||||
path: Hyprland.tar.xz
|
path: Hyprland.tar.xz
|
||||||
@@ -107,7 +107,6 @@ jobs:
|
|||||||
run: make release
|
run: make release
|
||||||
|
|
||||||
clang-format:
|
clang-format:
|
||||||
permissions: read-all
|
|
||||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork
|
||||||
name: "Code Style (Arch)"
|
name: "Code Style (Arch)"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -127,27 +126,3 @@ jobs:
|
|||||||
|
|
||||||
- name: clang-format check
|
- name: clang-format check
|
||||||
run: ninja -C build 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
|
|
||||||
|
4
.github/workflows/man-update.yaml
vendored
@@ -17,14 +17,14 @@ jobs:
|
|||||||
run: sudo apt install pandoc
|
run: sudo apt install pandoc
|
||||||
|
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.PAT }}
|
||||||
|
|
||||||
- name: Build man pages
|
- name: Build man pages
|
||||||
run: make man
|
run: make man
|
||||||
|
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
name: Commit
|
name: Commit
|
||||||
with:
|
with:
|
||||||
commit_message: "[gha] build man pages"
|
commit_message: "[gha] build man pages"
|
||||||
|
17
.github/workflows/nix-build.yml
vendored
@@ -1,5 +1,3 @@
|
|||||||
name: Nix (Build)
|
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
secrets:
|
secrets:
|
||||||
@@ -12,18 +10,21 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
package:
|
package:
|
||||||
- hyprland
|
- hyprland
|
||||||
# - hyprland-cross # cross compiling fails due to qt
|
|
||||||
# failure chain: hyprland-qtutils -> qt6.qtsvg -> qt6.qtbase -> psqlodbc & qt6.qttranslations
|
|
||||||
- xdg-desktop-portal-hyprland
|
- xdg-desktop-portal-hyprland
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: DeterminateSystems/nix-installer-action@main
|
- name: Clone repository
|
||||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.ref }}
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- uses: cachix/install-nix-action@v27
|
||||||
|
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||||
- uses: cachix/cachix-action@v15
|
- uses: cachix/cachix-action@v15
|
||||||
with:
|
with:
|
||||||
name: hyprland
|
name: hyprland
|
||||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||||
|
|
||||||
- run: nix build 'github:hyprwm/Hyprland?ref=${{ github.ref }}#${{ matrix.package }}' -L --extra-substituters "https://hyprland.cachix.org"
|
- run: nix build '.?submodules=1#${{ matrix.package }}' -L --extra-substituters "https://hyprland.cachix.org"
|
||||||
|
7
.github/workflows/nix-ci.yml
vendored
@@ -1,14 +1,15 @@
|
|||||||
name: Nix (CI)
|
name: Nix
|
||||||
|
|
||||||
on: [push, pull_request, workflow_dispatch]
|
on: [push, pull_request, workflow_dispatch]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-inputs:
|
update-inputs:
|
||||||
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||||
uses: ./.github/workflows/nix-update-inputs.yml
|
uses: ./.github/workflows/nix-update-inputs.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
build:
|
build:
|
||||||
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork)
|
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork) && !contains(needs.*.result, 'failure')
|
||||||
|
needs: update-inputs
|
||||||
uses: ./.github/workflows/nix-build.yml
|
uses: ./.github/workflows/nix-build.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
7
.github/workflows/nix-update-inputs.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: Nix (Update Inputs)
|
name: Nix
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
@@ -8,12 +8,11 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update:
|
update:
|
||||||
if: github.repository == 'hyprwm/Hyprland'
|
|
||||||
name: inputs
|
name: inputs
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.PAT }}
|
||||||
|
|
||||||
@@ -22,6 +21,6 @@ jobs:
|
|||||||
run: nix/update-inputs.sh
|
run: nix/update-inputs.sh
|
||||||
|
|
||||||
- name: Commit
|
- name: Commit
|
||||||
uses: stefanzweifel/git-auto-commit-action@v5
|
uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
with:
|
with:
|
||||||
commit_message: "[gha] Nix: update inputs"
|
commit_message: "[gha] Nix: update inputs"
|
||||||
|
3
.github/workflows/release.yaml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout Hyprland
|
- name: Checkout Hyprland
|
||||||
id: checkout
|
id: checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
@@ -20,6 +20,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git fetch --unshallow || echo "failed unshallowing"
|
git fetch --unshallow || echo "failed unshallowing"
|
||||||
bash -c scripts/generateVersion.sh
|
bash -c scripts/generateVersion.sh
|
||||||
|
mv scripts/generateVersion.sh scripts/generateVersion.sh.bak
|
||||||
|
|
||||||
- name: Create tarball with submodules
|
- name: Create tarball with submodules
|
||||||
id: tar
|
id: tar
|
||||||
|
2
.github/workflows/security-checks.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
security-events: write
|
security-events: write
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Scan with Flawfinder
|
- name: Scan with Flawfinder
|
||||||
uses: david-a-wheeler/flawfinder@8e4a779ad59dbfaee5da586aa9210853b701959c
|
uses: david-a-wheeler/flawfinder@8e4a779ad59dbfaee5da586aa9210853b701959c
|
||||||
|
18
.github/workflows/stale.yml
vendored
@@ -7,22 +7,22 @@ name: Mark stale issues and pull requests
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "7 */4 * * *"
|
- cron: '7 */4 * * *'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
stale:
|
stale:
|
||||||
if: github.repository == 'hyprwm/Hyprland'
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9
|
- uses: actions/stale@v5
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.STALEBOT_PAT }}
|
repo-token: ${{ secrets.STALEBOT_PAT }}
|
||||||
stale-issue-label: "stale"
|
stale-issue-label: 'stale'
|
||||||
stale-pr-label: "stale"
|
stale-pr-label: 'stale'
|
||||||
operations-per-run: 40
|
operations-per-run: 40
|
||||||
days-before-close: -1
|
days-before-close: -1
|
||||||
|
4
.gitignore
vendored
@@ -14,7 +14,6 @@ _deps
|
|||||||
|
|
||||||
build/
|
build/
|
||||||
result*
|
result*
|
||||||
/.pre-commit-config.yaml
|
|
||||||
/.vscode/
|
/.vscode/
|
||||||
/.idea/
|
/.idea/
|
||||||
.envrc
|
.envrc
|
||||||
@@ -40,6 +39,3 @@ PKGBUILD
|
|||||||
src/version.h
|
src/version.h
|
||||||
hyprpm/Makefile
|
hyprpm/Makefile
|
||||||
hyprctl/Makefile
|
hyprctl/Makefile
|
||||||
|
|
||||||
**/.#*.*
|
|
||||||
**/#*.*#
|
|
||||||
|
136
CMakeLists.txt
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.30)
|
cmake_minimum_required(VERSION 3.27)
|
||||||
|
|
||||||
# Get version
|
# Get version
|
||||||
file(READ "${CMAKE_SOURCE_DIR}/VERSION" VER_RAW)
|
file(READ "${CMAKE_SOURCE_DIR}/VERSION" VER_RAW)
|
||||||
@@ -15,7 +15,6 @@ include(GNUInstallDirs)
|
|||||||
set(HYPRLAND_VERSION ${VER})
|
set(HYPRLAND_VERSION ${VER})
|
||||||
set(PREFIX ${CMAKE_INSTALL_PREFIX})
|
set(PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||||
set(INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR})
|
set(INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
set(BINDIR ${CMAKE_INSTALL_BINDIR})
|
|
||||||
configure_file(hyprland.pc.in hyprland.pc @ONLY)
|
configure_file(hyprland.pc.in hyprland.pc @ONLY)
|
||||||
|
|
||||||
set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
|
set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
|
||||||
@@ -26,18 +25,8 @@ message(STATUS "Gathering git info")
|
|||||||
execute_process(COMMAND ./scripts/generateVersion.sh
|
execute_process(COMMAND ./scripts/generateVersion.sh
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
# udis
|
||||||
|
add_subdirectory("subprojects/udis86")
|
||||||
# Try to find canihavesomecoffee's udis86 using pkgconfig vmd/udis86 does not
|
|
||||||
# provide a .pc file and won't be detected this way
|
|
||||||
pkg_check_modules(udis_dep IMPORTED_TARGET udis86>=1.7.2)
|
|
||||||
|
|
||||||
# Fallback to subproject
|
|
||||||
if(NOT udis_dep_FOUND)
|
|
||||||
add_subdirectory("subprojects/udis86")
|
|
||||||
include_directories("subprojects/udis86")
|
|
||||||
message(STATUS "udis86 dependency not found, falling back to subproject")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE)
|
if(CMAKE_BUILD_TYPE)
|
||||||
string(TOLOWER ${CMAKE_BUILD_TYPE} BUILDTYPE_LOWER)
|
string(TOLOWER ${CMAKE_BUILD_TYPE} BUILDTYPE_LOWER)
|
||||||
@@ -58,6 +47,8 @@ else()
|
|||||||
set(BUILDTYPE_LOWER "release")
|
set(BUILDTYPE_LOWER "release")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
||||||
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
||||||
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
||||||
pkg_get_variable(WAYLAND_SCANNER_PKGDATA_DIR wayland-scanner pkgdatadir)
|
pkg_get_variable(WAYLAND_SCANNER_PKGDATA_DIR wayland-scanner pkgdatadir)
|
||||||
@@ -72,10 +63,7 @@ else()
|
|||||||
message(STATUS "Configuring Hyprland in Release with CMake")
|
message(STATUS "Configuring Hyprland in Release with CMake")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_compile_definitions(HYPRLAND_VERSION="${HYPRLAND_VERSION}")
|
include_directories(. "src/" "subprojects/udis86/" "protocols/")
|
||||||
|
|
||||||
include_directories(. "src/" "protocols/")
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 26)
|
set(CMAKE_CXX_STANDARD 26)
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
-Wall
|
-Wall
|
||||||
@@ -101,25 +89,18 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
|
find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
|
||||||
|
|
||||||
pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.5)
|
pkg_check_modules(hyprctl_deps REQUIRED IMPORTED_TARGET hyprutils>=0.2.1)
|
||||||
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.5.0)
|
|
||||||
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1)
|
|
||||||
|
|
||||||
add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}")
|
|
||||||
add_compile_definitions(HYPRLANG_VERSION="${hyprlang_dep_VERSION}")
|
|
||||||
add_compile_definitions(HYPRUTILS_VERSION="${hyprutils_dep_VERSION}")
|
|
||||||
add_compile_definitions(HYPRCURSOR_VERSION="${hyprcursor_dep_VERSION}")
|
|
||||||
add_compile_definitions(HYPRGRAPHICS_VERSION="${hyprgraphics_dep_VERSION}")
|
|
||||||
|
|
||||||
pkg_check_modules(
|
pkg_check_modules(
|
||||||
deps
|
deps
|
||||||
REQUIRED
|
REQUIRED
|
||||||
IMPORTED_TARGET
|
IMPORTED_TARGET
|
||||||
|
aquamarine
|
||||||
xkbcommon
|
xkbcommon
|
||||||
uuid
|
uuid
|
||||||
wayland-server>=1.22.90
|
wayland-server
|
||||||
|
wayland-client
|
||||||
|
wayland-cursor
|
||||||
wayland-protocols
|
wayland-protocols
|
||||||
cairo
|
cairo
|
||||||
pango
|
pango
|
||||||
@@ -128,9 +109,16 @@ pkg_check_modules(
|
|||||||
xcursor
|
xcursor
|
||||||
libdrm
|
libdrm
|
||||||
libinput
|
libinput
|
||||||
|
hwdata
|
||||||
|
libseat
|
||||||
|
libdisplay-info
|
||||||
|
libliftoff
|
||||||
|
libudev
|
||||||
gbm
|
gbm
|
||||||
gio-2.0
|
gio-2.0
|
||||||
re2)
|
hyprlang>=0.3.2
|
||||||
|
hyprcursor>=0.1.7
|
||||||
|
hyprutils>=0.2.1)
|
||||||
|
|
||||||
find_package(hyprwayland-scanner 0.3.10 REQUIRED)
|
find_package(hyprwayland-scanner 0.3.10 REQUIRED)
|
||||||
|
|
||||||
@@ -197,12 +185,6 @@ if(NOT HAS_TIMERFD AND epoll_FOUND)
|
|||||||
target_link_libraries(Hyprland PkgConfig::epoll)
|
target_link_libraries(Hyprland PkgConfig::epoll)
|
||||||
endif()
|
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)
|
if(LEGACY_RENDERER)
|
||||||
message(STATUS "Using the legacy GLES2 renderer!")
|
message(STATUS "Using the legacy GLES2 renderer!")
|
||||||
add_compile_definitions(LEGACY_RENDERER)
|
add_compile_definitions(LEGACY_RENDERER)
|
||||||
@@ -218,11 +200,14 @@ else()
|
|||||||
REQUIRED
|
REQUIRED
|
||||||
IMPORTED_TARGET
|
IMPORTED_TARGET
|
||||||
xcb
|
xcb
|
||||||
|
xwayland
|
||||||
|
xcb-util
|
||||||
xcb-render
|
xcb-render
|
||||||
xcb-xfixes
|
xcb-xfixes
|
||||||
xcb-icccm
|
xcb-icccm
|
||||||
xcb-composite
|
xcb-composite
|
||||||
xcb-res
|
xcb-res
|
||||||
|
xcb-ewmh
|
||||||
xcb-errors)
|
xcb-errors)
|
||||||
target_link_libraries(Hyprland PkgConfig::xdeps)
|
target_link_libraries(Hyprland PkgConfig::xdeps)
|
||||||
endif()
|
endif()
|
||||||
@@ -232,15 +217,6 @@ if(NO_SYSTEMD)
|
|||||||
else()
|
else()
|
||||||
message(STATUS "SYSTEMD support is requested (NO_SYSTEMD not defined)...")
|
message(STATUS "SYSTEMD support is requested (NO_SYSTEMD not defined)...")
|
||||||
add_compile_definitions(USES_SYSTEMD)
|
add_compile_definitions(USES_SYSTEMD)
|
||||||
|
|
||||||
# session file -uwsm
|
|
||||||
if(NO_UWSM)
|
|
||||||
message(STATUS "UWSM support is disabled...")
|
|
||||||
else()
|
|
||||||
message(STATUS "UWSM support is enabled (NO_UWSM not defined)...")
|
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/systemd/hyprland-uwsm.desktop
|
|
||||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||||
@@ -254,27 +230,14 @@ target_precompile_headers(Hyprland PRIVATE
|
|||||||
|
|
||||||
message(STATUS "Setting link libraries")
|
message(STATUS "Setting link libraries")
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(Hyprland rt PkgConfig::deps)
|
||||||
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()
|
|
||||||
target_link_libraries(Hyprland libudis86)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# used by `make installheaders`, to ensure the headers are generated
|
# used by `make installheaders`, to ensure the headers are generated
|
||||||
add_custom_target(generate-protocol-headers)
|
add_custom_target(generate-protocol-headers)
|
||||||
|
|
||||||
function(protocolnew protoPath protoName external)
|
function(protocolnew protoPath protoName external)
|
||||||
if(external)
|
if(external)
|
||||||
set(path ${protoPath})
|
set(path ${CMAKE_SOURCE_DIR}/${protoPath})
|
||||||
else()
|
else()
|
||||||
set(path ${WAYLAND_PROTOCOLS_DIR}/${protoPath})
|
set(path ${WAYLAND_PROTOCOLS_DIR}/${protoPath})
|
||||||
endif()
|
endif()
|
||||||
@@ -302,22 +265,14 @@ function(protocolWayland)
|
|||||||
PRIVATE ${CMAKE_SOURCE_DIR}/protocols/wayland.hpp)
|
PRIVATE ${CMAKE_SOURCE_DIR}/protocols/wayland.hpp)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads)
|
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads
|
||||||
|
libudis86 uuid)
|
||||||
|
|
||||||
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.6.0)
|
protocolnew("subprojects/hyprland-protocols/protocols"
|
||||||
if(hyprland_protocols_dep_FOUND)
|
"hyprland-global-shortcuts-v1" true)
|
||||||
pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir)
|
|
||||||
message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}")
|
|
||||||
else()
|
|
||||||
set(HYPRLAND_PROTOCOLS "subprojects/hyprland-protocols")
|
|
||||||
message(STATUS "hyprland-protocols subproject set to ${HYPRLAND_PROTOCOLS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-global-shortcuts-v1"
|
|
||||||
true)
|
|
||||||
protocolnew("unstable/text-input" "text-input-unstable-v1" false)
|
protocolnew("unstable/text-input" "text-input-unstable-v1" false)
|
||||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-toplevel-export-v1"
|
protocolnew("subprojects/hyprland-protocols/protocols"
|
||||||
true)
|
"hyprland-toplevel-export-v1" true)
|
||||||
protocolnew("protocols" "wlr-screencopy-unstable-v1" true)
|
protocolnew("protocols" "wlr-screencopy-unstable-v1" true)
|
||||||
protocolnew("protocols" "wlr-gamma-control-unstable-v1" true)
|
protocolnew("protocols" "wlr-gamma-control-unstable-v1" true)
|
||||||
protocolnew("protocols" "wlr-foreign-toplevel-management-unstable-v1" true)
|
protocolnew("protocols" "wlr-foreign-toplevel-management-unstable-v1" true)
|
||||||
@@ -328,15 +283,10 @@ protocolnew("protocols" "input-method-unstable-v2" true)
|
|||||||
protocolnew("protocols" "wlr-output-management-unstable-v1" true)
|
protocolnew("protocols" "wlr-output-management-unstable-v1" true)
|
||||||
protocolnew("protocols" "kde-server-decoration" true)
|
protocolnew("protocols" "kde-server-decoration" true)
|
||||||
protocolnew("protocols" "wlr-data-control-unstable-v1" true)
|
protocolnew("protocols" "wlr-data-control-unstable-v1" true)
|
||||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-focus-grab-v1" true)
|
protocolnew("subprojects/hyprland-protocols/protocols" "hyprland-focus-grab-v1"
|
||||||
|
true)
|
||||||
protocolnew("protocols" "wlr-layer-shell-unstable-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("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/tearing-control" "tearing-control-v1" false)
|
||||||
protocolnew("staging/fractional-scale" "fractional-scale-v1" false)
|
protocolnew("staging/fractional-scale" "fractional-scale-v1" false)
|
||||||
protocolnew("unstable/xdg-output" "xdg-output-unstable-v1" false)
|
protocolnew("unstable/xdg-output" "xdg-output-unstable-v1" false)
|
||||||
@@ -365,21 +315,12 @@ protocolnew("stable/viewporter" "viewporter" false)
|
|||||||
protocolnew("stable/linux-dmabuf" "linux-dmabuf-v1" false)
|
protocolnew("stable/linux-dmabuf" "linux-dmabuf-v1" false)
|
||||||
protocolnew("staging/drm-lease" "drm-lease-v1" false)
|
protocolnew("staging/drm-lease" "drm-lease-v1" false)
|
||||||
protocolnew("staging/linux-drm-syncobj" "linux-drm-syncobj-v1" false)
|
protocolnew("staging/linux-drm-syncobj" "linux-drm-syncobj-v1" false)
|
||||||
protocolnew("staging/xdg-dialog" "xdg-dialog-v1" false)
|
|
||||||
protocolnew("staging/single-pixel-buffer" "single-pixel-buffer-v1" false)
|
|
||||||
protocolnew("staging/security-context" "security-context-v1" false)
|
|
||||||
|
|
||||||
protocolwayland()
|
protocolwayland()
|
||||||
|
|
||||||
# tools
|
# tools
|
||||||
add_subdirectory(hyprctl)
|
add_subdirectory(hyprctl)
|
||||||
|
add_subdirectory(hyprpm)
|
||||||
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
|
# binary and symlink
|
||||||
install(TARGETS Hyprland)
|
install(TARGETS Hyprland)
|
||||||
@@ -390,18 +331,17 @@ install(
|
|||||||
${CMAKE_INSTALL_FULL_BINDIR}/Hyprland \
|
${CMAKE_INSTALL_FULL_BINDIR}/Hyprland \
|
||||||
\"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}/hyprland\" \
|
\"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}/hyprland\" \
|
||||||
)")
|
)")
|
||||||
|
|
||||||
# session file
|
# session file
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.desktop
|
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.desktop
|
||||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions)
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions)
|
||||||
|
|
||||||
# allow Hyprland to find assets
|
# allow Hyprland to find wallpapers
|
||||||
add_compile_definitions(DATAROOTDIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}")
|
add_compile_definitions(DATAROOTDIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}")
|
||||||
|
|
||||||
# installable assets
|
# wallpapers
|
||||||
file(GLOB_RECURSE INSTALLABLE_ASSETS "assets/install/*")
|
file(GLOB_RECURSE WALLPAPERS "assets/wall*")
|
||||||
list(FILTER INSTALLABLE_ASSETS EXCLUDE REGEX "meson.build")
|
install(FILES ${WALLPAPERS} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/hypr)
|
||||||
install(FILES ${INSTALLABLE_ASSETS}
|
|
||||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/hypr)
|
|
||||||
|
|
||||||
# default config
|
# default config
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.conf
|
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.conf
|
||||||
|
27
Makefile
@@ -1,27 +1,28 @@
|
|||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
|
|
||||||
stub:
|
|
||||||
@echo "Do not run $(MAKE) directly without any arguments. Please refer to the wiki on how to compile Hyprland."
|
|
||||||
|
|
||||||
legacyrenderer:
|
legacyrenderer:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build -G Ninja
|
||||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
cmake --build ./build --config Release --target all
|
||||||
|
chmod -R 777 ./build
|
||||||
|
|
||||||
legacyrendererdebug:
|
legacyrendererdebug:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build -G Ninja
|
||||||
cmake --build ./build --config Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
cmake --build ./build --config Release --target all
|
||||||
|
chmod -R 777 ./build
|
||||||
|
|
||||||
release:
|
release:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build -G Ninja
|
||||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
cmake --build ./build --config Release --target all
|
||||||
|
chmod -R 777 ./build
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build -G Ninja
|
||||||
cmake --build ./build --config Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
cmake --build ./build --config Debug --target all
|
||||||
|
chmod -R 777 ./build
|
||||||
|
|
||||||
nopch:
|
nopch:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -S . -B ./build
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -S . -B ./build -G Ninja
|
||||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
cmake --build ./build --config Release --target all
|
||||||
|
|
||||||
clear:
|
clear:
|
||||||
rm -rf build
|
rm -rf build
|
||||||
|
@@ -100,7 +100,7 @@ easy IPC, much more QoL stuff than other compositors and more...
|
|||||||
|
|
||||||
<!----------------------------------------------------------------------------->
|
<!----------------------------------------------------------------------------->
|
||||||
|
|
||||||
[Configure]: https://wiki.hyprland.org/Configuring/
|
[Configure]: https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
||||||
[Stars]: https://starchart.cc/hyprwm/Hyprland
|
[Stars]: https://starchart.cc/hyprwm/Hyprland
|
||||||
[Hypr]: https://github.com/hyprwm/Hypr
|
[Hypr]: https://github.com/hyprwm/Hypr
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 110 KiB |
Before Width: | Height: | Size: 48 KiB |
@@ -1,10 +0,0 @@
|
|||||||
globber = run_command('sh', '-c', 'find . -type f -not -name "*.build"', check: true)
|
|
||||||
files = globber.stdout().strip().split('\n')
|
|
||||||
|
|
||||||
foreach file : files
|
|
||||||
install_data(
|
|
||||||
file,
|
|
||||||
install_dir: join_paths(get_option('datadir'), 'hypr'),
|
|
||||||
install_tag: 'runtime',
|
|
||||||
)
|
|
||||||
endforeach
|
|
@@ -1,7 +1,7 @@
|
|||||||
install_data(
|
wallpapers = ['0', '1', '2']
|
||||||
'hyprland-portals.conf',
|
|
||||||
install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal'),
|
|
||||||
install_tag: 'runtime',
|
|
||||||
)
|
|
||||||
|
|
||||||
subdir('install')
|
foreach type : wallpapers
|
||||||
|
install_data(f'wall@type@.png', install_dir: join_paths(get_option('datadir'), 'hypr'), install_tag: 'runtime')
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
install_data('hyprland-portals.conf', install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal'), install_tag: 'runtime')
|
||||||
|
Before Width: | Height: | Size: 14 MiB After Width: | Height: | Size: 14 MiB |
Before Width: | Height: | Size: 5.9 MiB After Width: | Height: | Size: 5.9 MiB |
Before Width: | Height: | Size: 27 MiB After Width: | Height: | Size: 27 MiB |
@@ -10,8 +10,8 @@ Hyprland - Dynamic tiling Wayland compositor
|
|||||||
\f[B]Hyprland\f[R] [\f[I]arg [...]\f[R]].
|
\f[B]Hyprland\f[R] [\f[I]arg [...]\f[R]].
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
\f[B]Hyprland\f[R] is an independent, highly customizable, dynamic
|
\f[B]Hyprland\f[R] is a dynamic tiling Wayland compositor based on
|
||||||
tiling Wayland compositor that doesn\[aq]t sacrifice on its looks.
|
wlroots that doesn\[aq]t sacrifice on its looks.
|
||||||
.PP
|
.PP
|
||||||
You can launch Hyprland by either going into a TTY and executing
|
You can launch Hyprland by either going into a TTY and executing
|
||||||
\f[B]Hyprland\f[R], or with a login manager.
|
\f[B]Hyprland\f[R], or with a login manager.
|
||||||
|
@@ -14,8 +14,8 @@ SYNOPSIS
|
|||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
===========
|
===========
|
||||||
|
|
||||||
**Hyprland** is an independent, highly customizable,
|
**Hyprland** is a dynamic tiling Wayland compositor based on
|
||||||
dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
|
wlroots that doesn't sacrifice on its looks.
|
||||||
|
|
||||||
You can launch Hyprland by either going into a TTY and
|
You can launch Hyprland by either going into a TTY and
|
||||||
executing **Hyprland**, or with a login manager.
|
executing **Hyprland**, or with a login manager.
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
First of all, please remember to:
|
First of all, please remember to:
|
||||||
- Check that your issue is not a duplicate
|
- Check that your issue is not a duplicate
|
||||||
- Read the [FAQ](https://wiki.hyprland.org/FAQ/)
|
- Read the [FAQ](https://wiki.hyprland.org/FAQ/)
|
||||||
- Read the [Configuring Page](https://wiki.hyprland.org/Configuring/)
|
- Read the [Configuring Page](https://wiki.hyprland.org/Configuring/Configuring-Hyprland)
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
install_man('Hyprland.1')
|
install_man ('Hyprland.1')
|
||||||
install_man('hyprctl.1')
|
install_man ('hyprctl.1')
|
||||||
|
14
example/hyprland-session.service
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Hyprland - Tiling compositor with the looks
|
||||||
|
Documentation=man:Hyprland(1)
|
||||||
|
BindsTo=graphical-session.target
|
||||||
|
Before=graphical-session.target
|
||||||
|
Wants=graphical-session-pre.target
|
||||||
|
After=graphical-session-pre.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
ExecStart=/usr/bin/Hyprland
|
||||||
|
ExecStop=/usr/bin/hyprctl dispatch exit
|
||||||
|
Restart=on-failure
|
||||||
|
Slice=session.slice
|
@@ -1,6 +1,5 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Name=Hyprland (uwsm-managed)
|
Name=Hyprland
|
||||||
Comment=An intelligent dynamic tiling Wayland compositor
|
Comment=An intelligent dynamic tiling Wayland compositor
|
||||||
Exec=uwsm start -- hyprland.desktop
|
Exec=systemctl --user start --wait hyprland-session
|
||||||
DesktopNames=Hyprland
|
|
||||||
Type=Application
|
Type=Application
|
@@ -1,6 +1,6 @@
|
|||||||
# This is an example Hyprland config file.
|
# This is an example Hyprland config file.
|
||||||
# Refer to the wiki for more information.
|
# Refer to the wiki for more information.
|
||||||
# https://wiki.hyprland.org/Configuring/
|
# https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
||||||
|
|
||||||
# Please note not all available settings / options are set here.
|
# Please note not all available settings / options are set here.
|
||||||
# For a full list, see the wiki
|
# For a full list, see the wiki
|
||||||
@@ -81,18 +81,15 @@ general {
|
|||||||
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
||||||
decoration {
|
decoration {
|
||||||
rounding = 10
|
rounding = 10
|
||||||
rounding_power = 2
|
|
||||||
|
|
||||||
# Change transparency of focused and unfocused windows
|
# Change transparency of focused and unfocused windows
|
||||||
active_opacity = 1.0
|
active_opacity = 1.0
|
||||||
inactive_opacity = 1.0
|
inactive_opacity = 1.0
|
||||||
|
|
||||||
shadow {
|
drop_shadow = true
|
||||||
enabled = true
|
shadow_range = 4
|
||||||
range = 4
|
shadow_render_power = 3
|
||||||
render_power = 3
|
col.shadow = rgba(1a1a1aee)
|
||||||
color = rgba(1a1a1aee)
|
|
||||||
}
|
|
||||||
|
|
||||||
# https://wiki.hyprland.org/Configuring/Variables/#blur
|
# https://wiki.hyprland.org/Configuring/Variables/#blur
|
||||||
blur {
|
blur {
|
||||||
@@ -106,44 +103,20 @@ decoration {
|
|||||||
|
|
||||||
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
||||||
animations {
|
animations {
|
||||||
enabled = yes, please :)
|
enabled = true
|
||||||
|
|
||||||
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||||
|
|
||||||
bezier = easeOutQuint,0.23,1,0.32,1
|
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
|
||||||
bezier = easeInOutCubic,0.65,0.05,0.36,1
|
|
||||||
bezier = linear,0,0,1,1
|
|
||||||
bezier = almostLinear,0.5,0.5,0.75,1.0
|
|
||||||
bezier = quick,0.15,0,0.1,1
|
|
||||||
|
|
||||||
animation = global, 1, 10, default
|
animation = windows, 1, 7, myBezier
|
||||||
animation = border, 1, 5.39, easeOutQuint
|
animation = windowsOut, 1, 7, default, popin 80%
|
||||||
animation = windows, 1, 4.79, easeOutQuint
|
animation = border, 1, 10, default
|
||||||
animation = windowsIn, 1, 4.1, easeOutQuint, popin 87%
|
animation = borderangle, 1, 8, default
|
||||||
animation = windowsOut, 1, 1.49, linear, popin 87%
|
animation = fade, 1, 7, default
|
||||||
animation = fadeIn, 1, 1.73, almostLinear
|
animation = workspaces, 1, 6, default
|
||||||
animation = fadeOut, 1, 1.46, almostLinear
|
|
||||||
animation = fade, 1, 3.03, quick
|
|
||||||
animation = layers, 1, 3.81, easeOutQuint
|
|
||||||
animation = layersIn, 1, 4, easeOutQuint, fade
|
|
||||||
animation = layersOut, 1, 1.5, linear, fade
|
|
||||||
animation = fadeLayersIn, 1, 1.79, almostLinear
|
|
||||||
animation = fadeLayersOut, 1, 1.39, almostLinear
|
|
||||||
animation = workspaces, 1, 1.94, almostLinear, fade
|
|
||||||
animation = workspacesIn, 1, 1.21, almostLinear, fade
|
|
||||||
animation = workspacesOut, 1, 1.94, almostLinear, fade
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
|
|
||||||
# "Smart gaps" / "No gaps when only"
|
|
||||||
# uncomment all if you wish to use that.
|
|
||||||
# workspace = w[tv1], gapsout:0, gapsin:0
|
|
||||||
# workspace = f[1], gapsout:0, gapsin:0
|
|
||||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[tv1]
|
|
||||||
# windowrulev2 = rounding 0, floating:0, onworkspace:w[tv1]
|
|
||||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:f[1]
|
|
||||||
# windowrulev2 = rounding 0, floating:0, onworkspace:f[1]
|
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||||
dwindle {
|
dwindle {
|
||||||
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||||
@@ -255,19 +228,6 @@ bind = $mainMod, mouse_up, workspace, e-1
|
|||||||
bindm = $mainMod, mouse:272, movewindow
|
bindm = $mainMod, mouse:272, movewindow
|
||||||
bindm = $mainMod, mouse:273, resizewindow
|
bindm = $mainMod, mouse:273, resizewindow
|
||||||
|
|
||||||
# Laptop multimedia keys for volume and LCD brightness
|
|
||||||
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+
|
|
||||||
bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
|
||||||
bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
|
||||||
bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
|
||||||
bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+
|
|
||||||
bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%-
|
|
||||||
|
|
||||||
# Requires playerctl
|
|
||||||
bindl = , XF86AudioNext, exec, playerctl next
|
|
||||||
bindl = , XF86AudioPause, exec, playerctl play-pause
|
|
||||||
bindl = , XF86AudioPlay, exec, playerctl play-pause
|
|
||||||
bindl = , XF86AudioPrev, exec, playerctl previous
|
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
### WINDOWS AND WORKSPACES ###
|
### WINDOWS AND WORKSPACES ###
|
||||||
@@ -282,8 +242,4 @@ bindl = , XF86AudioPrev, exec, playerctl previous
|
|||||||
# Example windowrule v2
|
# Example windowrule v2
|
||||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||||
|
|
||||||
# Ignore maximize requests from apps. You'll probably like this.
|
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
|
||||||
windowrulev2 = suppressevent maximize, class:.*
|
|
||||||
|
|
||||||
# Fix some dragging issues with XWayland
|
|
||||||
windowrulev2 = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
|
|
||||||
|
@@ -3,5 +3,3 @@ Name=Hyprland
|
|||||||
Comment=An intelligent dynamic tiling Wayland compositor
|
Comment=An intelligent dynamic tiling Wayland compositor
|
||||||
Exec=Hyprland
|
Exec=Hyprland
|
||||||
Type=Application
|
Type=Application
|
||||||
DesktopNames=Hyprland
|
|
||||||
Keywords=tiling;wayland;compositor;
|
|
||||||
|
@@ -22,6 +22,5 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
@@ -1,10 +1,2 @@
|
|||||||
install_data(
|
install_data('hyprland.conf', install_dir: join_paths(get_option('datadir'), 'hypr'), install_tag: 'runtime')
|
||||||
'hyprland.conf',
|
install_data('hyprland.desktop', install_dir: join_paths(get_option('datadir'), 'wayland-sessions'), install_tag: 'runtime')
|
||||||
install_dir: join_paths(get_option('datadir'), 'hypr'),
|
|
||||||
install_tag: 'runtime',
|
|
||||||
)
|
|
||||||
install_data(
|
|
||||||
'hyprland.desktop',
|
|
||||||
install_dir: join_paths(get_option('datadir'), 'wayland-sessions'),
|
|
||||||
install_tag: 'runtime',
|
|
||||||
)
|
|
||||||
|
263
flake.lock
generated
@@ -16,11 +16,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737636397,
|
"lastModified": 1724273991,
|
||||||
"narHash": "sha256-F5MbBj3QVorycVSFE9qjuOTLtIQBqt2VWbXa0uwzm98=",
|
"narHash": "sha256-+aUSOXKGpS5CRm1oTitgNAr05ThQNbKIXalZHl3nC6Y=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "aquamarine",
|
"repo": "aquamarine",
|
||||||
"rev": "7fe006981fae53e931f513026fc754e322f13145",
|
"rev": "9a3161ad4c78dc420d1cbb3aae638222608c7de4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -29,43 +29,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1696426674,
|
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gitignore": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"pre-commit-hooks",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1709087332,
|
|
||||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "gitignore.nix",
|
|
||||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "gitignore.nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprcursor": {
|
"hyprcursor": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"hyprlang": [
|
"hyprlang": [
|
||||||
@@ -79,11 +42,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737634937,
|
"lastModified": 1722623071,
|
||||||
"narHash": "sha256-Ffw4ujFpi++6pPHe+gCBOfDgAoNlzVPZN6MReC1beu8=",
|
"narHash": "sha256-sLADpVgebpCBFXkA1FlCXtvEPu1tdEsTfqK1hfeHySE=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprcursor",
|
"repo": "hyprcursor",
|
||||||
"rev": "9c5dd1f7c825ee47f72727ad0a4e16ca46a2688e",
|
"rev": "912d56025f03d41b1ad29510c423757b4379eb1c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -92,47 +55,23 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hyprgraphics": {
|
|
||||||
"inputs": {
|
|
||||||
"hyprutils": [
|
|
||||||
"hyprutils"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"systems": [
|
|
||||||
"systems"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1737634889,
|
|
||||||
"narHash": "sha256-9JZE3KxcXOqZH9zs3UeadngDiK/yIACTiAR8HSA/TNI=",
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprgraphics",
|
|
||||||
"rev": "0d77b4895ad5f1bb3b0ee43103a5246c58b65591",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprgraphics",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprland-protocols": {
|
"hyprland-protocols": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
"xdph",
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"systems": [
|
"systems": [
|
||||||
|
"xdph",
|
||||||
"systems"
|
"systems"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737556638,
|
"lastModified": 1721326555,
|
||||||
"narHash": "sha256-laKgI3mr2qz6tas/q3tuGPxMdsGhBi/w+HO+hO2f1AY=",
|
"narHash": "sha256-zCu4R0CSHEactW9JqYki26gy8h9f6rHmSwj4XJmlHgg=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprland-protocols",
|
"repo": "hyprland-protocols",
|
||||||
"rev": "4c75dd5c015c8a0e5a34c6d02a018a650f57feb5",
|
"rev": "5a11232266bf1a1f5952d5b179c3f4b2facaaa84",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -141,88 +80,7 @@
|
|||||||
"type": "github"
|
"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"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"systems": [
|
|
||||||
"systems"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1737811848,
|
|
||||||
"narHash": "sha256-WZ7LeiKHk5Y94MU5gHIWn0r8asWxYOvie4LqfCjVIZU=",
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprland-qtutils",
|
|
||||||
"rev": "9c0831ff98856c0f312fcb8b57553fbe3dd34d5b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hyprwm",
|
|
||||||
"repo": "hyprland-qtutils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hyprlang": {
|
"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": {
|
"inputs": {
|
||||||
"hyprutils": [
|
"hyprutils": [
|
||||||
"hyprutils"
|
"hyprutils"
|
||||||
@@ -235,11 +93,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737634606,
|
"lastModified": 1724174162,
|
||||||
"narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=",
|
"narHash": "sha256-fOOBLwil6M9QWMCiSULwjMQzrXhHXUnEqmjHX5ZHeVI=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprlang",
|
"repo": "hyprlang",
|
||||||
"rev": "f41271d35cc0f370d300413d756c2677f386af9d",
|
"rev": "16e5c9465f04477d8a3dd48a0a26bf437986336c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -249,35 +107,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hyprutils": {
|
"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": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
@@ -287,11 +116,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737725508,
|
"lastModified": 1722869141,
|
||||||
"narHash": "sha256-jGmcPc6y/prg/4A8KGYqJ27nSPaProCMiFadaxNAKvA=",
|
"narHash": "sha256-0KU4qhyMp441qfwbirNg3+wbm489KnEjXOz2I/RbeFs=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprutils",
|
"repo": "hyprutils",
|
||||||
"rev": "fb0c2d1de3d1ef7396d19c18ac09e12bd956929e",
|
"rev": "0252fd13e78e60fb0da512a212e56007515a49f7",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -310,11 +139,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1735493474,
|
"lastModified": 1721324119,
|
||||||
"narHash": "sha256-fktzv4NaqKm94VAkAoVqO/nqQlw+X0/tJJNAeCSfzK4=",
|
"narHash": "sha256-SOOqIT27/X792+vsLSeFdrNTF+OSRp5qXv6Te+fb2Qg=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprwayland-scanner",
|
"repo": "hyprwayland-scanner",
|
||||||
"rev": "de913476b59ee88685fdc018e77b8f6637a2ae0b",
|
"rev": "a048a6cb015340bd82f97c1f40a4b595ca85cc30",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -325,11 +154,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737632463,
|
"lastModified": 1724224976,
|
||||||
"narHash": "sha256-38J9QfeGSej341ouwzqf77WIHAScihAKCt8PQJ+NH28=",
|
"narHash": "sha256-Z/ELQhrSd7bMzTO8r7NZgi9g5emh+aRKoCdaAv5fiO0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "0aa475546ed21629c4f5bbf90e38c846a99ec9e9",
|
"rev": "c374d94f1536013ca8e92341b540eba4c22f9c62",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -339,40 +168,14 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pre-commit-hooks": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat",
|
|
||||||
"gitignore": "gitignore",
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1737465171,
|
|
||||||
"narHash": "sha256-R10v2hoJRLq8jcL4syVFag7nIGE7m13qO48wRIukWNg=",
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "git-hooks.nix",
|
|
||||||
"rev": "9364dc02281ce2d37a1f55b6e51f7c0f65a75f17",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "git-hooks.nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"aquamarine": "aquamarine",
|
"aquamarine": "aquamarine",
|
||||||
"hyprcursor": "hyprcursor",
|
"hyprcursor": "hyprcursor",
|
||||||
"hyprgraphics": "hyprgraphics",
|
"hyprlang": "hyprlang",
|
||||||
"hyprland-protocols": "hyprland-protocols",
|
"hyprutils": "hyprutils",
|
||||||
"hyprland-qtutils": "hyprland-qtutils",
|
|
||||||
"hyprlang": "hyprlang_2",
|
|
||||||
"hyprutils": "hyprutils_2",
|
|
||||||
"hyprwayland-scanner": "hyprwayland-scanner",
|
"hyprwayland-scanner": "hyprwayland-scanner",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"pre-commit-hooks": "pre-commit-hooks",
|
|
||||||
"systems": "systems",
|
"systems": "systems",
|
||||||
"xdph": "xdph"
|
"xdph": "xdph"
|
||||||
}
|
}
|
||||||
@@ -394,18 +197,10 @@
|
|||||||
},
|
},
|
||||||
"xdph": {
|
"xdph": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"hyprland-protocols": [
|
"hyprland-protocols": "hyprland-protocols",
|
||||||
"hyprland-protocols"
|
|
||||||
],
|
|
||||||
"hyprlang": [
|
"hyprlang": [
|
||||||
"hyprlang"
|
"hyprlang"
|
||||||
],
|
],
|
||||||
"hyprutils": [
|
|
||||||
"hyprutils"
|
|
||||||
],
|
|
||||||
"hyprwayland-scanner": [
|
|
||||||
"hyprwayland-scanner"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
@@ -414,11 +209,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737634991,
|
"lastModified": 1724073926,
|
||||||
"narHash": "sha256-dBAnb7Kbnier30cA7AgxVSxxARmxKZ1vHZT33THSIr8=",
|
"narHash": "sha256-nWlUL43jOFHf+KW6Hqrx+W/r1XdXuDyb0wC/SrHsOu4=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "xdg-desktop-portal-hyprland",
|
"repo": "xdg-desktop-portal-hyprland",
|
||||||
"rev": "e09dfe2726c8008f983e45a0aa1a3b7416aaeb8a",
|
"rev": "a08ecbbf33598924e93542f737fc6169a26b481e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
61
flake.nix
@@ -22,26 +22,6 @@
|
|||||||
inputs.hyprlang.follows = "hyprlang";
|
inputs.hyprlang.follows = "hyprlang";
|
||||||
};
|
};
|
||||||
|
|
||||||
hyprgraphics = {
|
|
||||||
url = "github:hyprwm/hyprgraphics";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
inputs.systems.follows = "systems";
|
|
||||||
inputs.hyprutils.follows = "hyprutils";
|
|
||||||
};
|
|
||||||
|
|
||||||
hyprland-protocols = {
|
|
||||||
url = "github:hyprwm/hyprland-protocols";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
inputs.systems.follows = "systems";
|
|
||||||
};
|
|
||||||
|
|
||||||
hyprland-qtutils = {
|
|
||||||
url = "github:hyprwm/hyprland-qtutils";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
inputs.systems.follows = "systems";
|
|
||||||
inputs.hyprutils.follows = "hyprutils";
|
|
||||||
};
|
|
||||||
|
|
||||||
hyprlang = {
|
hyprlang = {
|
||||||
url = "github:hyprwm/hyprlang";
|
url = "github:hyprwm/hyprlang";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
@@ -65,15 +45,7 @@
|
|||||||
url = "github:hyprwm/xdg-desktop-portal-hyprland";
|
url = "github:hyprwm/xdg-desktop-portal-hyprland";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
inputs.systems.follows = "systems";
|
inputs.systems.follows = "systems";
|
||||||
inputs.hyprland-protocols.follows = "hyprland-protocols";
|
|
||||||
inputs.hyprlang.follows = "hyprlang";
|
inputs.hyprlang.follows = "hyprlang";
|
||||||
inputs.hyprutils.follows = "hyprutils";
|
|
||||||
inputs.hyprwayland-scanner.follows = "hyprwayland-scanner";
|
|
||||||
};
|
|
||||||
|
|
||||||
pre-commit-hooks = {
|
|
||||||
url = "github:cachix/git-hooks.nix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,15 +65,6 @@
|
|||||||
hyprland-extras
|
hyprland-extras
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
pkgsCrossFor = eachSystem (system: crossSystem:
|
|
||||||
import nixpkgs {
|
|
||||||
localSystem = system;
|
|
||||||
inherit crossSystem;
|
|
||||||
overlays = with self.overlays; [
|
|
||||||
hyprland-packages
|
|
||||||
hyprland-extras
|
|
||||||
];
|
|
||||||
});
|
|
||||||
in {
|
in {
|
||||||
overlays = import ./nix/overlays.nix {inherit self lib inputs;};
|
overlays = import ./nix/overlays.nix {inherit self lib inputs;};
|
||||||
|
|
||||||
@@ -111,18 +74,6 @@
|
|||||||
self.packages.${system})
|
self.packages.${system})
|
||||||
// {
|
// {
|
||||||
inherit (self.packages.${system}) xdg-desktop-portal-hyprland;
|
inherit (self.packages.${system}) xdg-desktop-portal-hyprland;
|
||||||
pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
|
|
||||||
src = ./.;
|
|
||||||
hooks = {
|
|
||||||
hyprland-treewide-formatter = {
|
|
||||||
enable = true;
|
|
||||||
entry = "${self.formatter.${system}}/bin/hyprland-treewide-formatter";
|
|
||||||
pass_filenames = false;
|
|
||||||
excludes = ["subprojects"];
|
|
||||||
always_run = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
packages = eachSystem (system: {
|
packages = eachSystem (system: {
|
||||||
@@ -130,30 +81,34 @@
|
|||||||
inherit
|
inherit
|
||||||
(pkgsFor.${system})
|
(pkgsFor.${system})
|
||||||
# hyprland-packages
|
# hyprland-packages
|
||||||
|
|
||||||
hyprland
|
hyprland
|
||||||
hyprland-debug
|
hyprland-debug
|
||||||
hyprland-legacy-renderer
|
hyprland-legacy-renderer
|
||||||
hyprland-unwrapped
|
hyprland-unwrapped
|
||||||
# hyprland-extras
|
# hyprland-extras
|
||||||
|
|
||||||
xdg-desktop-portal-hyprland
|
xdg-desktop-portal-hyprland
|
||||||
;
|
;
|
||||||
hyprland-cross = (pkgsCrossFor.${system} "aarch64-linux").hyprland;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
devShells = eachSystem (system: {
|
devShells = eachSystem (system: {
|
||||||
default =
|
default =
|
||||||
pkgsFor.${system}.mkShell.override {
|
pkgsFor.${system}.mkShell.override {
|
||||||
inherit (self.packages.${system}.default) stdenv;
|
stdenv = pkgsFor.${system}.gcc14Stdenv;
|
||||||
} {
|
} {
|
||||||
name = "hyprland-shell";
|
name = "hyprland-shell";
|
||||||
|
nativeBuildInputs = with pkgsFor.${system}; [
|
||||||
|
expat
|
||||||
|
libxml2
|
||||||
|
];
|
||||||
hardeningDisable = ["fortify"];
|
hardeningDisable = ["fortify"];
|
||||||
inputsFrom = [pkgsFor.${system}.hyprland];
|
inputsFrom = [pkgsFor.${system}.hyprland];
|
||||||
packages = [pkgsFor.${system}.clang-tools];
|
packages = [pkgsFor.${system}.clang-tools];
|
||||||
inherit (self.checks.${system}.pre-commit-check) shellHook;
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
formatter = eachSystem (system: pkgsFor.${system}.callPackage ./nix/formatter.nix {});
|
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||||
|
|
||||||
nixosModules.default = import ./nix/module.nix inputs;
|
nixosModules.default = import ./nix/module.nix inputs;
|
||||||
homeManagerModules.default = import ./nix/hm-module.nix self;
|
homeManagerModules.default = import ./nix/hm-module.nix self;
|
||||||
|
@@ -5,7 +5,7 @@ project(
|
|||||||
DESCRIPTION "Control utility for Hyprland"
|
DESCRIPTION "Control utility for Hyprland"
|
||||||
)
|
)
|
||||||
|
|
||||||
pkg_check_modules(hyprctl_deps REQUIRED IMPORTED_TARGET hyprutils>=0.2.4 re2)
|
pkg_check_modules(deps REQUIRED IMPORTED_TARGET hyprutils>=0.1.1)
|
||||||
|
|
||||||
add_executable(hyprctl "main.cpp")
|
add_executable(hyprctl "main.cpp")
|
||||||
|
|
||||||
|
@@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
const std::string_view USAGE = R"#(usage: hyprctl [flags] <command> [args...|--help]
|
const std::string_view USAGE = R"#(usage: hyprctl [flags] <command> [args...|--help]
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
#include <re2/re2.h>
|
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@@ -19,12 +17,13 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <print>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
#include <regex>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <hyprutils/string/String.hpp>
|
#include <hyprutils/string/String.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -45,24 +44,18 @@ struct SInstanceData {
|
|||||||
bool valid = true;
|
bool valid = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
void log(const std::string& str) {
|
void log(std::string str) {
|
||||||
if (quiet)
|
if (quiet)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::println("{}", str);
|
std::cout << str << "\n";
|
||||||
}
|
|
||||||
|
|
||||||
static int getUID() {
|
|
||||||
const auto UID = getuid();
|
|
||||||
const auto PWUID = getpwuid(UID);
|
|
||||||
return PWUID ? PWUID->pw_uid : UID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getRuntimeDir() {
|
std::string getRuntimeDir() {
|
||||||
const auto XDG = getenv("XDG_RUNTIME_DIR");
|
const auto XDG = getenv("XDG_RUNTIME_DIR");
|
||||||
|
|
||||||
if (!XDG) {
|
if (!XDG) {
|
||||||
const std::string USERID = std::to_string(getUID());
|
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
|
||||||
return "/run/user/" + USERID + "/hypr";
|
return "/run/user/" + USERID + "/hypr";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,11 +65,6 @@ std::string getRuntimeDir() {
|
|||||||
std::vector<SInstanceData> instances() {
|
std::vector<SInstanceData> instances() {
|
||||||
std::vector<SInstanceData> result;
|
std::vector<SInstanceData> result;
|
||||||
|
|
||||||
try {
|
|
||||||
if (!std::filesystem::exists(getRuntimeDir()))
|
|
||||||
return {};
|
|
||||||
} catch (std::exception& e) { return {}; }
|
|
||||||
|
|
||||||
for (const auto& el : std::filesystem::directory_iterator(getRuntimeDir())) {
|
for (const auto& el : std::filesystem::directory_iterator(getRuntimeDir())) {
|
||||||
if (!el.is_directory() || !std::filesystem::exists(el.path().string() + "/hyprland.lock"))
|
if (!el.is_directory() || !std::filesystem::exists(el.path().string() + "/hyprland.lock"))
|
||||||
continue;
|
continue;
|
||||||
@@ -117,7 +105,7 @@ std::vector<SInstanceData> instances() {
|
|||||||
static volatile bool sigintReceived = false;
|
static volatile bool sigintReceived = false;
|
||||||
void intHandler(int sig) {
|
void intHandler(int sig) {
|
||||||
sigintReceived = true;
|
sigintReceived = true;
|
||||||
std::println("[hyprctl] SIGINT received, closing connection");
|
std::cout << "[hyprctl] SIGINT received, closing connection" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rollingRead(const int socket) {
|
int rollingRead(const int socket) {
|
||||||
@@ -127,12 +115,12 @@ int rollingRead(const int socket) {
|
|||||||
constexpr size_t BUFFER_SIZE = 8192;
|
constexpr size_t BUFFER_SIZE = 8192;
|
||||||
std::array<char, BUFFER_SIZE> buffer = {0};
|
std::array<char, BUFFER_SIZE> buffer = {0};
|
||||||
long sizeWritten = 0;
|
long sizeWritten = 0;
|
||||||
std::println("[hyprctl] reading from socket following up log:");
|
std::cout << "[hyprctl] reading from socket following up log:" << std::endl;
|
||||||
while (!sigintReceived) {
|
while (!sigintReceived) {
|
||||||
sizeWritten = read(socket, buffer.data(), BUFFER_SIZE);
|
sizeWritten = read(socket, buffer.data(), BUFFER_SIZE);
|
||||||
if (sizeWritten < 0 && errno != EAGAIN) {
|
if (sizeWritten < 0 && errno != EAGAIN) {
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
std::println("Couldn't read (5): {}: {}", strerror(errno), errno);
|
std::cout << "Couldn't read (5) " << strerror(errno) << ":" << errno << std::endl;
|
||||||
close(socket);
|
close(socket);
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
@@ -141,7 +129,7 @@ int rollingRead(const int socket) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (sizeWritten > 0) {
|
if (sizeWritten > 0) {
|
||||||
std::println("{}", std::string(buffer.data(), sizeWritten));
|
std::cout << std::string(buffer.data(), sizeWritten);
|
||||||
buffer.fill('\0');
|
buffer.fill('\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +162,7 @@ int request(std::string arg, int minArgs = 0, bool needRoll = false) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string USERID = std::to_string(getUID());
|
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
|
||||||
|
|
||||||
sockaddr_un serverAddress = {0};
|
sockaddr_un serverAddress = {0};
|
||||||
serverAddress.sun_family = AF_UNIX;
|
serverAddress.sun_family = AF_UNIX;
|
||||||
@@ -244,7 +232,7 @@ int requestHyprpaper(std::string arg) {
|
|||||||
sockaddr_un serverAddress = {0};
|
sockaddr_un serverAddress = {0};
|
||||||
serverAddress.sun_family = AF_UNIX;
|
serverAddress.sun_family = AF_UNIX;
|
||||||
|
|
||||||
const std::string USERID = std::to_string(getUID());
|
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
|
||||||
|
|
||||||
std::string socketPath = getRuntimeDir() + "/" + instanceSignature + "/.hyprpaper.sock";
|
std::string socketPath = getRuntimeDir() + "/" + instanceSignature + "/.hyprpaper.sock";
|
||||||
|
|
||||||
@@ -282,11 +270,10 @@ int requestHyprpaper(std::string arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void batchRequest(std::string arg, bool json) {
|
void batchRequest(std::string arg, bool json) {
|
||||||
std::string commands = arg.substr(arg.find_first_of(' ') + 1);
|
std::string commands = arg.substr(arg.find_first_of(" ") + 1);
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
RE2::GlobalReplace(&commands, ";\\s*", ";j/");
|
commands = "j/" + std::regex_replace(commands, std::regex(";\\s*"), ";j/");
|
||||||
commands.insert(0, "j/");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string rq = "[[BATCH]]" + commands;
|
std::string rq = "[[BATCH]]" + commands;
|
||||||
@@ -300,12 +287,12 @@ void instancesRequest(bool json) {
|
|||||||
std::vector<SInstanceData> inst = instances();
|
std::vector<SInstanceData> inst = instances();
|
||||||
|
|
||||||
if (!json) {
|
if (!json) {
|
||||||
for (auto const& el : inst) {
|
for (auto& el : inst) {
|
||||||
result += std::format("instance {}:\n\ttime: {}\n\tpid: {}\n\twl socket: {}\n\n", el.id, el.time, el.pid, el.wlSocket);
|
result += std::format("instance {}:\n\ttime: {}\n\tpid: {}\n\twl socket: {}\n\n", el.id, el.time, el.pid, el.wlSocket);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result += '[';
|
result += '[';
|
||||||
for (auto const& el : inst) {
|
for (auto& el : inst) {
|
||||||
result += std::format(R"#(
|
result += std::format(R"#(
|
||||||
{{
|
{{
|
||||||
"instance": "{}",
|
"instance": "{}",
|
||||||
@@ -323,11 +310,11 @@ void instancesRequest(bool json) {
|
|||||||
log(result + "\n");
|
log(result + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> splitArgs(int argc, char** argv) {
|
std::deque<std::string> splitArgs(int argc, char** argv) {
|
||||||
std::vector<std::string> result;
|
std::deque<std::string> result;
|
||||||
|
|
||||||
for (auto i = 1 /* skip the executable */; i < argc; ++i)
|
for (auto i = 1 /* skip the executable */; i < argc; ++i)
|
||||||
result.emplace_back(argv[i]);
|
result.push_back(std::string(argv[i]));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -336,7 +323,7 @@ int main(int argc, char** argv) {
|
|||||||
bool parseArgs = true;
|
bool parseArgs = true;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
std::println("{}", USAGE);
|
std::cout << USAGE << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,7 +360,7 @@ int main(int argc, char** argv) {
|
|||||||
++i;
|
++i;
|
||||||
|
|
||||||
if (i >= ARGS.size()) {
|
if (i >= ARGS.size()) {
|
||||||
std::println("{}", USAGE);
|
std::cout << USAGE << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,24 +371,24 @@ int main(int argc, char** argv) {
|
|||||||
const std::string& cmd = ARGS[0];
|
const std::string& cmd = ARGS[0];
|
||||||
|
|
||||||
if (cmd == "hyprpaper") {
|
if (cmd == "hyprpaper") {
|
||||||
std::println("{}", HYPRPAPER_HELP);
|
std::cout << HYPRPAPER_HELP << std::endl;
|
||||||
} else if (cmd == "notify") {
|
} else if (cmd == "notify") {
|
||||||
std::println("{}", NOTIFY_HELP);
|
std::cout << NOTIFY_HELP << std::endl;
|
||||||
} else if (cmd == "output") {
|
} else if (cmd == "output") {
|
||||||
std::println("{}", OUTPUT_HELP);
|
std::cout << OUTPUT_HELP << std::endl;
|
||||||
} else if (cmd == "plugin") {
|
} else if (cmd == "plugin") {
|
||||||
std::println("{}", PLUGIN_HELP);
|
std::cout << PLUGIN_HELP << std::endl;
|
||||||
} else if (cmd == "setprop") {
|
} else if (cmd == "setprop") {
|
||||||
std::println("{}", SETPROP_HELP);
|
std::cout << SETPROP_HELP << std::endl;
|
||||||
} else if (cmd == "switchxkblayout") {
|
} else if (cmd == "switchxkblayout") {
|
||||||
std::println("{}", SWITCHXKBLAYOUT_HELP);
|
std::cout << SWITCHXKBLAYOUT_HELP << std::endl;
|
||||||
} else {
|
} else {
|
||||||
std::println("{}", USAGE);
|
std::cout << USAGE << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
std::println("{}", USAGE);
|
std::cout << USAGE << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +399,7 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fullRequest.empty()) {
|
if (fullRequest.empty()) {
|
||||||
std::println("{}", USAGE);
|
std::cout << USAGE << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +476,7 @@ int main(int argc, char** argv) {
|
|||||||
else if (fullRequest.contains("/decorations"))
|
else if (fullRequest.contains("/decorations"))
|
||||||
exitStatus = request(fullRequest, 1);
|
exitStatus = request(fullRequest, 1);
|
||||||
else if (fullRequest.contains("/--help"))
|
else if (fullRequest.contains("/--help"))
|
||||||
std::println("{}", USAGE);
|
std::cout << USAGE << std::endl;
|
||||||
else if (fullRequest.contains("/rollinglog") && needRoll)
|
else if (fullRequest.contains("/rollinglog") && needRoll)
|
||||||
exitStatus = request(fullRequest, 0, true);
|
exitStatus = request(fullRequest, 0, true);
|
||||||
else {
|
else {
|
||||||
|
@@ -1,27 +1,10 @@
|
|||||||
executable(
|
executable('hyprctl', 'main.cpp',
|
||||||
'hyprctl',
|
|
||||||
'main.cpp',
|
|
||||||
dependencies: [
|
dependencies: [
|
||||||
dependency('hyprutils', version: '>= 0.1.1'),
|
dependency('hyprutils', version: '>= 0.1.1'),
|
||||||
dependency('re2', required: true)
|
|
||||||
],
|
],
|
||||||
install: true,
|
install: true
|
||||||
)
|
)
|
||||||
|
|
||||||
install_data(
|
install_data('hyprctl.bash', install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'), install_tag: 'runtime', rename: 'hyprctl')
|
||||||
'hyprctl.bash',
|
install_data('hyprctl.fish', install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'), install_tag: 'runtime')
|
||||||
install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'),
|
install_data('hyprctl.zsh', install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'), install_tag: 'runtime', rename: '_hyprctl')
|
||||||
install_tag: 'runtime',
|
|
||||||
rename: 'hyprctl',
|
|
||||||
)
|
|
||||||
install_data(
|
|
||||||
'hyprctl.fish',
|
|
||||||
install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'),
|
|
||||||
install_tag: 'runtime',
|
|
||||||
)
|
|
||||||
install_data(
|
|
||||||
'hyprctl.zsh',
|
|
||||||
install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'),
|
|
||||||
install_tag: 'runtime',
|
|
||||||
rename: '_hyprctl',
|
|
||||||
)
|
|
||||||
|
@@ -9,25 +9,11 @@ file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp")
|
|||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
pkg_check_modules(hyprpm_deps REQUIRED IMPORTED_TARGET tomlplusplus hyprutils>=0.2.4)
|
pkg_check_modules(deps REQUIRED IMPORTED_TARGET tomlplusplus hyprutils>=0.1.1)
|
||||||
|
|
||||||
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})
|
add_executable(hyprpm ${SRCFILES})
|
||||||
|
|
||||||
target_link_libraries(hyprpm PUBLIC PkgConfig::hyprpm_deps glaze::glaze)
|
target_link_libraries(hyprpm PUBLIC PkgConfig::deps)
|
||||||
|
|
||||||
# binary
|
# binary
|
||||||
install(TARGETS hyprpm)
|
install(TARGETS hyprpm)
|
||||||
|
@@ -14,7 +14,7 @@ hyprpm [<FLAGS>]... <ARGUMENT>
|
|||||||
| (list) "List all installed plugins"
|
| (list) "List all installed plugins"
|
||||||
| (enable <PLUGINS>) "Load a plugin"
|
| (enable <PLUGINS>) "Load a plugin"
|
||||||
| (disable <PLUGINS>) "Unload 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}' }}};
|
<PLUGINS> ::= {{{ hyprpm list | awk '/Plugin/{print $4}' }}};
|
||||||
|
@@ -1,13 +1,14 @@
|
|||||||
#include "DataState.hpp"
|
#include "DataState.hpp"
|
||||||
#include <toml++/toml.hpp>
|
#include <toml++/toml.hpp>
|
||||||
#include <print>
|
#include <iostream>
|
||||||
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "PluginManager.hpp"
|
#include "PluginManager.hpp"
|
||||||
|
|
||||||
std::filesystem::path DataState::getDataStatePath() {
|
std::string DataState::getDataStatePath() {
|
||||||
const auto HOME = getenv("HOME");
|
const auto HOME = getenv("HOME");
|
||||||
if (!HOME) {
|
if (!HOME) {
|
||||||
std::println(stderr, "DataState: no $HOME");
|
std::cerr << "DataState: no $HOME\n";
|
||||||
throw std::runtime_error("no $HOME");
|
throw std::runtime_error("no $HOME");
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -15,29 +16,12 @@ std::filesystem::path DataState::getDataStatePath() {
|
|||||||
const auto XDG_DATA_HOME = getenv("XDG_DATA_HOME");
|
const auto XDG_DATA_HOME = getenv("XDG_DATA_HOME");
|
||||||
|
|
||||||
if (XDG_DATA_HOME)
|
if (XDG_DATA_HOME)
|
||||||
return std::filesystem::path{XDG_DATA_HOME} / "hyprpm";
|
return std::string{XDG_DATA_HOME} + "/hyprpm";
|
||||||
return std::filesystem::path{HOME} / ".local/share/hyprpm";
|
return std::string{HOME} + "/.local/share/hyprpm";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataState::getHeadersPath() {
|
std::string DataState::getHeadersPath() {
|
||||||
return getDataStatePath() / "headersRoot";
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataState::ensureStateStoreExists() {
|
void DataState::ensureStateStoreExists() {
|
||||||
@@ -53,7 +37,7 @@ void DataState::ensureStateStoreExists() {
|
|||||||
void DataState::addNewPluginRepo(const SPluginRepository& repo) {
|
void DataState::addNewPluginRepo(const SPluginRepository& repo) {
|
||||||
ensureStateStoreExists();
|
ensureStateStoreExists();
|
||||||
|
|
||||||
const auto PATH = getDataStatePath() / repo.name;
|
const auto PATH = getDataStatePath() + "/" + repo.name;
|
||||||
|
|
||||||
std::filesystem::create_directories(PATH);
|
std::filesystem::create_directories(PATH);
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@@ -65,22 +49,20 @@ void DataState::addNewPluginRepo(const SPluginRepository& repo) {
|
|||||||
{"rev", repo.rev}
|
{"rev", repo.rev}
|
||||||
}}
|
}}
|
||||||
};
|
};
|
||||||
for (auto const& p : repo.plugins) {
|
for (auto& p : repo.plugins) {
|
||||||
const auto filename = p.name + ".so";
|
|
||||||
|
|
||||||
// copy .so to the good place
|
// copy .so to the good place
|
||||||
if (std::filesystem::exists(p.filename))
|
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{
|
DATA.emplace(p.name, toml::table{
|
||||||
{"filename", filename},
|
{"filename", p.name + ".so"},
|
||||||
{"enabled", p.enabled},
|
{"enabled", p.enabled},
|
||||||
{"failed", p.failed}
|
{"failed", p.failed}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
std::ofstream ofs(PATH / "state.toml", std::ios::trunc);
|
std::ofstream ofs(PATH + "/state.toml", std::ios::trunc);
|
||||||
ofs << DATA;
|
ofs << DATA;
|
||||||
ofs.close();
|
ofs.close();
|
||||||
}
|
}
|
||||||
@@ -90,10 +72,17 @@ bool DataState::pluginRepoExists(const std::string& urlOrName) {
|
|||||||
|
|
||||||
const auto PATH = getDataStatePath();
|
const auto PATH = getDataStatePath();
|
||||||
|
|
||||||
for (const auto& stateFile : getPluginStates()) {
|
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||||
const auto NAME = STATE["repository"]["name"].value_or("");
|
continue;
|
||||||
const auto URL = STATE["repository"]["url"].value_or("");
|
|
||||||
|
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)
|
if (URL == urlOrName || NAME == urlOrName)
|
||||||
return true;
|
return true;
|
||||||
@@ -107,22 +96,29 @@ void DataState::removePluginRepo(const std::string& urlOrName) {
|
|||||||
|
|
||||||
const auto PATH = getDataStatePath();
|
const auto PATH = getDataStatePath();
|
||||||
|
|
||||||
for (const auto& stateFile : getPluginStates()) {
|
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||||
const auto NAME = STATE["repository"]["name"].value_or("");
|
continue;
|
||||||
const auto URL = STATE["repository"]["url"].value_or("");
|
|
||||||
|
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) {
|
if (URL == urlOrName || NAME == urlOrName) {
|
||||||
|
|
||||||
// unload the plugins!!
|
// 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"))
|
if (!file.path().string().ends_with(".so"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
g_pPluginManager->loadUnloadPlugin(std::filesystem::absolute(file.path()), false);
|
g_pPluginManager->loadUnloadPlugin(std::filesystem::absolute(file.path()), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::remove_all(stateFile.parent_path());
|
std::filesystem::remove_all(entry.path());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,7 +139,7 @@ void DataState::updateGlobalState(const SGlobalState& state) {
|
|||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
std::ofstream ofs(PATH / "state.toml", std::ios::trunc);
|
std::ofstream ofs(PATH + "/state.toml", std::ios::trunc);
|
||||||
ofs << DATA;
|
ofs << DATA;
|
||||||
ofs.close();
|
ofs.close();
|
||||||
}
|
}
|
||||||
@@ -151,12 +147,12 @@ void DataState::updateGlobalState(const SGlobalState& state) {
|
|||||||
SGlobalState DataState::getGlobalState() {
|
SGlobalState DataState::getGlobalState() {
|
||||||
ensureStateStoreExists();
|
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{};
|
return SGlobalState{};
|
||||||
|
|
||||||
auto DATA = toml::parse_file(stateFile.c_str());
|
auto DATA = toml::parse_file(PATH + "/state.toml");
|
||||||
|
|
||||||
SGlobalState state;
|
SGlobalState state;
|
||||||
state.headersHashCompiled = DATA["state"]["hash"].value_or("");
|
state.headersHashCompiled = DATA["state"]["hash"].value_or("");
|
||||||
@@ -171,8 +167,15 @@ std::vector<SPluginRepository> DataState::getAllRepositories() {
|
|||||||
const auto PATH = getDataStatePath();
|
const auto PATH = getDataStatePath();
|
||||||
|
|
||||||
std::vector<SPluginRepository> repos;
|
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 NAME = STATE["repository"]["name"].value_or("");
|
||||||
const auto URL = STATE["repository"]["url"].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();
|
const auto PATH = getDataStatePath();
|
||||||
|
|
||||||
for (const auto& stateFile : getPluginStates()) {
|
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
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) {
|
for (const auto& [key, val] : STATE) {
|
||||||
if (key == "repository")
|
if (key == "repository")
|
||||||
continue;
|
continue;
|
||||||
@@ -221,11 +231,10 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) {
|
|||||||
if (FAILED)
|
if (FAILED)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto modifiedState = STATE;
|
(*STATE[key].as_table()).insert_or_assign("enabled", enabled);
|
||||||
(*modifiedState[key].as_table()).insert_or_assign("enabled", enabled);
|
|
||||||
|
|
||||||
std::ofstream state(stateFile, std::ios::trunc);
|
std::ofstream state(entry.path().string() + "/state.toml", std::ios::trunc);
|
||||||
state << modifiedState;
|
state << STATE;
|
||||||
state.close();
|
state.close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <filesystem>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Plugin.hpp"
|
#include "Plugin.hpp"
|
||||||
@@ -10,15 +9,14 @@ struct SGlobalState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace DataState {
|
namespace DataState {
|
||||||
std::filesystem::path getDataStatePath();
|
std::string getDataStatePath();
|
||||||
std::string getHeadersPath();
|
std::string getHeadersPath();
|
||||||
std::vector<std::filesystem::path> getPluginStates();
|
void ensureStateStoreExists();
|
||||||
void ensureStateStoreExists();
|
void addNewPluginRepo(const SPluginRepository& repo);
|
||||||
void addNewPluginRepo(const SPluginRepository& repo);
|
void removePluginRepo(const std::string& urlOrName);
|
||||||
void removePluginRepo(const std::string& urlOrName);
|
bool pluginRepoExists(const std::string& urlOrName);
|
||||||
bool pluginRepoExists(const std::string& urlOrName);
|
void updateGlobalState(const SGlobalState& state);
|
||||||
void updateGlobalState(const SGlobalState& state);
|
SGlobalState getGlobalState();
|
||||||
SGlobalState getGlobalState();
|
bool setPluginEnabled(const std::string& name, bool enabled);
|
||||||
bool setPluginEnabled(const std::string& name, bool enabled);
|
std::vector<SPluginRepository> getAllRepositories();
|
||||||
std::vector<SPluginRepository> getAllRepositories();
|
|
||||||
};
|
};
|
@@ -6,7 +6,7 @@ CManifest::CManifest(const eManifestType type, const std::string& path) {
|
|||||||
auto manifest = toml::parse_file(path);
|
auto manifest = toml::parse_file(path);
|
||||||
|
|
||||||
if (type == MANIFEST_HYPRLOAD) {
|
if (type == MANIFEST_HYPRLOAD) {
|
||||||
for (auto const& [key, val] : manifest) {
|
for (auto& [key, val] : manifest) {
|
||||||
if (key.str().ends_with(".build"))
|
if (key.str().ends_with(".build"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ CManifest::CManifest(const eManifestType type, const std::string& path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& [key, val] : manifest) {
|
for (auto& [key, val] : manifest) {
|
||||||
if (key.str() == "repository")
|
if (key.str() == "repository")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
enum eHeadersErrors {
|
enum eHeadersErrors {
|
||||||
HEADERS_OK = 0,
|
HEADERS_OK = 0,
|
||||||
@@ -27,8 +26,7 @@ enum ePluginLoadStateReturn {
|
|||||||
LOADSTATE_OK = 0,
|
LOADSTATE_OK = 0,
|
||||||
LOADSTATE_FAIL,
|
LOADSTATE_FAIL,
|
||||||
LOADSTATE_PARTIAL_FAIL,
|
LOADSTATE_PARTIAL_FAIL,
|
||||||
LOADSTATE_HEADERS_OUTDATED,
|
LOADSTATE_HEADERS_OUTDATED
|
||||||
LOADSTATE_HYPRLAND_UPDATED
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHyprlandVersion {
|
struct SHyprlandVersion {
|
||||||
@@ -51,10 +49,10 @@ class CPluginManager {
|
|||||||
|
|
||||||
bool enablePlugin(const std::string& name);
|
bool enablePlugin(const std::string& name);
|
||||||
bool disablePlugin(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);
|
bool loadUnloadPlugin(const std::string& path, bool load);
|
||||||
SHyprlandVersion getHyprlandVersion(bool running = true);
|
SHyprlandVersion getHyprlandVersion();
|
||||||
|
|
||||||
void notify(const eNotifyIcons icon, uint32_t color, int durationMs, const std::string& message);
|
void notify(const eNotifyIcons icon, uint32_t color, int durationMs, const std::string& message);
|
||||||
|
|
||||||
@@ -70,7 +68,7 @@ class CPluginManager {
|
|||||||
std::string headerError(const eHeadersErrors err);
|
std::string headerError(const eHeadersErrors err);
|
||||||
std::string headerErrorShort(const eHeadersErrors err);
|
std::string headerErrorShort(const eHeadersErrors err);
|
||||||
|
|
||||||
std::string m_szWorkingPluginDirectory;
|
std::string m_szWorkingPluginDirectory = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CPluginManager> g_pPluginManager;
|
inline std::unique_ptr<CPluginManager> g_pPluginManager;
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <format>
|
|
||||||
#include <string>
|
|
||||||
#include "Colors.hpp"
|
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
std::string statusString(const std::string_view emoji, const std::string_view color, const std::string_view fmt, Args&&... args) {
|
|
||||||
std::string ret = std::format("{}{}{} ", color, emoji, Colors::RESET);
|
|
||||||
ret += std::vformat(fmt, std::make_format_args(args...));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
std::string successString(const std::string_view fmt, Args&&... args) {
|
|
||||||
return statusString("✔", Colors::GREEN, fmt, args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
std::string failureString(const std::string_view fmt, Args&&... args) {
|
|
||||||
return statusString("✖", Colors::RED, fmt, args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
std::string verboseString(const std::string_view fmt, Args&&... args) {
|
|
||||||
return statusString("[v]", Colors::BLUE, fmt, args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
std::string infoString(const std::string_view fmt, Args&&... args) {
|
|
||||||
return statusString("→", Colors::RESET, fmt, args...);
|
|
||||||
}
|
|
@@ -1,16 +1,15 @@
|
|||||||
|
#include "progress/CProgressBar.hpp"
|
||||||
#include "helpers/Colors.hpp"
|
#include "helpers/Colors.hpp"
|
||||||
#include "helpers/StringUtils.hpp"
|
|
||||||
#include "core/PluginManager.hpp"
|
#include "core/PluginManager.hpp"
|
||||||
#include "core/DataState.hpp"
|
#include "core/DataState.hpp"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <print>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
constexpr std::string_view HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
const std::string HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
||||||
┃
|
┃
|
||||||
┣ add [url] [git rev] → Install a new plugin repository from git. Git revision
|
┣ add [url] [git rev] → Install a new plugin repository from git. Git revision
|
||||||
┃ is optional, when set, commit locks are ignored.
|
┃ is optional, when set, commit locks are ignored.
|
||||||
@@ -23,8 +22,7 @@ constexpr std::string_view HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
|||||||
┃
|
┃
|
||||||
┣ Flags:
|
┣ Flags:
|
||||||
┃
|
┃
|
||||||
┣ --notify | -n → Send a hyprland notification for important events (including both successes and fail events)
|
┣ --notify | -n → Send a hyprland notification for important events (e.g. load fail)
|
||||||
┣ --notify-fail | -nn → Send a hyprland notification for fail events only
|
|
||||||
┣ --help | -h → Show this menu
|
┣ --help | -h → Show this menu
|
||||||
┣ --verbose | -v → Enable too much logging
|
┣ --verbose | -v → Enable too much logging
|
||||||
┣ --force | -f → Force an operation ignoring checks (e.g. update -f)
|
┣ --force | -f → Force an operation ignoring checks (e.g. update -f)
|
||||||
@@ -32,38 +30,36 @@ constexpr std::string_view HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
|||||||
┗
|
┗
|
||||||
)#";
|
)#";
|
||||||
|
|
||||||
int main(int argc, char** argv, char** envp) {
|
int main(int argc, char** argv, char** envp) {
|
||||||
std::vector<std::string> ARGS{argc};
|
std::vector<std::string> ARGS{argc};
|
||||||
for (int i = 0; i < argc; ++i) {
|
for (int i = 0; i < argc; ++i) {
|
||||||
ARGS[i] = std::string{argv[i]};
|
ARGS[i] = std::string{argv[i]};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ARGS.size() < 2) {
|
if (ARGS.size() < 2) {
|
||||||
std::println(stderr, "{}", HELP);
|
std::cout << HELP;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> command;
|
std::vector<std::string> command;
|
||||||
bool notify = false, notifyFail = false, verbose = false, force = false, noShallow = false;
|
bool notify = false, verbose = false, force = false, noShallow = false;
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
if (ARGS[i].starts_with("-")) {
|
if (ARGS[i].starts_with("-")) {
|
||||||
if (ARGS[i] == "--help" || ARGS[i] == "-h") {
|
if (ARGS[i] == "--help" || ARGS[i] == "-h") {
|
||||||
std::println("{}", HELP);
|
std::cout << HELP;
|
||||||
return 0;
|
return 0;
|
||||||
} else if (ARGS[i] == "--notify" || ARGS[i] == "-n") {
|
} else if (ARGS[i] == "--notify" || ARGS[i] == "-n") {
|
||||||
notify = true;
|
notify = true;
|
||||||
} else if (ARGS[i] == "--notify-fail" || ARGS[i] == "-nn") {
|
|
||||||
notifyFail = notify = true;
|
|
||||||
} else if (ARGS[i] == "--verbose" || ARGS[i] == "-v") {
|
} else if (ARGS[i] == "--verbose" || ARGS[i] == "-v") {
|
||||||
verbose = true;
|
verbose = true;
|
||||||
} else if (ARGS[i] == "--no-shallow" || ARGS[i] == "-s") {
|
} else if (ARGS[i] == "--no-shallow" || ARGS[i] == "-s") {
|
||||||
noShallow = true;
|
noShallow = true;
|
||||||
} else if (ARGS[i] == "--force" || ARGS[i] == "-f") {
|
} else if (ARGS[i] == "--force" || ARGS[i] == "-f") {
|
||||||
force = true;
|
force = true;
|
||||||
std::println("{}", statusString("!", Colors::RED, "Using --force, I hope you know what you are doing."));
|
std::cout << Colors::RED << "!" << Colors::RESET << " Using --force, I hope you know what you are doing.\n";
|
||||||
} else {
|
} else {
|
||||||
std::println(stderr, "Unrecognized option {}", ARGS[i]);
|
std::cerr << "Unrecognized option " << ARGS[i] << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -72,8 +68,8 @@ int main(int argc, char** argv, char** envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (command.empty()) {
|
if (command.empty()) {
|
||||||
std::println(stderr, "{}", HELP);
|
std::cout << HELP;
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pPluginManager = std::make_unique<CPluginManager>();
|
g_pPluginManager = std::make_unique<CPluginManager>();
|
||||||
@@ -82,7 +78,7 @@ int main(int argc, char** argv, char** envp) {
|
|||||||
|
|
||||||
if (command[0] == "add") {
|
if (command[0] == "add") {
|
||||||
if (command.size() < 2) {
|
if (command.size() < 2) {
|
||||||
std::println(stderr, "{}", failureString("Not enough args for add."));
|
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for add.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +90,7 @@ int main(int argc, char** argv, char** envp) {
|
|||||||
return g_pPluginManager->addNewPluginRepo(command[1], rev) ? 0 : 1;
|
return g_pPluginManager->addNewPluginRepo(command[1], rev) ? 0 : 1;
|
||||||
} else if (command[0] == "remove") {
|
} else if (command[0] == "remove") {
|
||||||
if (ARGS.size() < 2) {
|
if (ARGS.size() < 2) {
|
||||||
std::println(stderr, "{}", failureString("Not enough args for remove."));
|
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for remove.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +99,7 @@ int main(int argc, char** argv, char** envp) {
|
|||||||
bool headersValid = g_pPluginManager->headersValid() == HEADERS_OK;
|
bool headersValid = g_pPluginManager->headersValid() == HEADERS_OK;
|
||||||
bool headers = g_pPluginManager->updateHeaders(force);
|
bool headers = g_pPluginManager->updateHeaders(force);
|
||||||
if (headers) {
|
if (headers) {
|
||||||
const auto HLVER = g_pPluginManager->getHyprlandVersion(false);
|
const auto HLVER = g_pPluginManager->getHyprlandVersion();
|
||||||
auto GLOBALSTATE = DataState::getGlobalState();
|
auto GLOBALSTATE = DataState::getGlobalState();
|
||||||
const auto COMPILEDOUTDATED = HLVER.hash != GLOBALSTATE.headersHashCompiled;
|
const auto COMPILEDOUTDATED = HLVER.hash != GLOBALSTATE.headersHashCompiled;
|
||||||
|
|
||||||
@@ -114,39 +110,32 @@ int main(int argc, char** argv, char** envp) {
|
|||||||
|
|
||||||
auto ret2 = g_pPluginManager->ensurePluginsLoadState();
|
auto ret2 = g_pPluginManager->ensurePluginsLoadState();
|
||||||
|
|
||||||
if (ret2 == LOADSTATE_HYPRLAND_UPDATED)
|
|
||||||
g_pPluginManager->notify(ICON_INFO, 0, 10000, "[hyprpm] Updated plugins, but Hyprland was updated. Please restart Hyprland.");
|
|
||||||
|
|
||||||
if (ret2 != LOADSTATE_OK)
|
if (ret2 != LOADSTATE_OK)
|
||||||
return 1;
|
return 1;
|
||||||
} else if (notify)
|
} else if (notify)
|
||||||
g_pPluginManager->notify(ICON_ERROR, 0, 10000, "[hyprpm] Couldn't update headers");
|
g_pPluginManager->notify(ICON_ERROR, 0, 10000, "[hyprpm] Couldn't update headers");
|
||||||
} else if (command[0] == "enable") {
|
} else if (command[0] == "enable") {
|
||||||
if (ARGS.size() < 2) {
|
if (ARGS.size() < 2) {
|
||||||
std::println(stderr, "{}", failureString("Not enough args for enable."));
|
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for enable.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_pPluginManager->enablePlugin(command[1])) {
|
if (!g_pPluginManager->enablePlugin(command[1])) {
|
||||||
std::println(stderr, "{}", failureString("Couldn't enable plugin (missing?)"));
|
std::cerr << Colors::RED << "✖" << Colors::RESET << " Couldn't enable plugin (missing?)\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ret = g_pPluginManager->ensurePluginsLoadState();
|
auto ret = g_pPluginManager->ensurePluginsLoadState();
|
||||||
|
|
||||||
if (ret == LOADSTATE_HYPRLAND_UPDATED)
|
|
||||||
g_pPluginManager->notify(ICON_INFO, 0, 10000, "[hyprpm] Enabled plugin, but Hyprland was updated. Please restart Hyprland.");
|
|
||||||
|
|
||||||
if (ret != LOADSTATE_OK)
|
if (ret != LOADSTATE_OK)
|
||||||
return 1;
|
return 1;
|
||||||
} else if (command[0] == "disable") {
|
} else if (command[0] == "disable") {
|
||||||
if (command.size() < 2) {
|
if (command.size() < 2) {
|
||||||
std::println(stderr, "{}", failureString("Not enough args for disable."));
|
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for disable.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_pPluginManager->disablePlugin(command[1])) {
|
if (!g_pPluginManager->disablePlugin(command[1])) {
|
||||||
std::println(stderr, "{}", failureString("Couldn't disable plugin (missing?)"));
|
std::cerr << Colors::RED << "✖" << Colors::RESET << " Couldn't disable plugin (missing?)\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +143,7 @@ int main(int argc, char** argv, char** envp) {
|
|||||||
if (ret != LOADSTATE_OK)
|
if (ret != LOADSTATE_OK)
|
||||||
return 1;
|
return 1;
|
||||||
} else if (command[0] == "reload") {
|
} else if (command[0] == "reload") {
|
||||||
auto ret = g_pPluginManager->ensurePluginsLoadState(force);
|
auto ret = g_pPluginManager->ensurePluginsLoadState();
|
||||||
|
|
||||||
if (ret != LOADSTATE_OK && notify) {
|
if (ret != LOADSTATE_OK && notify) {
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
@@ -165,14 +154,13 @@ int main(int argc, char** argv, char** envp) {
|
|||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 1;
|
} else if (notify) {
|
||||||
} else if (notify && !notifyFail) {
|
|
||||||
g_pPluginManager->notify(ICON_OK, 0, 4000, "[hyprpm] Loaded plugins");
|
g_pPluginManager->notify(ICON_OK, 0, 4000, "[hyprpm] Loaded plugins");
|
||||||
}
|
}
|
||||||
} else if (command[0] == "list") {
|
} else if (command[0] == "list") {
|
||||||
g_pPluginManager->listAllPlugins();
|
g_pPluginManager->listAllPlugins();
|
||||||
} else {
|
} else {
|
||||||
std::println(stderr, "{}", HELP);
|
std::cout << HELP;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,32 +1,15 @@
|
|||||||
globber = run_command('sh', '-c', 'find . -name "*.cpp" | sort', check: true)
|
globber = run_command('sh', '-c', 'find . -name "*.cpp" | sort', check: true)
|
||||||
src = globber.stdout().strip().split('\n')
|
src = globber.stdout().strip().split('\n')
|
||||||
|
|
||||||
executable(
|
executable('hyprpm', src,
|
||||||
'hyprpm',
|
|
||||||
src,
|
|
||||||
dependencies: [
|
dependencies: [
|
||||||
dependency('hyprutils', version: '>= 0.1.1'),
|
dependency('hyprutils', version: '>= 0.1.1'),
|
||||||
dependency('threads'),
|
dependency('threads'),
|
||||||
dependency('tomlplusplus'),
|
dependency('tomlplusplus')
|
||||||
dependency('glaze', method: 'cmake'),
|
|
||||||
],
|
],
|
||||||
install: true,
|
install : true
|
||||||
)
|
)
|
||||||
|
|
||||||
install_data(
|
install_data('../hyprpm.bash', install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'), install_tag: 'runtime', rename: 'hyprpm')
|
||||||
'../hyprpm.bash',
|
install_data('../hyprpm.fish', install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'), install_tag: 'runtime')
|
||||||
install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'),
|
install_data('../hyprpm.zsh', install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'), install_tag: 'runtime', rename: '_hyprpm')
|
||||||
install_tag: 'runtime',
|
|
||||||
rename: 'hyprpm',
|
|
||||||
)
|
|
||||||
install_data(
|
|
||||||
'../hyprpm.fish',
|
|
||||||
install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'),
|
|
||||||
install_tag: 'runtime',
|
|
||||||
)
|
|
||||||
install_data(
|
|
||||||
'../hyprpm.zsh',
|
|
||||||
install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'),
|
|
||||||
install_tag: 'runtime',
|
|
||||||
rename: '_hyprpm',
|
|
||||||
)
|
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
#include "CProgressBar.hpp"
|
#include "CProgressBar.hpp"
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
#include <print>
|
#include <sys/ioctl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@@ -16,12 +16,11 @@ void CProgressBar::printMessageAbove(const std::string& msg) {
|
|||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
|
||||||
std::string spaces;
|
std::string spaces;
|
||||||
spaces.reserve(w.ws_col);
|
|
||||||
for (size_t i = 0; i < w.ws_col; ++i) {
|
for (size_t i = 0; i < w.ws_col; ++i) {
|
||||||
spaces += ' ';
|
spaces += ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
std::println("\r{}\r{}", spaces, msg);
|
std::cout << "\r" << spaces << "\r" << msg << "\n";
|
||||||
print();
|
print();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,16 +29,15 @@ void CProgressBar::print() {
|
|||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
|
||||||
if (m_bFirstPrint)
|
if (m_bFirstPrint)
|
||||||
std::print("\n");
|
std::cout << "\n";
|
||||||
m_bFirstPrint = false;
|
m_bFirstPrint = false;
|
||||||
|
|
||||||
std::string spaces;
|
std::string spaces;
|
||||||
spaces.reserve(w.ws_col);
|
|
||||||
for (size_t i = 0; i < w.ws_col; ++i) {
|
for (size_t i = 0; i < w.ws_col; ++i) {
|
||||||
spaces += ' ';
|
spaces += ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
std::print("\r{}\r", spaces);
|
std::cout << "\r" << spaces << "\r";
|
||||||
|
|
||||||
std::string message = "";
|
std::string message = "";
|
||||||
|
|
||||||
@@ -76,7 +74,7 @@ void CProgressBar::print() {
|
|||||||
message += " " + std::format("{} / {}", m_iSteps, m_iMaxSteps) + " ";
|
message += " " + std::format("{} / {}", m_iSteps, m_iMaxSteps) + " ";
|
||||||
|
|
||||||
// draw message
|
// draw message
|
||||||
std::print("{} {}", message, m_szCurrentMessage);
|
std::cout << message + " " + m_szCurrentMessage;
|
||||||
|
|
||||||
std::fflush(stdout);
|
std::fflush(stdout);
|
||||||
}
|
}
|
66
meson.build
@@ -1,17 +1,13 @@
|
|||||||
project(
|
project('Hyprland', 'cpp', 'c',
|
||||||
'Hyprland',
|
version : run_command('cat', join_paths(meson.source_root(), 'VERSION'), check: true).stdout().strip(),
|
||||||
'cpp',
|
default_options : [
|
||||||
'c',
|
|
||||||
version: run_command('cat', join_paths(meson.project_source_root(), 'VERSION'), check: true).stdout().strip(),
|
|
||||||
default_options: [
|
|
||||||
'warning_level=2',
|
'warning_level=2',
|
||||||
'default_library=static',
|
'default_library=static',
|
||||||
'optimization=3',
|
'optimization=3',
|
||||||
'buildtype=release',
|
'buildtype=release',
|
||||||
'debug=false',
|
'debug=false',
|
||||||
'cpp_std=c++26',
|
'cpp_std=c++26',
|
||||||
],
|
])
|
||||||
)
|
|
||||||
|
|
||||||
datarootdir = '-DDATAROOTDIR="' + get_option('prefix') / get_option('datadir') + '"'
|
datarootdir = '-DDATAROOTDIR="' + get_option('prefix') / get_option('datadir') + '"'
|
||||||
add_project_arguments(
|
add_project_arguments(
|
||||||
@@ -20,28 +16,16 @@ add_project_arguments(
|
|||||||
'-Wno-unused-value',
|
'-Wno-unused-value',
|
||||||
'-Wno-missing-field-initializers',
|
'-Wno-missing-field-initializers',
|
||||||
'-Wno-narrowing',
|
'-Wno-narrowing',
|
||||||
'-Wno-pointer-arith', datarootdir,
|
'-Wno-pointer-arith',
|
||||||
'-DHYPRLAND_VERSION="' + meson.project_version() + '"',
|
datarootdir,
|
||||||
],
|
],
|
||||||
language: 'cpp',
|
language: 'cpp')
|
||||||
)
|
|
||||||
|
|
||||||
cpp_compiler = meson.get_compiler('cpp')
|
cpp_compiler = meson.get_compiler('cpp')
|
||||||
if cpp_compiler.check_header('execinfo.h')
|
if cpp_compiler.check_header('execinfo.h')
|
||||||
add_project_arguments('-DHAS_EXECINFO', language: 'cpp')
|
add_project_arguments('-DHAS_EXECINFO', language: 'cpp')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
aquamarine = dependency('aquamarine', version: '>=0.4.5')
|
|
||||||
hyprcursor = dependency('hyprcursor', version: '>=0.1.7')
|
|
||||||
hyprgraphics = dependency('hyprgraphics', version: '>= 0.1.1')
|
|
||||||
hyprlang = dependency('hyprlang', version: '>= 0.3.2')
|
|
||||||
hyprutils = dependency('hyprutils', version: '>= 0.2.3')
|
|
||||||
add_project_arguments(['-DAQUAMARINE_VERSION="@0@"'.format(aquamarine.version())], language: 'cpp')
|
|
||||||
add_project_arguments(['-DHYPRCURSOR_VERSION="@0@"'.format(hyprcursor.version())], language: 'cpp')
|
|
||||||
add_project_arguments(['-DHYPRGRAPHICS_VERSION="@0@"'.format(hyprgraphics.version())], language: 'cpp')
|
|
||||||
add_project_arguments(['-DHYPRLANG_VERSION="@0@"'.format(hyprlang.version())], language: 'cpp')
|
|
||||||
add_project_arguments(['-DHYPRUTILS_VERSION="@0@"'.format(hyprutils.version())], language: 'cpp')
|
|
||||||
|
|
||||||
xcb_dep = dependency('xcb', required: get_option('xwayland'))
|
xcb_dep = dependency('xcb', required: get_option('xwayland'))
|
||||||
xcb_composite_dep = dependency('xcb-composite', required: get_option('xwayland'))
|
xcb_composite_dep = dependency('xcb-composite', required: get_option('xwayland'))
|
||||||
xcb_errors_dep = dependency('xcb-errors', required: get_option('xwayland'))
|
xcb_errors_dep = dependency('xcb-errors', required: get_option('xwayland'))
|
||||||
@@ -50,7 +34,11 @@ xcb_render_dep = dependency('xcb-render', required: get_option('xwayland'))
|
|||||||
xcb_res_dep = dependency('xcb-res', required: get_option('xwayland'))
|
xcb_res_dep = dependency('xcb-res', required: get_option('xwayland'))
|
||||||
xcb_xfixes_dep = dependency('xcb-xfixes', required: get_option('xwayland'))
|
xcb_xfixes_dep = dependency('xcb-xfixes', required: get_option('xwayland'))
|
||||||
|
|
||||||
gio_dep = dependency('gio-2.0', required: true)
|
gio_dep = dependency('gio-2.0', required:true)
|
||||||
|
|
||||||
|
cmake = import('cmake')
|
||||||
|
udis = cmake.subproject('udis86')
|
||||||
|
udis86 = udis.dependency('libudis86')
|
||||||
|
|
||||||
if not xcb_dep.found()
|
if not xcb_dep.found()
|
||||||
add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
|
add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
|
||||||
@@ -58,19 +46,9 @@ endif
|
|||||||
|
|
||||||
backtrace_dep = cpp_compiler.find_library('execinfo', required: false)
|
backtrace_dep = cpp_compiler.find_library('execinfo', required: false)
|
||||||
epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs
|
epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs
|
||||||
inotify_dep = dependency('libinotify', required: false) # inotify on BSDs
|
|
||||||
|
|
||||||
re2 = dependency('re2', required: true)
|
if get_option('systemd').enabled()
|
||||||
|
|
||||||
# Handle options
|
|
||||||
systemd_option = get_option('systemd')
|
|
||||||
systemd = dependency('systemd', required: systemd_option)
|
|
||||||
systemd_option.enable_auto_if(systemd.found())
|
|
||||||
|
|
||||||
if (systemd_option.enabled())
|
|
||||||
message('Enabling systemd integration')
|
|
||||||
add_project_arguments('-DUSES_SYSTEMD', language: 'cpp')
|
add_project_arguments('-DUSES_SYSTEMD', language: 'cpp')
|
||||||
subdir('systemd')
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if get_option('legacy_renderer').enabled()
|
if get_option('legacy_renderer').enabled()
|
||||||
@@ -81,36 +59,22 @@ if get_option('buildtype') == 'debug'
|
|||||||
add_project_arguments('-DHYPRLAND_DEBUG', language: 'cpp')
|
add_project_arguments('-DHYPRLAND_DEBUG', language: 'cpp')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Generate hyprland version and populate version.h
|
version_h = run_command('sh', '-c', 'scripts/generateVersion.sh', check: true)
|
||||||
run_command('sh', '-c', 'scripts/generateVersion.sh', check: true)
|
|
||||||
|
|
||||||
# Install headers
|
|
||||||
globber = run_command('find', 'src', '-name', '*.h*', check: true)
|
globber = run_command('find', 'src', '-name', '*.h*', check: true)
|
||||||
headers = globber.stdout().strip().split('\n')
|
headers = globber.stdout().strip().split('\n')
|
||||||
foreach file : headers
|
foreach file : headers
|
||||||
install_headers(file, subdir: 'hyprland', preserve_path: true)
|
install_headers(file, subdir: 'hyprland', preserve_path: true)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
tracy = dependency('tracy', static: true, required: get_option('tracy_enable'))
|
|
||||||
|
|
||||||
if get_option('tracy_enable') and get_option('buildtype') != 'debugoptimized'
|
|
||||||
warning('Profiling builds should set -- buildtype = debugoptimized')
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
subdir('protocols')
|
subdir('protocols')
|
||||||
subdir('src')
|
subdir('src')
|
||||||
subdir('hyprctl')
|
subdir('hyprctl')
|
||||||
|
subdir('hyprpm/src')
|
||||||
subdir('assets')
|
subdir('assets')
|
||||||
subdir('example')
|
subdir('example')
|
||||||
subdir('docs')
|
subdir('docs')
|
||||||
|
|
||||||
if get_option('hyprpm').enabled()
|
|
||||||
subdir('hyprpm/src')
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Generate hyprland.pc
|
|
||||||
pkg_install_dir = join_paths(get_option('datadir'), 'pkgconfig')
|
pkg_install_dir = join_paths(get_option('datadir'), 'pkgconfig')
|
||||||
|
|
||||||
import('pkgconfig').generate(
|
import('pkgconfig').generate(
|
||||||
|
@@ -1,6 +1,3 @@
|
|||||||
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')
|
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')
|
||||||
option('systemd', type: 'feature', value: 'auto', description: 'Enable systemd integration')
|
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('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')
|
|
||||||
|
272
nix/default.nix
@@ -1,38 +1,43 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
stdenv,
|
stdenv,
|
||||||
stdenvAdapters,
|
|
||||||
pkg-config,
|
pkg-config,
|
||||||
pkgconf,
|
pkgconf,
|
||||||
makeWrapper,
|
makeWrapper,
|
||||||
cmake,
|
cmake,
|
||||||
meson,
|
|
||||||
ninja,
|
ninja,
|
||||||
aquamarine,
|
aquamarine,
|
||||||
binutils,
|
binutils,
|
||||||
cairo,
|
cairo,
|
||||||
|
expat,
|
||||||
|
fribidi,
|
||||||
git,
|
git,
|
||||||
glaze,
|
hwdata,
|
||||||
hyprcursor,
|
hyprcursor,
|
||||||
hyprgraphics,
|
|
||||||
hyprland-protocols,
|
|
||||||
hyprland-qtutils,
|
|
||||||
hyprlang,
|
hyprlang,
|
||||||
hyprutils,
|
hyprutils,
|
||||||
hyprwayland-scanner,
|
hyprwayland-scanner,
|
||||||
|
jq,
|
||||||
libGL,
|
libGL,
|
||||||
|
libdatrie,
|
||||||
|
libdisplay-info,
|
||||||
libdrm,
|
libdrm,
|
||||||
libexecinfo,
|
libexecinfo,
|
||||||
libinput,
|
libinput,
|
||||||
libxkbcommon,
|
libliftoff,
|
||||||
|
libselinux,
|
||||||
|
libsepol,
|
||||||
|
libthai,
|
||||||
libuuid,
|
libuuid,
|
||||||
|
libxkbcommon,
|
||||||
mesa,
|
mesa,
|
||||||
pango,
|
pango,
|
||||||
pciutils,
|
pciutils,
|
||||||
re2,
|
pcre2,
|
||||||
|
python3,
|
||||||
|
seatd,
|
||||||
systemd,
|
systemd,
|
||||||
tomlplusplus,
|
tomlplusplus,
|
||||||
udis86-hyprland,
|
|
||||||
wayland,
|
wayland,
|
||||||
wayland-protocols,
|
wayland-protocols,
|
||||||
wayland-scanner,
|
wayland-scanner,
|
||||||
@@ -45,151 +50,140 @@
|
|||||||
wrapRuntimeDeps ? true,
|
wrapRuntimeDeps ? true,
|
||||||
version ? "git",
|
version ? "git",
|
||||||
commit,
|
commit,
|
||||||
revCount,
|
|
||||||
date,
|
date,
|
||||||
# deprecated flags
|
# deprecated flags
|
||||||
enableNvidiaPatches ? false,
|
enableNvidiaPatches ? false,
|
||||||
nvidiaPatches ? false,
|
nvidiaPatches ? false,
|
||||||
hidpiXWayland ? false,
|
hidpiXWayland ? false,
|
||||||
}: let
|
}:
|
||||||
inherit (builtins) baseNameOf foldl' readFile;
|
assert lib.assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed.";
|
||||||
inherit (lib.asserts) assertMsg;
|
assert lib.assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` has been removed.";
|
||||||
inherit (lib.attrsets) mapAttrsToList;
|
assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hyprland.org/Configuring/XWayland";
|
||||||
inherit (lib.lists) flatten concatLists optional optionals;
|
stdenv.mkDerivation {
|
||||||
inherit (lib.sources) cleanSourceWith cleanSource;
|
pname = "hyprland${lib.optionalString debug "-debug"}";
|
||||||
inherit (lib.strings) hasSuffix makeBinPath optionalString mesonBool mesonEnable trim;
|
inherit version;
|
||||||
|
|
||||||
adapters = flatten [
|
src = lib.cleanSourceWith {
|
||||||
stdenvAdapters.useMoldLinker
|
filter = name: type: let
|
||||||
(lib.optional debug stdenvAdapters.keepDebugInfo)
|
baseName = baseNameOf (toString name);
|
||||||
];
|
in
|
||||||
|
! (lib.hasSuffix ".nix" baseName);
|
||||||
|
src = lib.cleanSource ../.;
|
||||||
|
};
|
||||||
|
|
||||||
customStdenv = foldl' (acc: adapter: adapter acc) stdenv adapters;
|
patches = [
|
||||||
in
|
# forces GCC to use -std=c++26
|
||||||
assert assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed.";
|
./stdcxx.patch
|
||||||
assert assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` has been removed.";
|
];
|
||||||
assert assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hyprland.org/Configuring/XWayland";
|
|
||||||
customStdenv.mkDerivation (finalAttrs: {
|
|
||||||
pname = "hyprland${optionalString debug "-debug"}";
|
|
||||||
inherit version;
|
|
||||||
|
|
||||||
src = cleanSourceWith {
|
postPatch = ''
|
||||||
filter = name: _type: let
|
# Fix hardcoded paths to /usr installation
|
||||||
baseName = baseNameOf (toString name);
|
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
|
||||||
in
|
|
||||||
! (hasSuffix ".nix" baseName);
|
|
||||||
src = cleanSource ../.;
|
|
||||||
};
|
|
||||||
|
|
||||||
postPatch = ''
|
# Remove extra @PREFIX@ to fix pkg-config paths
|
||||||
# Fix hardcoded paths to /usr installation
|
sed -i "s#@PREFIX@/##g" hyprland.pc.in
|
||||||
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
|
'';
|
||||||
|
|
||||||
# Remove extra @PREFIX@ to fix pkg-config paths
|
COMMITS = commit;
|
||||||
sed -i "s#@PREFIX@/##g" hyprland.pc.in
|
DATE = date;
|
||||||
'';
|
DIRTY = lib.optionalString (commit == "") "dirty";
|
||||||
|
HASH = commit;
|
||||||
|
|
||||||
COMMITS = revCount;
|
nativeBuildInputs = [
|
||||||
DATE = date;
|
hyprwayland-scanner
|
||||||
DIRTY = optionalString (commit == "") "dirty";
|
jq
|
||||||
HASH = commit;
|
makeWrapper
|
||||||
TAG = "v${trim (readFile "${finalAttrs.src}/VERSION")}";
|
cmake
|
||||||
|
ninja
|
||||||
|
pkg-config
|
||||||
|
python3 # for udis86
|
||||||
|
# re-add after https://github.com/NixOS/nixpkgs/pull/214906 hits nixos-unstable
|
||||||
|
# wayland-scanner
|
||||||
|
];
|
||||||
|
|
||||||
depsBuildBuild = [
|
outputs = [
|
||||||
pkg-config
|
"out"
|
||||||
];
|
"man"
|
||||||
|
"dev"
|
||||||
|
];
|
||||||
|
|
||||||
nativeBuildInputs = [
|
buildInputs = lib.concatLists [
|
||||||
hyprwayland-scanner
|
[
|
||||||
makeWrapper
|
aquamarine
|
||||||
meson
|
cairo
|
||||||
ninja
|
expat
|
||||||
cmake # needed for glaze
|
fribidi
|
||||||
pkg-config
|
git
|
||||||
];
|
hwdata
|
||||||
|
hyprcursor
|
||||||
|
hyprlang
|
||||||
|
hyprutils
|
||||||
|
libdatrie
|
||||||
|
libdisplay-info
|
||||||
|
libdrm
|
||||||
|
libGL
|
||||||
|
libinput
|
||||||
|
libliftoff
|
||||||
|
libselinux
|
||||||
|
libsepol
|
||||||
|
libthai
|
||||||
|
libuuid
|
||||||
|
libxkbcommon
|
||||||
|
mesa
|
||||||
|
pango
|
||||||
|
pciutils
|
||||||
|
pcre2
|
||||||
|
seatd
|
||||||
|
tomlplusplus
|
||||||
|
wayland
|
||||||
|
wayland-protocols
|
||||||
|
xorg.libXcursor
|
||||||
|
]
|
||||||
|
(lib.optionals stdenv.hostPlatform.isMusl [libexecinfo])
|
||||||
|
(lib.optionals enableXWayland [
|
||||||
|
xorg.libxcb
|
||||||
|
xorg.libXdmcp
|
||||||
|
xorg.xcbutil
|
||||||
|
xorg.xcbutilerrors
|
||||||
|
xorg.xcbutilrenderutil
|
||||||
|
xorg.xcbutilwm
|
||||||
|
xwayland
|
||||||
|
])
|
||||||
|
(lib.optionals withSystemd [systemd])
|
||||||
|
];
|
||||||
|
|
||||||
outputs = [
|
cmakeBuildType =
|
||||||
"out"
|
if debug
|
||||||
"man"
|
then "Debug"
|
||||||
"dev"
|
else "RelWithDebInfo";
|
||||||
];
|
|
||||||
|
|
||||||
buildInputs = concatLists [
|
# we want as much debug info as possible
|
||||||
[
|
dontStrip = debug;
|
||||||
aquamarine
|
|
||||||
cairo
|
cmakeFlags = [
|
||||||
git
|
(lib.cmakeBool "NO_XWAYLAND" (!enableXWayland))
|
||||||
glaze
|
(lib.cmakeBool "LEGACY_RENDERER" legacyRenderer)
|
||||||
hyprcursor
|
(lib.cmakeBool "NO_SYSTEMD" (!withSystemd))
|
||||||
hyprgraphics
|
];
|
||||||
hyprland-protocols
|
|
||||||
hyprlang
|
postInstall = ''
|
||||||
hyprutils
|
${lib.optionalString wrapRuntimeDeps ''
|
||||||
libdrm
|
wrapProgram $out/bin/Hyprland \
|
||||||
libGL
|
--suffix PATH : ${lib.makeBinPath [
|
||||||
libinput
|
binutils
|
||||||
libuuid
|
|
||||||
libxkbcommon
|
|
||||||
mesa
|
|
||||||
pango
|
|
||||||
pciutils
|
pciutils
|
||||||
re2
|
pkgconf
|
||||||
tomlplusplus
|
]}
|
||||||
udis86-hyprland
|
''}
|
||||||
wayland
|
'';
|
||||||
wayland-protocols
|
|
||||||
wayland-scanner
|
|
||||||
xorg.libXcursor
|
|
||||||
]
|
|
||||||
(optionals customStdenv.hostPlatform.isMusl [libexecinfo])
|
|
||||||
(optionals enableXWayland [
|
|
||||||
xorg.libxcb
|
|
||||||
xorg.libXdmcp
|
|
||||||
xorg.xcbutilerrors
|
|
||||||
xorg.xcbutilrenderutil
|
|
||||||
xorg.xcbutilwm
|
|
||||||
xwayland
|
|
||||||
])
|
|
||||||
(optional withSystemd systemd)
|
|
||||||
];
|
|
||||||
|
|
||||||
mesonBuildType =
|
passthru.providedSessions = ["hyprland"];
|
||||||
if debug
|
|
||||||
then "debugoptimized"
|
|
||||||
else "release";
|
|
||||||
|
|
||||||
mesonFlags = flatten [
|
meta = {
|
||||||
(mapAttrsToList mesonEnable {
|
homepage = "https://github.com/hyprwm/Hyprland";
|
||||||
"xwayland" = enableXWayland;
|
description = "Dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
|
||||||
"legacy_renderer" = legacyRenderer;
|
license = lib.licenses.bsd3;
|
||||||
"uwsm" = false;
|
platforms = lib.platforms.linux;
|
||||||
"hyprpm" = false;
|
mainProgram = "Hyprland";
|
||||||
})
|
};
|
||||||
(mapAttrsToList mesonBool {
|
}
|
||||||
"b_pch" = false;
|
|
||||||
"tracy_enable" = false;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
postInstall = ''
|
|
||||||
${optionalString wrapRuntimeDeps ''
|
|
||||||
wrapProgram $out/bin/Hyprland \
|
|
||||||
--suffix PATH : ${makeBinPath [
|
|
||||||
binutils
|
|
||||||
hyprland-qtutils
|
|
||||||
pciutils
|
|
||||||
pkgconf
|
|
||||||
]}
|
|
||||||
''}
|
|
||||||
'';
|
|
||||||
|
|
||||||
passthru.providedSessions = ["hyprland"];
|
|
||||||
|
|
||||||
meta = {
|
|
||||||
homepage = "https://github.com/hyprwm/Hyprland";
|
|
||||||
description = "Dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
|
|
||||||
license = lib.licenses.bsd3;
|
|
||||||
platforms = lib.platforms.linux;
|
|
||||||
mainProgram = "Hyprland";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
|
@@ -1,64 +0,0 @@
|
|||||||
{
|
|
||||||
writeShellApplication,
|
|
||||||
deadnix,
|
|
||||||
statix,
|
|
||||||
alejandra,
|
|
||||||
llvmPackages_19,
|
|
||||||
fd,
|
|
||||||
}:
|
|
||||||
writeShellApplication {
|
|
||||||
name = "hyprland-treewide-formatter";
|
|
||||||
runtimeInputs = [
|
|
||||||
deadnix
|
|
||||||
statix
|
|
||||||
alejandra
|
|
||||||
llvmPackages_19.clang-tools
|
|
||||||
fd
|
|
||||||
];
|
|
||||||
text = ''
|
|
||||||
# shellcheck disable=SC2148
|
|
||||||
|
|
||||||
# common excludes
|
|
||||||
excludes="subprojects"
|
|
||||||
|
|
||||||
nix_format() {
|
|
||||||
if [ "$*" = 0 ]; then
|
|
||||||
fd '.*\.nix' . -E "$excludes" -x statix fix -- {} \;
|
|
||||||
fd '.*\.nix' . -E "$excludes" -X deadnix -e -- {} \; -X alejandra {} \;
|
|
||||||
elif [ -d "$1" ]; then
|
|
||||||
fd '.*\.nix' "$1" -E "$excludes" -i -x statix fix -- {} \;
|
|
||||||
fd '.*\.nix' "$1" -E "$excludes" -i -X deadnix -e -- {} \; -X alejandra {} \;
|
|
||||||
else
|
|
||||||
statix fix -- "$1"
|
|
||||||
deadnix -e "$1"
|
|
||||||
alejandra "$1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
cpp_format() {
|
|
||||||
if [ "$*" = 0 ] || [ "$1" = "." ]; then
|
|
||||||
fd '.*\.cpp' . -E "$excludes" | xargs clang-format --verbose -i
|
|
||||||
elif [ -d "$1" ]; then
|
|
||||||
fd '.*\.cpp' "$1" -E "$excludes" | xargs clang-format --verbose -i
|
|
||||||
else
|
|
||||||
clang-format --verbose -i "$1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in "$@"; do
|
|
||||||
case ''${i##*.} in
|
|
||||||
"nix")
|
|
||||||
nix_format "$i"
|
|
||||||
;;
|
|
||||||
"cpp")
|
|
||||||
cpp_format "$i"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
nix_format "$i"
|
|
||||||
cpp_format "$i"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
}
|
|
205
nix/module.nix
@@ -7,206 +7,15 @@ inputs: {
|
|||||||
inherit (pkgs.stdenv.hostPlatform) system;
|
inherit (pkgs.stdenv.hostPlatform) system;
|
||||||
cfg = config.programs.hyprland;
|
cfg = config.programs.hyprland;
|
||||||
|
|
||||||
# basically 1:1 taken from https://github.com/nix-community/home-manager/blob/master/modules/services/window-managers/hyprland.nix
|
package = inputs.self.packages.${system}.hyprland;
|
||||||
toHyprconf = {
|
portalPackage = inputs.self.packages.${system}.xdg-desktop-portal-hyprland.override {
|
||||||
attrs,
|
hyprland = cfg.finalPackage;
|
||||||
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 {
|
in {
|
||||||
options = {
|
config = {
|
||||||
programs.hyprland = {
|
programs.hyprland = {
|
||||||
plugins = lib.mkOption {
|
package = lib.mkDefault package;
|
||||||
type = with lib.types; listOf (either package path);
|
portalPackage = lib.mkDefault portalPackage;
|
||||||
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 {
|
|
||||||
hyprland = cfg.finalPackage;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
(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;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
@@ -22,33 +22,22 @@ in {
|
|||||||
# Dependencies
|
# Dependencies
|
||||||
inputs.aquamarine.overlays.default
|
inputs.aquamarine.overlays.default
|
||||||
inputs.hyprcursor.overlays.default
|
inputs.hyprcursor.overlays.default
|
||||||
inputs.hyprgraphics.overlays.default
|
|
||||||
inputs.hyprland-protocols.overlays.default
|
|
||||||
inputs.hyprland-qtutils.overlays.default
|
|
||||||
inputs.hyprlang.overlays.default
|
inputs.hyprlang.overlays.default
|
||||||
inputs.hyprutils.overlays.default
|
inputs.hyprutils.overlays.default
|
||||||
inputs.hyprwayland-scanner.overlays.default
|
inputs.hyprwayland-scanner.overlays.default
|
||||||
self.overlays.udis86
|
|
||||||
|
|
||||||
# Hyprland packages themselves
|
# Hyprland packages themselves
|
||||||
(final: _prev: let
|
(final: prev: let
|
||||||
date = mkDate (self.lastModifiedDate or "19700101");
|
date = mkDate (self.lastModifiedDate or "19700101");
|
||||||
in {
|
in {
|
||||||
hyprland = final.callPackage ./default.nix {
|
hyprland = final.callPackage ./default.nix {
|
||||||
stdenv = final.gcc14Stdenv;
|
stdenv = final.gcc14Stdenv;
|
||||||
version = "${version}+date=${date}_${self.shortRev or "dirty"}";
|
version = "${version}+date=${date}_${self.shortRev or "dirty"}";
|
||||||
commit = self.rev or "";
|
commit = self.rev or "";
|
||||||
revCount = self.sourceInfo.revCount or "";
|
|
||||||
inherit date;
|
inherit date;
|
||||||
};
|
};
|
||||||
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
|
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
|
||||||
|
hyprland-debug = final.hyprland.override {debug = true;};
|
||||||
# Build major libs with debug to get as much info as possible in a stacktrace
|
|
||||||
hyprland-debug = final.hyprland.override {
|
|
||||||
aquamarine = final.aquamarine.override {debug = true;};
|
|
||||||
hyprutils = final.hyprutils.override {debug = true;};
|
|
||||||
debug = true;
|
|
||||||
};
|
|
||||||
hyprland-legacy-renderer = final.hyprland.override {legacyRenderer = true;};
|
hyprland-legacy-renderer = final.hyprland.override {legacyRenderer = true;};
|
||||||
|
|
||||||
# deprecated packages
|
# deprecated packages
|
||||||
@@ -71,22 +60,6 @@ in {
|
|||||||
# Packages for extra software recommended for usage with Hyprland,
|
# Packages for extra software recommended for usage with Hyprland,
|
||||||
# including forked or patched packages for compatibility.
|
# including forked or patched packages for compatibility.
|
||||||
hyprland-extras = lib.composeManyExtensions [
|
hyprland-extras = lib.composeManyExtensions [
|
||||||
inputs.xdph.overlays.default
|
inputs.xdph.overlays.xdg-desktop-portal-hyprland
|
||||||
];
|
];
|
||||||
|
|
||||||
# udis86 from nixpkgs is too old, and also does not provide a .pc file
|
|
||||||
# this version is the one used in the git submodule, and allows us to
|
|
||||||
# fetch the source without '?submodules=1'
|
|
||||||
udis86 = final: prev: {
|
|
||||||
udis86-hyprland = prev.udis86.overrideAttrs (_self: _super: {
|
|
||||||
src = final.fetchFromGitHub {
|
|
||||||
owner = "canihavesomecoffee";
|
|
||||||
repo = "udis86";
|
|
||||||
rev = "5336633af70f3917760a6d441ff02d93477b0c86";
|
|
||||||
hash = "sha256-HifdUQPGsKQKQprByeIznvRLONdOXeolOsU5nkwIv3g=";
|
|
||||||
};
|
|
||||||
|
|
||||||
patches = [];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
12
nix/stdcxx.patch
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||||
|
index cfbd431f..73e8e0c2 100644
|
||||||
|
--- a/CMakeLists.txt
|
||||||
|
+++ b/CMakeLists.txt
|
||||||
|
@@ -64,6 +64,7 @@ endif()
|
||||||
|
include_directories(. "src/" "subprojects/udis86/" "protocols/")
|
||||||
|
set(CMAKE_CXX_STANDARD 26)
|
||||||
|
add_compile_options(
|
||||||
|
+ -std=c++26
|
||||||
|
-Wall
|
||||||
|
-Wextra
|
||||||
|
-Wno-unused-parameter
|
@@ -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>
|
|
@@ -1,82 +1,76 @@
|
|||||||
wayland_protos = dependency(
|
wayland_protos = dependency('wayland-protocols',
|
||||||
'wayland-protocols',
|
|
||||||
version: '>=1.32',
|
version: '>=1.32',
|
||||||
fallback: 'wayland-protocols',
|
fallback: 'wayland-protocols',
|
||||||
default_options: ['tests=false'],
|
default_options: ['tests=false'],
|
||||||
)
|
)
|
||||||
|
|
||||||
hyprland_protos = dependency(
|
hyprland_protos = dependency('hyprland-protocols',
|
||||||
'hyprland-protocols',
|
version: '>=0.2',
|
||||||
version: '>=0.6',
|
fallback: 'hyprland-protocols',
|
||||||
fallback: 'hyprland-protocols',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
wayland_protocol_dir = wayland_protos.get_variable('pkgdatadir')
|
wl_protocol_dir = wayland_protos.get_variable('pkgdatadir')
|
||||||
hyprland_protocol_dir = hyprland_protos.get_variable('pkgdatadir')
|
hl_protocol_dir = hyprland_protos.get_variable('pkgdatadir')
|
||||||
|
|
||||||
hyprwayland_scanner_dep = dependency('hyprwayland-scanner', version: '>=0.3.10', native: true)
|
hyprwayland_scanner_dep = dependency('hyprwayland-scanner', version: '>=0.3.8', native: true)
|
||||||
hyprwayland_scanner = find_program(
|
hyprwayland_scanner = find_program(
|
||||||
hyprwayland_scanner_dep.get_variable('hyprwayland_scanner'),
|
hyprwayland_scanner_dep.get_variable('hyprwayland_scanner'),
|
||||||
native: true,
|
native: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
protocols = [
|
new_protocols = [
|
||||||
'wlr-gamma-control-unstable-v1.xml',
|
['wlr-gamma-control-unstable-v1.xml'],
|
||||||
'wlr-foreign-toplevel-management-unstable-v1.xml',
|
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
||||||
'wlr-output-power-management-unstable-v1.xml',
|
['wlr-output-power-management-unstable-v1.xml'],
|
||||||
'input-method-unstable-v2.xml',
|
['input-method-unstable-v2.xml'],
|
||||||
'virtual-keyboard-unstable-v1.xml',
|
['virtual-keyboard-unstable-v1.xml'],
|
||||||
'wlr-virtual-pointer-unstable-v1.xml',
|
['wlr-virtual-pointer-unstable-v1.xml'],
|
||||||
'wlr-output-management-unstable-v1.xml',
|
['wlr-output-management-unstable-v1.xml'],
|
||||||
'kde-server-decoration.xml',
|
['kde-server-decoration.xml'],
|
||||||
'wlr-layer-shell-unstable-v1.xml',
|
['wlr-layer-shell-unstable-v1.xml'],
|
||||||
'wayland-drm.xml',
|
['wayland-drm.xml'],
|
||||||
'wlr-data-control-unstable-v1.xml',
|
['wlr-data-control-unstable-v1.xml'],
|
||||||
'wlr-screencopy-unstable-v1.xml',
|
['wlr-screencopy-unstable-v1.xml'],
|
||||||
'xx-color-management-v4.xml',
|
[hl_protocol_dir, 'protocols/hyprland-global-shortcuts-v1.xml'],
|
||||||
'frog-color-management-v1.xml',
|
[hl_protocol_dir, 'protocols/hyprland-toplevel-export-v1.xml'],
|
||||||
hyprland_protocol_dir / 'protocols/hyprland-global-shortcuts-v1.xml',
|
[hl_protocol_dir, 'protocols/hyprland-focus-grab-v1.xml'],
|
||||||
hyprland_protocol_dir / 'protocols/hyprland-toplevel-export-v1.xml',
|
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
|
||||||
hyprland_protocol_dir / 'protocols/hyprland-focus-grab-v1.xml',
|
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
||||||
hyprland_protocol_dir / 'protocols/hyprland-ctm-control-v1.xml',
|
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||||
hyprland_protocol_dir / 'protocols/hyprland-surface-v1.xml',
|
[wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'],
|
||||||
hyprland_protocol_dir / 'protocols/hyprland-lock-notify-v1.xml',
|
[wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'],
|
||||||
wayland_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
|
[wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'],
|
||||||
wayland_protocol_dir / 'staging/fractional-scale/fractional-scale-v1.xml',
|
[wl_protocol_dir, 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml'],
|
||||||
wayland_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',
|
[wl_protocol_dir, 'staging/alpha-modifier/alpha-modifier-v1.xml'],
|
||||||
wayland_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
[wl_protocol_dir, 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml'],
|
||||||
wayland_protocol_dir / 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml',
|
[wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'],
|
||||||
wayland_protocol_dir / 'unstable/relative-pointer/relative-pointer-unstable-v1.xml',
|
[wl_protocol_dir, 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml'],
|
||||||
wayland_protocol_dir / 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml',
|
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v3.xml'],
|
||||||
wayland_protocol_dir / 'staging/alpha-modifier/alpha-modifier-v1.xml',
|
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'],
|
||||||
wayland_protocol_dir / 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml',
|
[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
|
||||||
wayland_protocol_dir / 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml',
|
[wl_protocol_dir, 'staging/xdg-activation/xdg-activation-v1.xml'],
|
||||||
wayland_protocol_dir / 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml',
|
[wl_protocol_dir, 'staging/ext-idle-notify/ext-idle-notify-v1.xml'],
|
||||||
wayland_protocol_dir / 'unstable/text-input/text-input-unstable-v3.xml',
|
[wl_protocol_dir, 'staging/ext-session-lock/ext-session-lock-v1.xml'],
|
||||||
wayland_protocol_dir / 'unstable/text-input/text-input-unstable-v1.xml',
|
[wl_protocol_dir, 'stable/tablet/tablet-v2.xml'],
|
||||||
wayland_protocol_dir / 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml',
|
[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml'],
|
||||||
wayland_protocol_dir / 'staging/xdg-activation/xdg-activation-v1.xml',
|
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||||
wayland_protocol_dir / 'staging/ext-idle-notify/ext-idle-notify-v1.xml',
|
[wl_protocol_dir, 'unstable/primary-selection/primary-selection-unstable-v1.xml'],
|
||||||
wayland_protocol_dir / 'staging/ext-session-lock/ext-session-lock-v1.xml',
|
[wl_protocol_dir, 'staging/xwayland-shell/xwayland-shell-v1.xml'],
|
||||||
wayland_protocol_dir / 'stable/tablet/tablet-v2.xml',
|
[wl_protocol_dir, 'stable/viewporter/viewporter.xml'],
|
||||||
wayland_protocol_dir / 'stable/presentation-time/presentation-time.xml',
|
[wl_protocol_dir, 'stable/linux-dmabuf/linux-dmabuf-v1.xml'],
|
||||||
wayland_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
|
[wl_protocol_dir, 'staging/drm-lease/drm-lease-v1.xml'],
|
||||||
wayland_protocol_dir / 'unstable/primary-selection/primary-selection-unstable-v1.xml',
|
[wl_protocol_dir, 'staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml'],
|
||||||
wayland_protocol_dir / 'staging/xwayland-shell/xwayland-shell-v1.xml',
|
|
||||||
wayland_protocol_dir / 'stable/viewporter/viewporter.xml',
|
|
||||||
wayland_protocol_dir / 'stable/linux-dmabuf/linux-dmabuf-v1.xml',
|
|
||||||
wayland_protocol_dir / 'staging/drm-lease/drm-lease-v1.xml',
|
|
||||||
wayland_protocol_dir / 'staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml',
|
|
||||||
wayland_protocol_dir / 'staging/xdg-dialog/xdg-dialog-v1.xml',
|
|
||||||
wayland_protocol_dir / 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml',
|
|
||||||
wayland_protocol_dir / 'staging/security-context/security-context-v1.xml',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
wl_protocols = []
|
wl_protos_src = []
|
||||||
foreach protocol : protocols
|
wl_protos_headers = []
|
||||||
wl_protocols += custom_target(
|
|
||||||
protocol.underscorify(),
|
new_wl_protos = []
|
||||||
input: protocol,
|
foreach p : new_protocols
|
||||||
|
xml = join_paths(p)
|
||||||
|
new_wl_protos += custom_target(
|
||||||
|
xml.underscorify(),
|
||||||
|
input: xml,
|
||||||
install: true,
|
install: true,
|
||||||
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
||||||
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
||||||
@@ -84,26 +78,31 @@ foreach protocol : protocols
|
|||||||
)
|
)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
# wayland.xml generation
|
wayland_server_dep = dependency('wayland-server', version: '>=1.20.0')
|
||||||
wayland_scanner = dependency('wayland-scanner')
|
wayland_server_dir = wayland_server_dep.get_variable('pkgdatadir')
|
||||||
wayland_scanner_datadir = wayland_scanner.get_variable('pkgdatadir')
|
|
||||||
|
|
||||||
wayland_xml = wayland_scanner_datadir / 'wayland.xml'
|
wl_server_protos = [
|
||||||
wayland_protocol = custom_target(
|
wayland_server_dir / 'wayland.xml'
|
||||||
wayland_xml.underscorify(),
|
]
|
||||||
input: wayland_xml,
|
wl_server_protos_gen = []
|
||||||
install: true,
|
foreach p : wl_server_protos
|
||||||
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
wl_server_protos_gen += custom_target(
|
||||||
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
p.underscorify(),
|
||||||
command: [hyprwayland_scanner, '--wayland-enums', '@INPUT@', '@OUTDIR@'],
|
input: p,
|
||||||
)
|
install: true,
|
||||||
|
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
||||||
|
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
||||||
|
command: [hyprwayland_scanner, '--wayland-enums', '@INPUT@', '@OUTDIR@'],
|
||||||
|
)
|
||||||
|
endforeach
|
||||||
|
|
||||||
lib_server_protos = static_library(
|
lib_server_protos = static_library(
|
||||||
'server_protos',
|
'server_protos',
|
||||||
wl_protocols + wayland_protocol,
|
wl_protos_src + wl_protos_headers + new_wl_protos + wl_server_protos_gen,
|
||||||
|
dependencies: wayland_server_dep.partial_dependency(compile_args: true),
|
||||||
)
|
)
|
||||||
|
|
||||||
server_protos = declare_dependency(
|
server_protos = declare_dependency(
|
||||||
link_with: lib_server_protos,
|
link_with: lib_server_protos,
|
||||||
sources: wl_protocols + wayland_protocol,
|
sources: wl_protos_headers + new_wl_protos,
|
||||||
)
|
)
|
||||||
|
1307
src/Compositor.cpp
@@ -1,23 +1,41 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
|
||||||
#include "defines.hpp"
|
#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/XWaylandManager.hpp"
|
||||||
|
#include "managers/input/InputManager.hpp"
|
||||||
|
#include "managers/LayoutManager.hpp"
|
||||||
#include "managers/KeybindManager.hpp"
|
#include "managers/KeybindManager.hpp"
|
||||||
|
#include "managers/AnimationManager.hpp"
|
||||||
|
#include "managers/EventManager.hpp"
|
||||||
|
#include "managers/ProtocolManager.hpp"
|
||||||
#include "managers/SessionLockManager.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 "desktop/Window.hpp"
|
||||||
#include "protocols/types/ColorManagement.hpp"
|
#include "render/Renderer.hpp"
|
||||||
#include "helpers/memory/Memory.hpp"
|
#include "render/OpenGL.hpp"
|
||||||
|
#include "hyprerror/HyprError.hpp"
|
||||||
|
#include "plugins/PluginSystem.hpp"
|
||||||
|
#include "helpers/Watchdog.hpp"
|
||||||
|
|
||||||
#include <aquamarine/backend/Backend.hpp>
|
#include <aquamarine/backend/Backend.hpp>
|
||||||
#include <aquamarine/output/Output.hpp>
|
#include <aquamarine/output/Output.hpp>
|
||||||
|
|
||||||
class CWLSurfaceResource;
|
class CWLSurfaceResource;
|
||||||
struct SWorkspaceRule;
|
|
||||||
|
|
||||||
enum eManagersInitStage : uint8_t {
|
enum eManagersInitStage {
|
||||||
STAGE_PRIORITY = 0,
|
STAGE_PRIORITY = 0,
|
||||||
STAGE_BASICINIT,
|
STAGE_BASICINIT,
|
||||||
STAGE_LATE
|
STAGE_LATE
|
||||||
@@ -25,7 +43,7 @@ enum eManagersInitStage : uint8_t {
|
|||||||
|
|
||||||
class CCompositor {
|
class CCompositor {
|
||||||
public:
|
public:
|
||||||
CCompositor(bool onlyConfig = false);
|
CCompositor();
|
||||||
~CCompositor();
|
~CCompositor();
|
||||||
|
|
||||||
wl_display* m_sWLDisplay;
|
wl_display* m_sWLDisplay;
|
||||||
@@ -41,8 +59,8 @@ class CCompositor {
|
|||||||
std::string m_szInstancePath = "";
|
std::string m_szInstancePath = "";
|
||||||
std::string m_szCurrentSplash = "error";
|
std::string m_szCurrentSplash = "error";
|
||||||
|
|
||||||
std::vector<PHLMONITOR> m_vMonitors;
|
std::vector<SP<CMonitor>> m_vMonitors;
|
||||||
std::vector<PHLMONITOR> m_vRealMonitors; // for all monitors, even those turned off
|
std::vector<SP<CMonitor>> m_vRealMonitors; // for all monitors, even those turned off
|
||||||
std::vector<PHLWINDOW> m_vWindows;
|
std::vector<PHLWINDOW> m_vWindows;
|
||||||
std::vector<PHLLS> m_vLayers;
|
std::vector<PHLLS> m_vLayers;
|
||||||
std::vector<PHLWORKSPACE> m_vWorkspaces;
|
std::vector<PHLWORKSPACE> m_vWorkspaces;
|
||||||
@@ -62,7 +80,7 @@ class CCompositor {
|
|||||||
|
|
||||||
WP<CWLSurfaceResource> m_pLastFocus;
|
WP<CWLSurfaceResource> m_pLastFocus;
|
||||||
PHLWINDOWREF m_pLastWindow;
|
PHLWINDOWREF m_pLastWindow;
|
||||||
PHLMONITORREF m_pLastMonitor;
|
WP<CMonitor> m_pLastMonitor;
|
||||||
|
|
||||||
std::vector<PHLWINDOWREF> m_vWindowFocusHistory; // first element is the most recently focused.
|
std::vector<PHLWINDOWREF> m_vWindowFocusHistory; // first element is the most recently focused.
|
||||||
|
|
||||||
@@ -71,64 +89,72 @@ class CCompositor {
|
|||||||
bool m_bDPMSStateON = true;
|
bool m_bDPMSStateON = true;
|
||||||
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
|
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
|
||||||
bool m_bNextIsUnsafe = false;
|
bool m_bNextIsUnsafe = false;
|
||||||
PHLMONITORREF m_pUnsafeOutput; // fallback output for the unsafe state
|
CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state
|
||||||
bool m_bIsShuttingDown = false;
|
bool m_bIsShuttingDown = false;
|
||||||
bool m_bFinalRequests = false;
|
bool m_bDesktopEnvSet = false;
|
||||||
bool m_bDesktopEnvSet = false;
|
|
||||||
bool m_bWantsXwayland = true;
|
|
||||||
bool m_bOnlyConfigVerification = false;
|
|
||||||
|
|
||||||
// ------------------------------------------------- //
|
// ------------------------------------------------- //
|
||||||
|
|
||||||
PHLMONITOR getMonitorFromID(const MONITORID&);
|
CMonitor* getMonitorFromID(const MONITORID&);
|
||||||
PHLMONITOR getMonitorFromName(const std::string&);
|
CMonitor* getMonitorFromName(const std::string&);
|
||||||
PHLMONITOR getMonitorFromDesc(const std::string&);
|
CMonitor* getMonitorFromDesc(const std::string&);
|
||||||
PHLMONITOR getMonitorFromCursor();
|
CMonitor* getMonitorFromCursor();
|
||||||
PHLMONITOR getMonitorFromVector(const Vector2D&);
|
CMonitor* getMonitorFromVector(const Vector2D&);
|
||||||
void removeWindowFromVectorSafe(PHLWINDOW);
|
void removeWindowFromVectorSafe(PHLWINDOW);
|
||||||
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr);
|
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr);
|
||||||
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
|
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
|
||||||
bool monitorExists(PHLMONITOR);
|
bool monitorExists(CMonitor*);
|
||||||
PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
|
PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
|
||||||
SP<CWLSurfaceResource> vectorToLayerSurface(const Vector2D&, std::vector<PHLLSREF>*, Vector2D*, PHLLS*);
|
SP<CWLSurfaceResource> vectorToLayerSurface(const Vector2D&, std::vector<PHLLSREF>*, Vector2D*, PHLLS*);
|
||||||
SP<CWLSurfaceResource> vectorToLayerPopupSurface(const Vector2D&, PHLMONITOR monitor, Vector2D*, PHLLS*);
|
SP<CWLSurfaceResource> vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, PHLLS*);
|
||||||
SP<CWLSurfaceResource> vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl);
|
SP<CWLSurfaceResource> vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl);
|
||||||
Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, SP<CWLSurfaceResource>);
|
Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, SP<CWLSurfaceResource>);
|
||||||
PHLMONITOR getMonitorFromOutput(SP<Aquamarine::IOutput>);
|
CMonitor* getMonitorFromOutput(SP<Aquamarine::IOutput>);
|
||||||
PHLMONITOR getRealMonitorFromOutput(SP<Aquamarine::IOutput>);
|
CMonitor* getRealMonitorFromOutput(SP<Aquamarine::IOutput>);
|
||||||
PHLWINDOW getWindowFromSurface(SP<CWLSurfaceResource>);
|
PHLWINDOW getWindowFromSurface(SP<CWLSurfaceResource>);
|
||||||
PHLWINDOW getWindowFromHandle(uint32_t);
|
PHLWINDOW getWindowFromHandle(uint32_t);
|
||||||
|
bool isWorkspaceVisible(PHLWORKSPACE);
|
||||||
|
bool isWorkspaceVisibleNotCovered(PHLWORKSPACE);
|
||||||
PHLWORKSPACE getWorkspaceByID(const WORKSPACEID&);
|
PHLWORKSPACE getWorkspaceByID(const WORKSPACEID&);
|
||||||
PHLWORKSPACE getWorkspaceByName(const std::string&);
|
PHLWORKSPACE getWorkspaceByName(const std::string&);
|
||||||
PHLWORKSPACE getWorkspaceByString(const std::string&);
|
PHLWORKSPACE getWorkspaceByString(const std::string&);
|
||||||
void sanityCheckWorkspaces();
|
void sanityCheckWorkspaces();
|
||||||
|
void updateWorkspaceWindowDecos(const WORKSPACEID&);
|
||||||
|
void updateWorkspaceWindowData(const WORKSPACEID&);
|
||||||
|
int getWindowsOnWorkspace(const WORKSPACEID& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
||||||
|
int getGroupsOnWorkspace(const WORKSPACEID& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
||||||
PHLWINDOW getUrgentWindow();
|
PHLWINDOW getUrgentWindow();
|
||||||
|
bool hasUrgentWindowOnWorkspace(const WORKSPACEID&);
|
||||||
|
PHLWINDOW getFirstWindowOnWorkspace(const WORKSPACEID&);
|
||||||
|
PHLWINDOW getTopLeftWindowOnWorkspace(const WORKSPACEID&);
|
||||||
|
PHLWINDOW getFullscreenWindowOnWorkspace(const WORKSPACEID&);
|
||||||
bool isWindowActive(PHLWINDOW);
|
bool isWindowActive(PHLWINDOW);
|
||||||
void changeWindowZOrder(PHLWINDOW, bool);
|
void changeWindowZOrder(PHLWINDOW, bool);
|
||||||
void cleanupFadingOut(const MONITORID& monid);
|
void cleanupFadingOut(const MONITORID& monid);
|
||||||
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
|
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 = {});
|
||||||
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {}, bool visible = false);
|
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
||||||
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {}, bool visible = false);
|
|
||||||
WORKSPACEID getNextAvailableNamedWorkspace();
|
WORKSPACEID getNextAvailableNamedWorkspace();
|
||||||
bool isPointOnAnyMonitor(const Vector2D&);
|
bool isPointOnAnyMonitor(const Vector2D&);
|
||||||
bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr);
|
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
|
||||||
PHLMONITOR getMonitorInDirection(const char&);
|
CMonitor* getMonitorInDirection(const char&);
|
||||||
PHLMONITOR getMonitorInDirection(PHLMONITOR, const char&);
|
CMonitor* getMonitorInDirection(CMonitor*, const char&);
|
||||||
void updateAllWindowsAnimatedDecorationValues();
|
void updateAllWindowsAnimatedDecorationValues();
|
||||||
|
void updateWorkspaceWindows(const WORKSPACEID& id);
|
||||||
void updateWindowAnimatedDecorationValues(PHLWINDOW);
|
void updateWindowAnimatedDecorationValues(PHLWINDOW);
|
||||||
MONITORID getNextAvailableMonitorID(std::string const& name);
|
MONITORID getNextAvailableMonitorID(std::string const& name);
|
||||||
void moveWorkspaceToMonitor(PHLWORKSPACE, PHLMONITOR, bool noWarpCursor = false);
|
void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
|
||||||
void swapActiveWorkspaces(PHLMONITOR, PHLMONITOR);
|
void swapActiveWorkspaces(CMonitor*, CMonitor*);
|
||||||
PHLMONITOR getMonitorFromString(const std::string&);
|
CMonitor* getMonitorFromString(const std::string&);
|
||||||
bool workspaceIDOutOfBounds(const WORKSPACEID&);
|
bool workspaceIDOutOfBounds(const WORKSPACEID&);
|
||||||
void setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
void setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||||
void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||||
void setWindowFullscreenState(const PHLWINDOW PWINDOW, const SFullscreenState state);
|
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 changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON);
|
||||||
void updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
|
void updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
|
||||||
PHLWINDOW getX11Parent(PHLWINDOW);
|
PHLWINDOW getX11Parent(PHLWINDOW);
|
||||||
void scheduleFrameForMonitor(PHLMONITOR, Aquamarine::IOutput::scheduleFrameReason reason = Aquamarine::IOutput::AQ_SCHEDULE_CLIENT_UNKNOWN);
|
void scheduleFrameForMonitor(CMonitor*, Aquamarine::IOutput::scheduleFrameReason reason = Aquamarine::IOutput::AQ_SCHEDULE_CLIENT_UNKNOWN);
|
||||||
void addToFadingOutSafe(PHLLS);
|
void addToFadingOutSafe(PHLLS);
|
||||||
void removeFromFadingOutSafe(PHLLS);
|
void removeFromFadingOutSafe(PHLLS);
|
||||||
void addToFadingOutSafe(PHLWINDOW);
|
void addToFadingOutSafe(PHLWINDOW);
|
||||||
@@ -137,9 +163,11 @@ class CCompositor {
|
|||||||
PHLLS getLayerSurfaceFromSurface(SP<CWLSurfaceResource>);
|
PHLLS getLayerSurfaceFromSurface(SP<CWLSurfaceResource>);
|
||||||
void closeWindow(PHLWINDOW);
|
void closeWindow(PHLWINDOW);
|
||||||
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
||||||
|
void forceReportSizesToWindowsOnWorkspace(const WORKSPACEID&);
|
||||||
PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "",
|
PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "",
|
||||||
bool isEmpty = true); // will be deleted next frame if left empty and unfocused!
|
bool isEmtpy = true); // will be deleted next frame if left empty and unfocused!
|
||||||
void setActiveMonitor(PHLMONITOR);
|
void renameWorkspace(const WORKSPACEID&, const std::string& name = "");
|
||||||
|
void setActiveMonitor(CMonitor*);
|
||||||
bool isWorkspaceSpecial(const WORKSPACEID&);
|
bool isWorkspaceSpecial(const WORKSPACEID&);
|
||||||
WORKSPACEID getNewSpecialID();
|
WORKSPACEID getNewSpecialID();
|
||||||
void performUserChecks();
|
void performUserChecks();
|
||||||
@@ -151,11 +179,8 @@ class CCompositor {
|
|||||||
void setPreferredScaleForSurface(SP<CWLSurfaceResource> pSurface, double scale);
|
void setPreferredScaleForSurface(SP<CWLSurfaceResource> pSurface, double scale);
|
||||||
void setPreferredTransformForSurface(SP<CWLSurfaceResource> pSurface, wl_output_transform transform);
|
void setPreferredTransformForSurface(SP<CWLSurfaceResource> pSurface, wl_output_transform transform);
|
||||||
void updateSuspendedStates();
|
void updateSuspendedStates();
|
||||||
|
PHLWINDOW windowForCPointer(CWindow*);
|
||||||
void onNewMonitor(SP<Aquamarine::IOutput> output);
|
void onNewMonitor(SP<Aquamarine::IOutput> output);
|
||||||
void ensurePersistentWorkspacesPresent(const std::vector<SWorkspaceRule>& rules);
|
|
||||||
|
|
||||||
SImageDescription getPreferredImageDescription();
|
|
||||||
bool shouldChangePreferredImageDescription();
|
|
||||||
|
|
||||||
std::string explicitConfigPath;
|
std::string explicitConfigPath;
|
||||||
|
|
||||||
@@ -166,11 +191,10 @@ class CCompositor {
|
|||||||
void setRandomSplash();
|
void setRandomSplash();
|
||||||
void initManagers(eManagersInitStage stage);
|
void initManagers(eManagersInitStage stage);
|
||||||
void prepareFallbackOutput();
|
void prepareFallbackOutput();
|
||||||
bool isWindowAvailableForCycle(PHLWINDOW pWindow, PHLWINDOW w, bool focusableOnly, std::optional<bool> floating, bool anyWorkspace = false);
|
|
||||||
|
|
||||||
uint64_t m_iHyprlandPID = 0;
|
uint64_t m_iHyprlandPID = 0;
|
||||||
wl_event_source* m_critSigSource = nullptr;
|
wl_event_source* m_critSigSource = nullptr;
|
||||||
rlimit m_sOriginalNofile = {0};
|
rlimit m_sOriginalNofile = {0};
|
||||||
};
|
};
|
||||||
|
|
||||||
inline UP<CCompositor> g_pCompositor;
|
inline std::unique_ptr<CCompositor> g_pCompositor;
|
||||||
|
@@ -3,11 +3,11 @@
|
|||||||
#include "helpers/math/Math.hpp"
|
#include "helpers/math/Math.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <any>
|
#include <any>
|
||||||
#include <string>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <hyprutils/math/Box.hpp>
|
#include <hyprutils/math/Box.hpp>
|
||||||
|
|
||||||
enum eIcons : uint8_t {
|
using namespace Hyprutils::Math;
|
||||||
|
|
||||||
|
enum eIcons {
|
||||||
ICON_WARNING = 0,
|
ICON_WARNING = 0,
|
||||||
ICON_INFO,
|
ICON_INFO,
|
||||||
ICON_HINT,
|
ICON_HINT,
|
||||||
@@ -17,7 +17,7 @@ enum eIcons : uint8_t {
|
|||||||
ICON_NONE
|
ICON_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eRenderStage : uint8_t {
|
enum eRenderStage {
|
||||||
RENDER_PRE = 0, /* Before binding the gl context */
|
RENDER_PRE = 0, /* Before binding the gl context */
|
||||||
RENDER_BEGIN, /* Just when the rendering begins, nothing has been rendered yet. Damage, current render data in opengl valid. */
|
RENDER_BEGIN, /* Just when the rendering begins, nothing has been rendered yet. Damage, current render data in opengl valid. */
|
||||||
RENDER_PRE_WINDOWS, /* Pre windows, post bottom and overlay layers */
|
RENDER_PRE_WINDOWS, /* Pre windows, post bottom and overlay layers */
|
||||||
@@ -29,7 +29,7 @@ enum eRenderStage : uint8_t {
|
|||||||
RENDER_POST_WINDOW, /* After rendering a window (any pass) */
|
RENDER_POST_WINDOW, /* After rendering a window (any pass) */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eInputType : uint8_t {
|
enum eInputType {
|
||||||
INPUT_TYPE_AXIS = 0,
|
INPUT_TYPE_AXIS = 0,
|
||||||
INPUT_TYPE_BUTTON,
|
INPUT_TYPE_BUTTON,
|
||||||
INPUT_TYPE_DRAG_START,
|
INPUT_TYPE_DRAG_START,
|
||||||
@@ -41,7 +41,7 @@ struct SCallbackInfo {
|
|||||||
bool cancelled = false; /* on cancellable events, will cancel the event. */
|
bool cancelled = false; /* on cancellable events, will cancel the event. */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eHyprCtlOutputFormat : uint8_t {
|
enum eHyprCtlOutputFormat {
|
||||||
FORMAT_NORMAL = 0,
|
FORMAT_NORMAL = 0,
|
||||||
FORMAT_JSON
|
FORMAT_JSON
|
||||||
};
|
};
|
||||||
@@ -52,12 +52,6 @@ struct SHyprCtlCommand {
|
|||||||
std::function<std::string(eHyprCtlOutputFormat, std::string)> fn;
|
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 WINDOWID;
|
||||||
typedef int64_t MONITORID;
|
typedef int64_t MONITORID;
|
||||||
typedef int64_t WORKSPACEID;
|
typedef int64_t WORKSPACEID;
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
#include "../helpers/varlist/VarList.hpp"
|
#include "../helpers/varlist/VarList.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
enum eConfigValueDataTypes : int8_t {
|
enum eConfigValueDataTypes {
|
||||||
CVD_TYPE_INVALID = -1,
|
CVD_TYPE_INVALID = -1,
|
||||||
CVD_TYPE_GRADIENT = 0,
|
CVD_TYPE_GRADIENT = 0,
|
||||||
CVD_TYPE_CSS_VALUE = 1
|
CVD_TYPE_CSS_VALUE = 1
|
||||||
@@ -20,40 +20,24 @@ class ICustomConfigValueData {
|
|||||||
|
|
||||||
class CGradientValueData : public ICustomConfigValueData {
|
class CGradientValueData : public ICustomConfigValueData {
|
||||||
public:
|
public:
|
||||||
CGradientValueData() = default;
|
CGradientValueData() {};
|
||||||
CGradientValueData(CHyprColor col) {
|
CGradientValueData(CColor col) {
|
||||||
m_vColors.push_back(col);
|
m_vColors.push_back(col);
|
||||||
updateColorsOk();
|
|
||||||
};
|
};
|
||||||
virtual ~CGradientValueData() = default;
|
virtual ~CGradientValueData() {};
|
||||||
|
|
||||||
virtual eConfigValueDataTypes getDataType() {
|
virtual eConfigValueDataTypes getDataType() {
|
||||||
return CVD_TYPE_GRADIENT;
|
return CVD_TYPE_GRADIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(CHyprColor col) {
|
void reset(CColor col) {
|
||||||
m_vColors.clear();
|
m_vColors.clear();
|
||||||
m_vColors.emplace_back(col);
|
m_vColors.emplace_back(col);
|
||||||
m_fAngle = 0;
|
m_fAngle = 0;
|
||||||
updateColorsOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateColorsOk() {
|
|
||||||
m_vColorsOkLabA.clear();
|
|
||||||
for (auto& c : m_vColors) {
|
|
||||||
const auto OKLAB = c.asOkLab();
|
|
||||||
m_vColorsOkLabA.emplace_back(OKLAB.l);
|
|
||||||
m_vColorsOkLabA.emplace_back(OKLAB.a);
|
|
||||||
m_vColorsOkLabA.emplace_back(OKLAB.b);
|
|
||||||
m_vColorsOkLabA.emplace_back(c.a);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vector containing the colors */
|
/* Vector containing the colors */
|
||||||
std::vector<CHyprColor> m_vColors;
|
std::vector<CColor> m_vColors;
|
||||||
|
|
||||||
/* Vector containing pure colors for shoving into opengl */
|
|
||||||
std::vector<float> m_vColorsOkLabA;
|
|
||||||
|
|
||||||
/* Float corresponding to the angle (rad) */
|
/* Float corresponding to the angle (rad) */
|
||||||
float m_fAngle = 0;
|
float m_fAngle = 0;
|
||||||
|
@@ -104,30 +104,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.type = CONFIG_OPTION_INT,
|
.type = CONFIG_OPTION_INT,
|
||||||
.data = SConfigOptionDescription::SRangeData{0, 0, 4},
|
.data = SConfigOptionDescription::SRangeData{0, 0, 4},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "general:snap:enabled",
|
|
||||||
.description = "enable snapping for floating windows",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "general:snap:window_gap",
|
|
||||||
.description = "minimum gap in pixels between windows before snapping",
|
|
||||||
.type = CONFIG_OPTION_INT,
|
|
||||||
.data = SConfigOptionDescription::SRangeData{10, 0, 100},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "general:snap:monitor_gap",
|
|
||||||
.description = "minimum gap in pixels between window and monitor edges before snapping",
|
|
||||||
.type = CONFIG_OPTION_INT,
|
|
||||||
.data = SConfigOptionDescription::SRangeData{10, 0, 100},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "general:snap:border_overlap",
|
|
||||||
.description = "if true, windows snap such that only one border's worth of space is between them",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* decoration:
|
* decoration:
|
||||||
@@ -139,12 +115,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.type = CONFIG_OPTION_INT,
|
.type = CONFIG_OPTION_INT,
|
||||||
.data = SConfigOptionDescription::SRangeData{0, 0, 20},
|
.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{
|
SConfigOptionDescription{
|
||||||
.value = "decoration:active_opacity",
|
.value = "decoration:active_opacity",
|
||||||
.description = "opacity of active windows. [0.0 - 1.0]",
|
.description = "opacity of active windows. [0.0 - 1.0]",
|
||||||
@@ -164,55 +134,49 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "decoration:shadow:enabled",
|
.value = "decoration:drop_shadow",
|
||||||
.description = "enable drop shadows on windows",
|
.description = "enable drop shadows on windows",
|
||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
.data = SConfigOptionDescription::SBoolData{true},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "decoration:shadow:range",
|
.value = "decoration:shadow_range",
|
||||||
.description = "Shadow range (size) in layout px",
|
.description = "Shadow range (size) in layout px",
|
||||||
.type = CONFIG_OPTION_INT,
|
.type = CONFIG_OPTION_INT,
|
||||||
.data = SConfigOptionDescription::SRangeData{4, 0, 100},
|
.data = SConfigOptionDescription::SRangeData{4, 0, 100},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "decoration:shadow:render_power",
|
.value = "decoration:shadow_render_power",
|
||||||
.description = "in what power to render the falloff (more power, the faster the falloff) [1 - 4]",
|
.description = "in what power to render the falloff (more power, the faster the falloff) [1 - 4]",
|
||||||
.type = CONFIG_OPTION_INT,
|
.type = CONFIG_OPTION_INT,
|
||||||
.data = SConfigOptionDescription::SRangeData{3, 1, 4},
|
.data = SConfigOptionDescription::SRangeData{3, 1, 4},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "decoration:shadow:sharp",
|
.value = "decoration:shadow_ignore_window",
|
||||||
.description = "whether the shadow should be sharp or not. Akin to an infinitely high render power.",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "decoration:shadow:ignore_window",
|
|
||||||
.description = "if true, the shadow will not be rendered behind the window itself, only around it.",
|
.description = "if true, the shadow will not be rendered behind the window itself, only around it.",
|
||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
.data = SConfigOptionDescription::SBoolData{true},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "decoration:shadow:color",
|
.value = "decoration:col.shadow",
|
||||||
.description = "shadow's color. Alpha dictates shadow's opacity.",
|
.description = "shadow's color. Alpha dictates shadow's opacity.",
|
||||||
.type = CONFIG_OPTION_COLOR,
|
.type = CONFIG_OPTION_COLOR,
|
||||||
.data = SConfigOptionDescription::SColorData{0xee1a1a1a},
|
.data = SConfigOptionDescription::SColorData{0xee1a1a1a},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "decoration:shadow:color_inactive",
|
.value = "decoration:col.shadow_inactive",
|
||||||
.description = "inactive shadow color. (if not set, will fall back to col.shadow)",
|
.description = "inactive shadow color. (if not set, will fall back to col.shadow)",
|
||||||
.type = CONFIG_OPTION_COLOR,
|
.type = CONFIG_OPTION_COLOR,
|
||||||
.data = SConfigOptionDescription::SColorData{}, //TODO: UNSET?
|
.data = SConfigOptionDescription::SColorData{}, //##TODO UNSET?
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "decoration:shadow:offset",
|
.value = "decoration:shadow_offset",
|
||||||
.description = "shadow's rendering offset.",
|
.description = "shadow's rendering offset.",
|
||||||
.type = CONFIG_OPTION_VECTOR,
|
.type = CONFIG_OPTION_VECTOR,
|
||||||
.data = SConfigOptionDescription::SVectorData{{}, {-250, -250}, {250, 250}},
|
.data = SConfigOptionDescription::SVectorData{{}, {-250, -250}, {250, 250}},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "decoration:shadow:scale",
|
.value = "decoration:shadow_scale",
|
||||||
.description = "shadow's scale. [0.0 - 1.0]",
|
.description = "shadow's scale. [0.0 - 1.0]",
|
||||||
.type = CONFIG_OPTION_FLOAT,
|
.type = CONFIG_OPTION_FLOAT,
|
||||||
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
||||||
@@ -274,7 +238,7 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.value = "blur:ignore_opacity",
|
.value = "blur:ignore_opacity",
|
||||||
.description = "make the blur layer ignore the opacity of the window",
|
.description = "make the blur layer ignore the opacity of the window",
|
||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
.data = SConfigOptionDescription::SBoolData{false},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "blur:new_optimizations",
|
.value = "blur:new_optimizations",
|
||||||
@@ -337,18 +301,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.type = CONFIG_OPTION_FLOAT,
|
.type = CONFIG_OPTION_FLOAT,
|
||||||
.data = SConfigOptionDescription::SFloatData{0.2, 0, 1},
|
.data = SConfigOptionDescription::SFloatData{0.2, 0, 1},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "blur:input_methods",
|
|
||||||
.description = "whether to blur input methods (e.g. fcitx5)",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "blur:input_methods_ignorealpha",
|
|
||||||
.description = "works like ignorealpha in layer rules. If pixel opacity is below set value, will not blur. [0.0 - 1.0]",
|
|
||||||
.type = CONFIG_OPTION_FLOAT,
|
|
||||||
.data = SConfigOptionDescription::SFloatData{0.2, 0, 1},
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* animations:
|
* animations:
|
||||||
@@ -638,22 +590,16 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "input:tablet:output",
|
.value = "input:tablet:output",
|
||||||
.description = "the monitor to bind tablets. Can be current or a monitor name. Leave empty to map across all monitors.",
|
.description = "the monitor to bind tablets. Empty means unbound..",
|
||||||
.type = CONFIG_OPTION_STRING_SHORT,
|
.type = CONFIG_OPTION_STRING_SHORT,
|
||||||
.data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET?
|
.data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET?
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "input:tablet:region_position",
|
.value = "input:tablet:region_position",
|
||||||
.description = "position of the mapped region in monitor layout relative to the top left corner of the bound monitor or all monitors.",
|
.description = "position of the mapped region in monitor layout.",
|
||||||
.type = CONFIG_OPTION_VECTOR,
|
.type = CONFIG_OPTION_VECTOR,
|
||||||
.data = SConfigOptionDescription::SVectorData{{}, {-20000, -20000}, {20000, 20000}},
|
.data = SConfigOptionDescription::SVectorData{{}, {-20000, -20000}, {20000, 20000}},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "input:tablet:absolute_region_position",
|
|
||||||
.description = "whether to treat the region_position as an absolute position in monitor layout. Only applies when output is empty.",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "input:tablet:region_size",
|
.value = "input:tablet:region_size",
|
||||||
.description = "size of the mapped region. When this variable is set, tablet input will be mapped to the region. [0, 0] or invalid size means unset.",
|
.description = "size of the mapped region. When this variable is set, tablet input will be mapped to the region. [0, 0] or invalid size means unset.",
|
||||||
@@ -796,18 +742,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
.data = SConfigOptionDescription::SBoolData{true},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "group:merge_groups_on_drag",
|
|
||||||
.description = "whether window groups can be dragged into other groups",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "group:merge_groups_on_groupbar",
|
|
||||||
.description = "whether one group will be merged with another when dragged into its groupbar",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "general:col.border_active",
|
.value = "general:col.border_active",
|
||||||
.description = "border color for inactive windows",
|
.description = "border color for inactive windows",
|
||||||
@@ -832,30 +766,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.type = CONFIG_OPTION_GRADIENT,
|
.type = CONFIG_OPTION_GRADIENT,
|
||||||
.data = SConfigOptionDescription::SGradientData{"0x66775500"},
|
.data = SConfigOptionDescription::SGradientData{"0x66775500"},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "group:auto_group",
|
|
||||||
.description = "automatically group new windows",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "group:drag_into_group",
|
|
||||||
.description = "whether dragging a window into a unlocked group will merge them. Options: 0 (disabled), 1 (enabled), 2 (only when dragging into the groupbar)",
|
|
||||||
.type = CONFIG_OPTION_CHOICE,
|
|
||||||
.data = SConfigOptionDescription::SChoiceData{0, "disabled,enabled,only when dragging into the groupbar"},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "group:merge_floated_into_tiled_on_groupbar",
|
|
||||||
.description = "whether dragging a floating window into a tiled window groupbar will merge them",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "group:group_on_movetoworkspace",
|
|
||||||
.description = "whether using movetoworkspace[silent] will merge the window into the workspace's solitary unlocked group",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* group:groupbar:
|
* group:groupbar:
|
||||||
@@ -1127,30 +1037,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
.data = SConfigOptionDescription::SBoolData{true},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "misc:render_unfocused_fps",
|
|
||||||
.description = "the maximum limit for renderunfocused windows' fps in the background",
|
|
||||||
.type = CONFIG_OPTION_INT,
|
|
||||||
.data = SConfigOptionDescription::SRangeData{15, 1, 120},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "misc:disable_xdg_env_checks",
|
|
||||||
.description = "disable the warning if XDG environment is externally managed",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "misc:disable_hyprland_qtutils_check",
|
|
||||||
.description = "disable the warning if hyprland-qtutils is missing",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "misc:lockdead_screen_delay",
|
|
||||||
.description = "the delay in ms after the lockdead screen appears if the lock screen did not appear after a lock event occurred.",
|
|
||||||
.type = CONFIG_OPTION_INT,
|
|
||||||
.data = SConfigOptionDescription::SRangeData{1000, 0, 5000},
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* binds:
|
* binds:
|
||||||
@@ -1206,12 +1092,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
.data = SConfigOptionDescription::SBoolData{true},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "binds:movefocus_cycles_groupfirst",
|
|
||||||
.description = "If enabled, when in a grouped window, movefocus will cycle windows in the groups first, then at each ends of tabs, it'll move on to other windows/groups",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "binds:disable_keybind_grabbing",
|
.value = "binds:disable_keybind_grabbing",
|
||||||
.description = "If enabled, apps that request keybinds to be disabled (e.g. VMs) will not be able to do so.",
|
.description = "If enabled, apps that request keybinds to be disabled (e.g. VMs) will not be able to do so.",
|
||||||
@@ -1224,23 +1104,11 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
.data = SConfigOptionDescription::SBoolData{true},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "binds:allow_pin_fullscreen",
|
|
||||||
.description = "Allows fullscreen to pinned windows, and restore their pinned status afterwards",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xwayland:
|
* xwayland:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "xwayland:enabled",
|
|
||||||
.description = "allow running applications using X11",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "xwayland:use_nearest_neighbor",
|
.value = "xwayland:use_nearest_neighbor",
|
||||||
.description = "uses the nearest neighbor filtering for xwayland apps, making them pixelated rather than blurry",
|
.description = "uses the nearest neighbor filtering for xwayland apps, making them pixelated rather than blurry",
|
||||||
@@ -1295,30 +1163,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
.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:
|
* cursor:
|
||||||
@@ -1334,8 +1178,8 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "cursor:no_hardware_cursors",
|
.value = "cursor:no_hardware_cursors",
|
||||||
.description = "disables hardware cursors",
|
.description = "disables hardware cursors",
|
||||||
.type = CONFIG_OPTION_CHOICE,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SChoiceData{0, "Disabled,Enabled,Auto"},
|
.data = SConfigOptionDescription::SBoolData{false},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "cursor:no_break_fs_vrr",
|
.value = "cursor:no_break_fs_vrr",
|
||||||
@@ -1375,9 +1219,9 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "cursor:warp_on_change_workspace",
|
.value = "cursor:warp_on_change_workspace",
|
||||||
.description = "Move the cursor to the last focused window after changing the workspace. Options: 0 (Disabled), 1 (Enabled), 2 (Force - ignores cursor:no_warps option)",
|
.description = "If true, move the cursor to the last focused window after changing the workspace.",
|
||||||
.type = CONFIG_OPTION_CHOICE,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SChoiceData{0, "Disabled,Enabled,Force"},
|
.data = SConfigOptionDescription::SBoolData{false},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "cursor:default_monitor",
|
.value = "cursor:default_monitor",
|
||||||
@@ -1416,8 +1260,8 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.data = SConfigOptionDescription::SBoolData{true},
|
.data = SConfigOptionDescription::SBoolData{true},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "cursor:use_cpu_buffer",
|
.value = "cursor:allow_dumb_copy",
|
||||||
.description = "Makes HW cursors use a CPU buffer. Required on Nvidia to have HW cursors. Experimental",
|
.description = "Makes HW cursors work on Nvidia, at the cost of a possible hitch whenever the image changes",
|
||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
.data = SConfigOptionDescription::SBoolData{false},
|
||||||
},
|
},
|
||||||
@@ -1504,182 +1348,4 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
.type = CONFIG_OPTION_BOOL,
|
.type = CONFIG_OPTION_BOOL,
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
.data = SConfigOptionDescription::SBoolData{true},
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
|
||||||
* dwindle:
|
|
||||||
*/
|
|
||||||
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:pseudotile",
|
|
||||||
.description = "enable pseudotiling. Pseudotiled windows retain their floating size when tiled.",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:force_split",
|
|
||||||
.description = "0 -> split follows mouse, 1 -> always split to the left (new = left or top) 2 -> always split to the right (new = right or bottom)",
|
|
||||||
.type = CONFIG_OPTION_CHOICE,
|
|
||||||
.data = SConfigOptionDescription::SChoiceData{0, "follow mouse,left or top,right or bottom"},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:preserve_split",
|
|
||||||
.description = "if enabled, the split (side/top) will not change regardless of what happens to the container.",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:smart_split",
|
|
||||||
.description = "if enabled, allows a more precise control over the window split direction based on the cursor's position. The window is conceptually divided into four "
|
|
||||||
"triangles, and cursor's triangle determines the split direction. This feature also turns on preserve_split.",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:smart_resizing",
|
|
||||||
.description =
|
|
||||||
"if enabled, resizing direction will be determined by the mouse's position on the window (nearest to which corner). Else, it is based on the window's tiling position.",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:permanent_direction_override",
|
|
||||||
.description = "if enabled, makes the preselect direction persist until either this mode is turned off, another direction is specified, or a non-direction is specified "
|
|
||||||
"(anything other than l,r,u/t,d/b)",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:special_scale_factor",
|
|
||||||
.description = "specifies the scale factor of windows on the special workspace [0 - 1]",
|
|
||||||
.type = CONFIG_OPTION_FLOAT,
|
|
||||||
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:split_width_multiplier",
|
|
||||||
.description = "specifies the auto-split width multiplier",
|
|
||||||
.type = CONFIG_OPTION_FLOAT,
|
|
||||||
.data = SConfigOptionDescription::SFloatData{1, 0.1, 3},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:use_active_for_splits",
|
|
||||||
.description = "whether to prefer the active window or the mouse position for splits",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:default_split_ratio",
|
|
||||||
.description = "the default split ratio on window open. 1 means even 50/50 split. [0.1 - 1.9]",
|
|
||||||
.type = CONFIG_OPTION_FLOAT,
|
|
||||||
.data = SConfigOptionDescription::SFloatData{1, 0.1, 1.9},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "dwindle:split_bias",
|
|
||||||
.description = "specifies which window will receive the larger half of a split. positional - 0, current window - 1, opening window - 2 [0/1/2]",
|
|
||||||
.type = CONFIG_OPTION_CHOICE,
|
|
||||||
.data = SConfigOptionDescription::SChoiceData{0, "positional,current,opening"},
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* master:
|
|
||||||
*/
|
|
||||||
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:allow_small_split",
|
|
||||||
.description = "enable adding additional master windows in a horizontal split style",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:special_scale_factor",
|
|
||||||
.description = "the scale of the special workspace windows. [0.0 - 1.0]",
|
|
||||||
.type = CONFIG_OPTION_FLOAT,
|
|
||||||
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:mfact",
|
|
||||||
.description =
|
|
||||||
"the size as a percentage of the master window, for example `mfact = 0.70` would mean 70% of the screen will be the master window, and 30% the slave [0.0 - 1.0]",
|
|
||||||
.type = CONFIG_OPTION_FLOAT,
|
|
||||||
.data = SConfigOptionDescription::SFloatData{0.55, 0, 1},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:new_status",
|
|
||||||
.description = "`master`: new window becomes master; `slave`: new windows are added to slave stack; `inherit`: inherit from focused window",
|
|
||||||
.type = CONFIG_OPTION_STRING_SHORT,
|
|
||||||
.data = SConfigOptionDescription::SStringData{"slave"},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:new_on_top",
|
|
||||||
.description = "whether a newly open window should be on the top of the stack",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:new_on_active",
|
|
||||||
.description = "`before`, `after`: place new window relative to the focused window; `none`: place new window according to the value of `new_on_top`. ",
|
|
||||||
.type = CONFIG_OPTION_STRING_SHORT,
|
|
||||||
.data = SConfigOptionDescription::SStringData{"none"},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:orientation",
|
|
||||||
.description = "default placement of the master area, can be left, right, top, bottom or center",
|
|
||||||
.type = CONFIG_OPTION_STRING_SHORT,
|
|
||||||
.data = SConfigOptionDescription::SStringData{"left"},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:inherit_fullscreen",
|
|
||||||
.description = "inherit fullscreen status when cycling/swapping to another window (e.g. monocle layout)",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.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",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:center_ignores_reserved",
|
|
||||||
.description = "centers the master window on monitor ignoring reserved areas",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:smart_resizing",
|
|
||||||
.description =
|
|
||||||
"if enabled, resizing direction will be determined by the mouse's position on the window (nearest to which corner). Else, it is based on the window's tiling position.",
|
|
||||||
.type = CONFIG_OPTION_BOOL,
|
|
||||||
.data = SConfigOptionDescription::SBoolData{true},
|
|
||||||
},
|
|
||||||
SConfigOptionDescription{
|
|
||||||
.value = "master:drop_at_cursor",
|
|
||||||
.description = "when enabled, dragging and dropping windows will put them at the cursor position. Otherwise, when dropped at the stack side, they will go to the "
|
|
||||||
"top/bottom of the stack depending on new_on_top.",
|
|
||||||
.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,30 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <hyprutils/animation/AnimationConfig.hpp>
|
|
||||||
#define CONFIG_MANAGER_H
|
#define CONFIG_MANAGER_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include "../debug/Log.hpp"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <regex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
|
#include "../helpers/WLClasses.hpp"
|
||||||
#include "../helpers/Monitor.hpp"
|
#include "../helpers/Monitor.hpp"
|
||||||
|
#include "../helpers/varlist/VarList.hpp"
|
||||||
#include "../desktop/Window.hpp"
|
#include "../desktop/Window.hpp"
|
||||||
#include "../desktop/LayerRule.hpp"
|
#include "../desktop/LayerSurface.hpp"
|
||||||
|
|
||||||
|
#include "defaultConfig.hpp"
|
||||||
#include "ConfigDataValues.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>
|
#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*
|
#define HANDLE void*
|
||||||
|
|
||||||
struct SWorkspaceRule {
|
struct SWorkspaceRule {
|
||||||
@@ -53,14 +56,26 @@ struct SMonitorAdditionalReservedArea {
|
|||||||
int right = 0;
|
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 {
|
struct SPluginKeyword {
|
||||||
HANDLE handle = nullptr;
|
HANDLE handle = 0;
|
||||||
std::string name = "";
|
std::string name = "";
|
||||||
Hyprlang::PCONFIGHANDLERFUNC fn = nullptr;
|
Hyprlang::PCONFIGHANDLERFUNC fn = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SPluginVariable {
|
struct SPluginVariable {
|
||||||
HANDLE handle = nullptr;
|
HANDLE handle = 0;
|
||||||
std::string name = "";
|
std::string name = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,7 +84,7 @@ struct SExecRequestedRule {
|
|||||||
uint64_t iPid = 0;
|
uint64_t iPid = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eConfigOptionType : uint8_t {
|
enum eConfigOptionType : uint16_t {
|
||||||
CONFIG_OPTION_BOOL = 0,
|
CONFIG_OPTION_BOOL = 0,
|
||||||
CONFIG_OPTION_INT = 1, /* e.g. 0/1/2*/
|
CONFIG_OPTION_INT = 1, /* e.g. 0/1/2*/
|
||||||
CONFIG_OPTION_FLOAT = 2,
|
CONFIG_OPTION_FLOAT = 2,
|
||||||
@@ -81,7 +96,7 @@ enum eConfigOptionType : uint8_t {
|
|||||||
CONFIG_OPTION_VECTOR = 8,
|
CONFIG_OPTION_VECTOR = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eConfigOptionFlags : uint8_t {
|
enum eConfigOptionFlags : uint32_t {
|
||||||
CONFIG_OPTION_FLAG_PERCENTAGE = (1 << 0),
|
CONFIG_OPTION_FLAG_PERCENTAGE = (1 << 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -104,7 +119,7 @@ struct SConfigOptionDescription {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SColorData {
|
struct SColorData {
|
||||||
CHyprColor color;
|
CColor color;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SChoiceData {
|
struct SChoiceData {
|
||||||
@@ -133,18 +148,12 @@ struct SConfigOptionDescription {
|
|||||||
std::variant<SBoolData, SRangeData, SFloatData, SStringData, SColorData, SChoiceData, SGradientData, SVectorData> data;
|
std::variant<SBoolData, SRangeData, SFloatData, SStringData, SColorData, SChoiceData, SGradientData, SVectorData> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SFirstExecRequest {
|
|
||||||
std::string exec = "";
|
|
||||||
bool withRules = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CConfigManager {
|
class CConfigManager {
|
||||||
public:
|
public:
|
||||||
CConfigManager();
|
CConfigManager();
|
||||||
|
|
||||||
|
void tick();
|
||||||
void init();
|
void init();
|
||||||
void reload();
|
|
||||||
std::string verify();
|
|
||||||
|
|
||||||
int getDeviceInt(const std::string&, const std::string&, const std::string& fallback = "");
|
int getDeviceInt(const std::string&, const std::string&, const std::string& fallback = "");
|
||||||
float getDeviceFloat(const std::string&, const std::string&, const std::string& fallback = "");
|
float getDeviceFloat(const std::string&, const std::string&, const std::string& fallback = "");
|
||||||
@@ -156,155 +165,144 @@ class CConfigManager {
|
|||||||
|
|
||||||
void* const* getConfigValuePtr(const std::string&);
|
void* const* getConfigValuePtr(const std::string&);
|
||||||
Hyprlang::CConfigValue* getHyprlangConfigValuePtr(const std::string& name, const std::string& specialCat = "");
|
Hyprlang::CConfigValue* getHyprlangConfigValuePtr(const std::string& name, const std::string& specialCat = "");
|
||||||
std::string getMainConfigPath();
|
void onPluginLoadUnload(const std::string& name, bool load);
|
||||||
std::string getConfigString();
|
static std::string getMainConfigPath();
|
||||||
|
const std::string getConfigString();
|
||||||
|
|
||||||
SMonitorRule getMonitorRuleFor(const PHLMONITOR);
|
SMonitorRule getMonitorRuleFor(const CMonitor&);
|
||||||
SWorkspaceRule getWorkspaceRuleFor(PHLWORKSPACE workspace);
|
SWorkspaceRule getWorkspaceRuleFor(PHLWORKSPACE workspace);
|
||||||
std::string getDefaultWorkspaceFor(const std::string&);
|
std::string getDefaultWorkspaceFor(const std::string&);
|
||||||
|
|
||||||
PHLMONITOR getBoundMonitorForWS(const std::string&);
|
CMonitor* getBoundMonitorForWS(const std::string&);
|
||||||
std::string getBoundMonitorStringForWS(const std::string&);
|
std::string getBoundMonitorStringForWS(const std::string&);
|
||||||
const std::vector<SWorkspaceRule>& getAllWorkspaceRules();
|
const std::deque<SWorkspaceRule>& getAllWorkspaceRules();
|
||||||
|
|
||||||
std::vector<SP<CWindowRule>> getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false);
|
std::vector<SWindowRule> getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false);
|
||||||
std::vector<SP<CLayerRule>> getMatchingRules(PHLLS);
|
std::vector<SLayerRule> getMatchingRules(PHLLS);
|
||||||
void ensurePersistentWorkspacesPresent();
|
|
||||||
|
|
||||||
const std::vector<SConfigOptionDescription>& getAllDescriptions();
|
const std::vector<SConfigOptionDescription>& getAllDescriptions();
|
||||||
|
|
||||||
std::unordered_map<std::string, SMonitorAdditionalReservedArea> m_mAdditionalReservedAreas;
|
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 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 = {});
|
void addPluginKeyword(HANDLE handle, const std::string& name, Hyprlang::PCONFIGHANDLERFUNC fun, Hyprlang::SHandlerOptions opts = {});
|
||||||
void removePluginConfig(HANDLE handle);
|
void removePluginConfig(HANDLE handle);
|
||||||
|
|
||||||
// no-op when done.
|
// no-op when done.
|
||||||
void dispatchExecOnce();
|
void dispatchExecOnce();
|
||||||
void dispatchExecShutdown();
|
|
||||||
|
|
||||||
void performMonitorReload();
|
void performMonitorReload();
|
||||||
void ensureMonitorStatus();
|
void appendMonitorRule(const SMonitorRule&);
|
||||||
void ensureVRR(PHLMONITOR pMonitor = nullptr);
|
bool replaceMonitorRule(const SMonitorRule&);
|
||||||
|
void ensureMonitorStatus();
|
||||||
|
void ensureVRR(CMonitor* pMonitor = nullptr);
|
||||||
|
|
||||||
bool shouldUseSoftwareCursors();
|
std::string parseKeyword(const std::string&, const std::string&);
|
||||||
void updateWatcher();
|
|
||||||
|
|
||||||
std::string parseKeyword(const std::string&, const std::string&);
|
void addParseError(const std::string&);
|
||||||
|
|
||||||
void addParseError(const std::string&);
|
SAnimationPropertyConfig* getAnimationPropertyConfig(const std::string&);
|
||||||
|
|
||||||
SP<Hyprutils::Animation::SAnimationPropertyConfig> getAnimationPropertyConfig(const std::string&);
|
void addExecRule(const SExecRequestedRule&);
|
||||||
|
|
||||||
void addExecRule(const SExecRequestedRule&);
|
void handlePluginLoads();
|
||||||
|
std::string getErrors();
|
||||||
void handlePluginLoads();
|
|
||||||
std::string getErrors();
|
|
||||||
|
|
||||||
// keywords
|
// keywords
|
||||||
std::optional<std::string> handleRawExec(const std::string&, const std::string&);
|
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> handleExecOnce(const std::string&, const std::string&);
|
std::optional<std::string> handleMonitor(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleExecRawOnce(const std::string&, const std::string&);
|
std::optional<std::string> handleBind(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleExecShutdown(const std::string&, const std::string&);
|
std::optional<std::string> handleUnbind(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleMonitor(const std::string&, const std::string&);
|
std::optional<std::string> handleWindowRule(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleBind(const std::string&, const std::string&);
|
std::optional<std::string> handleLayerRule(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleUnbind(const std::string&, const std::string&);
|
std::optional<std::string> handleWindowRuleV2(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleWindowRule(const std::string&, const std::string&);
|
std::optional<std::string> handleWorkspaceRules(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleLayerRule(const std::string&, const std::string&);
|
std::optional<std::string> handleBezier(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleWindowRuleV2(const std::string&, const std::string&);
|
std::optional<std::string> handleAnimation(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleWorkspaceRules(const std::string&, const std::string&);
|
std::optional<std::string> handleSource(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleBezier(const std::string&, const std::string&);
|
std::optional<std::string> handleSubmap(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleAnimation(const std::string&, const std::string&);
|
std::optional<std::string> handleBlurLS(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleSource(const std::string&, const std::string&);
|
std::optional<std::string> handleBindWS(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleSubmap(const std::string&, const std::string&);
|
std::optional<std::string> handleEnv(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleBlurLS(const std::string&, const std::string&);
|
std::optional<std::string> handlePlugin(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleBindWS(const std::string&, const std::string&);
|
|
||||||
std::optional<std::string> handleEnv(const std::string&, const std::string&);
|
|
||||||
std::optional<std::string> handlePlugin(const std::string&, const std::string&);
|
|
||||||
|
|
||||||
std::string configCurrentPath;
|
std::string configCurrentPath;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::function<CWindowOverridableVar<bool>*(const PHLWINDOW&)>> mbWindowProperties = {
|
std::unordered_map<std::string, std::function<CWindowOverridableVar<bool>*(PHLWINDOW)>> mbWindowProperties = {
|
||||||
{"allowsinput", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.allowsInput; }},
|
{"allowsinput", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.allowsInput; }},
|
||||||
{"dimaround", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.dimAround; }},
|
{"dimaround", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.dimAround; }},
|
||||||
{"decorate", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.decorate; }},
|
{"decorate", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.decorate; }},
|
||||||
{"focusonactivate", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.focusOnActivate; }},
|
{"focusonactivate", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.focusOnActivate; }},
|
||||||
{"keepaspectratio", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.keepAspectRatio; }},
|
{"keepaspectratio", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.keepAspectRatio; }},
|
||||||
{"nearestneighbor", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.nearestNeighbor; }},
|
{"nearestneighbor", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.nearestNeighbor; }},
|
||||||
{"noanim", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noAnim; }},
|
{"noanim", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noAnim; }},
|
||||||
{"noblur", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noBlur; }},
|
{"noblur", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noBlur; }},
|
||||||
{"noborder", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noBorder; }},
|
{"noborder", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noBorder; }},
|
||||||
{"nodim", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noDim; }},
|
{"nodim", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noDim; }},
|
||||||
{"nofocus", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noFocus; }},
|
{"nofocus", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noFocus; }},
|
||||||
{"nomaxsize", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noMaxSize; }},
|
{"nomaxsize", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noMaxSize; }},
|
||||||
{"norounding", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noRounding; }},
|
{"norounding", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noRounding; }},
|
||||||
{"noshadow", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noShadow; }},
|
{"noshadow", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noShadow; }},
|
||||||
{"noshortcutsinhibit", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noShortcutsInhibit; }},
|
{"noshortcutsinhibit", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noShortcutsInhibit; }},
|
||||||
{"opaque", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.opaque; }},
|
{"opaque", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.opaque; }},
|
||||||
{"forcergbx", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.RGBX; }},
|
{"forcergbx", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.RGBX; }},
|
||||||
{"syncfullscreen", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.syncFullscreen; }},
|
{"syncfullscreen", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.syncFullscreen; }},
|
||||||
{"immediate", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.tearing; }},
|
{"immediate", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.tearing; }},
|
||||||
{"xray", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.xray; }},
|
{"xray", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.xray; }},
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<std::string, std::function<CWindowOverridableVar<int>*(const PHLWINDOW&)>> miWindowProperties = {
|
std::unordered_map<std::string, std::function<CWindowOverridableVar<int>*(PHLWINDOW)>> miWindowProperties = {
|
||||||
{"rounding", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.rounding; }},
|
{"rounding", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.rounding; }}, {"bordersize", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.borderSize; }}};
|
||||||
{"bordersize", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.borderSize; }},
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unordered_map<std::string, std::function<CWindowOverridableVar<float>*(PHLWINDOW)>> mfWindowProperties = {
|
bool m_bWantsMonitorReload = false;
|
||||||
{"roundingpower", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.roundingPower; }},
|
bool m_bForceReload = false;
|
||||||
{"scrollmouse", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollMouse; }},
|
bool m_bNoMonitorReload = false;
|
||||||
{"scrolltouchpad", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollTouchpad; }}};
|
bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking
|
||||||
|
|
||||||
bool m_bWantsMonitorReload = false;
|
|
||||||
bool m_bNoMonitorReload = false;
|
|
||||||
bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking
|
|
||||||
bool m_bLastConfigVerificationWasSuccessful = true;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UP<Hyprlang::CConfig> m_pConfig;
|
std::unique_ptr<Hyprlang::CConfig> m_pConfig;
|
||||||
|
|
||||||
std::vector<std::string> m_configPaths;
|
std::deque<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
|
std::string m_szCurrentSubmap = ""; // For storing the current keybind submap
|
||||||
|
|
||||||
std::vector<SExecRequestedRule> execRequestedRules; // rules requested with exec, e.g. [workspace 2] kitty
|
std::vector<SExecRequestedRule> execRequestedRules; // rules requested with exec, e.g. [workspace 2] kitty
|
||||||
|
|
||||||
std::vector<std::string> m_vDeclaredPlugins;
|
std::vector<std::string> m_vDeclaredPlugins;
|
||||||
std::vector<SPluginKeyword> pluginKeywords;
|
std::vector<SPluginKeyword> pluginKeywords;
|
||||||
std::vector<SPluginVariable> pluginVariables;
|
std::vector<SPluginVariable> pluginVariables;
|
||||||
|
|
||||||
bool isFirstLaunch = true; // For exec-once
|
bool isFirstLaunch = true; // For exec-once
|
||||||
|
|
||||||
std::vector<SMonitorRule> m_vMonitorRules;
|
std::deque<SMonitorRule> m_dMonitorRules;
|
||||||
std::vector<SWorkspaceRule> m_vWorkspaceRules;
|
std::deque<SWorkspaceRule> m_dWorkspaceRules;
|
||||||
std::vector<SP<CWindowRule>> m_vWindowRules;
|
std::deque<SWindowRule> m_dWindowRules;
|
||||||
std::vector<SP<CLayerRule>> m_vLayerRules;
|
std::deque<SLayerRule> m_dLayerRules;
|
||||||
std::vector<std::string> m_dBlurLSNamespaces;
|
std::deque<std::string> m_dBlurLSNamespaces;
|
||||||
|
|
||||||
bool firstExecDispatched = false;
|
bool firstExecDispatched = false;
|
||||||
bool m_bManualCrashInitiated = false;
|
bool m_bManualCrashInitiated = false;
|
||||||
|
std::deque<std::string> firstExecRequests;
|
||||||
|
|
||||||
std::vector<SFirstExecRequest> firstExecRequests; // bool is for if with rules
|
std::vector<std::pair<std::string, std::string>> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins
|
||||||
std::vector<std::string> finalExecRequests;
|
std::string m_szConfigErrors = "";
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins
|
|
||||||
std::string m_szConfigErrors = "";
|
|
||||||
|
|
||||||
// internal methods
|
// internal methods
|
||||||
void updateBlurredLS(const std::string&, const bool);
|
void setAnimForChildren(SAnimationPropertyConfig* const);
|
||||||
void setDefaultAnimationVars();
|
void updateBlurredLS(const std::string&, const bool);
|
||||||
std::optional<std::string> resetHLConfig();
|
void setDefaultAnimationVars();
|
||||||
std::optional<std::string> generateConfig(std::string configPath);
|
std::optional<std::string> resetHLConfig();
|
||||||
std::optional<std::string> verifyConfigExists();
|
static std::optional<std::string> generateConfig(std::string configPath);
|
||||||
void postConfigReload(const Hyprlang::CParseResult& result);
|
static std::optional<std::string> verifyConfigExists();
|
||||||
SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&);
|
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 <string>
|
||||||
#include <typeindex>
|
#include <typeindex>
|
||||||
#include <hyprlang.hpp>
|
#include <hyprlang.hpp>
|
||||||
|
#include "../debug/Log.hpp"
|
||||||
#include "../macros.hpp"
|
#include "../macros.hpp"
|
||||||
#include "ConfigManager.hpp"
|
#include "ConfigManager.hpp"
|
||||||
|
|
||||||
@@ -12,7 +13,6 @@ class CConfigValue {
|
|||||||
CConfigValue(const std::string& val) {
|
CConfigValue(const std::string& val) {
|
||||||
const auto PVHYPRLANG = g_pConfigManager->getHyprlangConfigValuePtr(val);
|
const auto PVHYPRLANG = g_pConfigManager->getHyprlangConfigValuePtr(val);
|
||||||
|
|
||||||
// NOLINTNEXTLINE
|
|
||||||
p_ = PVHYPRLANG->getDataStaticPtr();
|
p_ = PVHYPRLANG->getDataStaticPtr();
|
||||||
|
|
||||||
#ifdef HYPRLAND_DEBUG
|
#ifdef HYPRLAND_DEBUG
|
||||||
|
@@ -1,84 +0,0 @@
|
|||||||
#include "ConfigWatcher.hpp"
|
|
||||||
#include <sys/inotify.h>
|
|
||||||
#include "../debug/Log.hpp"
|
|
||||||
#include <ranges>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
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 | IN_DONT_FOLLOW),
|
|
||||||
.file = path,
|
|
||||||
});
|
|
||||||
|
|
||||||
std::error_code ec, ec2;
|
|
||||||
const auto CANONICAL = std::filesystem::canonical(path, ec);
|
|
||||||
const auto IS_SYMLINK = std::filesystem::is_symlink(path, ec2);
|
|
||||||
if (!ec && !ec2 && IS_SYMLINK) {
|
|
||||||
m_watches.emplace_back(SInotifyWatch{
|
|
||||||
.wd = inotify_add_watch(m_inotifyFd, CANONICAL.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>();
|
|
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
inline const std::string AUTOCONFIG = R"#(
|
inline const std::string AUTOCONFIG = R"#(
|
||||||
# #######################################################################################
|
# #######################################################################################
|
||||||
# AUTOGENERATED HYPRLAND CONFIG.
|
# AUTOGENERATED HYPR CONFIG.
|
||||||
# PLEASE USE THE CONFIG PROVIDED IN THE GIT REPO /examples/hyprland.conf AND EDIT IT,
|
# PLEASE USE THE CONFIG PROVIDED IN THE GIT REPO /examples/hypr.conf AND EDIT IT,
|
||||||
# OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
|
# OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
|
||||||
# #######################################################################################
|
# #######################################################################################
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ autogenerated = 1 # remove this line to remove the warning
|
|||||||
|
|
||||||
# This is an example Hyprland config file.
|
# This is an example Hyprland config file.
|
||||||
# Refer to the wiki for more information.
|
# Refer to the wiki for more information.
|
||||||
# https://wiki.hyprland.org/Configuring/
|
# https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
||||||
|
|
||||||
# Please note not all available settings / options are set here.
|
# Please note not all available settings / options are set here.
|
||||||
# For a full list, see the wiki
|
# For a full list, see the wiki
|
||||||
@@ -94,18 +94,15 @@ general {
|
|||||||
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
||||||
decoration {
|
decoration {
|
||||||
rounding = 10
|
rounding = 10
|
||||||
rounding_power = 2
|
|
||||||
|
|
||||||
# Change transparency of focused and unfocused windows
|
# Change transparency of focused and unfocused windows
|
||||||
active_opacity = 1.0
|
active_opacity = 1.0
|
||||||
inactive_opacity = 1.0
|
inactive_opacity = 1.0
|
||||||
|
|
||||||
shadow {
|
drop_shadow = true
|
||||||
enabled = true
|
shadow_range = 4
|
||||||
range = 4
|
shadow_render_power = 3
|
||||||
render_power = 3
|
col.shadow = rgba(1a1a1aee)
|
||||||
color = rgba(1a1a1aee)
|
|
||||||
}
|
|
||||||
|
|
||||||
# https://wiki.hyprland.org/Configuring/Variables/#blur
|
# https://wiki.hyprland.org/Configuring/Variables/#blur
|
||||||
blur {
|
blur {
|
||||||
@@ -119,44 +116,20 @@ decoration {
|
|||||||
|
|
||||||
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
||||||
animations {
|
animations {
|
||||||
enabled = yes, please :)
|
enabled = true
|
||||||
|
|
||||||
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||||
|
|
||||||
bezier = easeOutQuint,0.23,1,0.32,1
|
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
|
||||||
bezier = easeInOutCubic,0.65,0.05,0.36,1
|
|
||||||
bezier = linear,0,0,1,1
|
|
||||||
bezier = almostLinear,0.5,0.5,0.75,1.0
|
|
||||||
bezier = quick,0.15,0,0.1,1
|
|
||||||
|
|
||||||
animation = global, 1, 10, default
|
animation = windows, 1, 7, myBezier
|
||||||
animation = border, 1, 5.39, easeOutQuint
|
animation = windowsOut, 1, 7, default, popin 80%
|
||||||
animation = windows, 1, 4.79, easeOutQuint
|
animation = border, 1, 10, default
|
||||||
animation = windowsIn, 1, 4.1, easeOutQuint, popin 87%
|
animation = borderangle, 1, 8, default
|
||||||
animation = windowsOut, 1, 1.49, linear, popin 87%
|
animation = fade, 1, 7, default
|
||||||
animation = fadeIn, 1, 1.73, almostLinear
|
animation = workspaces, 1, 6, default
|
||||||
animation = fadeOut, 1, 1.46, almostLinear
|
|
||||||
animation = fade, 1, 3.03, quick
|
|
||||||
animation = layers, 1, 3.81, easeOutQuint
|
|
||||||
animation = layersIn, 1, 4, easeOutQuint, fade
|
|
||||||
animation = layersOut, 1, 1.5, linear, fade
|
|
||||||
animation = fadeLayersIn, 1, 1.79, almostLinear
|
|
||||||
animation = fadeLayersOut, 1, 1.39, almostLinear
|
|
||||||
animation = workspaces, 1, 1.94, almostLinear, fade
|
|
||||||
animation = workspacesIn, 1, 1.21, almostLinear, fade
|
|
||||||
animation = workspacesOut, 1, 1.94, almostLinear, fade
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
|
|
||||||
# "Smart gaps" / "No gaps when only"
|
|
||||||
# uncomment all if you wish to use that.
|
|
||||||
# workspace = w[tv1], gapsout:0, gapsin:0
|
|
||||||
# workspace = f[1], gapsout:0, gapsin:0
|
|
||||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[tv1]
|
|
||||||
# windowrulev2 = rounding 0, floating:0, onworkspace:w[tv1]
|
|
||||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:f[1]
|
|
||||||
# windowrulev2 = rounding 0, floating:0, onworkspace:f[1]
|
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||||
dwindle {
|
dwindle {
|
||||||
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||||
@@ -268,19 +241,6 @@ bind = $mainMod, mouse_up, workspace, e-1
|
|||||||
bindm = $mainMod, mouse:272, movewindow
|
bindm = $mainMod, mouse:272, movewindow
|
||||||
bindm = $mainMod, mouse:273, resizewindow
|
bindm = $mainMod, mouse:273, resizewindow
|
||||||
|
|
||||||
# Laptop multimedia keys for volume and LCD brightness
|
|
||||||
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
|
|
||||||
bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
|
||||||
bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
|
||||||
bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
|
||||||
bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+
|
|
||||||
bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%-
|
|
||||||
|
|
||||||
# Requires playerctl
|
|
||||||
bindl = , XF86AudioNext, exec, playerctl next
|
|
||||||
bindl = , XF86AudioPause, exec, playerctl play-pause
|
|
||||||
bindl = , XF86AudioPlay, exec, playerctl play-pause
|
|
||||||
bindl = , XF86AudioPrev, exec, playerctl previous
|
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
### WINDOWS AND WORKSPACES ###
|
### WINDOWS AND WORKSPACES ###
|
||||||
@@ -295,9 +255,5 @@ bindl = , XF86AudioPrev, exec, playerctl previous
|
|||||||
# Example windowrule v2
|
# Example windowrule v2
|
||||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||||
|
|
||||||
# Ignore maximize requests from apps. You'll probably like this.
|
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
|
||||||
windowrulev2 = suppressevent maximize, class:.*
|
|
||||||
|
|
||||||
# Fix some dragging issues with XWayland
|
|
||||||
windowrulev2 = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
|
|
||||||
)#";
|
)#";
|
||||||
|
@@ -2,11 +2,10 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <link.h>
|
#include <link.h>
|
||||||
#include <ctime>
|
#include <time.h>
|
||||||
#include <cerrno>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "../helpers/MiscFunctions.hpp"
|
|
||||||
|
|
||||||
#include "../plugins/PluginSystem.hpp"
|
#include "../plugins/PluginSystem.hpp"
|
||||||
#include "../signal-safe.hpp"
|
#include "../signal-safe.hpp"
|
||||||
@@ -32,10 +31,10 @@ static char const* const MESSAGES[] = {"Sorry, didn't mean to...",
|
|||||||
|
|
||||||
// <random> is not async-signal-safe, fake it with time(NULL) instead
|
// <random> is not async-signal-safe, fake it with time(NULL) instead
|
||||||
char const* getRandomMessage() {
|
char const* getRandomMessage() {
|
||||||
return MESSAGES[time(nullptr) % (sizeof(MESSAGES) / sizeof(MESSAGES[0]))];
|
return MESSAGES[time(NULL) % (sizeof(MESSAGES) / sizeof(MESSAGES[0]))];
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] inline void exitWithError(char const* err) {
|
[[noreturn]] inline void exit_with_error(char const* err) {
|
||||||
write(STDERR_FILENO, err, strlen(err));
|
write(STDERR_FILENO, err, strlen(err));
|
||||||
// perror() is not signal-safe, but we use it here
|
// perror() is not signal-safe, but we use it here
|
||||||
// because if the crash-handler already crashed, it can't get any worse.
|
// because if the crash-handler already crashed, it can't get any worse.
|
||||||
@@ -43,17 +42,17 @@ char const* getRandomMessage() {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NCrashReporter::createAndSaveCrash(int sig) {
|
void CrashReporter::createAndSaveCrash(int sig) {
|
||||||
int reportFd = -1;
|
int reportFd;
|
||||||
|
|
||||||
// We're in the signal handler, so we *only* have stack memory.
|
// We're in the signal handler, so we *only* have stack memory.
|
||||||
// To save as much stack memory as possible,
|
// To save as much stack memory as possible,
|
||||||
// destroy things as soon as possible.
|
// destroy things as soon as possible.
|
||||||
{
|
{
|
||||||
CMaxLengthCString<255> reportPath;
|
MaxLengthCString<255> reportPath;
|
||||||
|
|
||||||
const auto HOME = sigGetenv("HOME");
|
const auto HOME = sig_getenv("HOME");
|
||||||
const auto CACHE_HOME = sigGetenv("XDG_CACHE_HOME");
|
const auto CACHE_HOME = sig_getenv("XDG_CACHE_HOME");
|
||||||
|
|
||||||
if (CACHE_HOME && CACHE_HOME[0] != '\0') {
|
if (CACHE_HOME && CACHE_HOME[0] != '\0') {
|
||||||
reportPath += CACHE_HOME;
|
reportPath += CACHE_HOME;
|
||||||
@@ -62,24 +61,24 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
|||||||
reportPath += HOME;
|
reportPath += HOME;
|
||||||
reportPath += "/.cache/hyprland";
|
reportPath += "/.cache/hyprland";
|
||||||
} else {
|
} else {
|
||||||
exitWithError("$CACHE_HOME and $HOME not set, nowhere to report crash\n");
|
exit_with_error("$CACHE_HOME and $HOME not set, nowhere to report crash\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = mkdir(reportPath.getStr(), S_IRWXU);
|
int ret = mkdir(reportPath.get_str(), S_IRWXU);
|
||||||
//__asm__("int $3");
|
//__asm__("int $3");
|
||||||
if (ret < 0 && errno != EEXIST) {
|
if (ret < 0 && errno != EEXIST) {
|
||||||
exitWithError("failed to mkdir() crash report directory\n");
|
exit_with_error("failed to mkdir() crash report directory\n");
|
||||||
}
|
}
|
||||||
reportPath += "/hyprlandCrashReport";
|
reportPath += "/hyprlandCrashReport";
|
||||||
reportPath.writeNum(getpid());
|
reportPath.write_num(getpid());
|
||||||
reportPath += ".txt";
|
reportPath += ".txt";
|
||||||
|
|
||||||
{
|
{
|
||||||
CBufFileWriter<64> stderr(2);
|
BufFileWriter<64> stderr(2);
|
||||||
stderr += "Hyprland has crashed :( Consult the crash report at ";
|
stderr += "Hyprland has crashed :( Consult the crash report at ";
|
||||||
if (!reportPath.boundsExceeded()) {
|
if (!reportPath.boundsExceeded()) {
|
||||||
stderr += reportPath.getStr();
|
stderr += reportPath.get_str();
|
||||||
} else {
|
} else {
|
||||||
stderr += "[ERROR: Crash report path does not fit into memory! Check if your $CACHE_HOME/$HOME is too deeply nested. Max 255 characters.]";
|
stderr += "[ERROR: Crash report path does not fit into memory! Check if your $CACHE_HOME/$HOME is too deeply nested. Max 255 characters.]";
|
||||||
}
|
}
|
||||||
@@ -87,12 +86,12 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
|||||||
stderr.flush();
|
stderr.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
reportFd = open(reportPath.getStr(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
reportFd = open(reportPath.get_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||||
if (reportFd < 0) {
|
if (reportFd < 0) {
|
||||||
exitWithError("Failed to open crash report path for writing");
|
exit_with_error("Failed to open crash report path for writing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CBufFileWriter<512> finalCrashReport(reportFd);
|
BufFileWriter<512> finalCrashReport(reportFd);
|
||||||
|
|
||||||
finalCrashReport += "--------------------------------------------\n Hyprland Crash Report\n--------------------------------------------\n";
|
finalCrashReport += "--------------------------------------------\n Hyprland Crash Report\n--------------------------------------------\n";
|
||||||
finalCrashReport += getRandomMessage();
|
finalCrashReport += getRandomMessage();
|
||||||
@@ -101,7 +100,7 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
|||||||
finalCrashReport += "Hyprland received signal ";
|
finalCrashReport += "Hyprland received signal ";
|
||||||
finalCrashReport.writeNum(sig);
|
finalCrashReport.writeNum(sig);
|
||||||
finalCrashReport += '(';
|
finalCrashReport += '(';
|
||||||
finalCrashReport += sigStrsignal(sig);
|
finalCrashReport += sig_strsignal(sig);
|
||||||
finalCrashReport += ")\nVersion: ";
|
finalCrashReport += ")\nVersion: ";
|
||||||
finalCrashReport += GIT_COMMIT_HASH;
|
finalCrashReport += GIT_COMMIT_HASH;
|
||||||
finalCrashReport += "\nTag: ";
|
finalCrashReport += "\nTag: ";
|
||||||
@@ -112,7 +111,7 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
|||||||
#ifdef LEGACY_RENDERER
|
#ifdef LEGACY_RENDERER
|
||||||
finalCrashReport += "legacyrenderer\n";
|
finalCrashReport += "legacyrenderer\n";
|
||||||
#endif
|
#endif
|
||||||
#if ISDEBUG
|
#ifndef ISDEBUG
|
||||||
finalCrashReport += "debug\n";
|
finalCrashReport += "debug\n";
|
||||||
#endif
|
#endif
|
||||||
#ifdef NO_XWAYLAND
|
#ifdef NO_XWAYLAND
|
||||||
@@ -123,9 +122,9 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
|||||||
if (g_pPluginSystem && g_pPluginSystem->pluginCount() > 0) {
|
if (g_pPluginSystem && g_pPluginSystem->pluginCount() > 0) {
|
||||||
finalCrashReport += "Hyprland seems to be running with plugins. This crash might not be Hyprland's fault.\nPlugins:\n";
|
finalCrashReport += "Hyprland seems to be running with plugins. This crash might not be Hyprland's fault.\nPlugins:\n";
|
||||||
|
|
||||||
const size_t count = g_pPluginSystem->pluginCount();
|
size_t count = g_pPluginSystem->pluginCount();
|
||||||
std::vector<CPlugin*> plugins(count);
|
CPlugin* plugins[count];
|
||||||
g_pPluginSystem->sigGetPlugins(plugins.data(), count);
|
g_pPluginSystem->sig_getPlugins(plugins, count);
|
||||||
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
auto p = plugins[i];
|
auto p = plugins[i];
|
||||||
@@ -160,9 +159,9 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
|||||||
|
|
||||||
finalCrashReport += "GPU:\n\t";
|
finalCrashReport += "GPU:\n\t";
|
||||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||||
finalCrashReport.writeCmdOutput("pciconf -lv | grep -F -A4 vga");
|
finalCrashReport.writeCmdOutput("pciconf -lv | fgrep -A4 vga");
|
||||||
#else
|
#else
|
||||||
finalCrashReport.writeCmdOutput("lspci -vnn | grep -E '(VGA|Display|3D)'");
|
finalCrashReport.writeCmdOutput("lspci -vnn | grep VGA");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
finalCrashReport += "\n\nos-release:\n";
|
finalCrashReport += "\n\nos-release:\n";
|
||||||
@@ -242,5 +241,5 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
|||||||
|
|
||||||
finalCrashReport += "\n\nLog tail:\n";
|
finalCrashReport += "\n\nLog tail:\n";
|
||||||
|
|
||||||
finalCrashReport += std::string_view(Debug::rollingLog).substr(Debug::rollingLog.find('\n') + 1);
|
finalCrashReport += std::string_view(Debug::rollingLog).substr(Debug::rollingLog.find("\n") + 1);
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
|
|
||||||
namespace NCrashReporter {
|
namespace CrashReporter {
|
||||||
void createAndSaveCrash(int sig);
|
void createAndSaveCrash(int sig);
|
||||||
};
|
};
|
@@ -1,14 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Compositor.hpp"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "../helpers/MiscFunctions.hpp"
|
#include "../helpers/MiscFunctions.hpp"
|
||||||
#include "../desktop/Window.hpp"
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
// exposed for main.cpp
|
|
||||||
std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request);
|
|
||||||
std::string versionRequest(eHyprCtlOutputFormat format, std::string request);
|
|
||||||
|
|
||||||
class CHyprCtl {
|
class CHyprCtl {
|
||||||
public:
|
public:
|
||||||
CHyprCtl();
|
CHyprCtl();
|
||||||
@@ -38,4 +34,4 @@ class CHyprCtl {
|
|||||||
std::string m_socketPath;
|
std::string m_socketPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline UP<CHyprCtl> g_pHyprCtl;
|
inline std::unique_ptr<CHyprCtl> g_pHyprCtl;
|
||||||
|
@@ -2,21 +2,13 @@
|
|||||||
#include "HyprDebugOverlay.hpp"
|
#include "HyprDebugOverlay.hpp"
|
||||||
#include "config/ConfigValue.hpp"
|
#include "config/ConfigValue.hpp"
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../render/pass/TexPassElement.hpp"
|
|
||||||
#include "../render/Renderer.hpp"
|
|
||||||
#include "../managers/AnimationManager.hpp"
|
|
||||||
|
|
||||||
CHyprDebugOverlay::CHyprDebugOverlay() {
|
CHyprDebugOverlay::CHyprDebugOverlay() {
|
||||||
m_pTexture = makeShared<CTexture>();
|
m_pTexture = makeShared<CTexture>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprMonitorDebugOverlay::renderData(PHLMONITOR pMonitor, float durationUs) {
|
void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) {
|
||||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
m_dLastRenderTimes.push_back(durationUs / 1000.f);
|
||||||
|
|
||||||
if (!*PDEBUGOVERLAY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_dLastRenderTimes.emplace_back(durationUs / 1000.f);
|
|
||||||
|
|
||||||
if (m_dLastRenderTimes.size() > (long unsigned int)pMonitor->refreshRate)
|
if (m_dLastRenderTimes.size() > (long unsigned int)pMonitor->refreshRate)
|
||||||
m_dLastRenderTimes.pop_front();
|
m_dLastRenderTimes.pop_front();
|
||||||
@@ -25,13 +17,8 @@ void CHyprMonitorDebugOverlay::renderData(PHLMONITOR pMonitor, float durationUs)
|
|||||||
m_pMonitor = pMonitor;
|
m_pMonitor = pMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprMonitorDebugOverlay::renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs) {
|
void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) {
|
||||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
m_dLastRenderTimesNoOverlay.push_back(durationUs / 1000.f);
|
||||||
|
|
||||||
if (!*PDEBUGOVERLAY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_dLastRenderTimesNoOverlay.emplace_back(durationUs / 1000.f);
|
|
||||||
|
|
||||||
if (m_dLastRenderTimesNoOverlay.size() > (long unsigned int)pMonitor->refreshRate)
|
if (m_dLastRenderTimesNoOverlay.size() > (long unsigned int)pMonitor->refreshRate)
|
||||||
m_dLastRenderTimesNoOverlay.pop_front();
|
m_dLastRenderTimesNoOverlay.pop_front();
|
||||||
@@ -40,13 +27,8 @@ void CHyprMonitorDebugOverlay::renderDataNoOverlay(PHLMONITOR pMonitor, float du
|
|||||||
m_pMonitor = pMonitor;
|
m_pMonitor = pMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprMonitorDebugOverlay::frameData(PHLMONITOR pMonitor) {
|
void CHyprMonitorDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
m_dLastFrametimes.push_back(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - m_tpLastFrame).count() / 1000.f);
|
||||||
|
|
||||||
if (!*PDEBUGOVERLAY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_dLastFrametimes.emplace_back(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - m_tpLastFrame).count() / 1000.f);
|
|
||||||
|
|
||||||
if (m_dLastFrametimes.size() > (long unsigned int)pMonitor->refreshRate)
|
if (m_dLastFrametimes.size() > (long unsigned int)pMonitor->refreshRate)
|
||||||
m_dLastFrametimes.pop_front();
|
m_dLastFrametimes.pop_front();
|
||||||
@@ -57,7 +39,7 @@ void CHyprMonitorDebugOverlay::frameData(PHLMONITOR pMonitor) {
|
|||||||
m_pMonitor = pMonitor;
|
m_pMonitor = pMonitor;
|
||||||
|
|
||||||
// anim data too
|
// anim data too
|
||||||
const auto PMONITORFORTICKS = g_pHyprRenderer->m_pMostHzMonitor ? g_pHyprRenderer->m_pMostHzMonitor.lock() : g_pCompositor->m_pLastMonitor.lock();
|
const auto PMONITORFORTICKS = g_pHyprRenderer->m_pMostHzMonitor ? g_pHyprRenderer->m_pMostHzMonitor : g_pCompositor->m_pLastMonitor.get();
|
||||||
if (PMONITORFORTICKS) {
|
if (PMONITORFORTICKS) {
|
||||||
if (m_dLastAnimationTicks.size() > (long unsigned int)PMONITORFORTICKS->refreshRate)
|
if (m_dLastAnimationTicks.size() > (long unsigned int)PMONITORFORTICKS->refreshRate)
|
||||||
m_dLastAnimationTicks.pop_front();
|
m_dLastAnimationTicks.pop_front();
|
||||||
@@ -75,7 +57,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
|||||||
float avgFrametime = 0;
|
float avgFrametime = 0;
|
||||||
float maxFrametime = 0;
|
float maxFrametime = 0;
|
||||||
float minFrametime = 9999;
|
float minFrametime = 9999;
|
||||||
for (auto const& ft : m_dLastFrametimes) {
|
for (auto& ft : m_dLastFrametimes) {
|
||||||
if (ft > maxFrametime)
|
if (ft > maxFrametime)
|
||||||
maxFrametime = ft;
|
maxFrametime = ft;
|
||||||
if (ft < minFrametime)
|
if (ft < minFrametime)
|
||||||
@@ -88,7 +70,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
|||||||
float avgRenderTime = 0;
|
float avgRenderTime = 0;
|
||||||
float maxRenderTime = 0;
|
float maxRenderTime = 0;
|
||||||
float minRenderTime = 9999;
|
float minRenderTime = 9999;
|
||||||
for (auto const& rt : m_dLastRenderTimes) {
|
for (auto& rt : m_dLastRenderTimes) {
|
||||||
if (rt > maxRenderTime)
|
if (rt > maxRenderTime)
|
||||||
maxRenderTime = rt;
|
maxRenderTime = rt;
|
||||||
if (rt < minRenderTime)
|
if (rt < minRenderTime)
|
||||||
@@ -101,7 +83,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
|||||||
float avgRenderTimeNoOverlay = 0;
|
float avgRenderTimeNoOverlay = 0;
|
||||||
float maxRenderTimeNoOverlay = 0;
|
float maxRenderTimeNoOverlay = 0;
|
||||||
float minRenderTimeNoOverlay = 9999;
|
float minRenderTimeNoOverlay = 9999;
|
||||||
for (auto const& rt : m_dLastRenderTimesNoOverlay) {
|
for (auto& rt : m_dLastRenderTimesNoOverlay) {
|
||||||
if (rt > maxRenderTimeNoOverlay)
|
if (rt > maxRenderTimeNoOverlay)
|
||||||
maxRenderTimeNoOverlay = rt;
|
maxRenderTimeNoOverlay = rt;
|
||||||
if (rt < minRenderTimeNoOverlay)
|
if (rt < minRenderTimeNoOverlay)
|
||||||
@@ -114,7 +96,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
|||||||
float avgAnimMgrTick = 0;
|
float avgAnimMgrTick = 0;
|
||||||
float maxAnimMgrTick = 0;
|
float maxAnimMgrTick = 0;
|
||||||
float minAnimMgrTick = 9999;
|
float minAnimMgrTick = 9999;
|
||||||
for (auto const& at : m_dLastAnimationTicks) {
|
for (auto& at : m_dLastAnimationTicks) {
|
||||||
if (at > maxAnimMgrTick)
|
if (at > maxAnimMgrTick)
|
||||||
maxAnimMgrTick = at;
|
maxAnimMgrTick = at;
|
||||||
if (at < minAnimMgrTick)
|
if (at < minAnimMgrTick)
|
||||||
@@ -198,44 +180,29 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
|||||||
double posX = 0, posY = 0;
|
double posX = 0, posY = 0;
|
||||||
cairo_get_current_point(cr, &posX, &posY);
|
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,
|
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};
|
(int)maxTextW + 2, posY - offset - MARGIN_TOP + 2};
|
||||||
g_pHyprRenderer->damageBox(m_wbLastDrawnBox);
|
g_pHyprRenderer->damageBox(&m_wbLastDrawnBox);
|
||||||
|
|
||||||
return posY - offset;
|
return posY - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDebugOverlay::renderData(PHLMONITOR pMonitor, float durationUs) {
|
void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) {
|
||||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
|
||||||
|
|
||||||
if (!*PDEBUGOVERLAY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_mMonitorOverlays[pMonitor].renderData(pMonitor, durationUs);
|
m_mMonitorOverlays[pMonitor].renderData(pMonitor, durationUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDebugOverlay::renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs) {
|
void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) {
|
||||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
|
||||||
|
|
||||||
if (!*PDEBUGOVERLAY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, durationUs);
|
m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, durationUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDebugOverlay::frameData(PHLMONITOR pMonitor) {
|
void CHyprDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
|
||||||
|
|
||||||
if (!*PDEBUGOVERLAY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_mMonitorOverlays[pMonitor].frameData(pMonitor);
|
m_mMonitorOverlays[pMonitor].frameData(pMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDebugOverlay::draw() {
|
void CHyprDebugOverlay::draw() {
|
||||||
|
|
||||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front();
|
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
||||||
|
|
||||||
if (!m_pCairoSurface || !m_pCairo) {
|
if (!m_pCairoSurface || !m_pCairo) {
|
||||||
m_pCairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
m_pCairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||||
@@ -250,8 +217,8 @@ void CHyprDebugOverlay::draw() {
|
|||||||
|
|
||||||
// draw the things
|
// draw the things
|
||||||
int offsetY = 0;
|
int offsetY = 0;
|
||||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
offsetY += m_mMonitorOverlays[m].draw(offsetY);
|
offsetY += m_mMonitorOverlays[m.get()].draw(offsetY);
|
||||||
offsetY += 5; // for padding between mons
|
offsetY += 5; // for padding between mons
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,8 +238,6 @@ void CHyprDebugOverlay::draw() {
|
|||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||||
|
|
||||||
CTexPassElement::SRenderData data;
|
CBox pMonBox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
||||||
data.tex = m_pTexture;
|
g_pHyprOpenGL->renderTexture(m_pTexture, &pMonBox, 1.f);
|
||||||
data.box = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
|
||||||
g_pHyprRenderer->m_sRenderPass.add(makeShared<CTexPassElement>(data));
|
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
|
#include "../helpers/Monitor.hpp"
|
||||||
#include "../render/Texture.hpp"
|
#include "../render/Texture.hpp"
|
||||||
#include <cairo/cairo.h>
|
|
||||||
#include <map>
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <cairo/cairo.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
class CHyprRenderer;
|
class CHyprRenderer;
|
||||||
|
|
||||||
@@ -12,9 +13,9 @@ class CHyprMonitorDebugOverlay {
|
|||||||
public:
|
public:
|
||||||
int draw(int offset);
|
int draw(int offset);
|
||||||
|
|
||||||
void renderData(PHLMONITOR pMonitor, float durationUs);
|
void renderData(CMonitor* pMonitor, float durationUs);
|
||||||
void renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs);
|
void renderDataNoOverlay(CMonitor* pMonitor, float durationUs);
|
||||||
void frameData(PHLMONITOR pMonitor);
|
void frameData(CMonitor* pMonitor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::deque<float> m_dLastFrametimes;
|
std::deque<float> m_dLastFrametimes;
|
||||||
@@ -22,7 +23,7 @@ class CHyprMonitorDebugOverlay {
|
|||||||
std::deque<float> m_dLastRenderTimesNoOverlay;
|
std::deque<float> m_dLastRenderTimesNoOverlay;
|
||||||
std::deque<float> m_dLastAnimationTicks;
|
std::deque<float> m_dLastAnimationTicks;
|
||||||
std::chrono::high_resolution_clock::time_point m_tpLastFrame;
|
std::chrono::high_resolution_clock::time_point m_tpLastFrame;
|
||||||
PHLMONITORREF m_pMonitor;
|
CMonitor* m_pMonitor = nullptr;
|
||||||
CBox m_wbLastDrawnBox;
|
CBox m_wbLastDrawnBox;
|
||||||
|
|
||||||
friend class CHyprRenderer;
|
friend class CHyprRenderer;
|
||||||
@@ -32,20 +33,20 @@ class CHyprDebugOverlay {
|
|||||||
public:
|
public:
|
||||||
CHyprDebugOverlay();
|
CHyprDebugOverlay();
|
||||||
void draw();
|
void draw();
|
||||||
void renderData(PHLMONITOR, float durationUs);
|
void renderData(CMonitor*, float durationUs);
|
||||||
void renderDataNoOverlay(PHLMONITOR, float durationUs);
|
void renderDataNoOverlay(CMonitor*, float durationUs);
|
||||||
void frameData(PHLMONITOR);
|
void frameData(CMonitor*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<PHLMONITORREF, CHyprMonitorDebugOverlay> m_mMonitorOverlays;
|
std::unordered_map<CMonitor*, CHyprMonitorDebugOverlay> m_mMonitorOverlays;
|
||||||
|
|
||||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||||
cairo_t* m_pCairo = nullptr;
|
cairo_t* m_pCairo = nullptr;
|
||||||
|
|
||||||
SP<CTexture> m_pTexture;
|
SP<CTexture> m_pTexture;
|
||||||
|
|
||||||
friend class CHyprMonitorDebugOverlay;
|
friend class CHyprMonitorDebugOverlay;
|
||||||
friend class CHyprRenderer;
|
friend class CHyprRenderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline UP<CHyprDebugOverlay> g_pDebugOverlay;
|
inline std::unique_ptr<CHyprDebugOverlay> g_pDebugOverlay;
|
@@ -3,13 +3,8 @@
|
|||||||
#include "HyprNotificationOverlay.hpp"
|
#include "HyprNotificationOverlay.hpp"
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../config/ConfigValue.hpp"
|
#include "../config/ConfigValue.hpp"
|
||||||
#include "../render/pass/TexPassElement.hpp"
|
|
||||||
|
|
||||||
#include "../managers/AnimationManager.hpp"
|
inline auto iconBackendFromLayout(PangoLayout* layout) {
|
||||||
#include "../managers/HookSystemManager.hpp"
|
|
||||||
#include "../render/Renderer.hpp"
|
|
||||||
|
|
||||||
static inline auto iconBackendFromLayout(PangoLayout* layout) {
|
|
||||||
// preference: Nerd > FontAwesome > text
|
// preference: Nerd > FontAwesome > text
|
||||||
auto eIconBackendChecks = std::array<eIconBackend, 2>{ICONS_BACKEND_NF, ICONS_BACKEND_FA};
|
auto eIconBackendChecks = std::array<eIconBackend, 2>{ICONS_BACKEND_NF, ICONS_BACKEND_FA};
|
||||||
for (auto iconID : eIconBackendChecks) {
|
for (auto iconID : eIconBackendChecks) {
|
||||||
@@ -23,10 +18,10 @@ static inline auto iconBackendFromLayout(PangoLayout* layout) {
|
|||||||
|
|
||||||
CHyprNotificationOverlay::CHyprNotificationOverlay() {
|
CHyprNotificationOverlay::CHyprNotificationOverlay() {
|
||||||
static auto P = g_pHookSystem->hookDynamic("focusedMon", [&](void* self, SCallbackInfo& info, std::any param) {
|
static auto P = g_pHookSystem->hookDynamic("focusedMon", [&](void* self, SCallbackInfo& info, std::any param) {
|
||||||
if (m_vNotifications.size() == 0)
|
if (m_dNotifications.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_pHyprRenderer->damageBox(m_bLastDamage);
|
g_pHyprRenderer->damageBox(&m_bLastDamage);
|
||||||
});
|
});
|
||||||
|
|
||||||
m_pTexture = makeShared<CTexture>();
|
m_pTexture = makeShared<CTexture>();
|
||||||
@@ -39,34 +34,34 @@ CHyprNotificationOverlay::~CHyprNotificationOverlay() {
|
|||||||
cairo_surface_destroy(m_pCairoSurface);
|
cairo_surface_destroy(m_pCairoSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprNotificationOverlay::addNotification(const std::string& text, const CHyprColor& color, const float timeMs, const eIcons icon, const float fontSize) {
|
void CHyprNotificationOverlay::addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon, const float fontSize) {
|
||||||
const auto PNOTIF = m_vNotifications.emplace_back(makeUnique<SNotification>()).get();
|
const auto PNOTIF = m_dNotifications.emplace_back(std::make_unique<SNotification>()).get();
|
||||||
|
|
||||||
PNOTIF->text = icon != eIcons::ICON_NONE ? " " + text /* tiny bit of padding otherwise icon touches text */ : text;
|
PNOTIF->text = text;
|
||||||
PNOTIF->color = color == CHyprColor(0) ? ICONS_COLORS[icon] : color;
|
PNOTIF->color = color == CColor(0) ? ICONS_COLORS[icon] : color;
|
||||||
PNOTIF->started.reset();
|
PNOTIF->started.reset();
|
||||||
PNOTIF->timeMs = timeMs;
|
PNOTIF->timeMs = timeMs;
|
||||||
PNOTIF->icon = icon;
|
PNOTIF->icon = icon;
|
||||||
PNOTIF->fontSize = fontSize;
|
PNOTIF->fontSize = fontSize;
|
||||||
|
|
||||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
g_pCompositor->scheduleFrameForMonitor(m);
|
g_pCompositor->scheduleFrameForMonitor(m.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprNotificationOverlay::dismissNotifications(const int amount) {
|
void CHyprNotificationOverlay::dismissNotifications(const int amount) {
|
||||||
if (amount == -1)
|
if (amount == -1)
|
||||||
m_vNotifications.clear();
|
m_dNotifications.clear();
|
||||||
else {
|
else {
|
||||||
const int AMT = std::min(amount, static_cast<int>(m_vNotifications.size()));
|
const int AMT = std::min(amount, static_cast<int>(m_dNotifications.size()));
|
||||||
|
|
||||||
for (int i = 0; i < AMT; ++i) {
|
for (int i = 0; i < AMT; ++i) {
|
||||||
m_vNotifications.erase(m_vNotifications.begin());
|
m_dNotifications.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CBox CHyprNotificationOverlay::drawNotifications(PHLMONITOR pMonitor) {
|
CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
|
||||||
static constexpr auto ANIM_DURATION_MS = 600.0;
|
static constexpr auto ANIM_DURATION_MS = 600.0;
|
||||||
static constexpr auto ANIM_LAG_MS = 100.0;
|
static constexpr auto ANIM_LAG_MS = 100.0;
|
||||||
static constexpr auto NOTIF_LEFTBAR_SIZE = 5.0;
|
static constexpr auto NOTIF_LEFTBAR_SIZE = 5.0;
|
||||||
@@ -92,7 +87,7 @@ CBox CHyprNotificationOverlay::drawNotifications(PHLMONITOR pMonitor) {
|
|||||||
const auto iconBackendID = iconBackendFromLayout(layout);
|
const auto iconBackendID = iconBackendFromLayout(layout);
|
||||||
const auto PBEZIER = g_pAnimationManager->getBezier("default");
|
const auto PBEZIER = g_pAnimationManager->getBezier("default");
|
||||||
|
|
||||||
for (auto const& notif : m_vNotifications) {
|
for (auto& notif : m_dNotifications) {
|
||||||
const auto ICONPADFORNOTIF = notif->icon == ICON_NONE ? 0 : ICON_PAD;
|
const auto ICONPADFORNOTIF = notif->icon == ICON_NONE ? 0 : ICON_PAD;
|
||||||
const auto FONTSIZE = std::clamp((int)(notif->fontSize * ((pMonitor->vecPixelSize.x * SCALE) / 1920.f)), 8, 40);
|
const auto FONTSIZE = std::clamp((int)(notif->fontSize * ((pMonitor->vecPixelSize.x * SCALE) / 1920.f)), 8, 40);
|
||||||
|
|
||||||
@@ -187,12 +182,12 @@ CBox CHyprNotificationOverlay::drawNotifications(PHLMONITOR pMonitor) {
|
|||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
|
|
||||||
// cleanup notifs
|
// cleanup notifs
|
||||||
std::erase_if(m_vNotifications, [](const auto& notif) { return notif->started.getMillis() > notif->timeMs; });
|
std::erase_if(m_dNotifications, [](const auto& notif) { return notif->started.getMillis() > notif->timeMs; });
|
||||||
|
|
||||||
return CBox{(int)(pMonitor->vecPosition.x + pMonitor->vecSize.x - maxWidth - 20), (int)pMonitor->vecPosition.y, (int)maxWidth + 20, (int)offsetY + 10};
|
return CBox{(int)(pMonitor->vecPosition.x + pMonitor->vecSize.x - maxWidth - 20), (int)pMonitor->vecPosition.y, (int)maxWidth + 20, (int)offsetY + 10};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) {
|
void CHyprNotificationOverlay::draw(CMonitor* pMonitor) {
|
||||||
|
|
||||||
const auto MONSIZE = pMonitor->vecTransformedSize;
|
const auto MONSIZE = pMonitor->vecTransformedSize;
|
||||||
|
|
||||||
@@ -210,7 +205,7 @@ void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw the notifications
|
// Draw the notifications
|
||||||
if (m_vNotifications.size() == 0)
|
if (m_dNotifications.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Render to the monitor
|
// Render to the monitor
|
||||||
@@ -225,8 +220,8 @@ void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) {
|
|||||||
|
|
||||||
CBox damage = drawNotifications(pMonitor);
|
CBox damage = drawNotifications(pMonitor);
|
||||||
|
|
||||||
g_pHyprRenderer->damageBox(damage);
|
g_pHyprRenderer->damageBox(&damage);
|
||||||
g_pHyprRenderer->damageBox(m_bLastDamage);
|
g_pHyprRenderer->damageBox(&m_bLastDamage);
|
||||||
|
|
||||||
g_pCompositor->scheduleFrameForMonitor(pMonitor);
|
g_pCompositor->scheduleFrameForMonitor(pMonitor);
|
||||||
|
|
||||||
@@ -246,14 +241,10 @@ void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) {
|
|||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MONSIZE.x, MONSIZE.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MONSIZE.x, MONSIZE.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||||
|
|
||||||
CTexPassElement::SRenderData data;
|
CBox pMonBox = {0, 0, MONSIZE.x, MONSIZE.y};
|
||||||
data.tex = m_pTexture;
|
g_pHyprOpenGL->renderTexture(m_pTexture, &pMonBox, 1.f);
|
||||||
data.box = {0, 0, MONSIZE.x, MONSIZE.y};
|
|
||||||
data.a = 1.F;
|
|
||||||
|
|
||||||
g_pHyprRenderer->m_sRenderPass.add(makeShared<CTexPassElement>(data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CHyprNotificationOverlay::hasAny() {
|
bool CHyprNotificationOverlay::hasAny() {
|
||||||
return !m_vNotifications.empty();
|
return !m_dNotifications.empty();
|
||||||
}
|
}
|
||||||
|
@@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
#include "../helpers/Timer.hpp"
|
#include "../helpers/Timer.hpp"
|
||||||
|
#include "../helpers/Monitor.hpp"
|
||||||
#include "../render/Texture.hpp"
|
#include "../render/Texture.hpp"
|
||||||
#include "../SharedDefs.hpp"
|
#include "../SharedDefs.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <deque>
|
||||||
|
|
||||||
#include <cairo/cairo.h>
|
#include <cairo/cairo.h>
|
||||||
|
|
||||||
enum eIconBackend : uint8_t {
|
enum eIconBackend {
|
||||||
ICONS_BACKEND_NONE = 0,
|
ICONS_BACKEND_NONE = 0,
|
||||||
ICONS_BACKEND_NF,
|
ICONS_BACKEND_NF,
|
||||||
ICONS_BACKEND_FA
|
ICONS_BACKEND_FA
|
||||||
@@ -18,17 +19,17 @@ enum eIconBackend : uint8_t {
|
|||||||
static const std::array<std::array<std::string, ICON_NONE + 1>, 3 /* backends */> ICONS_ARRAY = {
|
static const std::array<std::array<std::string, ICON_NONE + 1>, 3 /* backends */> ICONS_ARRAY = {
|
||||||
std::array<std::string, ICON_NONE + 1>{"[!]", "[i]", "[Hint]", "[Err]", "[?]", "[ok]", ""},
|
std::array<std::string, ICON_NONE + 1>{"[!]", "[i]", "[Hint]", "[Err]", "[?]", "[ok]", ""},
|
||||||
std::array<std::string, ICON_NONE + 1>{"", "", "", "", "", "", ""}, std::array<std::string, ICON_NONE + 1>{"", "", "", "", "", ""}};
|
std::array<std::string, ICON_NONE + 1>{"", "", "", "", "", "", ""}, std::array<std::string, ICON_NONE + 1>{"", "", "", "", "", ""}};
|
||||||
static const std::array<CHyprColor, ICON_NONE + 1> ICONS_COLORS = {CHyprColor{255.0 / 255.0, 204 / 255.0, 102 / 255.0, 1.0},
|
static const std::array<CColor, ICON_NONE + 1> ICONS_COLORS = {CColor{255.0 / 255.0, 204 / 255.0, 102 / 255.0, 1.0},
|
||||||
CHyprColor{128 / 255.0, 255 / 255.0, 255 / 255.0, 1.0},
|
CColor{128 / 255.0, 255 / 255.0, 255 / 255.0, 1.0},
|
||||||
CHyprColor{179 / 255.0, 255 / 255.0, 204 / 255.0, 1.0},
|
CColor{179 / 255.0, 255 / 255.0, 204 / 255.0, 1.0},
|
||||||
CHyprColor{255 / 255.0, 77 / 255.0, 77 / 255.0, 1.0},
|
CColor{255 / 255.0, 77 / 255.0, 77 / 255.0, 1.0},
|
||||||
CHyprColor{255 / 255.0, 204 / 255.0, 153 / 255.0, 1.0},
|
CColor{255 / 255.0, 204 / 255.0, 153 / 255.0, 1.0},
|
||||||
CHyprColor{128 / 255.0, 255 / 255.0, 128 / 255.0, 1.0},
|
CColor{128 / 255.0, 255 / 255.0, 128 / 255.0, 1.0},
|
||||||
CHyprColor{0, 0, 0, 1.0}};
|
CColor{0, 0, 0, 1.0}};
|
||||||
|
|
||||||
struct SNotification {
|
struct SNotification {
|
||||||
std::string text = "";
|
std::string text = "";
|
||||||
CHyprColor color;
|
CColor color;
|
||||||
CTimer started;
|
CTimer started;
|
||||||
float timeMs = 0;
|
float timeMs = 0;
|
||||||
eIcons icon = ICON_NONE;
|
eIcons icon = ICON_NONE;
|
||||||
@@ -40,24 +41,24 @@ class CHyprNotificationOverlay {
|
|||||||
CHyprNotificationOverlay();
|
CHyprNotificationOverlay();
|
||||||
~CHyprNotificationOverlay();
|
~CHyprNotificationOverlay();
|
||||||
|
|
||||||
void draw(PHLMONITOR pMonitor);
|
void draw(CMonitor* pMonitor);
|
||||||
void addNotification(const std::string& text, const CHyprColor& color, const float timeMs, const eIcons icon = ICON_NONE, const float fontSize = 13.f);
|
void addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon = ICON_NONE, const float fontSize = 13.f);
|
||||||
void dismissNotifications(const int amount);
|
void dismissNotifications(const int amount);
|
||||||
bool hasAny();
|
bool hasAny();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CBox drawNotifications(PHLMONITOR pMonitor);
|
CBox drawNotifications(CMonitor* pMonitor);
|
||||||
CBox m_bLastDamage;
|
CBox m_bLastDamage;
|
||||||
|
|
||||||
std::vector<UP<SNotification>> m_vNotifications;
|
std::deque<std::unique_ptr<SNotification>> m_dNotifications;
|
||||||
|
|
||||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||||
cairo_t* m_pCairo = nullptr;
|
cairo_t* m_pCairo = nullptr;
|
||||||
|
|
||||||
PHLMONITORREF m_pLastMonitor;
|
CMonitor* m_pLastMonitor = nullptr;
|
||||||
Vector2D m_vecLastSize = Vector2D(-1, -1);
|
Vector2D m_vecLastSize = Vector2D(-1, -1);
|
||||||
|
|
||||||
SP<CTexture> m_pTexture;
|
SP<CTexture> m_pTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline UP<CHyprNotificationOverlay> g_pHyprNotificationOverlay;
|
inline std::unique_ptr<CHyprNotificationOverlay> g_pHyprNotificationOverlay;
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
|
#include "../Compositor.hpp"
|
||||||
#include "RollingLogFollow.hpp"
|
#include "RollingLogFollow.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <print>
|
#include <iostream>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
void Debug::init(const std::string& IS) {
|
void Debug::init(const std::string& IS) {
|
||||||
@@ -17,7 +18,7 @@ void Debug::close() {
|
|||||||
logOfs.close();
|
logOfs.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debug::log(eLogLevel level, std::string str) {
|
void Debug::log(LogLevel level, std::string str) {
|
||||||
if (level == TRACE && !trace)
|
if (level == TRACE && !trace)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -25,7 +26,6 @@ void Debug::log(eLogLevel level, std::string str) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
std::string coloredStr = str;
|
std::string coloredStr = str;
|
||||||
//NOLINTBEGIN
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case LOG:
|
case LOG:
|
||||||
str = "[LOG] " + str;
|
str = "[LOG] " + str;
|
||||||
@@ -53,14 +53,13 @@ void Debug::log(eLogLevel level, std::string str) {
|
|||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
//NOLINTEND
|
|
||||||
|
|
||||||
rollingLog += str + "\n";
|
rollingLog += str + "\n";
|
||||||
if (rollingLog.size() > ROLLING_LOG_SIZE)
|
if (rollingLog.size() > ROLLING_LOG_SIZE)
|
||||||
rollingLog = rollingLog.substr(rollingLog.size() - ROLLING_LOG_SIZE);
|
rollingLog = rollingLog.substr(rollingLog.size() - ROLLING_LOG_SIZE);
|
||||||
|
|
||||||
if (SRollingLogFollow::get().isRunning())
|
if (RollingLogFollow::Get().IsRunning())
|
||||||
SRollingLogFollow::get().addLog(str);
|
RollingLogFollow::Get().AddLog(str);
|
||||||
|
|
||||||
if (!disableLogs || !**disableLogs) {
|
if (!disableLogs || !**disableLogs) {
|
||||||
// log to a file
|
// log to a file
|
||||||
@@ -70,5 +69,5 @@ void Debug::log(eLogLevel level, std::string str) {
|
|||||||
|
|
||||||
// log it to the stdout too.
|
// log it to the stdout too.
|
||||||
if (!disableStdout)
|
if (!disableStdout)
|
||||||
std::println("{}", ((coloredLogs && !**coloredLogs) ? str : coloredStr));
|
std::cout << ((coloredLogs && !**coloredLogs) ? str : coloredStr) << "\n";
|
||||||
}
|
}
|
||||||
|
@@ -5,11 +5,13 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include "../includes.hpp"
|
||||||
|
#include "../helpers/MiscFunctions.hpp"
|
||||||
|
|
||||||
#define LOGMESSAGESIZE 1024
|
#define LOGMESSAGESIZE 1024
|
||||||
#define ROLLING_LOG_SIZE 4096
|
#define ROLLING_LOG_SIZE 4096
|
||||||
|
|
||||||
enum eLogLevel : int8_t {
|
enum LogLevel {
|
||||||
NONE = -1,
|
NONE = -1,
|
||||||
LOG = 0,
|
LOG = 0,
|
||||||
WARN,
|
WARN,
|
||||||
@@ -19,7 +21,6 @@ enum eLogLevel : int8_t {
|
|||||||
TRACE
|
TRACE
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
|
||||||
namespace Debug {
|
namespace Debug {
|
||||||
inline std::string logFile;
|
inline std::string logFile;
|
||||||
inline std::ofstream logOfs;
|
inline std::ofstream logOfs;
|
||||||
@@ -37,11 +38,10 @@ namespace Debug {
|
|||||||
void close();
|
void close();
|
||||||
|
|
||||||
//
|
//
|
||||||
void log(eLogLevel level, std::string str);
|
void log(LogLevel level, std::string str);
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
//NOLINTNEXTLINE
|
void log(LogLevel level, std::format_string<Args...> fmt, Args&&... args) {
|
||||||
void log(eLogLevel level, std::format_string<Args...> fmt, Args&&... args) {
|
|
||||||
std::lock_guard<std::mutex> guard(logMutex);
|
std::lock_guard<std::mutex> guard(logMutex);
|
||||||
|
|
||||||
if (level == TRACE && !trace)
|
if (level == TRACE && !trace)
|
||||||
@@ -55,9 +55,8 @@ namespace Debug {
|
|||||||
// print date and time to the ofs
|
// print date and time to the ofs
|
||||||
if (disableTime && !**disableTime) {
|
if (disableTime && !**disableTime) {
|
||||||
#ifndef _LIBCPP_VERSION
|
#ifndef _LIBCPP_VERSION
|
||||||
static auto current_zone = std::chrono::current_zone();
|
const auto zt = std::chrono::zoned_time{std::chrono::current_zone(), std::chrono::system_clock::now()};
|
||||||
const auto zt = std::chrono::zoned_time{current_zone, std::chrono::system_clock::now()};
|
const auto hms = std::chrono::hh_mm_ss{zt.get_local_time() - std::chrono::floor<std::chrono::days>(zt.get_local_time())};
|
||||||
const auto hms = std::chrono::hh_mm_ss{zt.get_local_time() - std::chrono::floor<std::chrono::days>(zt.get_local_time())};
|
|
||||||
#else
|
#else
|
||||||
// TODO: current clang 17 does not support `zoned_time`, remove this once clang 19 is ready
|
// TODO: current clang 17 does not support `zoned_time`, remove this once clang 19 is ready
|
||||||
const auto hms = std::chrono::hh_mm_ss{std::chrono::system_clock::now() - std::chrono::floor<std::chrono::days>(std::chrono::system_clock::now())};
|
const auto hms = std::chrono::hh_mm_ss{std::chrono::system_clock::now() - std::chrono::floor<std::chrono::days>(std::chrono::system_clock::now())};
|
||||||
|
@@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
|
||||||
namespace Debug {
|
namespace Debug {
|
||||||
struct SRollingLogFollow {
|
struct RollingLogFollow {
|
||||||
std::unordered_map<int, std::string> socketToRollingLogFollowQueue;
|
std::unordered_map<int, std::string> socketToRollingLogFollowQueue;
|
||||||
std::shared_mutex m;
|
std::shared_mutex m;
|
||||||
bool running = false;
|
bool running = false;
|
||||||
@@ -16,12 +15,12 @@ namespace Debug {
|
|||||||
return socketToRollingLogFollowQueue[socket].empty();
|
return socketToRollingLogFollowQueue[socket].empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string debugInfo() {
|
std::string DebugInfo() {
|
||||||
std::shared_lock<std::shared_mutex> r(m);
|
std::shared_lock<std::shared_mutex> r(m);
|
||||||
return std::format("RollingLogFollow, got {} connections", socketToRollingLogFollowQueue.size());
|
return std::format("RollingLogFollow, got {} connections", socketToRollingLogFollowQueue.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getLog(int socket) {
|
std::string GetLog(int socket) {
|
||||||
std::unique_lock<std::shared_mutex> w(m);
|
std::unique_lock<std::shared_mutex> w(m);
|
||||||
|
|
||||||
const std::string ret = socketToRollingLogFollowQueue[socket];
|
const std::string ret = socketToRollingLogFollowQueue[socket];
|
||||||
@@ -30,7 +29,7 @@ namespace Debug {
|
|||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
void addLog(const std::string& log) {
|
void AddLog(std::string log) {
|
||||||
std::unique_lock<std::shared_mutex> w(m);
|
std::unique_lock<std::shared_mutex> w(m);
|
||||||
running = true;
|
running = true;
|
||||||
std::vector<int> to_erase;
|
std::vector<int> to_erase;
|
||||||
@@ -38,26 +37,26 @@ namespace Debug {
|
|||||||
socketToRollingLogFollowQueue[p.first] += log + "\n";
|
socketToRollingLogFollowQueue[p.first] += log + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRunning() {
|
bool IsRunning() {
|
||||||
std::shared_lock<std::shared_mutex> r(m);
|
std::shared_lock<std::shared_mutex> r(m);
|
||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopFor(int socket) {
|
void StopFor(int socket) {
|
||||||
std::unique_lock<std::shared_mutex> w(m);
|
std::unique_lock<std::shared_mutex> w(m);
|
||||||
socketToRollingLogFollowQueue.erase(socket);
|
socketToRollingLogFollowQueue.erase(socket);
|
||||||
if (socketToRollingLogFollowQueue.empty())
|
if (socketToRollingLogFollowQueue.empty())
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void startFor(int socket) {
|
void StartFor(int socket) {
|
||||||
std::unique_lock<std::shared_mutex> w(m);
|
std::unique_lock<std::shared_mutex> w(m);
|
||||||
socketToRollingLogFollowQueue[socket] = std::format("[LOG] Following log to socket: {} started\n", socket);
|
socketToRollingLogFollowQueue[socket] = std::format("[LOG] Following log to socket: {} started\n", socket);
|
||||||
running = true;
|
running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRollingLogFollow& get() {
|
static RollingLogFollow& Get() {
|
||||||
static SRollingLogFollow instance;
|
static RollingLogFollow instance;
|
||||||
static std::mutex gm;
|
static std::mutex gm;
|
||||||
std::lock_guard<std::mutex> lock(gm);
|
std::lock_guard<std::mutex> lock(gm);
|
||||||
return instance;
|
return instance;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "includes.hpp"
|
#include "includes.hpp"
|
||||||
#include "debug/Log.hpp"
|
#include "debug/Log.hpp"
|
||||||
|
#include "helpers/WLListener.hpp"
|
||||||
#include "helpers/Color.hpp"
|
#include "helpers/Color.hpp"
|
||||||
#include "macros.hpp"
|
#include "macros.hpp"
|
||||||
#include "desktop/DesktopTypes.hpp"
|
#include "desktop/DesktopTypes.hpp"
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../helpers/memory/Memory.hpp"
|
#include "../macros.hpp"
|
||||||
class CWorkspace;
|
class CWorkspace;
|
||||||
class CWindow;
|
class CWindow;
|
||||||
class CLayerSurface;
|
class CLayerSurface;
|
||||||
class CMonitor;
|
|
||||||
|
|
||||||
/* Shared pointer to a workspace */
|
/* Shared pointer to a workspace */
|
||||||
typedef SP<CWorkspace> PHLWORKSPACE;
|
typedef SP<CWorkspace> PHLWORKSPACE;
|
||||||
@@ -19,8 +18,3 @@ typedef WP<CWindow> PHLWINDOWREF;
|
|||||||
typedef SP<CLayerSurface> PHLLS;
|
typedef SP<CLayerSurface> PHLLS;
|
||||||
/* Weak pointer to a layer surface */
|
/* Weak pointer to a layer surface */
|
||||||
typedef WP<CLayerSurface> PHLLSREF;
|
typedef WP<CLayerSurface> PHLLSREF;
|
||||||
|
|
||||||
/* Shared pointer to a monitor */
|
|
||||||
typedef SP<CMonitor> PHLMONITOR;
|
|
||||||
/* Weak pointer to a monitor */
|
|
||||||
typedef WP<CMonitor> PHLMONITORREF;
|
|
||||||
|
@@ -1,38 +0,0 @@
|
|||||||
#include <re2/re2.h>
|
|
||||||
#include "LayerRule.hpp"
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <algorithm>
|
|
||||||
#include "../debug/Log.hpp"
|
|
||||||
|
|
||||||
static const auto RULES = std::unordered_set<std::string>{"noanim", "blur", "blurpopups", "dimaround"};
|
|
||||||
static const auto RULES_PREFIX = std::unordered_set<std::string>{"ignorealpha", "ignorezero", "xray", "animation", "order"};
|
|
||||||
|
|
||||||
CLayerRule::CLayerRule(const std::string& rule_, const std::string& ns_) : targetNamespace(ns_), rule(rule_) {
|
|
||||||
const bool VALID = RULES.contains(rule) || std::any_of(RULES_PREFIX.begin(), RULES_PREFIX.end(), [&rule_](const auto& prefix) { return rule_.starts_with(prefix); });
|
|
||||||
|
|
||||||
if (!VALID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (rule == "noanim")
|
|
||||||
ruleType = RULE_NOANIM;
|
|
||||||
else if (rule == "blur")
|
|
||||||
ruleType = RULE_BLUR;
|
|
||||||
else if (rule == "blurpopups")
|
|
||||||
ruleType = RULE_BLURPOPUPS;
|
|
||||||
else if (rule == "dimaround")
|
|
||||||
ruleType = RULE_DIMAROUND;
|
|
||||||
else if (rule.starts_with("ignorealpha"))
|
|
||||||
ruleType = RULE_IGNOREALPHA;
|
|
||||||
else if (rule.starts_with("ignorezero"))
|
|
||||||
ruleType = RULE_IGNOREZERO;
|
|
||||||
else if (rule.starts_with("xray"))
|
|
||||||
ruleType = RULE_XRAY;
|
|
||||||
else if (rule.starts_with("animation"))
|
|
||||||
ruleType = RULE_ANIMATION;
|
|
||||||
else if (rule.starts_with("order"))
|
|
||||||
ruleType = RULE_ORDER;
|
|
||||||
else {
|
|
||||||
Debug::log(ERR, "CLayerRule: didn't match a rule that was found valid?!");
|
|
||||||
ruleType = RULE_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,31 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <cstdint>
|
|
||||||
#include "Rule.hpp"
|
|
||||||
|
|
||||||
class CLayerRule {
|
|
||||||
public:
|
|
||||||
CLayerRule(const std::string& rule, const std::string& targetNS);
|
|
||||||
|
|
||||||
enum eRuleType : uint8_t {
|
|
||||||
RULE_INVALID = 0,
|
|
||||||
RULE_NOANIM,
|
|
||||||
RULE_BLUR,
|
|
||||||
RULE_BLURPOPUPS,
|
|
||||||
RULE_DIMAROUND,
|
|
||||||
RULE_IGNOREALPHA,
|
|
||||||
RULE_IGNOREZERO,
|
|
||||||
RULE_XRAY,
|
|
||||||
RULE_ANIMATION,
|
|
||||||
RULE_ORDER,
|
|
||||||
RULE_ZUMBA,
|
|
||||||
};
|
|
||||||
|
|
||||||
eRuleType ruleType = RULE_INVALID;
|
|
||||||
|
|
||||||
const std::string targetNamespace;
|
|
||||||
const std::string rule;
|
|
||||||
|
|
||||||
CRuleRegexContainer targetNamespaceRegex;
|
|
||||||
};
|
|
@@ -4,18 +4,11 @@
|
|||||||
#include "../protocols/LayerShell.hpp"
|
#include "../protocols/LayerShell.hpp"
|
||||||
#include "../protocols/core/Compositor.hpp"
|
#include "../protocols/core/Compositor.hpp"
|
||||||
#include "../managers/SeatManager.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 CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||||
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
|
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
|
||||||
|
|
||||||
auto pMonitor = resource->monitor.empty() ? g_pCompositor->m_pLastMonitor.lock() : g_pCompositor->getMonitorFromName(resource->monitor);
|
CMonitor* pMonitor = resource->monitor.empty() ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->getMonitorFromName(resource->monitor);
|
||||||
|
|
||||||
pLS->surface->assign(resource->surface.lock(), pLS);
|
pLS->surface->assign(resource->surface.lock(), pLS);
|
||||||
|
|
||||||
@@ -25,26 +18,29 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pMonitor->pMirrorOf)
|
if (pMonitor->pMirrorOf)
|
||||||
pMonitor = g_pCompositor->m_vMonitors.front();
|
pMonitor = g_pCompositor->m_vMonitors.front().get();
|
||||||
|
|
||||||
pLS->self = pLS;
|
pLS->self = pLS;
|
||||||
|
|
||||||
pLS->szNamespace = resource->layerNamespace;
|
pLS->szNamespace = resource->layerNamespace;
|
||||||
|
|
||||||
pLS->layer = resource->current.layer;
|
pLS->layer = resource->current.layer;
|
||||||
pLS->popupHead = CPopup::create(pLS);
|
pLS->popupHead = std::make_unique<CPopup>(pLS);
|
||||||
pLS->monitor = pMonitor;
|
pLS->monitorID = pMonitor->ID;
|
||||||
pMonitor->m_aLayerSurfaceLayers[resource->current.layer].emplace_back(pLS);
|
pMonitor->m_aLayerSurfaceLayers[resource->current.layer].emplace_back(pLS);
|
||||||
|
|
||||||
pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace);
|
pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace);
|
||||||
|
|
||||||
g_pAnimationManager->createAnimation(0.f, pLS->alpha, g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"), pLS, AVARDAMAGE_ENTIRE);
|
pLS->alpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pLS->realPosition, g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE);
|
pLS->realPosition.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pLS->realSize, 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->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);
|
Debug::log(LOG, "LayerSurface {:x} (namespace {} layer {}) created on monitor {}", (uintptr_t)resource.get(), resource->layerNamespace, (int)pLS->layer, pMonitor->szName);
|
||||||
|
|
||||||
@@ -52,9 +48,9 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CLayerSurface::registerCallbacks() {
|
void CLayerSurface::registerCallbacks() {
|
||||||
alpha->setUpdateCallback([this](auto) {
|
alpha.setUpdateCallback([this](void*) {
|
||||||
if (dimAround)
|
if (dimAround)
|
||||||
g_pHyprRenderer->damageMonitor(monitor.lock());
|
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(monitorID));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +72,7 @@ CLayerSurface::~CLayerSurface() {
|
|||||||
g_pHyprRenderer->makeEGLCurrent();
|
g_pHyprRenderer->makeEGLCurrent();
|
||||||
std::erase_if(g_pHyprOpenGL->m_mLayerFramebuffers, [&](const auto& other) { return other.first.expired() || other.first.lock() == self.lock(); });
|
std::erase_if(g_pHyprOpenGL->m_mLayerFramebuffers, [&](const auto& other) { return other.first.expired() || other.first.lock() == self.lock(); });
|
||||||
|
|
||||||
for (auto const& mon : g_pCompositor->m_vRealMonitors) {
|
for (auto& mon : g_pCompositor->m_vRealMonitors) {
|
||||||
for (auto& lsl : mon->m_aLayerSurfaceLayers) {
|
for (auto& lsl : mon->m_aLayerSurfaceLayers) {
|
||||||
std::erase_if(lsl, [this](auto& ls) { return ls.expired() || ls.get() == this; });
|
std::erase_if(lsl, [this](auto& ls) { return ls.expired() || ls.get() == this; });
|
||||||
}
|
}
|
||||||
@@ -86,9 +82,9 @@ CLayerSurface::~CLayerSurface() {
|
|||||||
void CLayerSurface::onDestroy() {
|
void CLayerSurface::onDestroy() {
|
||||||
Debug::log(LOG, "LayerSurface {:x} destroyed", (uintptr_t)layerSurface.get());
|
Debug::log(LOG, "LayerSurface {:x} destroyed", (uintptr_t)layerSurface.get());
|
||||||
|
|
||||||
const auto PMONITOR = monitor.lock();
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||||
|
|
||||||
if (!PMONITOR)
|
if (!g_pCompositor->getMonitorFromID(monitorID))
|
||||||
Debug::log(WARN, "Layersurface destroyed on an invalid monitor (removed?)");
|
Debug::log(WARN, "Layersurface destroyed on an invalid monitor (removed?)");
|
||||||
|
|
||||||
if (!fadingOut) {
|
if (!fadingOut) {
|
||||||
@@ -97,8 +93,7 @@ void CLayerSurface::onDestroy() {
|
|||||||
onUnmap();
|
onUnmap();
|
||||||
} else {
|
} else {
|
||||||
Debug::log(LOG, "Removing LayerSurface that wasn't mapped.");
|
Debug::log(LOG, "Removing LayerSurface that wasn't mapped.");
|
||||||
if (alpha)
|
alpha.setValueAndWarp(0.f);
|
||||||
alpha->setValueAndWarp(0.f);
|
|
||||||
fadingOut = true;
|
fadingOut = true;
|
||||||
g_pCompositor->addToFadingOutSafe(self.lock());
|
g_pCompositor->addToFadingOutSafe(self.lock());
|
||||||
}
|
}
|
||||||
@@ -115,7 +110,7 @@ void CLayerSurface::onDestroy() {
|
|||||||
|
|
||||||
// and damage
|
// and damage
|
||||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
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;
|
readyToDelete = true;
|
||||||
@@ -142,7 +137,7 @@ void CLayerSurface::onMap() {
|
|||||||
g_pCompositor->removeFromFadingOutSafe(self.lock());
|
g_pCompositor->removeFromFadingOutSafe(self.lock());
|
||||||
|
|
||||||
// fix if it changed its mon
|
// fix if it changed its mon
|
||||||
const auto PMONITOR = monitor.lock();
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||||
|
|
||||||
if (!PMONITOR)
|
if (!PMONITOR)
|
||||||
return;
|
return;
|
||||||
@@ -179,8 +174,9 @@ void CLayerSurface::onMap() {
|
|||||||
position = Vector2D(geometry.x, geometry.y);
|
position = Vector2D(geometry.x, geometry.y);
|
||||||
|
|
||||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
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;
|
const auto WORKSPACE = PMONITOR->activeWorkspace;
|
||||||
|
const bool FULLSCREEN = WORKSPACE->m_bHasFullscreenWindow && WORKSPACE->m_efFullscreenMode == FSMODE_FULLSCREEN;
|
||||||
|
|
||||||
startAnimation(!(layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS));
|
startAnimation(!(layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS));
|
||||||
readyToDelete = false;
|
readyToDelete = false;
|
||||||
@@ -201,7 +197,7 @@ void CLayerSurface::onUnmap() {
|
|||||||
|
|
||||||
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
|
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
|
||||||
|
|
||||||
if (!monitor || g_pCompositor->m_bUnsafeState) {
|
if (!g_pCompositor->getMonitorFromID(monitorID) || g_pCompositor->m_bUnsafeState) {
|
||||||
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
|
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
|
||||||
|
|
||||||
g_pCompositor->addToFadingOutSafe(self.lock());
|
g_pCompositor->addToFadingOutSafe(self.lock());
|
||||||
@@ -215,7 +211,7 @@ void CLayerSurface::onUnmap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make a snapshot and start fade
|
// make a snapshot and start fade
|
||||||
g_pHyprRenderer->makeLayerSnapshot(self.lock());
|
g_pHyprOpenGL->makeLayerSnapshot(self.lock());
|
||||||
|
|
||||||
startAnimation(false);
|
startAnimation(false);
|
||||||
|
|
||||||
@@ -225,9 +221,9 @@ void CLayerSurface::onUnmap() {
|
|||||||
|
|
||||||
g_pCompositor->addToFadingOutSafe(self.lock());
|
g_pCompositor->addToFadingOutSafe(self.lock());
|
||||||
|
|
||||||
const auto PMONITOR = monitor.lock();
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||||
|
|
||||||
const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == surface->resource() || g_pSeatManager->state.pointerFocus == surface->resource();
|
const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource();
|
||||||
|
|
||||||
if (!PMONITOR)
|
if (!PMONITOR)
|
||||||
return;
|
return;
|
||||||
@@ -236,17 +232,17 @@ void CLayerSurface::onUnmap() {
|
|||||||
// vvvvvvvvvvvvv if there is a last focus and the last focus is not keyboard focusable, fallback to window
|
// vvvvvvvvvvvvv if there is a last focus and the last focus is not keyboard focusable, fallback to window
|
||||||
if (WASLASTFOCUS || (g_pCompositor->m_pLastFocus && g_pCompositor->m_pLastFocus->hlSurface && !g_pCompositor->m_pLastFocus->hlSurface->keyboardFocusable()))
|
if (WASLASTFOCUS || (g_pCompositor->m_pLastFocus && g_pCompositor->m_pLastFocus->hlSurface && !g_pCompositor->m_pLastFocus->hlSurface->keyboardFocusable()))
|
||||||
g_pInputManager->refocusLastWindow(PMONITOR);
|
g_pInputManager->refocusLastWindow(PMONITOR);
|
||||||
else if (g_pCompositor->m_pLastFocus && g_pCompositor->m_pLastFocus != surface->resource())
|
else if (g_pCompositor->m_pLastFocus)
|
||||||
g_pSeatManager->setKeyboardFocus(g_pCompositor->m_pLastFocus.lock());
|
g_pSeatManager->setKeyboardFocus(g_pCompositor->m_pLastFocus.lock());
|
||||||
|
|
||||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
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,
|
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};
|
(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);
|
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||||
}
|
}
|
||||||
@@ -260,13 +256,13 @@ void CLayerSurface::onCommit() {
|
|||||||
if (layerSurface->surface && !layerSurface->surface->current.texture) {
|
if (layerSurface->surface && !layerSurface->surface->current.texture) {
|
||||||
fadingOut = false;
|
fadingOut = false;
|
||||||
geometry = {};
|
geometry = {};
|
||||||
g_pHyprRenderer->arrangeLayersForMonitor(monitorID());
|
g_pHyprRenderer->arrangeLayersForMonitor(monitorID);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto PMONITOR = monitor.lock();
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||||
|
|
||||||
if (!PMONITOR)
|
if (!PMONITOR)
|
||||||
return;
|
return;
|
||||||
@@ -275,7 +271,7 @@ void CLayerSurface::onCommit() {
|
|||||||
g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd
|
g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd
|
||||||
|
|
||||||
CBox geomFixed = {geometry.x, geometry.y, geometry.width, geometry.height};
|
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 != 0) {
|
||||||
if (layerSurface->current.committed & CLayerShellResource::eCommittedState::STATE_LAYER) {
|
if (layerSurface->current.committed & CLayerShellResource::eCommittedState::STATE_LAYER) {
|
||||||
@@ -312,31 +308,21 @@ void CLayerSurface::onCommit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (realPosition->goal() != geometry.pos()) {
|
if (realPosition.goal() != geometry.pos()) {
|
||||||
if (realPosition->isBeingAnimated())
|
if (realPosition.isBeingAnimated())
|
||||||
*realPosition = geometry.pos();
|
realPosition = geometry.pos();
|
||||||
else
|
else
|
||||||
realPosition->setValueAndWarp(geometry.pos());
|
realPosition.setValueAndWarp(geometry.pos());
|
||||||
}
|
}
|
||||||
if (realSize->goal() != geometry.size()) {
|
if (realSize.goal() != geometry.size()) {
|
||||||
if (realSize->isBeingAnimated())
|
if (realSize.isBeingAnimated())
|
||||||
*realSize = geometry.size();
|
realSize = geometry.size();
|
||||||
else
|
else
|
||||||
realSize->setValueAndWarp(geometry.size());
|
realSize.setValueAndWarp(geometry.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapped && (layerSurface->current.committed & CLayerShellResource::eCommittedState::STATE_INTERACTIVITY)) {
|
if (mapped) {
|
||||||
bool WASLASTFOCUS = false;
|
const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource();
|
||||||
layerSurface->surface->breadthfirst(
|
|
||||||
[&WASLASTFOCUS](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) { WASLASTFOCUS = WASLASTFOCUS || g_pSeatManager->state.keyboardFocus == surf; },
|
|
||||||
nullptr);
|
|
||||||
if (!WASLASTFOCUS && popupHead) {
|
|
||||||
popupHead->breadthfirst(
|
|
||||||
[&WASLASTFOCUS](WP<CPopup> popup, void* data) {
|
|
||||||
WASLASTFOCUS = WASLASTFOCUS || (popup->m_pWLSurface && g_pSeatManager->state.keyboardFocus == popup->m_pWLSurface->resource());
|
|
||||||
},
|
|
||||||
nullptr);
|
|
||||||
}
|
|
||||||
const bool WASEXCLUSIVE = interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
|
const bool WASEXCLUSIVE = interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
|
||||||
const bool ISEXCLUSIVE = layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
|
const bool ISEXCLUSIVE = layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
|
||||||
|
|
||||||
@@ -346,13 +332,11 @@ void CLayerSurface::onCommit() {
|
|||||||
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
|
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
|
||||||
|
|
||||||
// if the surface was focused and interactive but now isn't, refocus
|
// if the surface was focused and interactive but now isn't, refocus
|
||||||
if (WASLASTFOCUS && layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
|
if (WASLASTFOCUS && !layerSurface->current.interactivity) {
|
||||||
// moveMouseUnified won't focus non interactive layers but it won't unfocus them either,
|
// moveMouseUnified won't focus non interactive layers but it won't unfocus them either,
|
||||||
// so unfocus the surface here.
|
// so unfocus the surface here.
|
||||||
g_pCompositor->focusSurface(nullptr);
|
g_pCompositor->focusSurface(nullptr);
|
||||||
g_pInputManager->refocusLastWindow(monitor.lock());
|
g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID));
|
||||||
} else if (WASLASTFOCUS && WASEXCLUSIVE && layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
|
|
||||||
g_pInputManager->simulateMouseMovement();
|
|
||||||
} else if (!WASEXCLUSIVE && ISEXCLUSIVE) {
|
} else if (!WASEXCLUSIVE && ISEXCLUSIVE) {
|
||||||
// if now exclusive and not previously
|
// if now exclusive and not previously
|
||||||
g_pSeatManager->setGrab(nullptr);
|
g_pSeatManager->setGrab(nullptr);
|
||||||
@@ -382,74 +366,50 @@ void CLayerSurface::applyRules() {
|
|||||||
xray = -1;
|
xray = -1;
|
||||||
animationStyle.reset();
|
animationStyle.reset();
|
||||||
|
|
||||||
for (auto const& rule : g_pConfigManager->getMatchingRules(self.lock())) {
|
for (auto& rule : g_pConfigManager->getMatchingRules(self.lock())) {
|
||||||
switch (rule->ruleType) {
|
if (rule.rule == "noanim")
|
||||||
case CLayerRule::RULE_NOANIM: {
|
noAnimations = true;
|
||||||
noAnimations = true;
|
else if (rule.rule == "blur")
|
||||||
break;
|
forceBlur = true;
|
||||||
}
|
else if (rule.rule == "blurpopups")
|
||||||
case CLayerRule::RULE_BLUR: {
|
forceBlurPopups = true;
|
||||||
forceBlur = true;
|
else if (rule.rule.starts_with("ignorealpha") || rule.rule.starts_with("ignorezero")) {
|
||||||
break;
|
const auto FIRST_SPACE_POS = rule.rule.find_first_of(' ');
|
||||||
}
|
std::string alphaValue = "";
|
||||||
case CLayerRule::RULE_BLURPOPUPS: {
|
if (FIRST_SPACE_POS != std::string::npos)
|
||||||
forceBlurPopups = true;
|
alphaValue = rule.rule.substr(FIRST_SPACE_POS + 1);
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CLayerRule::RULE_IGNOREALPHA:
|
|
||||||
case CLayerRule::RULE_IGNOREZERO: {
|
|
||||||
const auto FIRST_SPACE_POS = rule->rule.find_first_of(' ');
|
|
||||||
std::string alphaValue = "";
|
|
||||||
if (FIRST_SPACE_POS != std::string::npos)
|
|
||||||
alphaValue = rule->rule.substr(FIRST_SPACE_POS + 1);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ignoreAlpha = true;
|
ignoreAlpha = true;
|
||||||
if (!alphaValue.empty())
|
if (!alphaValue.empty())
|
||||||
ignoreAlphaValue = std::stof(alphaValue);
|
ignoreAlphaValue = std::stof(alphaValue);
|
||||||
} catch (...) { Debug::log(ERR, "Invalid value passed to ignoreAlpha"); }
|
} catch (...) { Debug::log(ERR, "Invalid value passed to ignoreAlpha"); }
|
||||||
break;
|
} else if (rule.rule == "dimaround") {
|
||||||
}
|
dimAround = true;
|
||||||
case CLayerRule::RULE_DIMAROUND: {
|
} else if (rule.rule.starts_with("xray")) {
|
||||||
dimAround = true;
|
CVarList vars{rule.rule, 0, ' '};
|
||||||
break;
|
try {
|
||||||
}
|
xray = configStringToInt(vars[1]);
|
||||||
case CLayerRule::RULE_XRAY: {
|
} catch (...) {}
|
||||||
CVarList vars{rule->rule, 0, ' '};
|
} else if (rule.rule.starts_with("animation")) {
|
||||||
try {
|
CVarList vars{rule.rule, 2, 's'};
|
||||||
xray = configStringToInt(vars[1]).value_or(false);
|
animationStyle = vars[1];
|
||||||
} catch (...) {}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CLayerRule::RULE_ANIMATION: {
|
|
||||||
CVarList vars{rule->rule, 2, 's'};
|
|
||||||
animationStyle = vars[1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CLayerRule::RULE_ORDER: {
|
|
||||||
CVarList vars{rule->rule, 2, 's'};
|
|
||||||
try {
|
|
||||||
order = std::stoi(vars[1]);
|
|
||||||
} catch (...) { Debug::log(ERR, "Invalid value passed to order"); }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLayerSurface::startAnimation(bool in, bool instant) {
|
void CLayerSurface::startAnimation(bool in, bool instant) {
|
||||||
|
const auto ANIMSTYLE = animationStyle.value_or(realPosition.m_pConfig->pValues->internalStyle);
|
||||||
if (in) {
|
if (in) {
|
||||||
realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn"));
|
realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn");
|
||||||
realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn"));
|
realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn");
|
||||||
alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"));
|
alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn");
|
||||||
} else {
|
} else {
|
||||||
realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut"));
|
realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut");
|
||||||
realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut"));
|
realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut");
|
||||||
alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut"));
|
alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto ANIMSTYLE = animationStyle.value_or(realPosition->getStyle());
|
|
||||||
if (ANIMSTYLE.starts_with("slide")) {
|
if (ANIMSTYLE.starts_with("slide")) {
|
||||||
// get closest edge
|
// get closest edge
|
||||||
const auto MIDDLE = geometry.middle();
|
const auto MIDDLE = geometry.middle();
|
||||||
@@ -490,9 +450,9 @@ void CLayerSurface::startAnimation(bool in, bool instant) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
realSize->setValueAndWarp(geometry.size());
|
realSize.setValueAndWarp(geometry.size());
|
||||||
alpha->setValueAndWarp(in ? 0.f : 1.f);
|
alpha.setValueAndWarp(in ? 0.f : 1.f);
|
||||||
*alpha = in ? 1.f : 0.f;
|
alpha = in ? 1.f : 0.f;
|
||||||
|
|
||||||
Vector2D prePos;
|
Vector2D prePos;
|
||||||
|
|
||||||
@@ -517,11 +477,11 @@ void CLayerSurface::startAnimation(bool in, bool instant) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (in) {
|
if (in) {
|
||||||
realPosition->setValueAndWarp(prePos);
|
realPosition.setValueAndWarp(prePos);
|
||||||
*realPosition = geometry.pos();
|
realPosition = geometry.pos();
|
||||||
} else {
|
} else {
|
||||||
realPosition->setValueAndWarp(geometry.pos());
|
realPosition.setValueAndWarp(geometry.pos());
|
||||||
*realPosition = prePos;
|
realPosition = prePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (ANIMSTYLE.starts_with("popin")) {
|
} else if (ANIMSTYLE.starts_with("popin")) {
|
||||||
@@ -540,25 +500,25 @@ void CLayerSurface::startAnimation(bool in, bool instant) {
|
|||||||
const auto GOALSIZE = (geometry.size() * minPerc).clamp({5, 5});
|
const auto GOALSIZE = (geometry.size() * minPerc).clamp({5, 5});
|
||||||
const auto GOALPOS = geometry.pos() + (geometry.size() - GOALSIZE) / 2.f;
|
const auto GOALPOS = geometry.pos() + (geometry.size() - GOALSIZE) / 2.f;
|
||||||
|
|
||||||
alpha->setValueAndWarp(in ? 0.f : 1.f);
|
alpha.setValueAndWarp(in ? 0.f : 1.f);
|
||||||
*alpha = in ? 1.f : 0.f;
|
alpha = in ? 1.f : 0.f;
|
||||||
|
|
||||||
if (in) {
|
if (in) {
|
||||||
realSize->setValueAndWarp(GOALSIZE);
|
realSize.setValueAndWarp(GOALSIZE);
|
||||||
realPosition->setValueAndWarp(GOALPOS);
|
realPosition.setValueAndWarp(GOALPOS);
|
||||||
*realSize = geometry.size();
|
realSize = geometry.size();
|
||||||
*realPosition = geometry.pos();
|
realPosition = geometry.pos();
|
||||||
} else {
|
} else {
|
||||||
realSize->setValueAndWarp(geometry.size());
|
realSize.setValueAndWarp(geometry.size());
|
||||||
realPosition->setValueAndWarp(geometry.pos());
|
realPosition.setValueAndWarp(geometry.pos());
|
||||||
*realSize = GOALSIZE;
|
realSize = GOALSIZE;
|
||||||
*realPosition = GOALPOS;
|
realPosition = GOALPOS;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// fade
|
// fade
|
||||||
realPosition->setValueAndWarp(geometry.pos());
|
realPosition.setValueAndWarp(geometry.pos());
|
||||||
realSize->setValueAndWarp(geometry.size());
|
realSize.setValueAndWarp(geometry.size());
|
||||||
*alpha = in ? 1.f : 0.f;
|
alpha = in ? 1.f : 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in)
|
if (!in)
|
||||||
@@ -569,7 +529,7 @@ bool CLayerSurface::isFadedOut() {
|
|||||||
if (!fadingOut)
|
if (!fadingOut)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !realPosition->isBeingAnimated() && !realSize->isBeingAnimated() && !alpha->isBeingAnimated();
|
return !realPosition.isBeingAnimated() && !realSize.isBeingAnimated() && !alpha.isBeingAnimated();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CLayerSurface::popupsCount() {
|
int CLayerSurface::popupsCount() {
|
||||||
@@ -577,10 +537,6 @@ int CLayerSurface::popupsCount() {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int no = -1; // we have one dummy
|
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;
|
return no;
|
||||||
}
|
}
|
||||||
|
|
||||||
MONITORID CLayerSurface::monitorID() {
|
|
||||||
return monitor ? monitor->ID : MONITOR_INVALID;
|
|
||||||
}
|
|
||||||
|
@@ -5,6 +5,11 @@
|
|||||||
#include "WLSurface.hpp"
|
#include "WLSurface.hpp"
|
||||||
#include "../helpers/AnimatedVariable.hpp"
|
#include "../helpers/AnimatedVariable.hpp"
|
||||||
|
|
||||||
|
struct SLayerRule {
|
||||||
|
std::string targetNamespace = "";
|
||||||
|
std::string rule = "";
|
||||||
|
};
|
||||||
|
|
||||||
class CLayerShellResource;
|
class CLayerShellResource;
|
||||||
|
|
||||||
class CLayerSurface {
|
class CLayerSurface {
|
||||||
@@ -17,17 +22,17 @@ class CLayerSurface {
|
|||||||
public:
|
public:
|
||||||
~CLayerSurface();
|
~CLayerSurface();
|
||||||
|
|
||||||
void applyRules();
|
void applyRules();
|
||||||
void startAnimation(bool in, bool instant = false);
|
void startAnimation(bool in, bool instant = false);
|
||||||
bool isFadedOut();
|
bool isFadedOut();
|
||||||
int popupsCount();
|
int popupsCount();
|
||||||
|
|
||||||
PHLANIMVAR<Vector2D> realPosition;
|
CAnimatedVariable<Vector2D> realPosition;
|
||||||
PHLANIMVAR<Vector2D> realSize;
|
CAnimatedVariable<Vector2D> realSize;
|
||||||
PHLANIMVAR<float> alpha;
|
CAnimatedVariable<float> alpha;
|
||||||
|
|
||||||
WP<CLayerShellResource> layerSurface;
|
WP<CLayerShellResource> layerSurface;
|
||||||
wl_list link;
|
wl_list link;
|
||||||
|
|
||||||
// the header providing the enum type cannot be imported here
|
// the header providing the enum type cannot be imported here
|
||||||
int interactivity = 0;
|
int interactivity = 0;
|
||||||
@@ -37,7 +42,7 @@ class CLayerSurface {
|
|||||||
bool mapped = false;
|
bool mapped = false;
|
||||||
uint32_t layer = 0;
|
uint32_t layer = 0;
|
||||||
|
|
||||||
PHLMONITORREF monitor;
|
MONITORID monitorID = -1;
|
||||||
|
|
||||||
bool fadingOut = false;
|
bool fadingOut = false;
|
||||||
bool readyToDelete = false;
|
bool readyToDelete = false;
|
||||||
@@ -50,7 +55,6 @@ class CLayerSurface {
|
|||||||
bool ignoreAlpha = false;
|
bool ignoreAlpha = false;
|
||||||
float ignoreAlphaValue = 0.f;
|
float ignoreAlphaValue = 0.f;
|
||||||
bool dimAround = false;
|
bool dimAround = false;
|
||||||
int64_t order = 0;
|
|
||||||
|
|
||||||
std::optional<std::string> animationStyle;
|
std::optional<std::string> animationStyle;
|
||||||
|
|
||||||
@@ -59,13 +63,12 @@ class CLayerSurface {
|
|||||||
CBox geometry = {0, 0, 0, 0};
|
CBox geometry = {0, 0, 0, 0};
|
||||||
Vector2D position;
|
Vector2D position;
|
||||||
std::string szNamespace = "";
|
std::string szNamespace = "";
|
||||||
UP<CPopup> popupHead;
|
std::unique_ptr<CPopup> popupHead;
|
||||||
|
|
||||||
void onDestroy();
|
void onDestroy();
|
||||||
void onMap();
|
void onMap();
|
||||||
void onUnmap();
|
void onUnmap();
|
||||||
void onCommit();
|
void onCommit();
|
||||||
MONITORID monitorID();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct {
|
struct {
|
||||||
@@ -79,6 +82,6 @@ class CLayerSurface {
|
|||||||
|
|
||||||
// For the list lookup
|
// For the list lookup
|
||||||
bool operator==(const CLayerSurface& rhs) const {
|
bool operator==(const CLayerSurface& rhs) const {
|
||||||
return layerSurface == rhs.layerSurface && monitor == rhs.monitor;
|
return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -4,45 +4,27 @@
|
|||||||
#include "../protocols/LayerShell.hpp"
|
#include "../protocols/LayerShell.hpp"
|
||||||
#include "../protocols/XDGShell.hpp"
|
#include "../protocols/XDGShell.hpp"
|
||||||
#include "../protocols/core/Compositor.hpp"
|
#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>
|
#include <ranges>
|
||||||
|
|
||||||
UP<CPopup> CPopup::create(PHLWINDOW pOwner) {
|
CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) {
|
||||||
auto popup = UP<CPopup>(new CPopup());
|
initAllSignals();
|
||||||
popup->m_pWindowOwner = pOwner;
|
|
||||||
popup->m_pSelf = popup;
|
|
||||||
popup->initAllSignals();
|
|
||||||
return popup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UP<CPopup> CPopup::create(PHLLS pOwner) {
|
CPopup::CPopup(PHLLS pOwner) : m_pLayerOwner(pOwner) {
|
||||||
auto popup = UP<CPopup>(new CPopup());
|
initAllSignals();
|
||||||
popup->m_pLayerOwner = pOwner;
|
|
||||||
popup->m_pSelf = popup;
|
|
||||||
popup->initAllSignals();
|
|
||||||
return popup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UP<CPopup> CPopup::create(SP<CXDGPopupResource> resource, WP<CPopup> pOwner) {
|
CPopup::CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner) : m_pParent(pOwner), m_pResource(popup) {
|
||||||
auto popup = UP<CPopup>(new CPopup());
|
m_pWLSurface = CWLSurface::create();
|
||||||
popup->m_pResource = resource;
|
m_pWLSurface->assign(popup->surface->surface.lock(), this);
|
||||||
popup->m_pWindowOwner = pOwner->m_pWindowOwner;
|
|
||||||
popup->m_pLayerOwner = pOwner->m_pLayerOwner;
|
|
||||||
popup->m_pParent = pOwner;
|
|
||||||
popup->m_pSelf = popup;
|
|
||||||
popup->m_pWLSurface = CWLSurface::create();
|
|
||||||
popup->m_pWLSurface->assign(resource->surface->surface.lock(), popup.get());
|
|
||||||
|
|
||||||
popup->m_vLastSize = resource->surface->current.geometry.size();
|
m_pLayerOwner = pOwner->m_pLayerOwner;
|
||||||
popup->reposition();
|
m_pWindowOwner = pOwner->m_pWindowOwner;
|
||||||
|
|
||||||
popup->initAllSignals();
|
m_vLastSize = popup->surface->current.geometry.size();
|
||||||
return popup;
|
reposition();
|
||||||
|
|
||||||
|
initAllSignals();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPopup::~CPopup() {
|
CPopup::~CPopup() {
|
||||||
@@ -73,8 +55,7 @@ void CPopup::initAllSignals() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CPopup::onNewPopup(SP<CXDGPopupResource> popup) {
|
void CPopup::onNewPopup(SP<CXDGPopupResource> popup) {
|
||||||
const auto& POPUP = m_vChildren.emplace_back(CPopup::create(popup, m_pSelf));
|
const auto POPUP = m_vChildren.emplace_back(makeShared<CPopup>(popup, this)).get();
|
||||||
POPUP->m_pSelf = POPUP;
|
|
||||||
Debug::log(LOG, "New popup at {:x}", (uintptr_t)POPUP);
|
Debug::log(LOG, "New popup at {:x}", (uintptr_t)POPUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,13 +80,13 @@ void CPopup::onMap() {
|
|||||||
|
|
||||||
CBox box = m_pWLSurface->resource()->extends();
|
CBox box = m_pWLSurface->resource()->extends();
|
||||||
box.translate(COORDS).expand(4);
|
box.translate(COORDS).expand(4);
|
||||||
g_pHyprRenderer->damageBox(box);
|
g_pHyprRenderer->damageBox(&box);
|
||||||
|
|
||||||
m_vLastPos = coordsRelativeToParent();
|
m_vLastPos = coordsRelativeToParent();
|
||||||
|
|
||||||
g_pInputManager->simulateMouseMovement();
|
g_pInputManager->simulateMouseMovement();
|
||||||
|
|
||||||
m_pSubsurfaceHead = CSubsurface::create(m_pSelf);
|
m_pSubsurfaceHead = std::make_unique<CSubsurface>(this);
|
||||||
|
|
||||||
//unconstrain();
|
//unconstrain();
|
||||||
sendScale();
|
sendScale();
|
||||||
@@ -125,37 +106,31 @@ void CPopup::onUnmap() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bMapped = false;
|
|
||||||
|
|
||||||
m_vLastSize = m_pResource->surface->surface->current.size;
|
m_vLastSize = m_pResource->surface->surface->current.size;
|
||||||
|
|
||||||
const auto COORDS = coordsGlobal();
|
const auto COORDS = coordsGlobal();
|
||||||
|
|
||||||
CBox box = m_pWLSurface->resource()->extends();
|
CBox box = m_pWLSurface->resource()->extends();
|
||||||
box.translate(COORDS).expand(4);
|
box.translate(COORDS).expand(4);
|
||||||
g_pHyprRenderer->damageBox(box);
|
g_pHyprRenderer->damageBox(&box);
|
||||||
|
|
||||||
m_pSubsurfaceHead.reset();
|
m_pSubsurfaceHead.reset();
|
||||||
|
|
||||||
|
g_pInputManager->simulateMouseMovement();
|
||||||
|
|
||||||
if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
|
if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
|
||||||
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
|
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
|
||||||
|
|
||||||
// damage all children
|
// damage all children
|
||||||
breadthfirst(
|
breadthfirst(
|
||||||
[](WP<CPopup> p, void* data) {
|
[](CPopup* p, void* data) {
|
||||||
if (!p->m_pResource)
|
if (!p->m_pResource)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto box = CBox{p->coordsGlobal(), p->size()};
|
auto box = CBox{p->coordsGlobal(), p->size()};
|
||||||
g_pHyprRenderer->damageBox(box);
|
g_pHyprRenderer->damageBox(&box);
|
||||||
},
|
},
|
||||||
nullptr);
|
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();
|
|
||||||
|
|
||||||
// if (WASLASTFOCUS)
|
|
||||||
// g_pInputManager->simulateMouseMovement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPopup::onCommit(bool ignoreSiblings) {
|
void CPopup::onCommit(bool ignoreSiblings) {
|
||||||
@@ -187,10 +162,10 @@ void CPopup::onCommit(bool ignoreSiblings) {
|
|||||||
|
|
||||||
if (m_vLastSize != m_pResource->surface->surface->current.size || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) {
|
if (m_vLastSize != m_pResource->surface->surface->current.size || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) {
|
||||||
CBox box = {localToGlobal(m_vLastPos), m_vLastSize};
|
CBox box = {localToGlobal(m_vLastPos), m_vLastSize};
|
||||||
g_pHyprRenderer->damageBox(box);
|
g_pHyprRenderer->damageBox(&box);
|
||||||
m_vLastSize = m_pResource->surface->surface->current.size;
|
m_vLastSize = m_pResource->surface->surface->current.size;
|
||||||
box = {COORDS, m_vLastSize};
|
box = {COORDS, m_vLastSize};
|
||||||
g_pHyprRenderer->damageBox(box);
|
g_pHyprRenderer->damageBox(&box);
|
||||||
|
|
||||||
m_vLastPos = COORDSLOCAL;
|
m_vLastPos = COORDSLOCAL;
|
||||||
}
|
}
|
||||||
@@ -227,20 +202,13 @@ void CPopup::reposition() {
|
|||||||
m_pResource->applyPositioning(box, COORDS);
|
m_pResource->applyPositioning(box, COORDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
SP<CWLSurface> CPopup::getT1Owner() {
|
|
||||||
if (m_pWindowOwner)
|
|
||||||
return m_pWindowOwner->m_pWLSurface;
|
|
||||||
else
|
|
||||||
return m_pLayerOwner->surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2D CPopup::coordsRelativeToParent() {
|
Vector2D CPopup::coordsRelativeToParent() {
|
||||||
Vector2D offset;
|
Vector2D offset;
|
||||||
|
|
||||||
if (!m_pResource)
|
if (!m_pResource)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
WP<CPopup> current = m_pSelf;
|
CPopup* current = this;
|
||||||
offset -= current->m_pResource->surface->current.geometry.pos();
|
offset -= current->m_pResource->surface->current.geometry.pos();
|
||||||
|
|
||||||
while (current->m_pParent && current->m_pResource) {
|
while (current->m_pParent && current->m_pResource) {
|
||||||
@@ -264,16 +232,16 @@ Vector2D CPopup::localToGlobal(const Vector2D& rel) {
|
|||||||
|
|
||||||
Vector2D CPopup::t1ParentCoords() {
|
Vector2D CPopup::t1ParentCoords() {
|
||||||
if (!m_pWindowOwner.expired())
|
if (!m_pWindowOwner.expired())
|
||||||
return m_pWindowOwner->m_vRealPosition->value();
|
return m_pWindowOwner->m_vRealPosition.value();
|
||||||
if (!m_pLayerOwner.expired())
|
if (!m_pLayerOwner.expired())
|
||||||
return m_pLayerOwner->realPosition->value();
|
return m_pLayerOwner->realPosition.value();
|
||||||
|
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPopup::recheckTree() {
|
void CPopup::recheckTree() {
|
||||||
WP<CPopup> curr = m_pSelf;
|
CPopup* curr = this;
|
||||||
while (curr->m_pParent) {
|
while (curr->m_pParent) {
|
||||||
curr = curr->m_pParent;
|
curr = curr->m_pParent;
|
||||||
}
|
}
|
||||||
@@ -282,9 +250,8 @@ void CPopup::recheckTree() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CPopup::recheckChildrenRecursive() {
|
void CPopup::recheckChildrenRecursive() {
|
||||||
std::vector<WP<CPopup>> cpy;
|
auto cpy = m_vChildren;
|
||||||
std::ranges::for_each(m_vChildren, [&cpy](const auto& el) { cpy.emplace_back(el); });
|
for (auto& c : cpy) {
|
||||||
for (auto const& c : cpy) {
|
|
||||||
c->onCommit(true);
|
c->onCommit(true);
|
||||||
c->recheckChildrenRecursive();
|
c->recheckChildrenRecursive();
|
||||||
}
|
}
|
||||||
@@ -314,17 +281,16 @@ bool CPopup::visible() {
|
|||||||
return false;
|
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*> nodes, std::function<void(CPopup*, void*)> fn, void* data) {
|
||||||
for (auto const& n : nodes) {
|
for (auto& n : nodes) {
|
||||||
fn(n, data);
|
fn(n, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<WP<CPopup>> nodes2;
|
std::vector<CPopup*> nodes2;
|
||||||
nodes2.reserve(nodes.size() * 2);
|
|
||||||
|
|
||||||
for (auto const& n : nodes) {
|
for (auto& n : nodes) {
|
||||||
for (auto const& c : n->m_vChildren) {
|
for (auto& c : n->m_vChildren) {
|
||||||
nodes2.push_back(c->m_pSelf);
|
nodes2.push_back(c.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,37 +298,35 @@ void CPopup::bfHelper(std::vector<WP<CPopup>> const& nodes, std::function<void(W
|
|||||||
bfHelper(nodes2, fn, data);
|
bfHelper(nodes2, fn, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPopup::breadthfirst(std::function<void(WP<CPopup>, void*)> fn, void* data) {
|
void CPopup::breadthfirst(std::function<void(CPopup*, void*)> fn, void* data) {
|
||||||
std::vector<WP<CPopup>> popups;
|
std::vector<CPopup*> popups;
|
||||||
popups.push_back(m_pSelf);
|
popups.push_back(this);
|
||||||
bfHelper(popups, fn, data);
|
bfHelper(popups, fn, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
WP<CPopup> CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||||
std::vector<WP<CPopup>> popups;
|
std::vector<CPopup*> popups;
|
||||||
breadthfirst([&popups](WP<CPopup> popup, void* data) { popups.push_back(popup); }, &popups);
|
breadthfirst([](CPopup* popup, void* data) { ((std::vector<CPopup*>*)data)->push_back(popup); }, &popups);
|
||||||
|
|
||||||
for (auto const& p : popups | std::views::reverse) {
|
for (auto& p : popups | std::views::reverse) {
|
||||||
if (!p->m_pResource || !p->m_bMapped)
|
if (!p->m_pResource)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!allowsInput) {
|
if (!allowsInput) {
|
||||||
const Vector2D offset =
|
const Vector2D offset = p->m_pResource ? (p->size() - p->m_pResource->geometry.size()) / 2.F : Vector2D{};
|
||||||
p->m_pResource && p->m_pResource->surface ? (p->size() - p->m_pResource->geometry.size()) / 2.F - p->m_pResource->surface->current.geometry.pos() : Vector2D{};
|
const Vector2D size = p->m_pResource ? p->m_pResource->geometry.size() : p->size();
|
||||||
const Vector2D size = p->m_pResource ? p->m_pResource->geometry.size() : p->size();
|
|
||||||
|
|
||||||
const auto BOX = CBox{p->coordsGlobal() + offset, size};
|
const auto BOX = CBox{p->coordsGlobal() + offset, size};
|
||||||
if (BOX.containsPoint(globalCoords))
|
if (BOX.containsPoint(globalCoords))
|
||||||
return p;
|
return p;
|
||||||
} else {
|
} else {
|
||||||
const Vector2D offset =
|
const Vector2D offset = p->m_pResource ? (p->size() - p->m_pResource->geometry.size()) / 2.F : Vector2D{};
|
||||||
p->m_pResource && p->m_pResource->surface ? (p->size() - p->m_pResource->geometry.size()) / 2.F - p->m_pResource->surface->current.geometry.pos() : Vector2D{};
|
const auto REGION =
|
||||||
const auto REGION =
|
|
||||||
CRegion{p->m_pWLSurface->resource()->current.input}.intersect(CBox{{}, p->m_pWLSurface->resource()->current.size}).translate(p->coordsGlobal() + offset);
|
CRegion{p->m_pWLSurface->resource()->current.input}.intersect(CBox{{}, p->m_pWLSurface->resource()->current.size}).translate(p->coordsGlobal() + offset);
|
||||||
if (REGION.containsPoint(globalCoords))
|
if (REGION.containsPoint(globalCoords))
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@@ -1,58 +1,53 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
#include "Subsurface.hpp"
|
#include "Subsurface.hpp"
|
||||||
#include "../helpers/signal/Signal.hpp"
|
#include "../helpers/signal/Signal.hpp"
|
||||||
#include "../helpers/memory/Memory.hpp"
|
|
||||||
|
|
||||||
class CXDGPopupResource;
|
class CXDGPopupResource;
|
||||||
|
|
||||||
class CPopup {
|
class CPopup {
|
||||||
public:
|
public:
|
||||||
// dummy head nodes
|
// dummy head nodes
|
||||||
static UP<CPopup> create(PHLWINDOW pOwner);
|
CPopup(PHLWINDOW pOwner);
|
||||||
static UP<CPopup> create(PHLLS pOwner);
|
CPopup(PHLLS pOwner);
|
||||||
|
|
||||||
// real nodes
|
// real nodes
|
||||||
static UP<CPopup> create(SP<CXDGPopupResource> popup, WP<CPopup> pOwner);
|
CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner);
|
||||||
|
|
||||||
~CPopup();
|
~CPopup();
|
||||||
|
|
||||||
SP<CWLSurface> getT1Owner();
|
Vector2D coordsRelativeToParent();
|
||||||
Vector2D coordsRelativeToParent();
|
Vector2D coordsGlobal();
|
||||||
Vector2D coordsGlobal();
|
|
||||||
|
|
||||||
Vector2D size();
|
Vector2D size();
|
||||||
|
|
||||||
void onNewPopup(SP<CXDGPopupResource> popup);
|
void onNewPopup(SP<CXDGPopupResource> popup);
|
||||||
void onDestroy();
|
void onDestroy();
|
||||||
void onMap();
|
void onMap();
|
||||||
void onUnmap();
|
void onUnmap();
|
||||||
void onCommit(bool ignoreSiblings = false);
|
void onCommit(bool ignoreSiblings = false);
|
||||||
void onReposition();
|
void onReposition();
|
||||||
|
|
||||||
void recheckTree();
|
void recheckTree();
|
||||||
|
|
||||||
bool visible();
|
bool visible();
|
||||||
|
|
||||||
// will also loop over this node
|
// will also loop over this node
|
||||||
void breadthfirst(std::function<void(WP<CPopup>, void*)> fn, void* data);
|
void breadthfirst(std::function<void(CPopup*, void*)> fn, void* data);
|
||||||
WP<CPopup> at(const Vector2D& globalCoords, bool allowsInput = false);
|
CPopup* at(const Vector2D& globalCoords, bool allowsInput = false);
|
||||||
|
|
||||||
//
|
//
|
||||||
SP<CWLSurface> m_pWLSurface;
|
SP<CWLSurface> m_pWLSurface;
|
||||||
WP<CPopup> m_pSelf;
|
|
||||||
bool m_bMapped = false;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CPopup() = default;
|
|
||||||
|
|
||||||
// T1 owners, each popup has to have one of these
|
// T1 owners, each popup has to have one of these
|
||||||
PHLWINDOWREF m_pWindowOwner;
|
PHLWINDOWREF m_pWindowOwner;
|
||||||
PHLLSREF m_pLayerOwner;
|
PHLLSREF m_pLayerOwner;
|
||||||
|
|
||||||
// T2 owners
|
// T2 owners
|
||||||
WP<CPopup> m_pParent;
|
CPopup* m_pParent = nullptr;
|
||||||
|
|
||||||
WP<CXDGPopupResource> m_pResource;
|
WP<CXDGPopupResource> m_pResource;
|
||||||
|
|
||||||
@@ -61,11 +56,12 @@ class CPopup {
|
|||||||
|
|
||||||
bool m_bRequestedReposition = false;
|
bool m_bRequestedReposition = false;
|
||||||
|
|
||||||
bool m_bInert = false;
|
bool m_bInert = false;
|
||||||
|
bool m_bMapped = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
std::vector<UP<CPopup>> m_vChildren;
|
std::vector<SP<CPopup>> m_vChildren;
|
||||||
UP<CSubsurface> m_pSubsurfaceHead;
|
std::unique_ptr<CSubsurface> m_pSubsurfaceHead;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CHyprSignalListener newPopup;
|
CHyprSignalListener newPopup;
|
||||||
@@ -84,5 +80,5 @@ class CPopup {
|
|||||||
|
|
||||||
Vector2D localToGlobal(const Vector2D& rel);
|
Vector2D localToGlobal(const Vector2D& rel);
|
||||||
Vector2D t1ParentCoords();
|
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*> 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,54 +4,39 @@
|
|||||||
#include "../config/ConfigValue.hpp"
|
#include "../config/ConfigValue.hpp"
|
||||||
#include "../protocols/core/Compositor.hpp"
|
#include "../protocols/core/Compositor.hpp"
|
||||||
#include "../protocols/core/Subcompositor.hpp"
|
#include "../protocols/core/Subcompositor.hpp"
|
||||||
#include "../render/Renderer.hpp"
|
|
||||||
#include "../managers/input/InputManager.hpp"
|
|
||||||
|
|
||||||
UP<CSubsurface> CSubsurface::create(PHLWINDOW pOwner) {
|
CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) {
|
||||||
auto subsurface = UP<CSubsurface>(new CSubsurface());
|
initSignals();
|
||||||
subsurface->m_pWindowParent = pOwner;
|
initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
|
||||||
subsurface->m_pSelf = subsurface;
|
|
||||||
|
|
||||||
subsurface->initSignals();
|
|
||||||
subsurface->initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
|
|
||||||
return subsurface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UP<CSubsurface> CSubsurface::create(WP<CPopup> pOwner) {
|
CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) {
|
||||||
auto subsurface = UP<CSubsurface>(new CSubsurface());
|
initSignals();
|
||||||
subsurface->m_pPopupParent = pOwner;
|
initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
|
||||||
subsurface->m_pSelf = subsurface;
|
|
||||||
subsurface->initSignals();
|
|
||||||
subsurface->initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
|
|
||||||
return subsurface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UP<CSubsurface> CSubsurface::create(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner) {
|
CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) {
|
||||||
auto subsurface = UP<CSubsurface>(new CSubsurface());
|
m_pWLSurface = CWLSurface::create();
|
||||||
subsurface->m_pWindowParent = pOwner;
|
m_pWLSurface->assign(pSubsurface->surface.lock(), this);
|
||||||
subsurface->m_pSubsurface = pSubsurface;
|
initSignals();
|
||||||
subsurface->m_pSelf = subsurface;
|
initExistingSubsurfaces(pSubsurface->surface.lock());
|
||||||
subsurface->m_pWLSurface = CWLSurface::create();
|
|
||||||
subsurface->m_pWLSurface->assign(pSubsurface->surface.lock(), subsurface.get());
|
|
||||||
subsurface->initSignals();
|
|
||||||
subsurface->initExistingSubsurfaces(pSubsurface->surface.lock());
|
|
||||||
return subsurface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UP<CSubsurface> CSubsurface::create(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner) {
|
CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
|
||||||
auto subsurface = UP<CSubsurface>(new CSubsurface());
|
m_pWLSurface = CWLSurface::create();
|
||||||
subsurface->m_pPopupParent = pOwner;
|
m_pWLSurface->assign(pSubsurface->surface.lock(), this);
|
||||||
subsurface->m_pSubsurface = pSubsurface;
|
initSignals();
|
||||||
subsurface->m_pSelf = subsurface;
|
initExistingSubsurfaces(pSubsurface->surface.lock());
|
||||||
subsurface->m_pWLSurface = CWLSurface::create();
|
|
||||||
subsurface->m_pWLSurface->assign(pSubsurface->surface.lock(), subsurface.get());
|
|
||||||
subsurface->initSignals();
|
|
||||||
subsurface->initExistingSubsurfaces(pSubsurface->surface.lock());
|
|
||||||
return subsurface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSubsurface::~CSubsurface() {
|
CSubsurface::~CSubsurface() {
|
||||||
;
|
hyprListener_newSubsurface.removeCallback();
|
||||||
|
|
||||||
|
if (!m_pSubsurface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hyprListener_commitSubsurface.removeCallback();
|
||||||
|
hyprListener_destroySubsurface.removeCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSubsurface::initSignals() {
|
void CSubsurface::initSignals() {
|
||||||
@@ -80,7 +65,7 @@ void CSubsurface::checkSiblingDamage() {
|
|||||||
|
|
||||||
const double SCALE = m_pWindowParent.lock() && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0;
|
const double SCALE = m_pWindowParent.lock() && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0;
|
||||||
|
|
||||||
for (auto const& n : m_pParent->m_vChildren) {
|
for (auto& n : m_pParent->m_vChildren) {
|
||||||
if (n.get() == this)
|
if (n.get() == this)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -90,7 +75,7 @@ void CSubsurface::checkSiblingDamage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CSubsurface::recheckDamageForSubsurfaces() {
|
void CSubsurface::recheckDamageForSubsurfaces() {
|
||||||
for (auto const& n : m_vChildren) {
|
for (auto& n : m_vChildren) {
|
||||||
const auto COORDS = n->coordsGlobal();
|
const auto COORDS = n->coordsGlobal();
|
||||||
g_pHyprRenderer->damageSurface(n->m_pWLSurface->resource(), COORDS.x, COORDS.y);
|
g_pHyprRenderer->damageSurface(n->m_pWLSurface->resource(), COORDS.x, COORDS.y);
|
||||||
}
|
}
|
||||||
@@ -120,20 +105,11 @@ void CSubsurface::onCommit() {
|
|||||||
checkSiblingDamage();
|
checkSiblingDamage();
|
||||||
|
|
||||||
if (m_vLastSize != m_pWLSurface->resource()->current.size) {
|
if (m_vLastSize != m_pWLSurface->resource()->current.size) {
|
||||||
// TODO: fix this
|
CBox box{COORDS, m_vLastSize};
|
||||||
// CBox box{COORDS, m_vLastSize};
|
g_pHyprRenderer->damageBox(&box);
|
||||||
// g_pHyprRenderer->damageBox(box);
|
m_vLastSize = m_pWLSurface->resource()->current.size;
|
||||||
// m_vLastSize = m_pWLSurface->resource()->current.size;
|
box = {COORDS, m_vLastSize};
|
||||||
// box = {COORDS, m_vLastSize};
|
g_pHyprRenderer->damageBox(&box);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,18 +127,16 @@ void CSubsurface::onDestroy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CSubsurface::onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface) {
|
void CSubsurface::onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface) {
|
||||||
WP<CSubsurface> PSUBSURFACE;
|
CSubsurface* PSUBSURFACE = nullptr;
|
||||||
|
|
||||||
if (!m_pWindowParent.expired())
|
if (!m_pWindowParent.expired())
|
||||||
PSUBSURFACE = m_vChildren.emplace_back(CSubsurface::create(pSubsurface, m_pWindowParent.lock()));
|
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent.lock())).get();
|
||||||
else if (m_pPopupParent)
|
else if (m_pPopupParent)
|
||||||
PSUBSURFACE = m_vChildren.emplace_back(CSubsurface::create(pSubsurface, m_pPopupParent));
|
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pPopupParent)).get();
|
||||||
|
|
||||||
PSUBSURFACE->m_pSelf = PSUBSURFACE;
|
|
||||||
|
|
||||||
ASSERT(PSUBSURFACE);
|
ASSERT(PSUBSURFACE);
|
||||||
|
|
||||||
PSUBSURFACE->m_pParent = m_pSelf;
|
PSUBSURFACE->m_pParent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSubsurface::onMap() {
|
void CSubsurface::onMap() {
|
||||||
@@ -171,7 +145,7 @@ void CSubsurface::onMap() {
|
|||||||
const auto COORDS = coordsGlobal();
|
const auto COORDS = coordsGlobal();
|
||||||
CBox box{COORDS, m_vLastSize};
|
CBox box{COORDS, m_vLastSize};
|
||||||
box.expand(4);
|
box.expand(4);
|
||||||
g_pHyprRenderer->damageBox(box);
|
g_pHyprRenderer->damageBox(&box);
|
||||||
|
|
||||||
if (!m_pWindowParent.expired())
|
if (!m_pWindowParent.expired())
|
||||||
m_pWindowParent->updateSurfaceScaleTransformDetails();
|
m_pWindowParent->updateSurfaceScaleTransformDetails();
|
||||||
@@ -181,7 +155,7 @@ void CSubsurface::onUnmap() {
|
|||||||
const auto COORDS = coordsGlobal();
|
const auto COORDS = coordsGlobal();
|
||||||
CBox box{COORDS, m_vLastSize};
|
CBox box{COORDS, m_vLastSize};
|
||||||
box.expand(4);
|
box.expand(4);
|
||||||
g_pHyprRenderer->damageBox(box);
|
g_pHyprRenderer->damageBox(&box);
|
||||||
|
|
||||||
if (m_pWLSurface->resource() == g_pCompositor->m_pLastFocus)
|
if (m_pWLSurface->resource() == g_pCompositor->m_pLastFocus)
|
||||||
g_pInputManager->releaseAllMouseButtons();
|
g_pInputManager->releaseAllMouseButtons();
|
||||||
@@ -201,7 +175,7 @@ Vector2D CSubsurface::coordsGlobal() {
|
|||||||
Vector2D coords = coordsRelativeToParent();
|
Vector2D coords = coordsRelativeToParent();
|
||||||
|
|
||||||
if (!m_pWindowParent.expired())
|
if (!m_pWindowParent.expired())
|
||||||
coords += m_pWindowParent->m_vRealPosition->value();
|
coords += m_pWindowParent->m_vRealPosition.value();
|
||||||
else if (m_pPopupParent)
|
else if (m_pPopupParent)
|
||||||
coords += m_pPopupParent->coordsGlobal();
|
coords += m_pPopupParent->coordsGlobal();
|
||||||
|
|
||||||
@@ -209,7 +183,7 @@ Vector2D CSubsurface::coordsGlobal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CSubsurface::initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface) {
|
void CSubsurface::initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface) {
|
||||||
for (auto const& s : pSurface->subsurfaces) {
|
for (auto& s : pSurface->subsurfaces) {
|
||||||
if (!s || s->surface->hlSurface /* already assigned */)
|
if (!s || s->surface->hlSurface /* already assigned */)
|
||||||
continue;
|
continue;
|
||||||
onNewSubsurface(s.lock());
|
onNewSubsurface(s.lock());
|
||||||
|
@@ -10,34 +10,34 @@ class CWLSubsurfaceResource;
|
|||||||
class CSubsurface {
|
class CSubsurface {
|
||||||
public:
|
public:
|
||||||
// root dummy nodes
|
// root dummy nodes
|
||||||
static UP<CSubsurface> create(PHLWINDOW pOwner);
|
CSubsurface(PHLWINDOW pOwner);
|
||||||
static UP<CSubsurface> create(WP<CPopup> pOwner);
|
CSubsurface(CPopup* pOwner);
|
||||||
|
|
||||||
// real nodes
|
// real nodes
|
||||||
static UP<CSubsurface> create(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner);
|
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner);
|
||||||
static UP<CSubsurface> create(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner);
|
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner);
|
||||||
|
|
||||||
~CSubsurface();
|
~CSubsurface();
|
||||||
|
|
||||||
Vector2D coordsRelativeToParent();
|
Vector2D coordsRelativeToParent();
|
||||||
Vector2D coordsGlobal();
|
Vector2D coordsGlobal();
|
||||||
|
|
||||||
Vector2D size();
|
Vector2D size();
|
||||||
|
|
||||||
void onCommit();
|
void onCommit();
|
||||||
void onDestroy();
|
void onDestroy();
|
||||||
void onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface);
|
void onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface);
|
||||||
void onMap();
|
void onMap();
|
||||||
void onUnmap();
|
void onUnmap();
|
||||||
|
|
||||||
bool visible();
|
bool visible();
|
||||||
|
|
||||||
void recheckDamageForSubsurfaces();
|
void recheckDamageForSubsurfaces();
|
||||||
|
|
||||||
WP<CSubsurface> m_pSelf;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSubsurface() = default;
|
DYNLISTENER(destroySubsurface);
|
||||||
|
DYNLISTENER(commitSubsurface);
|
||||||
|
DYNLISTENER(newSubsurface);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CHyprSignalListener destroySubsurface;
|
CHyprSignalListener destroySubsurface;
|
||||||
@@ -52,16 +52,16 @@ class CSubsurface {
|
|||||||
Vector2D m_vLastSize = {};
|
Vector2D m_vLastSize = {};
|
||||||
|
|
||||||
// if nullptr, means it's a dummy node
|
// if nullptr, means it's a dummy node
|
||||||
WP<CSubsurface> m_pParent;
|
CSubsurface* m_pParent = nullptr;
|
||||||
|
|
||||||
PHLWINDOWREF m_pWindowParent;
|
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;
|
bool m_bInert = false;
|
||||||
|
|
||||||
void initSignals();
|
void initSignals();
|
||||||
void initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface);
|
void initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface);
|
||||||
void checkSiblingDamage();
|
void checkSiblingDamage();
|
||||||
};
|
};
|
@@ -1,9 +1,7 @@
|
|||||||
#include "WLSurface.hpp"
|
#include "WLSurface.hpp"
|
||||||
#include "LayerSurface.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../desktop/Window.hpp"
|
|
||||||
#include "../protocols/core/Compositor.hpp"
|
#include "../protocols/core/Compositor.hpp"
|
||||||
#include "../protocols/LayerShell.hpp"
|
#include "../protocols/LayerShell.hpp"
|
||||||
#include "../render/Renderer.hpp"
|
|
||||||
|
|
||||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface) {
|
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface) {
|
||||||
m_pResource = pSurface;
|
m_pResource = pSurface;
|
||||||
@@ -64,7 +62,7 @@ bool CWLSurface::small() const {
|
|||||||
|
|
||||||
const auto O = m_pWindowOwner.lock();
|
const auto O = m_pWindowOwner.lock();
|
||||||
|
|
||||||
return O->m_vReportedSize.x > m_pResource->current.size.x + 1 || O->m_vReportedSize.y > m_pResource->current.size.y + 1;
|
return O->m_vReportedSize.x > m_pResource->current.bufferSize.x + 1 || O->m_vReportedSize.y > m_pResource->current.bufferSize.y + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D CWLSurface::correctSmallVec() const {
|
Vector2D CWLSurface::correctSmallVec() const {
|
||||||
@@ -74,7 +72,7 @@ Vector2D CWLSurface::correctSmallVec() const {
|
|||||||
const auto SIZE = getViewporterCorrectedSize();
|
const auto SIZE = getViewporterCorrectedSize();
|
||||||
const auto O = m_pWindowOwner.lock();
|
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 {
|
Vector2D CWLSurface::correctSmallVecBuf() const {
|
||||||
|
@@ -84,11 +84,7 @@ class CWLSurface {
|
|||||||
static SP<CWLSurface> fromResource(SP<CWLSurfaceResource> pSurface);
|
static SP<CWLSurface> fromResource(SP<CWLSurfaceResource> pSurface);
|
||||||
|
|
||||||
// used by the alpha-modifier protocol
|
// used by the alpha-modifier protocol
|
||||||
float m_fAlphaModifier = 1.F;
|
float m_pAlphaModifier = 1.F;
|
||||||
|
|
||||||
// used by the hyprland-surface protocol
|
|
||||||
float m_fOverallOpacity = 1.F;
|
|
||||||
CRegion m_visibleRegion;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CSignal destroy;
|
CSignal destroy;
|
||||||
@@ -120,5 +116,4 @@ class CWLSurface {
|
|||||||
} listeners;
|
} listeners;
|
||||||
|
|
||||||
friend class CPointerConstraint;
|
friend class CPointerConstraint;
|
||||||
friend class CXxColorManagerV4;
|
|
||||||
};
|
};
|
@@ -1,10 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <deque>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include "../config/ConfigDataValues.hpp"
|
#include "../config/ConfigDataValues.hpp"
|
||||||
|
#include "../defines.hpp"
|
||||||
#include "../helpers/AnimatedVariable.hpp"
|
#include "../helpers/AnimatedVariable.hpp"
|
||||||
#include "../helpers/math/Math.hpp"
|
#include "../helpers/math/Math.hpp"
|
||||||
#include "../helpers/signal/Signal.hpp"
|
#include "../helpers/signal/Signal.hpp"
|
||||||
@@ -12,25 +12,23 @@
|
|||||||
#include "../macros.hpp"
|
#include "../macros.hpp"
|
||||||
#include "../managers/XWaylandManager.hpp"
|
#include "../managers/XWaylandManager.hpp"
|
||||||
#include "../render/decorations/IHyprWindowDecoration.hpp"
|
#include "../render/decorations/IHyprWindowDecoration.hpp"
|
||||||
#include "../render/Transformer.hpp"
|
|
||||||
#include "DesktopTypes.hpp"
|
#include "DesktopTypes.hpp"
|
||||||
#include "Popup.hpp"
|
#include "Popup.hpp"
|
||||||
#include "Subsurface.hpp"
|
#include "Subsurface.hpp"
|
||||||
#include "WLSurface.hpp"
|
#include "WLSurface.hpp"
|
||||||
#include "Workspace.hpp"
|
#include "Workspace.hpp"
|
||||||
#include "WindowRule.hpp"
|
|
||||||
|
|
||||||
class CXDGSurfaceResource;
|
class CXDGSurfaceResource;
|
||||||
class CXWaylandSurface;
|
class CXWaylandSurface;
|
||||||
|
|
||||||
enum eIdleInhibitMode : uint8_t {
|
enum eIdleInhibitMode {
|
||||||
IDLEINHIBIT_NONE = 0,
|
IDLEINHIBIT_NONE = 0,
|
||||||
IDLEINHIBIT_ALWAYS,
|
IDLEINHIBIT_ALWAYS,
|
||||||
IDLEINHIBIT_FULLSCREEN,
|
IDLEINHIBIT_FULLSCREEN,
|
||||||
IDLEINHIBIT_FOCUS
|
IDLEINHIBIT_FOCUS
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eGroupRules : uint8_t {
|
enum eGroupRules {
|
||||||
// effective only during first map, except for _ALWAYS variant
|
// effective only during first map, except for _ALWAYS variant
|
||||||
GROUP_NONE = 0,
|
GROUP_NONE = 0,
|
||||||
GROUP_SET = 1 << 0, // Open as new group or add to focused group
|
GROUP_SET = 1 << 0, // Open as new group or add to focused group
|
||||||
@@ -42,7 +40,7 @@ enum eGroupRules : uint8_t {
|
|||||||
GROUP_OVERRIDE = 1 << 6, // Override other rules
|
GROUP_OVERRIDE = 1 << 6, // Override other rules
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eGetWindowProperties : uint8_t {
|
enum eGetWindowProperties {
|
||||||
WINDOW_ONLY = 0,
|
WINDOW_ONLY = 0,
|
||||||
RESERVED_EXTENTS = 1 << 0,
|
RESERVED_EXTENTS = 1 << 0,
|
||||||
INPUT_EXTENTS = 1 << 1,
|
INPUT_EXTENTS = 1 << 1,
|
||||||
@@ -52,13 +50,12 @@ enum eGetWindowProperties : uint8_t {
|
|||||||
USE_PROP_TILED = 1 << 5,
|
USE_PROP_TILED = 1 << 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eSuppressEvents : uint8_t {
|
enum eSuppressEvents {
|
||||||
SUPPRESS_NONE = 0,
|
SUPPRESS_NONE = 0,
|
||||||
SUPPRESS_FULLSCREEN = 1 << 0,
|
SUPPRESS_FULLSCREEN = 1 << 0,
|
||||||
SUPPRESS_MAXIMIZE = 1 << 1,
|
SUPPRESS_MAXIMIZE = 1 << 1,
|
||||||
SUPPRESS_ACTIVATE = 1 << 2,
|
SUPPRESS_ACTIVATE = 1 << 2,
|
||||||
SUPPRESS_ACTIVATE_FOCUSONLY = 1 << 3,
|
SUPPRESS_ACTIVATE_FOCUSONLY = 1 << 3,
|
||||||
SUPPRESS_FULLSCREEN_OUTPUT = 1 << 4,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IWindowTransformer;
|
class IWindowTransformer;
|
||||||
@@ -67,7 +64,7 @@ struct SAlphaValue {
|
|||||||
float m_fAlpha;
|
float m_fAlpha;
|
||||||
bool m_bOverride;
|
bool m_bOverride;
|
||||||
|
|
||||||
float applyAlpha(float alpha) const {
|
float applyAlpha(float alpha) {
|
||||||
if (m_bOverride)
|
if (m_bOverride)
|
||||||
return m_fAlpha;
|
return m_fAlpha;
|
||||||
else
|
else
|
||||||
@@ -75,8 +72,8 @@ struct SAlphaValue {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eOverridePriority : uint8_t {
|
enum eOverridePriority {
|
||||||
PRIORITY_LAYOUT = 0,
|
PRIORITY_LAYOUT,
|
||||||
PRIORITY_WORKSPACE_RULE,
|
PRIORITY_WORKSPACE_RULE,
|
||||||
PRIORITY_WINDOW_RULE,
|
PRIORITY_WINDOW_RULE,
|
||||||
PRIORITY_SET_PROP,
|
PRIORITY_SET_PROP,
|
||||||
@@ -88,7 +85,9 @@ class CWindowOverridableVar {
|
|||||||
CWindowOverridableVar(T const& value, eOverridePriority priority) {
|
CWindowOverridableVar(T const& value, eOverridePriority priority) {
|
||||||
values[priority] = value;
|
values[priority] = value;
|
||||||
}
|
}
|
||||||
CWindowOverridableVar(T const& value) : defaultValue{value} {}
|
CWindowOverridableVar(T const& value) {
|
||||||
|
defaultValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
CWindowOverridableVar() = default;
|
CWindowOverridableVar() = default;
|
||||||
~CWindowOverridableVar() = default;
|
~CWindowOverridableVar() = default;
|
||||||
@@ -145,13 +144,6 @@ class CWindowOverridableVar {
|
|||||||
unset(priority);
|
unset(priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
operator std::optional<T>() {
|
|
||||||
if (hasValue())
|
|
||||||
return value();
|
|
||||||
else
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<eOverridePriority, T> values;
|
std::map<eOverridePriority, T> values;
|
||||||
T defaultValue; // used for toggling, so required for bool
|
T defaultValue; // used for toggling, so required for bool
|
||||||
@@ -182,15 +174,10 @@ struct SWindowData {
|
|||||||
CWindowOverridableVar<bool> syncFullscreen = true;
|
CWindowOverridableVar<bool> syncFullscreen = true;
|
||||||
CWindowOverridableVar<bool> tearing = false;
|
CWindowOverridableVar<bool> tearing = false;
|
||||||
CWindowOverridableVar<bool> xray = false;
|
CWindowOverridableVar<bool> xray = false;
|
||||||
CWindowOverridableVar<bool> renderUnfocused = false;
|
|
||||||
|
|
||||||
CWindowOverridableVar<int> rounding;
|
CWindowOverridableVar<int> rounding;
|
||||||
CWindowOverridableVar<float> roundingPower;
|
|
||||||
CWindowOverridableVar<int> borderSize;
|
CWindowOverridableVar<int> borderSize;
|
||||||
|
|
||||||
CWindowOverridableVar<float> scrollMouse;
|
|
||||||
CWindowOverridableVar<float> scrollTouchpad;
|
|
||||||
|
|
||||||
CWindowOverridableVar<std::string> animationStyle;
|
CWindowOverridableVar<std::string> animationStyle;
|
||||||
CWindowOverridableVar<Vector2D> maxSize;
|
CWindowOverridableVar<Vector2D> maxSize;
|
||||||
CWindowOverridableVar<Vector2D> minSize;
|
CWindowOverridableVar<Vector2D> minSize;
|
||||||
@@ -199,12 +186,32 @@ struct SWindowData {
|
|||||||
CWindowOverridableVar<CGradientValueData> inactiveBorderColor;
|
CWindowOverridableVar<CGradientValueData> inactiveBorderColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SWindowRule {
|
||||||
|
std::string szRule;
|
||||||
|
std::string szValue;
|
||||||
|
|
||||||
|
bool v2 = false;
|
||||||
|
std::string szTitle;
|
||||||
|
std::string szClass;
|
||||||
|
std::string szInitialTitle;
|
||||||
|
std::string szInitialClass;
|
||||||
|
std::string szTag;
|
||||||
|
int bX11 = -1; // -1 means "ANY"
|
||||||
|
int bFloating = -1;
|
||||||
|
int bFullscreen = -1;
|
||||||
|
int bPinned = -1;
|
||||||
|
int bFocus = -1;
|
||||||
|
std::string szFullscreenState = ""; // empty means any
|
||||||
|
std::string szOnWorkspace = ""; // empty means any
|
||||||
|
std::string szWorkspace = ""; // empty means any
|
||||||
|
};
|
||||||
|
|
||||||
struct SInitialWorkspaceToken {
|
struct SInitialWorkspaceToken {
|
||||||
PHLWINDOWREF primaryOwner;
|
PHLWINDOWREF primaryOwner;
|
||||||
std::string workspace;
|
std::string workspace;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SFullscreenState {
|
struct sFullscreenState {
|
||||||
eFullscreenMode internal = FSMODE_NONE;
|
eFullscreenMode internal = FSMODE_NONE;
|
||||||
eFullscreenMode client = FSMODE_NONE;
|
eFullscreenMode client = FSMODE_NONE;
|
||||||
};
|
};
|
||||||
@@ -235,8 +242,8 @@ class CWindow {
|
|||||||
Vector2D m_vSize = Vector2D(0, 0);
|
Vector2D m_vSize = Vector2D(0, 0);
|
||||||
|
|
||||||
// this is the real position and size used to draw the thing
|
// this is the real position and size used to draw the thing
|
||||||
PHLANIMVAR<Vector2D> m_vRealPosition;
|
CAnimatedVariable<Vector2D> m_vRealPosition;
|
||||||
PHLANIMVAR<Vector2D> m_vRealSize;
|
CAnimatedVariable<Vector2D> m_vRealSize;
|
||||||
|
|
||||||
// for not spamming the protocols
|
// for not spamming the protocols
|
||||||
Vector2D m_vReportedPosition;
|
Vector2D m_vReportedPosition;
|
||||||
@@ -263,13 +270,13 @@ class CWindow {
|
|||||||
bool m_bIsFloating = false;
|
bool m_bIsFloating = false;
|
||||||
bool m_bDraggingTiled = false; // for dragging around tiled windows
|
bool m_bDraggingTiled = false; // for dragging around tiled windows
|
||||||
bool m_bWasMaximized = false;
|
bool m_bWasMaximized = false;
|
||||||
SFullscreenState m_sFullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE};
|
sFullscreenState m_sFullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE};
|
||||||
|
MONITORID m_iMonitorID = -1;
|
||||||
std::string m_szTitle = "";
|
std::string m_szTitle = "";
|
||||||
std::string m_szClass = "";
|
std::string m_szClass = "";
|
||||||
std::string m_szInitialTitle = "";
|
std::string m_szInitialTitle = "";
|
||||||
std::string m_szInitialClass = "";
|
std::string m_szInitialClass = "";
|
||||||
PHLWORKSPACE m_pWorkspace;
|
PHLWORKSPACE m_pWorkspace;
|
||||||
PHLMONITORREF m_pMonitor;
|
|
||||||
|
|
||||||
bool m_bIsMapped = false;
|
bool m_bIsMapped = false;
|
||||||
|
|
||||||
@@ -281,6 +288,8 @@ class CWindow {
|
|||||||
// XWayland stuff
|
// XWayland stuff
|
||||||
bool m_bIsX11 = false;
|
bool m_bIsX11 = false;
|
||||||
PHLWINDOWREF m_pX11Parent;
|
PHLWINDOWREF m_pX11Parent;
|
||||||
|
uint64_t m_iX11Type = 0;
|
||||||
|
bool m_bIsModal = false;
|
||||||
bool m_bX11DoesntWantBorders = false;
|
bool m_bX11DoesntWantBorders = false;
|
||||||
bool m_bX11ShouldntFocus = false;
|
bool m_bX11ShouldntFocus = false;
|
||||||
float m_fX11SurfaceScaledBy = 1.f;
|
float m_fX11SurfaceScaledBy = 1.f;
|
||||||
@@ -290,37 +299,33 @@ class CWindow {
|
|||||||
bool m_bNoInitialFocus = false;
|
bool m_bNoInitialFocus = false;
|
||||||
|
|
||||||
// Fullscreen and Maximize
|
// Fullscreen and Maximize
|
||||||
bool m_bWantsInitialFullscreen = false;
|
bool m_bWantsInitialFullscreen = false;
|
||||||
MONITORID m_iWantsInitialFullscreenMonitor = MONITOR_INVALID;
|
|
||||||
|
|
||||||
// bitfield eSuppressEvents
|
// bitfield eSuppressEvents
|
||||||
uint64_t m_eSuppressedEvents = SUPPRESS_NONE;
|
uint64_t m_eSuppressedEvents = SUPPRESS_NONE;
|
||||||
|
|
||||||
// desktop components
|
// desktop components
|
||||||
UP<CSubsurface> m_pSubsurfaceHead;
|
std::unique_ptr<CSubsurface> m_pSubsurfaceHead;
|
||||||
UP<CPopup> m_pPopupHead;
|
std::unique_ptr<CPopup> m_pPopupHead;
|
||||||
|
|
||||||
// Animated border
|
// Animated border
|
||||||
CGradientValueData m_cRealBorderColor = {0};
|
CGradientValueData m_cRealBorderColor = {0};
|
||||||
CGradientValueData m_cRealBorderColorPrevious = {0};
|
CGradientValueData m_cRealBorderColorPrevious = {0};
|
||||||
PHLANIMVAR<float> m_fBorderFadeAnimationProgress;
|
CAnimatedVariable<float> m_fBorderFadeAnimationProgress;
|
||||||
PHLANIMVAR<float> m_fBorderAngleAnimationProgress;
|
CAnimatedVariable<float> m_fBorderAngleAnimationProgress;
|
||||||
|
|
||||||
// Fade in-out
|
// Fade in-out
|
||||||
PHLANIMVAR<float> m_fAlpha;
|
CAnimatedVariable<float> m_fAlpha;
|
||||||
bool m_bFadingOut = false;
|
bool m_bFadingOut = false;
|
||||||
bool m_bReadyToDelete = false;
|
bool m_bReadyToDelete = false;
|
||||||
Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in
|
Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in
|
||||||
Vector2D m_vOriginalClosedSize; // drawing the closing animations
|
Vector2D m_vOriginalClosedSize; // drawing the closing animations
|
||||||
SBoxExtents m_eOriginalClosedExtents;
|
SBoxExtents m_eOriginalClosedExtents;
|
||||||
bool m_bAnimatingIn = false;
|
bool m_bAnimatingIn = false;
|
||||||
|
|
||||||
// For pinned (sticky) windows
|
// For pinned (sticky) windows
|
||||||
bool m_bPinned = false;
|
bool m_bPinned = false;
|
||||||
|
|
||||||
// For preserving pinned state when fullscreening a pinned window
|
|
||||||
bool m_bPinFullscreened = false;
|
|
||||||
|
|
||||||
// urgency hint
|
// urgency hint
|
||||||
bool m_bIsUrgent = false;
|
bool m_bIsUrgent = false;
|
||||||
|
|
||||||
@@ -329,32 +334,26 @@ class CWindow {
|
|||||||
|
|
||||||
// Window decorations
|
// Window decorations
|
||||||
// TODO: make this a SP.
|
// TODO: make this a SP.
|
||||||
std::vector<UP<IHyprWindowDecoration>> m_dWindowDecorations;
|
std::deque<std::unique_ptr<IHyprWindowDecoration>> m_dWindowDecorations;
|
||||||
std::vector<IHyprWindowDecoration*> m_vDecosToRemove;
|
std::vector<IHyprWindowDecoration*> m_vDecosToRemove;
|
||||||
|
|
||||||
// Special render data, rules, etc
|
// Special render data, rules, etc
|
||||||
SWindowData m_sWindowData;
|
SWindowData m_sWindowData;
|
||||||
|
|
||||||
// Transformers
|
// Transformers
|
||||||
std::vector<UP<IWindowTransformer>> m_vTransformers;
|
std::vector<std::unique_ptr<IWindowTransformer>> m_vTransformers;
|
||||||
|
|
||||||
// for alpha
|
// for alpha
|
||||||
PHLANIMVAR<float> m_fActiveInactiveAlpha;
|
CAnimatedVariable<float> m_fActiveInactiveAlpha;
|
||||||
PHLANIMVAR<float> m_fMovingFromWorkspaceAlpha;
|
|
||||||
|
|
||||||
// animated shadow color
|
// animated shadow color
|
||||||
PHLANIMVAR<CHyprColor> m_cRealShadowColor;
|
CAnimatedVariable<CColor> m_cRealShadowColor;
|
||||||
|
|
||||||
// animated tint
|
// 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;
|
|
||||||
|
|
||||||
// swallowing
|
// swallowing
|
||||||
PHLWINDOWREF m_pSwallowed;
|
PHLWINDOWREF m_pSwallowed;
|
||||||
bool m_bGroupSwallowed = false;
|
|
||||||
|
|
||||||
// focus stuff
|
// focus stuff
|
||||||
bool m_bStayFocused = false;
|
bool m_bStayFocused = false;
|
||||||
@@ -381,13 +380,13 @@ class CWindow {
|
|||||||
bool m_bTearingHint = false;
|
bool m_bTearingHint = false;
|
||||||
|
|
||||||
// stores the currently matched window rules
|
// stores the currently matched window rules
|
||||||
std::vector<SP<CWindowRule>> m_vMatchedRules;
|
std::vector<SWindowRule> m_vMatchedRules;
|
||||||
|
|
||||||
// window tags
|
// window tags
|
||||||
CTagKeeper m_tags;
|
CTagKeeper m_tags;
|
||||||
|
|
||||||
// For the list lookup
|
// For the list lookup
|
||||||
bool operator==(const CWindow& rhs) const {
|
bool operator==(const CWindow& rhs) {
|
||||||
return m_pXDGSurface == rhs.m_pXDGSurface && m_pXWaylandSurface == rhs.m_pXWaylandSurface && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize &&
|
return m_pXDGSurface == rhs.m_pXDGSurface && m_pXWaylandSurface == rhs.m_pXWaylandSurface && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize &&
|
||||||
m_bFadingOut == rhs.m_bFadingOut;
|
m_bFadingOut == rhs.m_bFadingOut;
|
||||||
}
|
}
|
||||||
@@ -396,49 +395,50 @@ class CWindow {
|
|||||||
CBox getFullWindowBoundingBox();
|
CBox getFullWindowBoundingBox();
|
||||||
SBoxExtents getFullWindowExtents();
|
SBoxExtents getFullWindowExtents();
|
||||||
CBox getWindowBoxUnified(uint64_t props);
|
CBox getWindowBoxUnified(uint64_t props);
|
||||||
|
CBox getWindowMainSurfaceBox();
|
||||||
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
||||||
void addWindowDeco(UP<IHyprWindowDecoration> deco);
|
void addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco);
|
||||||
void updateWindowDecos();
|
void updateWindowDecos();
|
||||||
void removeWindowDeco(IHyprWindowDecoration* deco);
|
void removeWindowDeco(IHyprWindowDecoration* deco);
|
||||||
void uncacheWindowDecos();
|
void uncacheWindowDecos();
|
||||||
bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {});
|
bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {});
|
||||||
pid_t getPID();
|
pid_t getPID();
|
||||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||||
|
void removeDecorationByType(eDecorationType);
|
||||||
void updateToplevel();
|
void updateToplevel();
|
||||||
void updateSurfaceScaleTransformDetails(bool force = false);
|
void updateSurfaceScaleTransformDetails(bool force = false);
|
||||||
void moveToWorkspace(PHLWORKSPACE);
|
void moveToWorkspace(PHLWORKSPACE);
|
||||||
PHLWINDOW x11TransientFor();
|
PHLWINDOW X11TransientFor();
|
||||||
void onUnmap();
|
void onUnmap();
|
||||||
void onMap();
|
void onMap();
|
||||||
void setHidden(bool hidden);
|
void setHidden(bool hidden);
|
||||||
bool isHidden();
|
bool isHidden();
|
||||||
void applyDynamicRule(const SP<CWindowRule>& r);
|
void applyDynamicRule(const SWindowRule& r);
|
||||||
void updateDynamicRules();
|
void updateDynamicRules();
|
||||||
SBoxExtents getFullWindowReservedArea();
|
SBoxExtents getFullWindowReservedArea();
|
||||||
Vector2D middle();
|
Vector2D middle();
|
||||||
bool opaque();
|
bool opaque();
|
||||||
float rounding();
|
float rounding();
|
||||||
float roundingPower();
|
|
||||||
bool canBeTorn();
|
bool canBeTorn();
|
||||||
void setSuspended(bool suspend);
|
void setSuspended(bool suspend);
|
||||||
bool visibleOnMonitor(PHLMONITOR pMonitor);
|
bool visibleOnMonitor(CMonitor* pMonitor);
|
||||||
WORKSPACEID workspaceID();
|
WORKSPACEID workspaceID();
|
||||||
MONITORID monitorID();
|
|
||||||
bool onSpecialWorkspace();
|
bool onSpecialWorkspace();
|
||||||
void activate(bool force = false);
|
void activate(bool force = false);
|
||||||
int surfacesCount();
|
int surfacesCount();
|
||||||
void clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize);
|
|
||||||
bool isFullscreen();
|
bool isFullscreen();
|
||||||
bool isEffectiveInternalFSMode(const eFullscreenMode);
|
bool isEffectiveInternalFSMode(const eFullscreenMode);
|
||||||
|
|
||||||
int getRealBorderSize();
|
int getRealBorderSize();
|
||||||
float getScrollMouse();
|
|
||||||
float getScrollTouchpad();
|
|
||||||
void updateWindowData();
|
void updateWindowData();
|
||||||
void updateWindowData(const struct SWorkspaceRule&);
|
void updateWindowData(const struct SWorkspaceRule&);
|
||||||
void onBorderAngleAnimEnd(WP<Hyprutils::Animation::CBaseAnimatedVariable> pav);
|
|
||||||
|
void onBorderAngleAnimEnd(void* ptr);
|
||||||
bool isInCurvedCorner(double x, double y);
|
bool isInCurvedCorner(double x, double y);
|
||||||
bool hasPopupAt(const Vector2D& pos);
|
bool hasPopupAt(const Vector2D& pos);
|
||||||
int popupsCount();
|
int popupsCount();
|
||||||
|
|
||||||
void applyGroupRules();
|
void applyGroupRules();
|
||||||
void createGroup();
|
void createGroup();
|
||||||
void destroyGroup();
|
void destroyGroup();
|
||||||
@@ -455,25 +455,15 @@ class CWindow {
|
|||||||
void switchWithWindowInGroup(PHLWINDOW pWindow);
|
void switchWithWindowInGroup(PHLWINDOW pWindow);
|
||||||
void setAnimationsToMove();
|
void setAnimationsToMove();
|
||||||
void onWorkspaceAnimUpdate();
|
void onWorkspaceAnimUpdate();
|
||||||
void onFocusAnimUpdate();
|
|
||||||
void onUpdateState();
|
void onUpdateState();
|
||||||
void onUpdateMeta();
|
void onUpdateMeta();
|
||||||
void onX11Configure(CBox box);
|
void onX11Configure(CBox box);
|
||||||
void onResourceChangeX11();
|
void onResourceChangeX11();
|
||||||
std::string fetchTitle();
|
std::string fetchTitle();
|
||||||
std::string fetchClass();
|
std::string fetchClass();
|
||||||
void warpCursor(bool force = false);
|
void warpCursor();
|
||||||
PHLWINDOW getSwallower();
|
PHLWINDOW getSwallower();
|
||||||
void unsetWindowData(eOverridePriority priority);
|
void unsetWindowData(eOverridePriority priority);
|
||||||
bool isX11OverrideRedirect();
|
|
||||||
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};
|
|
||||||
}
|
|
||||||
|
|
||||||
// listeners
|
// listeners
|
||||||
void onAck(uint32_t serial);
|
void onAck(uint32_t serial);
|
||||||
@@ -560,7 +550,7 @@ struct std::formatter<PHLWINDOW, CharT> : std::formatter<CharT> {
|
|||||||
if (formatWorkspace)
|
if (formatWorkspace)
|
||||||
std::format_to(out, ", workspace: {}", w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID);
|
std::format_to(out, ", workspace: {}", w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID);
|
||||||
if (formatMonitor)
|
if (formatMonitor)
|
||||||
std::format_to(out, ", monitor: {}", w->monitorID());
|
std::format_to(out, ", monitor: {}", w->m_iMonitorID);
|
||||||
if (formatClass)
|
if (formatClass)
|
||||||
std::format_to(out, ", class: {}", w->m_szClass);
|
std::format_to(out, ", class: {}", w->m_szClass);
|
||||||
return std::format_to(out, "]");
|
return std::format_to(out, "]");
|
||||||
|
@@ -1,91 +0,0 @@
|
|||||||
#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>{
|
|
||||||
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused",
|
|
||||||
};
|
|
||||||
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",
|
|
||||||
};
|
|
||||||
|
|
||||||
CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool isV2, bool isExecRule) : szValue(value), szRule(rule), v2(isV2), execRule(isExecRule) {
|
|
||||||
const auto VALS = CVarList(rule, 2, ' ');
|
|
||||||
const bool VALID = RULES.contains(rule) || std::any_of(RULES_PREFIX.begin(), RULES_PREFIX.end(), [&rule](auto prefix) { return rule.starts_with(prefix); }) ||
|
|
||||||
(g_pConfigManager->mbWindowProperties.find(VALS[0]) != g_pConfigManager->mbWindowProperties.end()) ||
|
|
||||||
(g_pConfigManager->miWindowProperties.find(VALS[0]) != g_pConfigManager->miWindowProperties.end()) ||
|
|
||||||
(g_pConfigManager->mfWindowProperties.find(VALS[0]) != g_pConfigManager->mfWindowProperties.end());
|
|
||||||
|
|
||||||
if (!VALID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (rule == "float")
|
|
||||||
ruleType = RULE_FLOAT;
|
|
||||||
else if (rule == "fullscreen")
|
|
||||||
ruleType = RULE_FULLSCREEN;
|
|
||||||
else if (rule == "maximize")
|
|
||||||
ruleType = RULE_MAXIMIZE;
|
|
||||||
else if (rule == "noinitialfocus")
|
|
||||||
ruleType = RULE_NOINITIALFOCUS;
|
|
||||||
else if (rule == "pin")
|
|
||||||
ruleType = RULE_PIN;
|
|
||||||
else if (rule == "stayfocused")
|
|
||||||
ruleType = RULE_STAYFOCUSED;
|
|
||||||
else if (rule == "tile")
|
|
||||||
ruleType = RULE_TILE;
|
|
||||||
else if (rule == "renderunfocused")
|
|
||||||
ruleType = RULE_RENDERUNFOCUSED;
|
|
||||||
else if (rule.starts_with("animation"))
|
|
||||||
ruleType = RULE_ANIMATION;
|
|
||||||
else if (rule.starts_with("bordercolor"))
|
|
||||||
ruleType = RULE_BORDERCOLOR;
|
|
||||||
else if (rule.starts_with("center"))
|
|
||||||
ruleType = RULE_CENTER;
|
|
||||||
else if (rule.starts_with("fullscreenstate"))
|
|
||||||
ruleType = RULE_FULLSCREENSTATE;
|
|
||||||
else if (rule.starts_with("group"))
|
|
||||||
ruleType = RULE_GROUP;
|
|
||||||
else if (rule.starts_with("idleinhibit"))
|
|
||||||
ruleType = RULE_IDLEINHIBIT;
|
|
||||||
else if (rule.starts_with("maxsize"))
|
|
||||||
ruleType = RULE_MAXSIZE;
|
|
||||||
else if (rule.starts_with("minsize"))
|
|
||||||
ruleType = RULE_MINSIZE;
|
|
||||||
else if (rule.starts_with("monitor"))
|
|
||||||
ruleType = RULE_MONITOR;
|
|
||||||
else if (rule.starts_with("move"))
|
|
||||||
ruleType = RULE_MOVE;
|
|
||||||
else if (rule.starts_with("opacity"))
|
|
||||||
ruleType = RULE_OPACITY;
|
|
||||||
else if (rule.starts_with("plugin:"))
|
|
||||||
ruleType = RULE_PLUGIN;
|
|
||||||
else if (rule.starts_with("pseudo"))
|
|
||||||
ruleType = RULE_PSEUDO;
|
|
||||||
else if (rule.starts_with("size"))
|
|
||||||
ruleType = RULE_SIZE;
|
|
||||||
else if (rule.starts_with("suppressevent"))
|
|
||||||
ruleType = RULE_SUPPRESSEVENT;
|
|
||||||
else if (rule.starts_with("tag"))
|
|
||||||
ruleType = RULE_TAG;
|
|
||||||
else if (rule.starts_with("workspace"))
|
|
||||||
ruleType = RULE_WORKSPACE;
|
|
||||||
else if (rule.starts_with("prop"))
|
|
||||||
ruleType = RULE_PROP;
|
|
||||||
else {
|
|
||||||
// check if this is a prop.
|
|
||||||
const CVarList VARS(rule, 0, 's', true);
|
|
||||||
if (g_pConfigManager->miWindowProperties.find(VARS[0]) != g_pConfigManager->miWindowProperties.end() ||
|
|
||||||
g_pConfigManager->mbWindowProperties.find(VARS[0]) != g_pConfigManager->mbWindowProperties.end() ||
|
|
||||||
g_pConfigManager->mfWindowProperties.find(VARS[0]) != g_pConfigManager->mfWindowProperties.end()) {
|
|
||||||
*const_cast<std::string*>(&szRule) = "prop " + rule;
|
|
||||||
ruleType = RULE_PROP;
|
|
||||||
Debug::log(LOG, "CWindowRule: direct prop rule found, rewritten {} -> {}", rule, szRule);
|
|
||||||
} else {
|
|
||||||
Debug::log(ERR, "CWindowRule: didn't match a rule that was found valid?!");
|
|
||||||
ruleType = RULE_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|