mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-02 05:01:56 -07:00
Compare commits
100 Commits
v0.2.2beta
...
v0.5.0beta
Author | SHA1 | Date | |
---|---|---|---|
|
dc5cc15474 | ||
|
3a2ac11e3e | ||
|
90a859af27 | ||
|
c6953329d5 | ||
|
c451e13e4f | ||
|
d68e09a707 | ||
|
b4de91111a | ||
|
750961e9c1 | ||
|
b5a446ddfd | ||
|
fbc7853459 | ||
|
53146ccf69 | ||
|
506977c13d | ||
|
09b130374d | ||
|
b53c093b88 | ||
|
8929172bc2 | ||
|
6317f64ba0 | ||
|
824d8b954d | ||
|
49fc1ccdb4 | ||
|
c218ed4432 | ||
|
f97b90859a | ||
|
1841d244f0 | ||
|
47404534d0 | ||
|
b7e21d0fa9 | ||
|
90024e534d | ||
|
248ce66459 | ||
|
638b44cabd | ||
|
8f0b963729 | ||
|
7b73570f11 | ||
|
a0f3fc794e | ||
|
263664c58a | ||
|
da80eb8e57 | ||
|
0b8fe2a0aa | ||
|
1642b1ff66 | ||
|
7b9583c1f2 | ||
|
cc80b68545 | ||
|
2bddfa81bc | ||
|
85d91c3d3c | ||
|
d80c90233b | ||
|
d0ca043122 | ||
|
92da453d4d | ||
|
433e4a0eef | ||
|
b62e530fdb | ||
|
663fba76ae | ||
|
d73e05cc68 | ||
|
066ea296ff | ||
|
72c967aa89 | ||
|
c474e8253a | ||
|
20936ad2a4 | ||
|
d743ac7bb1 | ||
|
322a495412 | ||
|
63d6c594b9 | ||
|
09e77bf844 | ||
|
3d4832990c | ||
|
84a0fa0f34 | ||
|
2cd2f8b5b5 | ||
|
172d6cd498 | ||
|
02269af777 | ||
|
e2592522d3 | ||
|
d76c982d2e | ||
|
ef855440c6 | ||
|
246aa000f5 | ||
|
1a93b2a756 | ||
|
10c2bd0686 | ||
|
f99ad521a4 | ||
|
9486a230c7 | ||
|
6f3b004199 | ||
|
19b17b590c | ||
|
f9c8a72e46 | ||
|
e11cb8b328 | ||
|
7b568d7ad8 | ||
|
a2f718059b | ||
|
feb0499597 | ||
|
601abc7e92 | ||
|
7451890fd7 | ||
|
f5cdb5b95e | ||
|
7afcf656bd | ||
|
6daa866beb | ||
|
9447fcd603 | ||
|
9acf15efd7 | ||
|
b5a100379e | ||
|
4f76d5d8d7 | ||
|
8d850b0ce1 | ||
|
0f28d2ae55 | ||
|
d2451aea4b | ||
|
680705ff91 | ||
|
300fc2ab0f | ||
|
02210d3d96 | ||
|
879345c1e9 | ||
|
1e3bea5e70 | ||
|
f64cae2b7f | ||
|
c433b14e3d | ||
|
8d1c495878 | ||
|
4264a0b08d | ||
|
40ab062a3c | ||
|
35bcea38e3 | ||
|
1ccb944509 | ||
|
c600249aee | ||
|
6d6e967a8d | ||
|
f6b8a96621 | ||
|
8e8d5a99c2 |
12
.github/ISSUE_TEMPLATE/bug_report.md
vendored
12
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -7,12 +7,6 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Describe the bug**
|
Please consult the issue guidelines at
|
||||||
|
https://github.com/vaxerski/Hyprland/blob/main/docs/ISSUE_GUIDELINES.md
|
||||||
|
BEFORE submitting.
|
||||||
**Images/videos/anything that would help**
|
|
||||||
|
|
||||||
|
|
||||||
Please attach a log (it's in /tmp/hypr/hyprland.log) and, if crashing, a crashdump (coredumpctl, then coredumpctl info <pid>)
|
|
||||||
|
|
||||||
*Please do NOT attach coredumps from any packaged version of Hyprland (AUR, etc.). Compile manually, and THEN attach a coredump of that.*
|
|
||||||
|
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -7,4 +7,6 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Describe in detail your idea.**
|
Please consult the issue guidelines at
|
||||||
|
https://github.com/vaxerski/Hyprland/blob/main/docs/ISSUE_GUIDELINES.md
|
||||||
|
BEFORE submitting.
|
||||||
|
7
.github/workflows/nix-update.yaml
vendored
7
.github/workflows/nix-update.yaml
vendored
@@ -1,9 +1,6 @@
|
|||||||
name: "Nix: update lockfile"
|
name: "Nix: update lockfile"
|
||||||
|
|
||||||
on:
|
on: [push, workflow_dispatch]
|
||||||
schedule:
|
|
||||||
- cron: '0 0 */14 * *'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update:
|
update:
|
||||||
@@ -19,7 +16,7 @@ jobs:
|
|||||||
auto-optimise-store = true
|
auto-optimise-store = true
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
- name: Update lockfile
|
- name: Update lockfile
|
||||||
run: nix flake update
|
run: nix/update-inputs.sh
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
with:
|
with:
|
||||||
commit_message: "[gha] bump flake inputs"
|
commit_message: "[gha] bump flake inputs"
|
||||||
|
12
Makefile
12
Makefile
@@ -59,6 +59,16 @@ pointer-constraints-unstable-v1-protocol.c:
|
|||||||
|
|
||||||
pointer-constraints-unstable-v1-protocol.o: pointer-constraints-unstable-v1-protocol.h
|
pointer-constraints-unstable-v1-protocol.o: pointer-constraints-unstable-v1-protocol.h
|
||||||
|
|
||||||
|
tablet-unstable-v2-protocol.h:
|
||||||
|
$(WAYLAND_SCANNER) server-header \
|
||||||
|
protocols/tablet-unstable-v2.xml $@
|
||||||
|
|
||||||
|
tablet-unstable-v2-protocol.c:
|
||||||
|
$(WAYLAND_SCANNER) private-code \
|
||||||
|
protocols/tablet-unstable-v2.xml $@
|
||||||
|
|
||||||
|
tablet-unstable-v2-protocol.o: tablet-unstable-v2-protocol.h
|
||||||
|
|
||||||
idle-protocol.h:
|
idle-protocol.h:
|
||||||
$(WAYLAND_SCANNER) server-header \
|
$(WAYLAND_SCANNER) server-header \
|
||||||
protocols/idle.xml $@
|
protocols/idle.xml $@
|
||||||
@@ -114,7 +124,7 @@ uninstall:
|
|||||||
rm -f ${PREFIX}/bin/hyprctl
|
rm -f ${PREFIX}/bin/hyprctl
|
||||||
rm -rf ${PREFIX}/share/hyprland
|
rm -rf ${PREFIX}/share/hyprland
|
||||||
|
|
||||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o
|
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o
|
||||||
|
|
||||||
config:
|
config:
|
||||||
make protocols
|
make protocols
|
||||||
|
23
README.md
23
README.md
@@ -37,10 +37,9 @@ For Hyprland without the `land` part, see [Hypr], the Xorg window manager.
|
|||||||
|
|
||||||
# Notice
|
# Notice
|
||||||
|
|
||||||
This project is still in its early development, expect bugs.
|
Hyprland is still in pretty early development compared to some other Wayland compositors.
|
||||||
|
|
||||||
Once you get it working though, it's pretty stable.<br/>
|
|
||||||
|
|
||||||
|
Although Hyprland is pretty stable, it may have some bugs.
|
||||||
|
|
||||||
### Help Wanted
|
### Help Wanted
|
||||||
|
|
||||||
@@ -52,18 +51,22 @@ Try it out and report bugs / suggestions!
|
|||||||
- Easily expandable and readable codebase
|
- Easily expandable and readable codebase
|
||||||
- Config reloaded instantly upon saving
|
- Config reloaded instantly upon saving
|
||||||
- Custom bezier curve based animations
|
- Custom bezier curve based animations
|
||||||
- wlr_ext workspaces protocol support
|
- `wlr_ext` workspaces protocol support
|
||||||
- Dual Kawase blur
|
- Dual Kawase blur
|
||||||
- Fully dynamic workspaces
|
- Fully dynamic workspaces
|
||||||
- Window / layer fade in / out
|
- Closely follows `wlroots-git`
|
||||||
- Tiling / floating / fullscreen windows
|
- Bundled wlroots
|
||||||
- Special Workspace (Scratchpad)
|
- Window/layer fade in/out
|
||||||
- Window / monitor rules
|
- Tiling/pseudotiling/floating/fullscreen windows
|
||||||
|
- Switching workspaces between window modes on the fly
|
||||||
|
- Special workspace (scratchpad)
|
||||||
|
- Window/monitor rules
|
||||||
- Socket-based IPC
|
- Socket-based IPC
|
||||||
- Event System for bash scripts
|
- Event system for bash scripts
|
||||||
- Rounded corners
|
- Rounded corners
|
||||||
- Full Damage tracking
|
- Full damage tracking
|
||||||
- Docks support
|
- Docks support
|
||||||
|
- Drawing tablet support
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
50
aur/PKGBUILD
50
aur/PKGBUILD
@@ -2,20 +2,60 @@
|
|||||||
|
|
||||||
_pkgname="hyprland"
|
_pkgname="hyprland"
|
||||||
pkgname="${_pkgname}"
|
pkgname="${_pkgname}"
|
||||||
pkgver="0.1.1beta"
|
pkgver="0.4.0beta"
|
||||||
pkgrel=2
|
pkgrel=2
|
||||||
pkgdesc="Hyprland is a dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
|
pkgdesc="A dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
|
||||||
arch=(any)
|
arch=(any)
|
||||||
url="https://github.com/vaxerski/Hyprland"
|
url="https://github.com/vaxerski/Hyprland"
|
||||||
license=('BSD')
|
license=('BSD')
|
||||||
depends=(libxcb xcb-proto xcb-util xcb-util-keysyms libxfixes libx11 libxcomposite xorg-xinput libxrender pixman wayland-protocols wlroots-git cairo pango)
|
depends=(
|
||||||
makedepends=(git cmake ninja gcc gdb)
|
libxcb
|
||||||
|
xcb-proto
|
||||||
|
xcb-util
|
||||||
|
xcb-util-keysyms
|
||||||
|
libxfixes
|
||||||
|
libx11
|
||||||
|
libxcomposite
|
||||||
|
xorg-xinput
|
||||||
|
libxrender
|
||||||
|
pixman
|
||||||
|
wayland-protocols
|
||||||
|
cairo
|
||||||
|
pango
|
||||||
|
polkit
|
||||||
|
glslang
|
||||||
|
libinput
|
||||||
|
libxcb
|
||||||
|
libxkbcommon
|
||||||
|
opengl-driver
|
||||||
|
pixman
|
||||||
|
wayland
|
||||||
|
xcb-util-errors
|
||||||
|
xcb-util-renderutil
|
||||||
|
xcb-util-wm
|
||||||
|
seatd
|
||||||
|
vulkan-icd-loader
|
||||||
|
vulkan-validation-layers
|
||||||
|
xorg-xwayland)
|
||||||
|
makedepends=(
|
||||||
|
git
|
||||||
|
cmake
|
||||||
|
ninja
|
||||||
|
gcc
|
||||||
|
gdb
|
||||||
|
meson
|
||||||
|
vulkan-headers
|
||||||
|
wayland-protocols
|
||||||
|
xorgproto)
|
||||||
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/vaxerski/hyprland/archive/v${pkgver}.tar.gz")
|
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/vaxerski/hyprland/archive/v${pkgver}.tar.gz")
|
||||||
sha256sums=('SKIP')
|
sha256sums=('5969e5f88426f90acdfb5958644733d8a9409389c2d345514c58a66cf74d2f91')
|
||||||
|
conflicts=("${_pkgname}")
|
||||||
|
provides=(hyprland)
|
||||||
options=(!makeflags !buildflags)
|
options=(!makeflags !buildflags)
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
cd "$srcdir/Hyprland-$pkgver"
|
cd "$srcdir/Hyprland-$pkgver"
|
||||||
|
git submodule update --init
|
||||||
make all
|
make all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
56
aur/PKGBUILD-bin
Normal file
56
aur/PKGBUILD-bin
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# Maintainer: ThatOneCalculator <kainoa@t1c.dev>
|
||||||
|
|
||||||
|
_pkgname="hyprland"
|
||||||
|
pkgname="${_pkgname}-bin"
|
||||||
|
pkgver="0.4.0beta"
|
||||||
|
pkgrel=2
|
||||||
|
pkgdesc="A dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
|
||||||
|
arch=(any)
|
||||||
|
url="https://github.com/vaxerski/Hyprland"
|
||||||
|
license=('BSD')
|
||||||
|
depends=(
|
||||||
|
libxcb
|
||||||
|
xcb-proto
|
||||||
|
xcb-util
|
||||||
|
xcb-util-keysyms
|
||||||
|
libxfixes
|
||||||
|
libx11
|
||||||
|
libxcomposite
|
||||||
|
xorg-xinput
|
||||||
|
libxrender
|
||||||
|
pixman
|
||||||
|
wayland-protocols
|
||||||
|
cairo
|
||||||
|
pango
|
||||||
|
polkit
|
||||||
|
glslang
|
||||||
|
libinput
|
||||||
|
libxcb
|
||||||
|
libxkbcommon
|
||||||
|
opengl-driver
|
||||||
|
pixman
|
||||||
|
wayland
|
||||||
|
xcb-util-errors
|
||||||
|
xcb-util-renderutil
|
||||||
|
xcb-util-wm
|
||||||
|
seatd
|
||||||
|
vulkan-icd-loader
|
||||||
|
vulkan-validation-layers
|
||||||
|
xorg-xwayland)
|
||||||
|
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/vaxerski/Hyprland/releases/download/v${pkgver}/v${pkgver}.tar.gz")
|
||||||
|
sha256sums=('5969e5f88426f90acdfb5958644733d8a9409389c2d345514c58a66cf74d2f91')
|
||||||
|
conflicts=("${_pkgname}")
|
||||||
|
provides=(hyprland)
|
||||||
|
|
||||||
|
package() {
|
||||||
|
cd "$srcdir/Hyprland-$pkgver"
|
||||||
|
mkdir -p "${pkgdir}/usr/share/wayland-sessions"
|
||||||
|
mkdir -p "${pkgdir}/usr/share/hyprland"
|
||||||
|
install -Dm755 ./Hyprland -t "${pkgdir}/usr/bin"
|
||||||
|
install -Dm755 ./hyprctl -t "${pkgdir}/usr/bin"
|
||||||
|
install -Dm755 ./libwlroots.so.11032 -t "${pkgdir}/usr/lib"
|
||||||
|
install -Dm644 assets/*.png -t "${pkgdir}/usr/share/hyprland"
|
||||||
|
install -Dm644 example/hyprland.desktop -t "${pkgdir}/usr/share/wayland-sessions"
|
||||||
|
install -Dm644 example/hyprland.conf -t "${pkgdir}/usr/share/hyprland"
|
||||||
|
install -Dm644 LICENSE -t "${pkgdir}/usr/share/licenses/${_pkgname}"
|
||||||
|
}
|
@@ -2,15 +2,54 @@
|
|||||||
|
|
||||||
_pkgname="hyprland"
|
_pkgname="hyprland"
|
||||||
pkgname="${_pkgname}-git"
|
pkgname="${_pkgname}-git"
|
||||||
pkgver=r568.g632d00c
|
pkgver=r673.gb62e530
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="Hyprland is a dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
|
pkgdesc="A dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
|
||||||
arch=(any)
|
arch=(any)
|
||||||
url="https://github.com/vaxerski/Hyprland"
|
url="https://github.com/vaxerski/Hyprland"
|
||||||
license=('BSD')
|
license=('BSD')
|
||||||
depends=(libxcb xcb-proto xcb-util xcb-util-keysyms libxfixes libx11 libxcomposite xorg-xinput libxrender pixman wayland-protocols wlroots-git cairo pango)
|
depends=(
|
||||||
makedepends=(git cmake ninja gcc gdb)
|
libxcb
|
||||||
|
xcb-proto
|
||||||
|
xcb-util
|
||||||
|
xcb-util-keysyms
|
||||||
|
libxfixes
|
||||||
|
libx11
|
||||||
|
libxcomposite
|
||||||
|
xorg-xinput
|
||||||
|
libxrender
|
||||||
|
pixman
|
||||||
|
wayland-protocols
|
||||||
|
cairo
|
||||||
|
pango
|
||||||
|
polkit
|
||||||
|
glslang
|
||||||
|
libinput
|
||||||
|
libxcb
|
||||||
|
libxkbcommon
|
||||||
|
opengl-driver
|
||||||
|
pixman
|
||||||
|
wayland
|
||||||
|
xcb-util-errors
|
||||||
|
xcb-util-renderutil
|
||||||
|
xcb-util-wm
|
||||||
|
seatd
|
||||||
|
vulkan-icd-loader
|
||||||
|
vulkan-validation-layers
|
||||||
|
xorg-xwayland)
|
||||||
|
makedepends=(
|
||||||
|
git
|
||||||
|
cmake
|
||||||
|
ninja
|
||||||
|
gcc
|
||||||
|
gdb
|
||||||
|
meson
|
||||||
|
vulkan-headers
|
||||||
|
wayland-protocols
|
||||||
|
xorgproto)
|
||||||
source=("${_pkgname}::git+https://github.com/vaxerski/Hyprland.git")
|
source=("${_pkgname}::git+https://github.com/vaxerski/Hyprland.git")
|
||||||
|
conflicts=("${_pkgname}")
|
||||||
|
provides=(hyprland)
|
||||||
sha256sums=('SKIP')
|
sha256sums=('SKIP')
|
||||||
options=(!makeflags !buildflags)
|
options=(!makeflags !buildflags)
|
||||||
|
|
||||||
@@ -24,6 +63,7 @@ pkgver() {
|
|||||||
|
|
||||||
build() {
|
build() {
|
||||||
cd "${srcdir}/${_pkgname}"
|
cd "${srcdir}/${_pkgname}"
|
||||||
|
git submodule update --init
|
||||||
make all
|
make all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
# Contributing
|
|
||||||
|
|
||||||
*Thank you for considering contributing to Hyprland.*
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
Check the [Wiki] for debugging instructions.
|
|
||||||
|
|
||||||
Afterwards, pick yourself an [Issue] or implement your own suggestion.
|
|
||||||
|
|
||||||
An good place to search for things to contribute is the [Projects Page]
|
|
||||||
|
|
||||||
*As Hyprland is still in its early stages of development, I'd recommend you stick to bug fixes first.*
|
|
||||||
|
|
||||||
## Pull Requests
|
|
||||||
|
|
||||||
- Please follow the code style
|
|
||||||
|
|
||||||
- Code must be readable
|
|
||||||
|
|
||||||
- Features should be useful
|
|
||||||
|
|
||||||
- Test your changes!
|
|
||||||
|
|
||||||
*Run it on bare metal and check if everything works.*
|
|
||||||
|
|
||||||
<!----------------------------------------------------------------------------->
|
|
||||||
|
|
||||||
[Issue]: https://github.com/vaxerski/Hyprland/issues
|
|
||||||
[Wiki]: https://github.com/vaxerski/Hyprland/wiki/Contributing-&-Debugging
|
|
||||||
[Projects page]: https://github.com/vaxerski/Hyprland/projects?type=beta
|
|
58
docs/ISSUE_GUIDELINES.md
Normal file
58
docs/ISSUE_GUIDELINES.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# Issue Guidelines
|
||||||
|
|
||||||
|
First of all, please remember to:
|
||||||
|
- Check that your issue is not a duplicate
|
||||||
|
- Read the [FAQ](https://github.com/vaxerski/Hyprland/wiki/FAQ)
|
||||||
|
- Read the [Configuring Page](https://github.com/vaxerski/Hyprland/wiki/Configuring-Hyprland)
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
# Reporting suggestions
|
||||||
|
Suggestions are welcome.
|
||||||
|
|
||||||
|
Many features can be implemented using bash scripts and Hyprland sockets, read up on those [Here](https://github.com/vaxerski/Hyprland/wiki/IPC). Please do not suggest features that can be implemented as such.
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
# Reporting bugs
|
||||||
|
|
||||||
|
All bug reports should have the following:
|
||||||
|
- Steps to reproduce
|
||||||
|
- Expected outcome
|
||||||
|
- Noted outcome
|
||||||
|
|
||||||
|
If your bug is one that doesn't crash Hyprland, but feels like invalid behavior, that's all you need to say.
|
||||||
|
|
||||||
|
If your bug crashes Hyprland, append additionally:
|
||||||
|
- The Hyprland log
|
||||||
|
- Coredump / Coredump analysis (with a stacktrace)
|
||||||
|
|
||||||
|
**Important**: Please do NOT use any package for reporting bugs! Clone and compile from source.
|
||||||
|
|
||||||
|
## Obtaining the Hyprland log
|
||||||
|
If you are in a TTY, and the hyprland session that crashed was the last one you launched, the log will be printed with
|
||||||
|
```
|
||||||
|
cat /tmp/hypr/$(ls -t /tmp/hypr/ | head -n 1)/hyprland.log
|
||||||
|
```
|
||||||
|
feel free to send it to a file, save, copy, etc.
|
||||||
|
|
||||||
|
if you are in a Hyprland session, and you want the log of the last session, use
|
||||||
|
```
|
||||||
|
cat /tmp/hypr/$(ls -t /tmp/hypr/ | head -n 2 | tail -n 1)/hyprland.log
|
||||||
|
```
|
||||||
|
|
||||||
|
basically, directories in /tmp/hypr are your sessions.
|
||||||
|
|
||||||
|
## Obtaining the Hyprland coredump
|
||||||
|
If you are on systemd, you can simply use
|
||||||
|
```
|
||||||
|
coredumpctl
|
||||||
|
```
|
||||||
|
then go to the end (press END on your keyboard) and remember the PID of the last `Hyprland` occurrence. It's the first number after the time, for example `2891`.
|
||||||
|
|
||||||
|
exit coredumpctl (ctrl+c) and use
|
||||||
|
```
|
||||||
|
coredumpctl info [PID]
|
||||||
|
```
|
||||||
|
where `[PID]` is the PID you remembered.
|
||||||
|
|
@@ -1,35 +0,0 @@
|
|||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
## Packages
|
|
||||||
|
|
||||||
*I do not maintain any packages, but some kind people have made them for me.*
|
|
||||||
|
|
||||||
**If I missed any, please let me know.**
|
|
||||||
|
|
||||||
## Notice
|
|
||||||
|
|
||||||
Since I am not the maintainer, I cannot guarantee that those packages will always work and be up to date.
|
|
||||||
|
|
||||||
***Use at your own disclosure.*** <br>
|
|
||||||
*If they don't work, try building manually.*
|
|
||||||
|
|
||||||
#### Arch ( AUR / -git )
|
|
||||||
|
|
||||||
```sh
|
|
||||||
yay -S hyprland-git
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
## Building / No XWayland / other
|
|
||||||
|
|
||||||
If your distro doesn't have **Hyprland** in its repositories, you want to modify it, or use custom build flags, please refer to the **[Wiki Page][Install]** for the installation instructions.
|
|
||||||
|
|
||||||
|
|
||||||
<!----------------------------------------------------------------------------->
|
|
||||||
|
|
||||||
[Install]: https://github.com/vaxerski/Hyprland/wiki/Installation
|
|
||||||
|
|
||||||
|
|
12
flake.lock
generated
12
flake.lock
generated
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1653581809,
|
"lastModified": 1654593855,
|
||||||
"narHash": "sha256-Uvka0V5MTGbeOfWte25+tfRL3moECDh1VwokWSZUdoY=",
|
"narHash": "sha256-c+SyXvj7THre87OyIdZfRVR+HhI/g1ZDrQ3VUtTuHkU=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "83658b28fe638a170a19b8933aa008b30640fbd1",
|
"rev": "033bd4fa9a8fbe0c68a88e925d9a884161044b25",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -26,11 +26,11 @@
|
|||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"host": "gitlab.freedesktop.org",
|
"host": "gitlab.freedesktop.org",
|
||||||
"lastModified": 1653733431,
|
"lastModified": 1654618691,
|
||||||
"narHash": "sha256-0JwNH2E9XlMVa7ZCsqxazpKwpZ2rW5QQjbk0DdZxa48=",
|
"narHash": "sha256-8y3u8CoigjoZOVbA2wCWBHlDNEakv0AVxU46/cOC00s=",
|
||||||
"owner": "wlroots",
|
"owner": "wlroots",
|
||||||
"repo": "wlroots",
|
"repo": "wlroots",
|
||||||
"rev": "93ee4c7684050807e959bb3b6d57826a72fba8c2",
|
"rev": "b89ed9015c3fbe8d339e9d65cf70fdca6e5645bc",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@@ -33,18 +33,18 @@
|
|||||||
in {
|
in {
|
||||||
packages = genSystems (system: {
|
packages = genSystems (system: {
|
||||||
wlroots = pkgsFor.${system}.wlroots.overrideAttrs (prev: {
|
wlroots = pkgsFor.${system}.wlroots.overrideAttrs (prev: {
|
||||||
version = mkVersion inputs.wlroots.lastModifiedDate;
|
version = mkVersion (toString (inputs.wlroots.lastModifiedDate or inputs.wlroots.lastModified or "19700101"));
|
||||||
src = inputs.wlroots;
|
src = inputs.wlroots;
|
||||||
});
|
});
|
||||||
default = pkgsFor.${system}.callPackage ./default.nix {
|
default = pkgsFor.${system}.callPackage ./nix/default.nix {
|
||||||
version = mkVersion self.lastModifiedDate;
|
version = mkVersion (toString (self.lastModifiedDate or self.lastModified or "19700101"));
|
||||||
inherit (self.packages.${system}) wlroots;
|
inherit (self.packages.${system}) wlroots;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
formatter = genSystems (system: pkgsFor.${system}.alejandra);
|
formatter = genSystems (system: pkgsFor.${system}.alejandra);
|
||||||
|
|
||||||
nixosModules.default = import ./module.nix self;
|
nixosModules.default = import ./nix/module.nix self;
|
||||||
|
|
||||||
# Deprecated
|
# Deprecated
|
||||||
overlays.default = _: prev: {
|
overlays.default = _: prev: {
|
||||||
|
@@ -23,6 +23,7 @@ usage: hyprctl [command] [(opt)args]
|
|||||||
clients
|
clients
|
||||||
activewindow
|
activewindow
|
||||||
layers
|
layers
|
||||||
|
devices
|
||||||
dispatch
|
dispatch
|
||||||
keyword
|
keyword
|
||||||
version
|
version
|
||||||
@@ -44,12 +45,25 @@ void request(std::string arg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the instance signature
|
||||||
|
auto instanceSig = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||||
|
|
||||||
|
if (!instanceSig) {
|
||||||
|
std::cout << "HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string instanceSigStr = std::string(instanceSig);
|
||||||
|
|
||||||
sockaddr_un serverAddress = {0};
|
sockaddr_un serverAddress = {0};
|
||||||
serverAddress.sun_family = AF_UNIX;
|
serverAddress.sun_family = AF_UNIX;
|
||||||
strcpy(serverAddress.sun_path, "/tmp/hypr/.socket.sock");
|
|
||||||
|
std::string socketPath = "/tmp/hypr/" + instanceSigStr + "/.socket.sock";
|
||||||
|
|
||||||
|
strcpy(serverAddress.sun_path, socketPath.c_str());
|
||||||
|
|
||||||
if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) {
|
if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) {
|
||||||
std::cout << "Couldn't connect to /tmp/hypr/.socket.sock. (3) Is Hyprland running?";
|
std::cout << "Couldn't connect to " << socketPath << ". (3)";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +131,7 @@ int main(int argc, char** argv) {
|
|||||||
else if (!strcmp(argv[1], "activewindow")) request("activewindow");
|
else if (!strcmp(argv[1], "activewindow")) request("activewindow");
|
||||||
else if (!strcmp(argv[1], "layers")) request("layers");
|
else if (!strcmp(argv[1], "layers")) request("layers");
|
||||||
else if (!strcmp(argv[1], "version")) request("version");
|
else if (!strcmp(argv[1], "version")) request("version");
|
||||||
|
else if (!strcmp(argv[1], "devices")) request("devices");
|
||||||
else if (!strcmp(argv[1], "reload")) request("reload");
|
else if (!strcmp(argv[1], "reload")) request("reload");
|
||||||
else if (!strcmp(argv[1], "dispatch")) dispatchRequest(argc, argv);
|
else if (!strcmp(argv[1], "dispatch")) dispatchRequest(argc, argv);
|
||||||
else if (!strcmp(argv[1], "keyword")) keywordRequest(argc, argv);
|
else if (!strcmp(argv[1], "keyword")) keywordRequest(argc, argv);
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
pname = "hyprland";
|
pname = "hyprland";
|
||||||
inherit version;
|
inherit version;
|
||||||
src = ./.;
|
src = ../.;
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
cmake
|
cmake
|
||||||
@@ -52,8 +52,12 @@ stdenv.mkDerivation {
|
|||||||
["-DCMAKE_BUILD_TYPE=Release"]
|
["-DCMAKE_BUILD_TYPE=Release"]
|
||||||
++ lib.optional (!enableXWayland) "-DNO_XWAYLAND=true";
|
++ lib.optional (!enableXWayland) "-DNO_XWAYLAND=true";
|
||||||
|
|
||||||
|
# enables building with nix-supplied wlroots instead of submodule
|
||||||
prePatch = ''
|
prePatch = ''
|
||||||
make config
|
sed -Ei 's/"\.\.\/wlroots\/include\/([a-zA-Z0-9./_-]+)"/<\1>/g' src/includes.hpp
|
||||||
|
'';
|
||||||
|
postPatch = ''
|
||||||
|
make protocols
|
||||||
'';
|
'';
|
||||||
|
|
||||||
postBuild = ''
|
postBuild = ''
|
19
nix/update-inputs.sh
Executable file
19
nix/update-inputs.sh
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env -S nix shell nixpkgs#gawk nixpkgs#git nixpkgs#moreutils nixpkgs#jq -c bash
|
||||||
|
|
||||||
|
# get wlroots revision from submodule
|
||||||
|
SUB_REV=$(git submodule status | awk '{ print substr($1,2)}')
|
||||||
|
# and from lockfile
|
||||||
|
CRT_REV=$(jq < flake.lock '.nodes.wlroots.locked.rev' -r)
|
||||||
|
|
||||||
|
if [ $SUB_REV != $CRT_REV ]; then
|
||||||
|
# update nixpkgs to latest version
|
||||||
|
nix flake lock --update-input nixpkgs
|
||||||
|
|
||||||
|
# update wlroots to submodule revision
|
||||||
|
nix flake lock --override-input wlroots "gitlab:wlroots/wlroots/$SUB_REV?host=gitlab.freedesktop.org"
|
||||||
|
|
||||||
|
# remove "dirty" mark from lockfile
|
||||||
|
jq < flake.lock 'del(.nodes.wlroots.original.rev)' | sponge flake.lock
|
||||||
|
else
|
||||||
|
echo "wlroots is up to date!"
|
||||||
|
fi
|
1178
protocols/tablet-unstable-v2.xml
Normal file
1178
protocols/tablet-unstable-v2.xml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,16 @@
|
|||||||
#include "Compositor.hpp"
|
#include "Compositor.hpp"
|
||||||
|
|
||||||
CCompositor::CCompositor() {
|
CCompositor::CCompositor() {
|
||||||
unlink("/tmp/hypr/hyprland.log");
|
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
|
||||||
unlink("/tmp/hypr/hyprlandd.log");
|
|
||||||
unlink("/tmp/hypr/.hyprlandrq");
|
|
||||||
|
|
||||||
system("mkdir -p /tmp/hypr");
|
Debug::init(m_szInstanceSignature);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Instance Signature: %s", m_szInstanceSignature.c_str());
|
||||||
|
|
||||||
|
setenv("HYPRLAND_INSTANCE_SIGNATURE", m_szInstanceSignature.c_str(), true);
|
||||||
|
|
||||||
|
const auto INSTANCEPATH = "/tmp/hypr/" + m_szInstanceSignature;
|
||||||
|
mkdir(INSTANCEPATH.c_str(), S_IRWXU | S_IRWXG);
|
||||||
|
|
||||||
m_sWLDisplay = wl_display_create();
|
m_sWLDisplay = wl_display_create();
|
||||||
|
|
||||||
@@ -104,6 +109,8 @@ CCompositor::CCompositor() {
|
|||||||
m_sWLRVirtPtrMgr = wlr_virtual_pointer_manager_v1_create(m_sWLDisplay);
|
m_sWLRVirtPtrMgr = wlr_virtual_pointer_manager_v1_create(m_sWLDisplay);
|
||||||
|
|
||||||
m_sWLRToplevelMgr = wlr_foreign_toplevel_manager_v1_create(m_sWLDisplay);
|
m_sWLRToplevelMgr = wlr_foreign_toplevel_manager_v1_create(m_sWLDisplay);
|
||||||
|
|
||||||
|
m_sWLRTabletManager = wlr_tablet_v2_create(m_sWLDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCompositor::~CCompositor() {
|
CCompositor::~CCompositor() {
|
||||||
@@ -137,6 +144,7 @@ void CCompositor::initAllSignals() {
|
|||||||
addWLSignal(&m_sWLRPointerConstraints->events.new_constraint, &Events::listen_newConstraint, m_sWLRPointerConstraints, "PointerConstraints");
|
addWLSignal(&m_sWLRPointerConstraints->events.new_constraint, &Events::listen_newConstraint, m_sWLRPointerConstraints, "PointerConstraints");
|
||||||
addWLSignal(&m_sWLRXDGDecoMgr->events.new_toplevel_decoration, &Events::listen_NewXDGDeco, m_sWLRXDGDecoMgr, "XDGDecoMgr");
|
addWLSignal(&m_sWLRXDGDecoMgr->events.new_toplevel_decoration, &Events::listen_NewXDGDeco, m_sWLRXDGDecoMgr, "XDGDecoMgr");
|
||||||
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
|
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
|
||||||
|
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
||||||
|
|
||||||
signal(SIGINT, handleCritSignal);
|
signal(SIGINT, handleCritSignal);
|
||||||
signal(SIGTERM, handleCritSignal);
|
signal(SIGTERM, handleCritSignal);
|
||||||
@@ -577,11 +585,11 @@ CWindow* CCompositor::getWindowForPopup(wlr_xdg_popup* popup) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::list<SLayerSurface*>* layerSurfaces, Vector2D* sCoords) {
|
wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::list<SLayerSurface*>* layerSurfaces, Vector2D* sCoords) {
|
||||||
for (auto& l : *layerSurfaces) {
|
for (auto it = layerSurfaces->rbegin(); it != layerSurfaces->rend(); it++) {
|
||||||
if (l->fadingOut || (l->layerSurface && !l->layerSurface->mapped))
|
if ((*it)->fadingOut || !(*it)->layerSurface || ((*it)->layerSurface && !(*it)->layerSurface->mapped))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto SURFACEAT = wlr_layer_surface_v1_surface_at(l->layerSurface, pos.x - l->geometry.x, pos.y - l->geometry.y, &sCoords->x, &sCoords->y);
|
const auto SURFACEAT = wlr_layer_surface_v1_surface_at((*it)->layerSurface, pos.x - (*it)->geometry.x, pos.y - (*it)->geometry.y, &sCoords->x, &sCoords->y);
|
||||||
|
|
||||||
if (SURFACEAT)
|
if (SURFACEAT)
|
||||||
return SURFACEAT;
|
return SURFACEAT;
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
#include "config/ConfigManager.hpp"
|
#include "config/ConfigManager.hpp"
|
||||||
#include "managers/ThreadManager.hpp"
|
#include "managers/ThreadManager.hpp"
|
||||||
#include "managers/XWaylandManager.hpp"
|
#include "managers/XWaylandManager.hpp"
|
||||||
#include "managers/InputManager.hpp"
|
#include "managers/input/InputManager.hpp"
|
||||||
#include "managers/LayoutManager.hpp"
|
#include "managers/LayoutManager.hpp"
|
||||||
#include "managers/KeybindManager.hpp"
|
#include "managers/KeybindManager.hpp"
|
||||||
#include "managers/AnimationManager.hpp"
|
#include "managers/AnimationManager.hpp"
|
||||||
@@ -59,10 +59,12 @@ public:
|
|||||||
wlr_xdg_decoration_manager_v1* m_sWLRXDGDecoMgr;
|
wlr_xdg_decoration_manager_v1* m_sWLRXDGDecoMgr;
|
||||||
wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr;
|
wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr;
|
||||||
wlr_foreign_toplevel_manager_v1* m_sWLRToplevelMgr;
|
wlr_foreign_toplevel_manager_v1* m_sWLRToplevelMgr;
|
||||||
|
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
||||||
// ------------------------------------------------- //
|
// ------------------------------------------------- //
|
||||||
|
|
||||||
|
|
||||||
const char* m_szWLDisplaySocket;
|
const char* m_szWLDisplaySocket;
|
||||||
|
std::string m_szInstanceSignature = "";
|
||||||
|
|
||||||
std::list<SMonitor> m_lMonitors;
|
std::list<SMonitor> m_lMonitors;
|
||||||
std::list<CWindow> m_lWindows;
|
std::list<CWindow> m_lWindows;
|
||||||
|
@@ -45,12 +45,14 @@ void CConfigManager::setDefaultVars() {
|
|||||||
configValues["decoration:active_opacity"].floatValue = 1;
|
configValues["decoration:active_opacity"].floatValue = 1;
|
||||||
configValues["decoration:inactive_opacity"].floatValue = 1;
|
configValues["decoration:inactive_opacity"].floatValue = 1;
|
||||||
configValues["decoration:fullscreen_opacity"].floatValue = 1;
|
configValues["decoration:fullscreen_opacity"].floatValue = 1;
|
||||||
|
configValues["decoration:multisample_edges"].intValue = 0;
|
||||||
|
|
||||||
configValues["dwindle:pseudotile"].intValue = 0;
|
configValues["dwindle:pseudotile"].intValue = 0;
|
||||||
configValues["dwindle:col.group_border"].intValue = 0x66777700;
|
configValues["dwindle:col.group_border"].intValue = 0x66777700;
|
||||||
configValues["dwindle:col.group_border_active"].intValue = 0x66ffff00;
|
configValues["dwindle:col.group_border_active"].intValue = 0x66ffff00;
|
||||||
configValues["dwindle:force_split"].intValue = 0;
|
configValues["dwindle:force_split"].intValue = 0;
|
||||||
configValues["dwindle:preserve_split"].intValue = 0;
|
configValues["dwindle:preserve_split"].intValue = 0;
|
||||||
|
configValues["dwindle:special_scale_factor"].floatValue = 0.8f;
|
||||||
|
|
||||||
configValues["animations:enabled"].intValue = 1;
|
configValues["animations:enabled"].intValue = 1;
|
||||||
configValues["animations:speed"].floatValue = 7.f;
|
configValues["animations:speed"].floatValue = 7.f;
|
||||||
@@ -80,6 +82,8 @@ void CConfigManager::setDefaultVars() {
|
|||||||
configValues["input:repeat_rate"].intValue = 25;
|
configValues["input:repeat_rate"].intValue = 25;
|
||||||
configValues["input:repeat_delay"].intValue = 600;
|
configValues["input:repeat_delay"].intValue = 600;
|
||||||
configValues["input:natural_scroll"].intValue = 0;
|
configValues["input:natural_scroll"].intValue = 0;
|
||||||
|
configValues["input:numlock_by_default"].intValue = 0;
|
||||||
|
configValues["input:force_no_accel"].intValue = 0;
|
||||||
configValues["input:touchpad:disable_while_typing"].intValue = 1;
|
configValues["input:touchpad:disable_while_typing"].intValue = 1;
|
||||||
|
|
||||||
configValues["input:follow_mouse"].intValue = 1;
|
configValues["input:follow_mouse"].intValue = 1;
|
||||||
@@ -152,8 +156,18 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
|||||||
|
|
||||||
void CConfigManager::handleRawExec(const std::string& command, const std::string& args) {
|
void CConfigManager::handleRawExec(const std::string& command, const std::string& args) {
|
||||||
// Exec in the background dont wait for it.
|
// Exec in the background dont wait for it.
|
||||||
|
|
||||||
|
std::string toExec = args;
|
||||||
|
|
||||||
|
if (g_pXWaylandManager->m_sWLRXWayland)
|
||||||
|
toExec = std::string("WAYLAND_DISPLAY=") + std::string(g_pCompositor->m_szWLDisplaySocket) + " DISPLAY=" + std::string(g_pXWaylandManager->m_sWLRXWayland->display_name) + " " + toExec;
|
||||||
|
else
|
||||||
|
toExec = std::string("WAYLAND_DISPLAY=") + std::string(g_pCompositor->m_szWLDisplaySocket) + " " + toExec;
|
||||||
|
|
||||||
|
Debug::log(LOG, "Config executing %s", toExec.c_str());
|
||||||
|
|
||||||
if (fork() == 0) {
|
if (fork() == 0) {
|
||||||
execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
|
execl("/bin/sh", "/bin/sh", "-c", toExec.c_str(), nullptr);
|
||||||
|
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
@@ -26,8 +26,9 @@ std::string monitorsRequest() {
|
|||||||
std::string clientsRequest() {
|
std::string clientsRequest() {
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
for (auto& w : g_pCompositor->m_lWindows) {
|
for (auto& w : g_pCompositor->m_lWindows) {
|
||||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\n",
|
if (w.m_bIsMapped)
|
||||||
&w, w.m_szTitle.c_str(), (int)w.m_vRealPosition.vec().x, (int)w.m_vRealPosition.vec().y, (int)w.m_vRealSize.vec().x, (int)w.m_vRealSize.vec().y, w.m_iWorkspaceID, (w.m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w.m_iWorkspaceID)->m_szName.c_str()), (int)w.m_bIsFloating, w.m_iMonitorID);
|
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\n",
|
||||||
|
&w, w.m_szTitle.c_str(), (int)w.m_vRealPosition.vec().x, (int)w.m_vRealPosition.vec().y, (int)w.m_vRealSize.vec().x, (int)w.m_vRealSize.vec().y, w.m_iWorkspaceID, (w.m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w.m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w.m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w.m_iWorkspaceID)).c_str()), (int)w.m_bIsFloating, w.m_iMonitorID, g_pXWaylandManager->getAppIDClass(&w).c_str());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -47,8 +48,8 @@ std::string activeWindowRequest() {
|
|||||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||||
return "Invalid";
|
return "Invalid";
|
||||||
|
|
||||||
return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\n",
|
return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\n",
|
||||||
PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating, (int)PWINDOW->m_iMonitorID);
|
PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating, (int)PWINDOW->m_iMonitorID, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string layersRequest() {
|
std::string layersRequest() {
|
||||||
@@ -72,6 +73,38 @@ std::string layersRequest() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string devicesRequest() {
|
||||||
|
std::string result = "";
|
||||||
|
|
||||||
|
result += "mice:\n";
|
||||||
|
|
||||||
|
for (auto& m : g_pInputManager->m_lMice) {
|
||||||
|
result += getFormat("\tMouse at %x:\n\t\t%s\n", &m, m.mouse->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
result += "\n\nKeyboards:\n";
|
||||||
|
|
||||||
|
for (auto& k : g_pInputManager->m_lKeyboards) {
|
||||||
|
result += getFormat("\tKeyboard at %x:\n\t\t%s\n", &k, k.keyboard->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
result += "\n\nTablets:\n";
|
||||||
|
|
||||||
|
for (auto& d : g_pInputManager->m_lTabletPads) {
|
||||||
|
result += getFormat("\tTablet Pad at %x (belongs to %x -> %s)\n", &d, d.pTabletParent, d.pTabletParent ? d.pTabletParent->wlrDevice ? d.pTabletParent->wlrDevice->name : "" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& d : g_pInputManager->m_lTablets) {
|
||||||
|
result += getFormat("\tTablet at %x:\n\t\t%s\n", &d, d.wlrDevice ? d.wlrDevice->name : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& d : g_pInputManager->m_lTabletTools) {
|
||||||
|
result += getFormat("\tTablet Tool at %x (belongs to %x)\n", &d, d.wlrTabletTool ? d.wlrTabletTool->data : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::string versionRequest() {
|
std::string versionRequest() {
|
||||||
std::string result = "Hyprland, built from branch " + std::string(GIT_BRANCH) + " at commit " + GIT_COMMIT_HASH + GIT_DIRTY + " (" + GIT_COMMIT_MESSAGE + ").\nflags: (if any)\n";
|
std::string result = "Hyprland, built from branch " + std::string(GIT_BRANCH) + " at commit " + GIT_COMMIT_HASH + GIT_DIRTY + " (" + GIT_COMMIT_MESSAGE + ").\nflags: (if any)\n";
|
||||||
|
|
||||||
@@ -186,6 +219,8 @@ std::string getReply(std::string request) {
|
|||||||
return versionRequest();
|
return versionRequest();
|
||||||
else if (request == "reload")
|
else if (request == "reload")
|
||||||
return reloadRequest();
|
return reloadRequest();
|
||||||
|
else if (request == "devices")
|
||||||
|
return devicesRequest();
|
||||||
else if (request.find("dispatch") == 0)
|
else if (request.find("dispatch") == 0)
|
||||||
return dispatchRequest(request);
|
return dispatchRequest(request);
|
||||||
else if (request.find("keyword") == 0)
|
else if (request.find("keyword") == 0)
|
||||||
@@ -246,11 +281,11 @@ void HyprCtl::startHyprCtlSocket() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink("/tmp/hypr/.socket.sock");
|
|
||||||
|
|
||||||
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
|
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
|
||||||
|
|
||||||
strcpy(SERVERADDRESS.sun_path, "/tmp/hypr/.socket.sock");
|
std::string socketPath = "/tmp/hypr/" + g_pCompositor->m_szInstanceSignature + "/.socket.sock";
|
||||||
|
|
||||||
|
strcpy(SERVERADDRESS.sun_path, socketPath.c_str());
|
||||||
|
|
||||||
bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
|
bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
|
||||||
|
|
||||||
@@ -262,7 +297,7 @@ void HyprCtl::startHyprCtlSocket() {
|
|||||||
|
|
||||||
char readBuffer[1024] = {0};
|
char readBuffer[1024] = {0};
|
||||||
|
|
||||||
Debug::log(LOG, "Hypr socket started.");
|
Debug::log(LOG, "Hypr socket started at %s", socketPath.c_str());
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);
|
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);
|
||||||
|
@@ -1,15 +1,22 @@
|
|||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
|
#include "../Compositor.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
void Debug::init(std::string IS) {
|
||||||
|
if (ISDEBUG)
|
||||||
|
logFile = "/tmp/hypr/" + IS + "/hyprlandd.log";
|
||||||
|
else
|
||||||
|
logFile = "/tmp/hypr/" + IS + "/hyprland.log";
|
||||||
|
}
|
||||||
|
|
||||||
void Debug::log(LogLevel level, const char* fmt, ...) {
|
void Debug::log(LogLevel level, const char* fmt, ...) {
|
||||||
|
|
||||||
// log to a file
|
// log to a file
|
||||||
const std::string DEBUGPATH = ISDEBUG ? "/tmp/hypr/hyprlandd.log" : "/tmp/hypr/hyprland.log";
|
|
||||||
std::ofstream ofs;
|
std::ofstream ofs;
|
||||||
ofs.open(DEBUGPATH, std::ios::out | std::ios::app);
|
ofs.open(logFile, std::ios::out | std::ios::app);
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case LOG:
|
case LOG:
|
||||||
|
@@ -12,5 +12,8 @@ enum LogLevel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace Debug {
|
namespace Debug {
|
||||||
|
void init(std::string IS);
|
||||||
void log(LogLevel level, const char* fmt, ...);
|
void log(LogLevel level, const char* fmt, ...);
|
||||||
|
|
||||||
|
inline std::string logFile;
|
||||||
};
|
};
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../helpers/WLClasses.hpp"
|
#include "../helpers/WLClasses.hpp"
|
||||||
#include "../managers/InputManager.hpp"
|
#include "../managers/input/InputManager.hpp"
|
||||||
#include "../render/Renderer.hpp"
|
#include "../render/Renderer.hpp"
|
||||||
|
|
||||||
// ---------------------------------------------------- //
|
// ---------------------------------------------------- //
|
||||||
@@ -73,13 +73,25 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
|
|||||||
Debug::log(LOG, "Attached a mouse with name %s", DEVICE->name);
|
Debug::log(LOG, "Attached a mouse with name %s", DEVICE->name);
|
||||||
g_pInputManager->newMouse(DEVICE);
|
g_pInputManager->newMouse(DEVICE);
|
||||||
break;
|
break;
|
||||||
|
case WLR_INPUT_DEVICE_TOUCH:
|
||||||
|
Debug::log(LOG, "Attached a touch device with name %s", DEVICE->name);
|
||||||
|
Debug::log(WARN, "!!!! Hyprland does not directly support touchscreens, bugs may occur !!!!");
|
||||||
|
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, DEVICE);
|
||||||
|
break;
|
||||||
|
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||||
|
Debug::log(LOG, "Attached a tablet tool with name %s", DEVICE->name);
|
||||||
|
g_pInputManager->newTabletTool(DEVICE);
|
||||||
|
break;
|
||||||
|
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||||
|
Debug::log(LOG, "Attached a tablet pad with name %s", DEVICE->name);
|
||||||
|
g_pInputManager->newTabletPad(DEVICE);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
Debug::log(WARN, "Unrecognized input device plugged in: %s", DEVICE->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t capabilities = WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD;
|
g_pInputManager->updateCapabilities(DEVICE);
|
||||||
|
|
||||||
wlr_seat_set_capabilities(g_pCompositor->m_sSeat.seat, capabilities);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_newConstraint(wl_listener* listener, void* data) {
|
void Events::listener_newConstraint(wl_listener* listener, void* data) {
|
||||||
|
@@ -109,4 +109,7 @@ namespace Events {
|
|||||||
|
|
||||||
// Deco XDG
|
// Deco XDG
|
||||||
LISTENER(NewXDGDeco);
|
LISTENER(NewXDGDeco);
|
||||||
|
|
||||||
|
// Renderer destroy
|
||||||
|
LISTENER(RendererDestroy);
|
||||||
};
|
};
|
@@ -1,6 +1,6 @@
|
|||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../helpers/WLClasses.hpp"
|
#include "../helpers/WLClasses.hpp"
|
||||||
#include "../managers/InputManager.hpp"
|
#include "../managers/input/InputManager.hpp"
|
||||||
#include "../render/Renderer.hpp"
|
#include "../render/Renderer.hpp"
|
||||||
#include "Events.hpp"
|
#include "Events.hpp"
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "New LayerSurface has no preferred monitor. Assigning Monitor %s", PMONITOR->szName);
|
Debug::log(LOG, "New LayerSurface has no preferred monitor. Assigning Monitor %s", PMONITOR->szName.c_str());
|
||||||
|
|
||||||
WLRLAYERSURFACE->output = PMONITOR->output;
|
WLRLAYERSURFACE->output = PMONITOR->output;
|
||||||
}
|
}
|
||||||
@@ -160,6 +160,12 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
|||||||
|
|
||||||
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
|
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
|
||||||
g_pHyprRenderer->damageBox(&geomFixed);
|
g_pHyprRenderer->damageBox(&geomFixed);
|
||||||
|
|
||||||
|
geomFixed = {layersurface->geometry.x + (int)PMONITOR->vecPosition.x, layersurface->geometry.y + (int)PMONITOR->vecPosition.y, (int)layersurface->layerSurface->surface->current.width, (int)layersurface->layerSurface->surface->current.height};
|
||||||
|
g_pHyprRenderer->damageBox(&geomFixed);
|
||||||
|
|
||||||
|
geomFixed = {layersurface->geometry.x, layersurface->geometry.y, (int)layersurface->layerSurface->surface->current.width, (int)layersurface->layerSurface->surface->current.height};
|
||||||
|
layersurface->geometry = geomFixed; // because the surface can overflow... for some reason?
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_commitLayerSurface(void* owner, void* data) {
|
void Events::listener_commitLayerSurface(void* owner, void* data) {
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../helpers/WLClasses.hpp"
|
#include "../helpers/WLClasses.hpp"
|
||||||
#include "../managers/InputManager.hpp"
|
#include "../managers/input/InputManager.hpp"
|
||||||
#include "../render/Renderer.hpp"
|
#include "../render/Renderer.hpp"
|
||||||
|
|
||||||
// ------------------------------ //
|
// ------------------------------ //
|
||||||
@@ -153,4 +153,8 @@ void Events::listener_InhibitDeactivate(wl_listener* listener, void* data) {
|
|||||||
|
|
||||||
g_pCompositor->m_sSeat.exclusiveClient = nullptr;
|
g_pCompositor->m_sSeat.exclusiveClient = nullptr;
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::listener_RendererDestroy(wl_listener* listener, void* data) {
|
||||||
|
Debug::log(LOG, "!!Renderer destroyed!!");
|
||||||
}
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../helpers/WLClasses.hpp"
|
#include "../helpers/WLClasses.hpp"
|
||||||
#include "../managers/InputManager.hpp"
|
#include "../managers/input/InputManager.hpp"
|
||||||
#include "../render/Renderer.hpp"
|
#include "../render/Renderer.hpp"
|
||||||
#include "Events.hpp"
|
#include "Events.hpp"
|
||||||
#include "../debug/HyprCtl.hpp"
|
#include "../debug/HyprCtl.hpp"
|
||||||
@@ -65,6 +65,10 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
|||||||
if (monitorRule.disabled) {
|
if (monitorRule.disabled) {
|
||||||
wlr_output_enable(OUTPUT, 0);
|
wlr_output_enable(OUTPUT, 0);
|
||||||
wlr_output_commit(OUTPUT);
|
wlr_output_commit(OUTPUT);
|
||||||
|
|
||||||
|
if (const auto PMONITOR = g_pCompositor->getMonitorFromName(std::string(OUTPUT->name)); PMONITOR) {
|
||||||
|
listener_monitorDestroy(nullptr, PMONITOR->output);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +160,10 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
static std::chrono::high_resolution_clock::time_point startRenderOverlay = std::chrono::high_resolution_clock::now();
|
static std::chrono::high_resolution_clock::time_point startRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||||
static std::chrono::high_resolution_clock::time_point endRenderOverlay = std::chrono::high_resolution_clock::now();
|
static std::chrono::high_resolution_clock::time_point endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
if (g_pConfigManager->getInt("debug:overlay") == 1) {
|
static auto *const PDEBUGOVERLAY = &g_pConfigManager->getConfigValuePtr("debug:overlay")->intValue;
|
||||||
|
static auto *const PDAMAGETRACKINGMODE = &g_pConfigManager->getConfigValuePtr("general:damage_tracking_internal")->intValue;
|
||||||
|
|
||||||
|
if (*PDEBUGOVERLAY == 1) {
|
||||||
startRender = std::chrono::high_resolution_clock::now();
|
startRender = std::chrono::high_resolution_clock::now();
|
||||||
g_pDebugOverlay->frameData(PMONITOR);
|
g_pDebugOverlay->frameData(PMONITOR);
|
||||||
}
|
}
|
||||||
@@ -176,9 +183,14 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
g_pConfigManager->performMonitorReload();
|
g_pConfigManager->performMonitorReload();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PMONITOR->needsFrameSkip) {
|
if (PMONITOR->framesToSkip > 0) {
|
||||||
PMONITOR->needsFrameSkip = false;
|
PMONITOR->framesToSkip -= 1;
|
||||||
wlr_output_schedule_frame(PMONITOR->output);
|
|
||||||
|
if (!PMONITOR->noFrameSchedule)
|
||||||
|
wlr_output_schedule_frame(PMONITOR->output);
|
||||||
|
else {
|
||||||
|
Debug::log(LOG, "NoFrameSchedule hit for %s.", PMONITOR->szName.c_str());
|
||||||
|
}
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -191,9 +203,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
bool hasChanged;
|
bool hasChanged;
|
||||||
pixman_region32_init(&damage);
|
pixman_region32_init(&damage);
|
||||||
|
|
||||||
const auto DTMODE = g_pConfigManager->getInt("general:damage_tracking_internal");
|
if (*PDAMAGETRACKINGMODE == -1) {
|
||||||
|
|
||||||
if (DTMODE == -1) {
|
|
||||||
Debug::log(CRIT, "Damage tracking mode -1 ????");
|
Debug::log(CRIT, "Damage tracking mode -1 ????");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -203,7 +213,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasChanged && DTMODE != DAMAGE_TRACKING_NONE) {
|
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE) {
|
||||||
pixman_region32_fini(&damage);
|
pixman_region32_fini(&damage);
|
||||||
wlr_output_rollback(PMONITOR->output);
|
wlr_output_rollback(PMONITOR->output);
|
||||||
wlr_output_schedule_frame(PMONITOR->output); // we update shit at the monitor's Hz so we need to schedule frames because rollback wont
|
wlr_output_schedule_frame(PMONITOR->output); // we update shit at the monitor's Hz so we need to schedule frames because rollback wont
|
||||||
@@ -211,19 +221,19 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if we have no tracking or full tracking, invalidate the entire monitor
|
// if we have no tracking or full tracking, invalidate the entire monitor
|
||||||
if (DTMODE == DAMAGE_TRACKING_NONE || DTMODE == DAMAGE_TRACKING_MONITOR) {
|
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR) {
|
||||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||||
|
|
||||||
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
||||||
} else {
|
} else {
|
||||||
|
static auto* const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
|
||||||
|
|
||||||
// if we use blur we need to expand the damage for proper blurring
|
// if we use blur we need to expand the damage for proper blurring
|
||||||
if (g_pConfigManager->getInt("decoration:blur") == 1) {
|
if (*PBLURENABLED == 1) {
|
||||||
// TODO: can this be optimized?
|
// TODO: can this be optimized?
|
||||||
const auto BLURSIZE = g_pConfigManager->getInt("decoration:blur_size");
|
static auto* const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_size")->intValue;
|
||||||
const auto BLURPASSES = g_pConfigManager->getInt("decoration:blur_passes");
|
static auto* const PBLURPASSES = &g_pConfigManager->getConfigValuePtr("decoration:blur_passes")->intValue;
|
||||||
|
const auto BLURRADIUS = *PBLURSIZE * pow(2, *PBLURPASSES); // is this 2^pass? I don't know but it works... I think.
|
||||||
const auto BLURRADIUS = BLURSIZE * pow(2, BLURPASSES); // is this 2^pass? I don't know but it works... I think.
|
|
||||||
|
|
||||||
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
||||||
|
|
||||||
@@ -248,7 +258,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
g_pHyprError->draw();
|
g_pHyprError->draw();
|
||||||
|
|
||||||
// for drawing the debug overlay
|
// for drawing the debug overlay
|
||||||
if (PMONITOR->ID == 0 && g_pConfigManager->getInt("debug:overlay") == 1) {
|
if (PMONITOR->ID == 0 && *PDEBUGOVERLAY == 1) {
|
||||||
startRenderOverlay = std::chrono::high_resolution_clock::now();
|
startRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||||
g_pDebugOverlay->draw();
|
g_pDebugOverlay->draw();
|
||||||
endRenderOverlay = std::chrono::high_resolution_clock::now();
|
endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||||
@@ -269,7 +279,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
const auto TRANSFORM = wlr_output_transform_invert(PMONITOR->output->transform);
|
const auto TRANSFORM = wlr_output_transform_invert(PMONITOR->output->transform);
|
||||||
wlr_region_transform(&frameDamage, &PMONITOR->damage->current, TRANSFORM, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
wlr_region_transform(&frameDamage, &PMONITOR->damage->current, TRANSFORM, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||||
|
|
||||||
if (DTMODE == DAMAGE_TRACKING_NONE || DTMODE == DAMAGE_TRACKING_MONITOR)
|
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR)
|
||||||
pixman_region32_union_rect(&frameDamage, &frameDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
pixman_region32_union_rect(&frameDamage, &frameDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||||
|
|
||||||
wlr_output_set_damage(PMONITOR->output, &frameDamage);
|
wlr_output_set_damage(PMONITOR->output, &frameDamage);
|
||||||
@@ -280,7 +290,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
|
|
||||||
wlr_output_schedule_frame(PMONITOR->output);
|
wlr_output_schedule_frame(PMONITOR->output);
|
||||||
|
|
||||||
if (g_pConfigManager->getInt("debug:overlay") == 1) {
|
if (*PDEBUGOVERLAY == 1) {
|
||||||
const float µs = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - startRender).count() / 1000.f;
|
const float µs = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - startRender).count() / 1000.f;
|
||||||
g_pDebugOverlay->renderData(PMONITOR, µs);
|
g_pDebugOverlay->renderData(PMONITOR, µs);
|
||||||
if (PMONITOR->ID == 0) {
|
if (PMONITOR->ID == 0) {
|
||||||
@@ -309,14 +319,16 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
|||||||
|
|
||||||
// Cleanup everything. Move windows back, snap cursor, shit.
|
// Cleanup everything. Move windows back, snap cursor, shit.
|
||||||
const auto BACKUPMON = &g_pCompositor->m_lMonitors.front();
|
const auto BACKUPMON = &g_pCompositor->m_lMonitors.front();
|
||||||
const auto BACKUPWORKSPACE = BACKUPMON->activeWorkspace > 0 ? std::to_string(BACKUPMON->activeWorkspace) : "name:" + g_pCompositor->getWorkspaceByID(BACKUPMON->activeWorkspace)->m_szName;
|
|
||||||
|
|
||||||
if (!BACKUPMON) {
|
if (!BACKUPMON) {
|
||||||
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
|
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
|
||||||
g_pCompositor->cleanupExit();
|
g_pCompositor->cleanupExit();
|
||||||
|
exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto BACKUPWORKSPACE = BACKUPMON->activeWorkspace > 0 ? std::to_string(BACKUPMON->activeWorkspace) : "name:" + g_pCompositor->getWorkspaceByID(BACKUPMON->activeWorkspace)->m_szName;
|
||||||
|
|
||||||
// snap cursor
|
// snap cursor
|
||||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f, BACKUPMON->vecPosition.y + BACKUPMON->vecTransformedSize.y / 2.f);
|
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f, BACKUPMON->vecPosition.y + BACKUPMON->vecTransformedSize.y / 2.f);
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../helpers/WLClasses.hpp"
|
#include "../helpers/WLClasses.hpp"
|
||||||
#include "../managers/InputManager.hpp"
|
#include "../managers/input/InputManager.hpp"
|
||||||
#include "../render/Renderer.hpp"
|
#include "../render/Renderer.hpp"
|
||||||
|
|
||||||
// --------------------------------------------- //
|
// --------------------------------------------- //
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../helpers/WLClasses.hpp"
|
#include "../helpers/WLClasses.hpp"
|
||||||
#include "../managers/InputManager.hpp"
|
#include "../managers/input/InputManager.hpp"
|
||||||
#include "../render/Renderer.hpp"
|
#include "../render/Renderer.hpp"
|
||||||
|
|
||||||
// ------------------------------------------------------------ //
|
// ------------------------------------------------------------ //
|
||||||
@@ -35,6 +35,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
PWINDOW->m_szTitle = g_pXWaylandManager->getTitle(PWINDOW);
|
PWINDOW->m_szTitle = g_pXWaylandManager->getTitle(PWINDOW);
|
||||||
PWINDOW->m_fAlpha = 255.f;
|
PWINDOW->m_fAlpha = 255.f;
|
||||||
|
|
||||||
|
// Set all windows tiled regardless of anything
|
||||||
|
g_pXWaylandManager->setWindowStyleTiled(PWINDOW, WLR_EDGE_LEFT | WLR_EDGE_RIGHT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM);
|
||||||
|
|
||||||
// Foreign Toplevel
|
// Foreign Toplevel
|
||||||
PWINDOW->m_phForeignToplevel = wlr_foreign_toplevel_handle_v1_create(g_pCompositor->m_sWLRToplevelMgr);
|
PWINDOW->m_phForeignToplevel = wlr_foreign_toplevel_handle_v1_create(g_pCompositor->m_sWLRToplevelMgr);
|
||||||
// TODO: handle foreign events (requests)
|
// TODO: handle foreign events (requests)
|
||||||
@@ -73,16 +76,23 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
|
|
||||||
// window rules
|
// window rules
|
||||||
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(PWINDOW);
|
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(PWINDOW);
|
||||||
|
std::string requestedWorkspace = "";
|
||||||
|
bool workspaceSilent = false;
|
||||||
|
|
||||||
for (auto& r : WINDOWRULES) {
|
for (auto& r : WINDOWRULES) {
|
||||||
if (r.szRule.find("monitor") == 0) {
|
if (r.szRule.find("monitor") == 0) {
|
||||||
try {
|
try {
|
||||||
const long int MONITOR = std::stoi(r.szRule.substr(r.szRule.find(" ")));
|
const auto MONITORSTR = r.szRule.substr(r.szRule.find(" "));
|
||||||
|
|
||||||
if (MONITOR >= (long int)g_pCompositor->m_lMonitors.size() || MONITOR < (long int)0)
|
if (MONITORSTR == "unset") {
|
||||||
PWINDOW->m_iMonitorID = 0;
|
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||||
else
|
} else {
|
||||||
PWINDOW->m_iMonitorID = MONITOR;
|
const long int MONITOR = std::stoi(MONITORSTR);
|
||||||
|
if (MONITOR >= (long int)g_pCompositor->m_lMonitors.size() || MONITOR < (long int)0)
|
||||||
|
PWINDOW->m_iMonitorID = 0;
|
||||||
|
else
|
||||||
|
PWINDOW->m_iMonitorID = MONITOR;
|
||||||
|
}
|
||||||
|
|
||||||
PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeWorkspace;
|
PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeWorkspace;
|
||||||
|
|
||||||
@@ -91,11 +101,14 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
Debug::log(ERR, "Rule monitor failed, rule: %s -> %s | err: %s", r.szRule.c_str(), r.szValue.c_str(), e.what());
|
Debug::log(ERR, "Rule monitor failed, rule: %s -> %s | err: %s", r.szRule.c_str(), r.szValue.c_str(), e.what());
|
||||||
}
|
}
|
||||||
} else if (r.szRule.find("workspace") == 0) {
|
} else if (r.szRule.find("workspace") == 0) {
|
||||||
// switch to workspace
|
// check if it isnt unset
|
||||||
g_pKeybindManager->m_mDispatchers["workspace"](r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
const auto WORKSPACERQ = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
|
||||||
|
|
||||||
PWINDOW->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID;
|
if (WORKSPACERQ == "unset") {
|
||||||
PWINDOW->m_iWorkspaceID = g_pCompositor->m_pLastMonitor->activeWorkspace;
|
requestedWorkspace = "";
|
||||||
|
} else {
|
||||||
|
requestedWorkspace = WORKSPACERQ;
|
||||||
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Rule workspace matched by window %x, %s applied.", PWINDOW, r.szValue.c_str());
|
Debug::log(LOG, "Rule workspace matched by window %x, %s applied.", PWINDOW, r.szValue.c_str());
|
||||||
} else if (r.szRule.find("float") == 0) {
|
} else if (r.szRule.find("float") == 0) {
|
||||||
@@ -132,6 +145,25 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (requestedWorkspace != "") {
|
||||||
|
// process requested workspace
|
||||||
|
if (requestedWorkspace.find_first_of(' ') != std::string::npos) {
|
||||||
|
// check for silent
|
||||||
|
if (requestedWorkspace.find("silent") != std::string::npos) {
|
||||||
|
workspaceSilent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
requestedWorkspace = requestedWorkspace.substr(0, requestedWorkspace.find_first_of(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!workspaceSilent) {
|
||||||
|
g_pKeybindManager->m_mDispatchers["workspace"](requestedWorkspace);
|
||||||
|
|
||||||
|
PWINDOW->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID;
|
||||||
|
PWINDOW->m_iWorkspaceID = g_pCompositor->m_pLastMonitor->activeWorkspace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (PWINDOW->m_bIsFloating) {
|
if (PWINDOW->m_bIsFloating) {
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW);
|
g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW);
|
||||||
PWINDOW->m_bCreatedOverFullscreen = true;
|
PWINDOW->m_bCreatedOverFullscreen = true;
|
||||||
@@ -205,6 +237,15 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
// do the animation thing
|
// do the animation thing
|
||||||
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, false);
|
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, false);
|
||||||
|
|
||||||
|
if (workspaceSilent) {
|
||||||
|
// move the window
|
||||||
|
if (g_pCompositor->m_pLastWindow == PWINDOW) {
|
||||||
|
g_pKeybindManager->m_mDispatchers["movetoworkspacesilent"](requestedWorkspace);
|
||||||
|
} else {
|
||||||
|
Debug::log(ERR, "Tried to set workspace silent rule to a nofocus window!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y);
|
Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,16 +46,35 @@ void wlr_signal_emit_safe(struct wl_signal *signal, void *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string getFormat(const char *fmt, ...) {
|
std::string getFormat(const char *fmt, ...) {
|
||||||
char buf[2048] = "";
|
char buf[LOGMESSAGESIZE] = "";
|
||||||
|
char* outputStr;
|
||||||
|
int logLen;
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
logLen = vsnprintf(buf, sizeof buf, fmt, args);
|
||||||
vsprintf(buf, fmt, args);
|
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
return std::string(buf);
|
if ((long unsigned int)logLen < sizeof buf) {
|
||||||
|
outputStr = strdup(buf);
|
||||||
|
} else {
|
||||||
|
outputStr = (char*)malloc(logLen + 1);
|
||||||
|
|
||||||
|
if (!outputStr) {
|
||||||
|
printf("CRITICAL: Cannot alloc size %d for log! (Out of memory?)", logLen + 1);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(outputStr, logLen + 1U, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string output = std::string(outputStr);
|
||||||
|
|
||||||
|
free(outputStr);
|
||||||
|
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void scaleBox(wlr_box* box, float scale) {
|
void scaleBox(wlr_box* box, float scale) {
|
||||||
@@ -116,7 +135,7 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isNumber(const std::string& str) {
|
bool isNumber(const std::string& str) {
|
||||||
return std::ranges::all_of(str.begin(), str.end(), [](char c) { return isdigit(c) != 0; });
|
return std::ranges::all_of(str.begin(), str.end(), [](char c) { return isdigit(c) != 0 || c == '-'; });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDirection(const std::string& arg) {
|
bool isDirection(const std::string& arg) {
|
||||||
@@ -172,7 +191,7 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
|||||||
searchID = lowestID;
|
searchID = lowestID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(searchID); PWORKSPACE) {
|
if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(searchID); PWORKSPACE && PWORKSPACE->m_iID != SPECIAL_WORKSPACE_ID) {
|
||||||
if (PWORKSPACE->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID) {
|
if (PWORKSPACE->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID) {
|
||||||
currentID = PWORKSPACE->m_iID;
|
currentID = PWORKSPACE->m_iID;
|
||||||
|
|
||||||
|
@@ -27,7 +27,8 @@ struct SMonitor {
|
|||||||
wlr_output* output = nullptr;
|
wlr_output* output = nullptr;
|
||||||
float refreshRate = 60;
|
float refreshRate = 60;
|
||||||
wlr_output_damage* damage = nullptr;
|
wlr_output_damage* damage = nullptr;
|
||||||
bool needsFrameSkip = false;
|
int framesToSkip = 0;
|
||||||
|
bool noFrameSchedule = false;
|
||||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
|
|
||||||
// for the special workspace
|
// for the special workspace
|
||||||
|
@@ -89,6 +89,20 @@ void SubsurfaceTree::destroySurfaceTree(SSurfaceTreeNode* pNode) {
|
|||||||
pNode->hyprListener_destroy.removeCallback();
|
pNode->hyprListener_destroy.removeCallback();
|
||||||
pNode->hyprListener_newSubsurface.removeCallback();
|
pNode->hyprListener_newSubsurface.removeCallback();
|
||||||
|
|
||||||
|
// damage
|
||||||
|
if (pNode->pSurface) {
|
||||||
|
wlr_box extents = {};
|
||||||
|
wlr_surface_get_extends(pNode->pSurface, &extents);
|
||||||
|
|
||||||
|
int lx = 0, ly = 0;
|
||||||
|
addSurfaceGlobalOffset(pNode, &lx, &ly);
|
||||||
|
|
||||||
|
extents.x += lx;
|
||||||
|
extents.y += ly;
|
||||||
|
|
||||||
|
g_pHyprRenderer->damageBox(&extents);
|
||||||
|
}
|
||||||
|
|
||||||
surfaceTreeNodes.remove(*pNode);
|
surfaceTreeNodes.remove(*pNode);
|
||||||
|
|
||||||
Debug::log(LOG, "SurfaceTree Node removed");
|
Debug::log(LOG, "SurfaceTree Node removed");
|
||||||
@@ -162,6 +176,8 @@ void Events::listener_unmapSubsurface(void* owner, void* data) {
|
|||||||
extents.x += lx;
|
extents.x += lx;
|
||||||
extents.y += ly;
|
extents.y += ly;
|
||||||
|
|
||||||
|
g_pHyprRenderer->damageBox(&extents);
|
||||||
|
|
||||||
SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
|
SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
|
||||||
subsurface->pChild = nullptr;
|
subsurface->pChild = nullptr;
|
||||||
}
|
}
|
||||||
|
@@ -69,6 +69,8 @@ struct SKeyboard {
|
|||||||
DYNLISTENER(keyboardKey);
|
DYNLISTENER(keyboardKey);
|
||||||
DYNLISTENER(keyboardDestroy);
|
DYNLISTENER(keyboardDestroy);
|
||||||
|
|
||||||
|
bool active = false;
|
||||||
|
|
||||||
// For the list lookup
|
// For the list lookup
|
||||||
bool operator==(const SKeyboard& rhs) {
|
bool operator==(const SKeyboard& rhs) {
|
||||||
return keyboard == rhs.keyboard;
|
return keyboard == rhs.keyboard;
|
||||||
@@ -151,4 +153,56 @@ struct SDrag {
|
|||||||
DYNLISTENER(mapIcon);
|
DYNLISTENER(mapIcon);
|
||||||
DYNLISTENER(unmapIcon);
|
DYNLISTENER(unmapIcon);
|
||||||
DYNLISTENER(commitIcon);
|
DYNLISTENER(commitIcon);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct STablet {
|
||||||
|
DYNLISTENER(Tip);
|
||||||
|
DYNLISTENER(Axis);
|
||||||
|
DYNLISTENER(Button);
|
||||||
|
DYNLISTENER(Proximity);
|
||||||
|
DYNLISTENER(Destroy);
|
||||||
|
|
||||||
|
wlr_tablet* wlrTablet = nullptr;
|
||||||
|
wlr_tablet_v2_tablet* wlrTabletV2 = nullptr;
|
||||||
|
wlr_input_device* wlrDevice = nullptr;
|
||||||
|
|
||||||
|
bool operator==(const STablet& b) {
|
||||||
|
return wlrDevice == b.wlrDevice;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct STabletTool {
|
||||||
|
wlr_tablet_tool* wlrTabletTool = nullptr;
|
||||||
|
wlr_tablet_v2_tablet_tool* wlrTabletToolV2 = nullptr;
|
||||||
|
|
||||||
|
wlr_tablet_v2_tablet* wlrTabletOwnerV2 = nullptr;
|
||||||
|
|
||||||
|
wlr_surface* pSurface = nullptr;
|
||||||
|
|
||||||
|
double tiltX = 0;
|
||||||
|
double tiltY = 0;
|
||||||
|
|
||||||
|
bool active = true;
|
||||||
|
|
||||||
|
DYNLISTENER(TabletToolDestroy);
|
||||||
|
DYNLISTENER(TabletToolSetCursor);
|
||||||
|
|
||||||
|
bool operator==(const STabletTool& b) {
|
||||||
|
return wlrTabletTool == b.wlrTabletTool;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct STabletPad {
|
||||||
|
wlr_tablet_v2_tablet_pad* wlrTabletPadV2 = nullptr;
|
||||||
|
STablet* pTabletParent = nullptr;
|
||||||
|
|
||||||
|
DYNLISTENER(Attach);
|
||||||
|
DYNLISTENER(Button);
|
||||||
|
DYNLISTENER(Strip);
|
||||||
|
DYNLISTENER(Ring);
|
||||||
|
DYNLISTENER(Destroy);
|
||||||
|
|
||||||
|
bool operator==(const STabletPad& b) {
|
||||||
|
return wlrTabletPadV2 == b.wlrTabletPadV2;
|
||||||
|
}
|
||||||
};
|
};
|
@@ -57,7 +57,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
|||||||
m_fAlpha.setValueAndWarp(255.f);
|
m_fAlpha.setValueAndWarp(255.f);
|
||||||
m_fAlpha = 0.f;
|
m_fAlpha = 0.f;
|
||||||
}
|
}
|
||||||
} else if ("slidevert") {
|
} else if (ANIMSTYLE == "slidevert") {
|
||||||
// fallback is slide
|
// fallback is slide
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||||
|
|
||||||
|
@@ -77,6 +77,9 @@ extern "C" {
|
|||||||
#include "../wlroots/include/wlr/util/log.h"
|
#include "../wlroots/include/wlr/util/log.h"
|
||||||
#include "../wlroots/include/wlr/xwayland.h"
|
#include "../wlroots/include/wlr/xwayland.h"
|
||||||
#include "../wlroots/include/wlr/util/region.h"
|
#include "../wlroots/include/wlr/util/region.h"
|
||||||
|
#include "../wlroots/include/wlr/types/wlr_tablet_pad.h"
|
||||||
|
#include "../wlroots/include/wlr/types/wlr_tablet_tool.h"
|
||||||
|
#include "../wlroots/include/wlr/types/wlr_tablet_v2.h"
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <X11/Xproto.h>
|
#include <X11/Xproto.h>
|
||||||
#include "../wlroots/include/wlr/render/egl.h"
|
#include "../wlroots/include/wlr/render/egl.h"
|
||||||
|
@@ -164,10 +164,12 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) {
|
|||||||
|
|
||||||
if (PWORKSPACE->m_bIsSpecialWorkspace) {
|
if (PWORKSPACE->m_bIsSpecialWorkspace) {
|
||||||
// if special, we adjust the coords a bit
|
// if special, we adjust the coords a bit
|
||||||
PWINDOW->m_vRealPosition = calcPos + (calcSize - calcSize * 0.8f) / 2.f;
|
static auto *const PSCALEFACTOR = &g_pConfigManager->getConfigValuePtr("dwindle:special_scale_factor")->floatValue;
|
||||||
PWINDOW->m_vRealSize = calcSize * 0.8f;
|
|
||||||
|
|
||||||
g_pXWaylandManager->setWindowSize(PWINDOW, calcSize * 0.8f);
|
PWINDOW->m_vRealPosition = calcPos + (calcSize - calcSize * *PSCALEFACTOR) / 2.f;
|
||||||
|
PWINDOW->m_vRealSize = calcSize * *PSCALEFACTOR;
|
||||||
|
|
||||||
|
g_pXWaylandManager->setWindowSize(PWINDOW, calcSize * *PSCALEFACTOR);
|
||||||
} else {
|
} else {
|
||||||
PWINDOW->m_vRealSize = calcSize;
|
PWINDOW->m_vRealSize = calcSize;
|
||||||
PWINDOW->m_vRealPosition = calcPos;
|
PWINDOW->m_vRealPosition = calcPos;
|
||||||
@@ -452,6 +454,13 @@ void CHyprDwindleLayout::onBeginDragWindow() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(DRAGGINGWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||||
|
Debug::log(LOG, "Rejecting drag on a fullscreen workspace.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DRAGGINGWINDOW->m_bDraggingTiled = false;
|
DRAGGINGWINDOW->m_bDraggingTiled = false;
|
||||||
|
|
||||||
if (!DRAGGINGWINDOW->m_bIsFloating) {
|
if (!DRAGGINGWINDOW->m_bIsFloating) {
|
||||||
@@ -508,80 +517,7 @@ void CHyprDwindleLayout::onMouseMove(const Vector2D& mousePos) {
|
|||||||
|
|
||||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||||
} else {
|
} else {
|
||||||
// we need to adjust the splitratio
|
resizeActiveWindow(TICKDELTA, DRAGGINGWINDOW);
|
||||||
|
|
||||||
// get some data about our window
|
|
||||||
const auto PNODE = getNodeFromWindow(DRAGGINGWINDOW);
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(DRAGGINGWINDOW->m_iMonitorID);
|
|
||||||
const bool DISPLAYLEFT = STICKS(DRAGGINGWINDOW->m_vPosition.x, PMONITOR->vecPosition.x + PMONITOR->vecReservedTopLeft.x);
|
|
||||||
const bool DISPLAYRIGHT = STICKS(DRAGGINGWINDOW->m_vPosition.x + DRAGGINGWINDOW->m_vSize.x, PMONITOR->vecPosition.x + PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x);
|
|
||||||
const bool DISPLAYTOP = STICKS(DRAGGINGWINDOW->m_vPosition.y, PMONITOR->vecPosition.y + PMONITOR->vecReservedTopLeft.y);
|
|
||||||
const bool DISPLAYBOTTOM = STICKS(DRAGGINGWINDOW->m_vPosition.y + DRAGGINGWINDOW->m_vSize.y, PMONITOR->vecPosition.y + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y);
|
|
||||||
|
|
||||||
// construct allowed movement
|
|
||||||
Vector2D allowedMovement = TICKDELTA;
|
|
||||||
if (DISPLAYLEFT && DISPLAYRIGHT)
|
|
||||||
allowedMovement.x = 0;
|
|
||||||
|
|
||||||
if (DISPLAYBOTTOM && DISPLAYTOP)
|
|
||||||
allowedMovement.y = 0;
|
|
||||||
|
|
||||||
// get the correct containers to apply splitratio to
|
|
||||||
const auto PPARENT = PNODE->pParent;
|
|
||||||
|
|
||||||
if (!PPARENT)
|
|
||||||
return; // the only window on a workspace, ignore
|
|
||||||
|
|
||||||
const bool PARENTSIDEBYSIDE = !PPARENT->splitTop;
|
|
||||||
|
|
||||||
// Get the parent's parent
|
|
||||||
auto PPARENT2 = PPARENT->pParent;
|
|
||||||
|
|
||||||
// No parent means we have only 2 windows, and thus one axis of freedom
|
|
||||||
if (!PPARENT2) {
|
|
||||||
if (PARENTSIDEBYSIDE) {
|
|
||||||
allowedMovement.x *= 2.f / PPARENT->size.x;
|
|
||||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
|
||||||
PPARENT->recalcSizePosRecursive();
|
|
||||||
} else {
|
|
||||||
allowedMovement.y *= 2.f / PPARENT->size.y;
|
|
||||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
|
||||||
PPARENT->recalcSizePosRecursive();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get first parent with other split
|
|
||||||
while(PPARENT2 && PPARENT2->splitTop == !PARENTSIDEBYSIDE)
|
|
||||||
PPARENT2 = PPARENT2->pParent;
|
|
||||||
|
|
||||||
// no parent, one axis of freedom
|
|
||||||
if (!PPARENT2) {
|
|
||||||
if (PARENTSIDEBYSIDE) {
|
|
||||||
allowedMovement.x *= 2.f / PPARENT->size.x;
|
|
||||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
|
||||||
PPARENT->recalcSizePosRecursive();
|
|
||||||
} else {
|
|
||||||
allowedMovement.y *= 2.f / PPARENT->size.y;
|
|
||||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
|
||||||
PPARENT->recalcSizePosRecursive();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2 axes of freedom
|
|
||||||
const auto SIDECONTAINER = PARENTSIDEBYSIDE ? PPARENT : PPARENT2;
|
|
||||||
const auto TOPCONTAINER = PARENTSIDEBYSIDE ? PPARENT2 : PPARENT;
|
|
||||||
|
|
||||||
allowedMovement.x *= 2.f / SIDECONTAINER->size.x;
|
|
||||||
allowedMovement.y *= 2.f / TOPCONTAINER->size.y;
|
|
||||||
|
|
||||||
SIDECONTAINER->splitRatio = std::clamp(SIDECONTAINER->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
|
||||||
TOPCONTAINER->splitRatio = std::clamp(TOPCONTAINER->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
|
||||||
SIDECONTAINER->recalcSizePosRecursive();
|
|
||||||
TOPCONTAINER->recalcSizePosRecursive();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,6 +535,97 @@ void CHyprDwindleLayout::onMouseMove(const Vector2D& mousePos) {
|
|||||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* pWindow) {
|
||||||
|
|
||||||
|
const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_pLastWindow;
|
||||||
|
|
||||||
|
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||||
|
|
||||||
|
if (!PNODE) {
|
||||||
|
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() + pixResize);
|
||||||
|
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(std::clamp(PWINDOW->m_vRealSize.vec().x, (double)20, (double)999999), std::clamp(PWINDOW->m_vRealSize.vec().y, (double)20, (double)999999)));
|
||||||
|
|
||||||
|
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get some data about our window
|
||||||
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||||
|
const bool DISPLAYLEFT = STICKS(PWINDOW->m_vPosition.x, PMONITOR->vecPosition.x + PMONITOR->vecReservedTopLeft.x);
|
||||||
|
const bool DISPLAYRIGHT = STICKS(PWINDOW->m_vPosition.x + PWINDOW->m_vSize.x, PMONITOR->vecPosition.x + PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x);
|
||||||
|
const bool DISPLAYTOP = STICKS(PWINDOW->m_vPosition.y, PMONITOR->vecPosition.y + PMONITOR->vecReservedTopLeft.y);
|
||||||
|
const bool DISPLAYBOTTOM = STICKS(PWINDOW->m_vPosition.y + PWINDOW->m_vSize.y, PMONITOR->vecPosition.y + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y);
|
||||||
|
|
||||||
|
// construct allowed movement
|
||||||
|
Vector2D allowedMovement = pixResize;
|
||||||
|
if (DISPLAYLEFT && DISPLAYRIGHT)
|
||||||
|
allowedMovement.x = 0;
|
||||||
|
|
||||||
|
if (DISPLAYBOTTOM && DISPLAYTOP)
|
||||||
|
allowedMovement.y = 0;
|
||||||
|
|
||||||
|
// get the correct containers to apply splitratio to
|
||||||
|
const auto PPARENT = PNODE->pParent;
|
||||||
|
|
||||||
|
if (!PPARENT)
|
||||||
|
return; // the only window on a workspace, ignore
|
||||||
|
|
||||||
|
const bool PARENTSIDEBYSIDE = !PPARENT->splitTop;
|
||||||
|
|
||||||
|
// Get the parent's parent
|
||||||
|
auto PPARENT2 = PPARENT->pParent;
|
||||||
|
|
||||||
|
// No parent means we have only 2 windows, and thus one axis of freedom
|
||||||
|
if (!PPARENT2) {
|
||||||
|
if (PARENTSIDEBYSIDE) {
|
||||||
|
allowedMovement.x *= 2.f / PPARENT->size.x;
|
||||||
|
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
||||||
|
PPARENT->recalcSizePosRecursive();
|
||||||
|
} else {
|
||||||
|
allowedMovement.y *= 2.f / PPARENT->size.y;
|
||||||
|
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
||||||
|
PPARENT->recalcSizePosRecursive();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get first parent with other split
|
||||||
|
while (PPARENT2 && PPARENT2->splitTop == !PARENTSIDEBYSIDE)
|
||||||
|
PPARENT2 = PPARENT2->pParent;
|
||||||
|
|
||||||
|
// no parent, one axis of freedom
|
||||||
|
if (!PPARENT2) {
|
||||||
|
if (PARENTSIDEBYSIDE) {
|
||||||
|
allowedMovement.x *= 2.f / PPARENT->size.x;
|
||||||
|
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
||||||
|
PPARENT->recalcSizePosRecursive();
|
||||||
|
} else {
|
||||||
|
allowedMovement.y *= 2.f / PPARENT->size.y;
|
||||||
|
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
||||||
|
PPARENT->recalcSizePosRecursive();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 axes of freedom
|
||||||
|
const auto SIDECONTAINER = PARENTSIDEBYSIDE ? PPARENT : PPARENT2;
|
||||||
|
const auto TOPCONTAINER = PARENTSIDEBYSIDE ? PPARENT2 : PPARENT;
|
||||||
|
|
||||||
|
allowedMovement.x *= 2.f / SIDECONTAINER->size.x;
|
||||||
|
allowedMovement.y *= 2.f / TOPCONTAINER->size.y;
|
||||||
|
|
||||||
|
SIDECONTAINER->splitRatio = std::clamp(SIDECONTAINER->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
||||||
|
TOPCONTAINER->splitRatio = std::clamp(TOPCONTAINER->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
||||||
|
SIDECONTAINER->recalcSizePosRecursive();
|
||||||
|
TOPCONTAINER->recalcSizePosRecursive();
|
||||||
|
}
|
||||||
|
|
||||||
void CHyprDwindleLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
void CHyprDwindleLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||||
wlr_box desiredGeometry = {0};
|
wlr_box desiredGeometry = {0};
|
||||||
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
|
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
|
||||||
|
@@ -48,6 +48,7 @@ public:
|
|||||||
virtual void recalculateWindow(CWindow*);
|
virtual void recalculateWindow(CWindow*);
|
||||||
virtual void changeWindowFloatingMode(CWindow*);
|
virtual void changeWindowFloatingMode(CWindow*);
|
||||||
virtual void onBeginDragWindow();
|
virtual void onBeginDragWindow();
|
||||||
|
virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr);
|
||||||
virtual void onEndDragWindow();
|
virtual void onEndDragWindow();
|
||||||
virtual void onMouseMove(const Vector2D&);
|
virtual void onMouseMove(const Vector2D&);
|
||||||
virtual void onWindowCreatedFloating(CWindow*);
|
virtual void onWindowCreatedFloating(CWindow*);
|
||||||
|
@@ -49,6 +49,12 @@ public:
|
|||||||
as.
|
as.
|
||||||
*/
|
*/
|
||||||
virtual void onBeginDragWindow() = 0;
|
virtual void onBeginDragWindow() = 0;
|
||||||
|
/*
|
||||||
|
Called when a user requests a resize of the current window by a vec
|
||||||
|
Vector2D holds pixel values
|
||||||
|
Optional pWindow for a specific window
|
||||||
|
*/
|
||||||
|
virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr) = 0;
|
||||||
/*
|
/*
|
||||||
Called when a window is ended being dragged
|
Called when a window is ended being dragged
|
||||||
(mouse up)
|
(mouse up)
|
||||||
|
11
src/main.cpp
11
src/main.cpp
@@ -3,6 +3,7 @@
|
|||||||
#include "Compositor.hpp"
|
#include "Compositor.hpp"
|
||||||
#include "config/ConfigManager.hpp"
|
#include "config/ConfigManager.hpp"
|
||||||
#include "init/initHelpers.hpp"
|
#include "init/initHelpers.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
// I am a bad bad boy and have used some global vars here,
|
// I am a bad bad boy and have used some global vars here,
|
||||||
// just for this file
|
// just for this file
|
||||||
@@ -19,17 +20,19 @@ int main(int argc, char** argv) {
|
|||||||
ignoreSudo = true;
|
ignoreSudo = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
system("mkdir -p /tmp/hypr");
|
||||||
|
|
||||||
if (!ignoreSudo) {
|
if (!ignoreSudo) {
|
||||||
if (Init::isSudo()) {
|
if (Init::isSudo()) {
|
||||||
Debug::log(CRIT, "Hyprland shall not be run as the root user. If you really want to, use the --i-am-really-stupid flag.");
|
std::cout << "Hyprland shall not be run as the root user. If you really want to, use the --i-am-really-stupid flag.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Debug::log(WARN, "Running with ignored root checks, I surely hope you know what you're doing.");
|
std::cout << "Running with ignored root checks, I surely hope you know what you're doing.\n";
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Welcome to Hyprland!");
|
std::cout << "Welcome to Hyprland!\n";
|
||||||
|
|
||||||
// let's init the compositor.
|
// let's init the compositor.
|
||||||
// it initializes basic Wayland stuff in the constructor.
|
// it initializes basic Wayland stuff in the constructor.
|
||||||
|
@@ -23,20 +23,22 @@ void CAnimationManager::tick() {
|
|||||||
|
|
||||||
bool animationsDisabled = false;
|
bool animationsDisabled = false;
|
||||||
|
|
||||||
if (!g_pConfigManager->getInt("animations:enabled"))
|
static auto *const PANIMENABLED = &g_pConfigManager->getConfigValuePtr("animations:enabled")->intValue;
|
||||||
|
|
||||||
|
if (!*PANIMENABLED)
|
||||||
animationsDisabled = true;
|
animationsDisabled = true;
|
||||||
|
|
||||||
const float ANIMSPEED = g_pConfigManager->getFloat("animations:speed");
|
static auto *const PANIMSPEED = &g_pConfigManager->getConfigValuePtr("animations:speed")->floatValue;
|
||||||
const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size");
|
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||||
const auto BEZIERSTR = g_pConfigManager->getString("animations:curve");
|
static auto *const BEZIERSTR = &g_pConfigManager->getConfigValuePtr("animations:curve")->strValue;
|
||||||
|
|
||||||
auto DEFAULTBEZIER = m_mBezierCurves.find(BEZIERSTR);
|
auto DEFAULTBEZIER = m_mBezierCurves.find(*BEZIERSTR);
|
||||||
if (DEFAULTBEZIER == m_mBezierCurves.end())
|
if (DEFAULTBEZIER == m_mBezierCurves.end())
|
||||||
DEFAULTBEZIER = m_mBezierCurves.find("default");
|
DEFAULTBEZIER = m_mBezierCurves.find("default");
|
||||||
|
|
||||||
for (auto& av : m_lAnimatedVariables) {
|
for (auto& av : m_lAnimatedVariables) {
|
||||||
// get speed
|
// get speed
|
||||||
const auto SPEED = *av->m_pSpeed == 0 ? ANIMSPEED : *av->m_pSpeed;
|
const auto SPEED = *av->m_pSpeed == 0 ? *PANIMSPEED : *av->m_pSpeed;
|
||||||
|
|
||||||
// window stuff
|
// window stuff
|
||||||
const auto PWINDOW = (CWindow*)av->m_pWindow;
|
const auto PWINDOW = (CWindow*)av->m_pWindow;
|
||||||
@@ -45,28 +47,13 @@ void CAnimationManager::tick() {
|
|||||||
|
|
||||||
wlr_box WLRBOXPREV = {0,0,0,0};
|
wlr_box WLRBOXPREV = {0,0,0,0};
|
||||||
if (PWINDOW) {
|
if (PWINDOW) {
|
||||||
WLRBOXPREV = {(int)PWINDOW->m_vRealPosition.vec().x - BORDERSIZE - 1, (int)PWINDOW->m_vRealPosition.vec().y - BORDERSIZE - 1, (int)PWINDOW->m_vRealSize.vec().x + 2 * BORDERSIZE + 2, (int)PWINDOW->m_vRealSize.vec().y + 2 * BORDERSIZE + 2};
|
WLRBOXPREV = {(int)PWINDOW->m_vRealPosition.vec().x - (int)*PBORDERSIZE - 1, (int)PWINDOW->m_vRealPosition.vec().y - (int)*PBORDERSIZE - 1, (int)PWINDOW->m_vRealSize.vec().x + 2 * (int)*PBORDERSIZE + 2, (int)PWINDOW->m_vRealSize.vec().y + 2 * (int)*PBORDERSIZE + 2};
|
||||||
} else if (PWORKSPACE) {
|
} else if (PWORKSPACE) {
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||||
WLRBOXPREV = {(int)PMONITOR->vecPosition.x, (int)PMONITOR->vecPosition.y, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y};
|
WLRBOXPREV = {(int)PMONITOR->vecPosition.x, (int)PMONITOR->vecPosition.y, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y};
|
||||||
} else if (PLAYER) {
|
} else if (PLAYER) {
|
||||||
WLRBOXPREV = PLAYER->geometry;
|
WLRBOXPREV = PLAYER->geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if it's disabled, if so, warp
|
|
||||||
if (av->m_pEnabled == 0 || animationsDisabled) {
|
|
||||||
av->warp();
|
|
||||||
g_pHyprRenderer->damageBox(&WLRBOXPREV);
|
|
||||||
|
|
||||||
if (PWINDOW) {
|
|
||||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
|
||||||
// set size and pos if valid
|
|
||||||
if (g_pCompositor->windowValidMapped(PWINDOW))
|
|
||||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// beziers are with a switch unforto
|
// beziers are with a switch unforto
|
||||||
// TODO: maybe do something cleaner
|
// TODO: maybe do something cleaner
|
||||||
@@ -78,6 +65,13 @@ void CAnimationManager::tick() {
|
|||||||
switch (av->m_eVarType) {
|
switch (av->m_eVarType) {
|
||||||
case AVARTYPE_FLOAT: {
|
case AVARTYPE_FLOAT: {
|
||||||
if (!deltazero(av->m_fValue, av->m_fGoal)) {
|
if (!deltazero(av->m_fValue, av->m_fGoal)) {
|
||||||
|
|
||||||
|
// for disabled anims just warp
|
||||||
|
if (av->m_pEnabled == 0 || animationsDisabled) {
|
||||||
|
av->warp();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const auto DELTA = av->m_fGoal - av->m_fBegun;
|
const auto DELTA = av->m_fGoal - av->m_fBegun;
|
||||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||||
|
|
||||||
@@ -96,6 +90,13 @@ void CAnimationManager::tick() {
|
|||||||
}
|
}
|
||||||
case AVARTYPE_VECTOR: {
|
case AVARTYPE_VECTOR: {
|
||||||
if (!deltazero(av->m_vValue, av->m_vGoal)) {
|
if (!deltazero(av->m_vValue, av->m_vGoal)) {
|
||||||
|
|
||||||
|
// for disabled anims just warp
|
||||||
|
if (av->m_pEnabled == 0 || animationsDisabled) {
|
||||||
|
av->warp();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const auto DELTA = av->m_vGoal - av->m_vBegun;
|
const auto DELTA = av->m_vGoal - av->m_vBegun;
|
||||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||||
|
|
||||||
@@ -114,6 +115,13 @@ void CAnimationManager::tick() {
|
|||||||
}
|
}
|
||||||
case AVARTYPE_COLOR: {
|
case AVARTYPE_COLOR: {
|
||||||
if (!deltazero(av->m_cValue, av->m_cGoal)) {
|
if (!deltazero(av->m_cValue, av->m_cGoal)) {
|
||||||
|
|
||||||
|
// for disabled anims just warp
|
||||||
|
if (av->m_pEnabled == 0 || animationsDisabled) {
|
||||||
|
av->warp();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const auto DELTA = av->m_cGoal - av->m_cBegun;
|
const auto DELTA = av->m_cGoal - av->m_cBegun;
|
||||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||||
|
|
||||||
@@ -152,8 +160,9 @@ void CAnimationManager::tick() {
|
|||||||
RASSERT(PWINDOW, "Tried to AVARDAMAGE_BORDER a non-window AVAR!");
|
RASSERT(PWINDOW, "Tried to AVARDAMAGE_BORDER a non-window AVAR!");
|
||||||
|
|
||||||
// damage only the border.
|
// damage only the border.
|
||||||
const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size") + 1; // +1 for padding and shit
|
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||||
const auto ROUNDINGSIZE = g_pConfigManager->getInt("decoration:rounding") + 1;
|
const auto ROUNDINGSIZE = *PROUNDING + 1;
|
||||||
|
const auto BORDERSIZE = *PBORDERSIZE;
|
||||||
|
|
||||||
// damage for old box
|
// damage for old box
|
||||||
g_pHyprRenderer->damageBox(WLRBOXPREV.x - BORDERSIZE, WLRBOXPREV.y - BORDERSIZE, WLRBOXPREV.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // top
|
g_pHyprRenderer->damageBox(WLRBOXPREV.x - BORDERSIZE, WLRBOXPREV.y - BORDERSIZE, WLRBOXPREV.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // top
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
#include "EventManager.hpp"
|
#include "EventManager.hpp"
|
||||||
|
#include "../Compositor.hpp"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -26,10 +27,9 @@ void CEventManager::startThread() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink("/tmp/hypr/.socket2.sock");
|
|
||||||
|
|
||||||
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
|
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
|
||||||
strcpy(SERVERADDRESS.sun_path, "/tmp/hypr/.socket2.sock");
|
std::string socketPath = "/tmp/hypr/" + g_pCompositor->m_szInstanceSignature + "/.socket2.sock";
|
||||||
|
strcpy(SERVERADDRESS.sun_path, socketPath.c_str());
|
||||||
|
|
||||||
bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
|
bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ void CEventManager::startThread() {
|
|||||||
sockaddr_in clientAddress;
|
sockaddr_in clientAddress;
|
||||||
socklen_t clientSize = sizeof(clientAddress);
|
socklen_t clientSize = sizeof(clientAddress);
|
||||||
|
|
||||||
Debug::log(LOG, "Hypr socket 2 started.");
|
Debug::log(LOG, "Hypr socket 2 started at %s", socketPath.c_str());
|
||||||
|
|
||||||
// set the socket nonblock
|
// set the socket nonblock
|
||||||
int flags = fcntl(SOCKET, F_GETFL, 0);
|
int flags = fcntl(SOCKET, F_GETFL, 0);
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
#include "KeybindManager.hpp"
|
#include "KeybindManager.hpp"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
CKeybindManager::CKeybindManager() {
|
CKeybindManager::CKeybindManager() {
|
||||||
// initialize all dispatchers
|
// initialize all dispatchers
|
||||||
|
|
||||||
@@ -24,6 +26,10 @@ CKeybindManager::CKeybindManager() {
|
|||||||
m_mDispatchers["movecurrentworkspacetomonitor"] = moveCurrentWorkspaceToMonitor;
|
m_mDispatchers["movecurrentworkspacetomonitor"] = moveCurrentWorkspaceToMonitor;
|
||||||
m_mDispatchers["moveworkspacetomonitor"] = moveWorkspaceToMonitor;
|
m_mDispatchers["moveworkspacetomonitor"] = moveWorkspaceToMonitor;
|
||||||
m_mDispatchers["togglespecialworkspace"] = toggleSpecialWorkspace;
|
m_mDispatchers["togglespecialworkspace"] = toggleSpecialWorkspace;
|
||||||
|
m_mDispatchers["forcerendererreload"] = forceRendererReload;
|
||||||
|
m_mDispatchers["resizeactive"] = resizeActive;
|
||||||
|
m_mDispatchers["cyclenext"] = circleNext;
|
||||||
|
m_mDispatchers["focuswindowbyclass"] = focusWindowByClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::addKeybind(SKeybind kb) {
|
void CKeybindManager::addKeybind(SKeybind kb) {
|
||||||
@@ -109,8 +115,17 @@ bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) {
|
|||||||
|
|
||||||
const auto PSESSION = wlr_backend_get_session(g_pCompositor->m_sWLRBackend);
|
const auto PSESSION = wlr_backend_get_session(g_pCompositor->m_sWLRBackend);
|
||||||
if (PSESSION) {
|
if (PSESSION) {
|
||||||
const auto TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
const int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
||||||
wlr_session_change_vt(PSESSION, TTY);
|
wlr_session_change_vt(PSESSION, TTY);
|
||||||
|
|
||||||
|
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||||
|
g_pHyprOpenGL->destroyMonitorResources(&m); // mark resources as unusable anymore
|
||||||
|
m.noFrameSchedule = true;
|
||||||
|
m.framesToSkip = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(LOG, "Switched to VT %i, destroyed all render data, frames to skip for each: 2", TTY);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,14 +352,19 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
|||||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
|
|
||||||
|
|
||||||
const auto OLDWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
|
const auto OLDWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
// hack
|
// hack
|
||||||
std::string unusedName;
|
std::string unusedName;
|
||||||
const auto WORKSPACEID = getWorkspaceIDFromString(args, unusedName);
|
const auto WORKSPACEID = getWorkspaceIDFromString(args, unusedName);
|
||||||
|
|
||||||
|
if (WORKSPACEID == PWINDOW->m_iWorkspaceID) {
|
||||||
|
Debug::log(LOG, "Not moving to workspace because it didn't change.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
|
||||||
|
|
||||||
g_pKeybindManager->changeworkspace(args);
|
g_pKeybindManager->changeworkspace(args);
|
||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||||
@@ -397,6 +417,8 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
|||||||
for (auto& m : g_pCompositor->m_lMonitors)
|
for (auto& m : g_pCompositor->m_lMonitors)
|
||||||
m.specialWorkspaceOpen = false;
|
m.specialWorkspaceOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_pInputManager->refocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||||
@@ -453,6 +475,8 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
|||||||
POLDWORKSPACEONMON->m_fAlpha.setValueAndWarp(255.f);
|
POLDWORKSPACEONMON->m_fAlpha.setValueAndWarp(255.f);
|
||||||
|
|
||||||
m_bSuppressWorkspaceChangeEvents = false;
|
m_bSuppressWorkspaceChangeEvents = false;
|
||||||
|
|
||||||
|
g_pInputManager->refocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::moveFocusTo(std::string args) {
|
void CKeybindManager::moveFocusTo(std::string args) {
|
||||||
@@ -749,6 +773,8 @@ void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
||||||
|
if (args.find_first_of(' ') == std::string::npos)
|
||||||
|
return;
|
||||||
|
|
||||||
std::string workspace = args.substr(0, args.find_first_of(' '));
|
std::string workspace = args.substr(0, args.find_first_of(' '));
|
||||||
std::string monitor = args.substr(args.find_first_of(' ') + 1);
|
std::string monitor = args.substr(args.find_first_of(' ') + 1);
|
||||||
@@ -821,4 +847,63 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CKeybindManager::forceRendererReload(std::string args) {
|
||||||
|
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||||
|
auto rule = g_pConfigManager->getMonitorRuleFor(m.szName);
|
||||||
|
g_pHyprRenderer->applyMonitorRule(&m, &rule, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKeybindManager::resizeActive(std::string args) {
|
||||||
|
if (args.find_first_of(' ') == std::string::npos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string x = args.substr(0, args.find_first_of(' '));
|
||||||
|
std::string y = args.substr(args.find_first_of(' ') + 1);
|
||||||
|
|
||||||
|
if (!isNumber(x) || !isNumber(y)) {
|
||||||
|
Debug::log(ERR, "resizeTiledWindow: args not numbers");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int X = std::stoi(x);
|
||||||
|
const int Y = std::stoi(y);
|
||||||
|
|
||||||
|
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(Vector2D(X, Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKeybindManager::circleNext(std::string) {
|
||||||
|
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_pCompositor->focusWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
||||||
|
|
||||||
|
const auto MIDPOINT = g_pCompositor->m_pLastWindow->m_vRealPosition.goalv() + g_pCompositor->m_pLastWindow->m_vRealSize.goalv() / 2.f;
|
||||||
|
|
||||||
|
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, MIDPOINT.x, MIDPOINT.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKeybindManager::focusWindowByClass(std::string clazz) {
|
||||||
|
std::regex classCheck(clazz);
|
||||||
|
|
||||||
|
for (auto& w : g_pCompositor->m_lWindows) {
|
||||||
|
const auto windowClass = g_pXWaylandManager->getAppIDClass(&w);
|
||||||
|
|
||||||
|
if (!std::regex_search(windowClass, classCheck))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Debug::log(LOG, "Focusing to window name: %s", w.m_szTitle.c_str());
|
||||||
|
|
||||||
|
changeworkspace(std::to_string(w.m_iWorkspaceID));
|
||||||
|
|
||||||
|
g_pCompositor->focusWindow(&w);
|
||||||
|
|
||||||
|
const auto MIDPOINT = w.m_vRealPosition.goalv() + w.m_vRealSize.goalv() / 2.f;
|
||||||
|
|
||||||
|
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, MIDPOINT.x, MIDPOINT.y);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -54,6 +54,10 @@ private:
|
|||||||
static void moveCurrentWorkspaceToMonitor(std::string);
|
static void moveCurrentWorkspaceToMonitor(std::string);
|
||||||
static void moveWorkspaceToMonitor(std::string);
|
static void moveWorkspaceToMonitor(std::string);
|
||||||
static void toggleSpecialWorkspace(std::string);
|
static void toggleSpecialWorkspace(std::string);
|
||||||
|
static void forceRendererReload(std::string);
|
||||||
|
static void resizeActive(std::string);
|
||||||
|
static void circleNext(std::string);
|
||||||
|
static void focusWindowByClass(std::string);
|
||||||
|
|
||||||
friend class CCompositor;
|
friend class CCompositor;
|
||||||
};
|
};
|
||||||
|
@@ -94,6 +94,9 @@ std::string CHyprXWaylandManager::getAppIDClass(CWindow* pWindow) {
|
|||||||
try {
|
try {
|
||||||
if (pWindow->m_bIsX11) {
|
if (pWindow->m_bIsX11) {
|
||||||
if (pWindow->m_uSurface.xwayland) {
|
if (pWindow->m_uSurface.xwayland) {
|
||||||
|
if (!pWindow->m_bMappedX11 || !pWindow->m_bIsMapped)
|
||||||
|
return "unmanaged X11";
|
||||||
|
|
||||||
return std::string(pWindow->m_uSurface.xwayland->_class);
|
return std::string(pWindow->m_uSurface.xwayland->_class);
|
||||||
}
|
}
|
||||||
} else if (pWindow->m_uSurface.xdg) {
|
} else if (pWindow->m_uSurface.xdg) {
|
||||||
@@ -123,9 +126,10 @@ void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, const Vector2D& size)
|
|||||||
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, size.x, size.y);
|
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, size.x, size.y);
|
||||||
else {
|
else {
|
||||||
// I don't know if this is fucking correct, but the fucking idea of putting shadows into a window's surface is borderline criminal.
|
// I don't know if this is fucking correct, but the fucking idea of putting shadows into a window's surface is borderline criminal.
|
||||||
const auto XDELTA = pWindow->m_uSurface.xdg->surface->current.width - pWindow->m_uSurface.xdg->current.geometry.width;
|
|
||||||
const auto YDELTA = pWindow->m_uSurface.xdg->surface->current.height - pWindow->m_uSurface.xdg->current.geometry.height;
|
const auto XDELTA = pWindow->m_uSurface.xdg->current.geometry.width && pWindow->m_uSurface.xdg->current.geometry.height ? pWindow->m_uSurface.xdg->surface->current.width - pWindow->m_uSurface.xdg->current.geometry.width : 0;
|
||||||
|
const auto YDELTA = pWindow->m_uSurface.xdg->current.geometry.width && pWindow->m_uSurface.xdg->current.geometry.height ? pWindow->m_uSurface.xdg->surface->current.height - pWindow->m_uSurface.xdg->current.geometry.height : 0;
|
||||||
|
|
||||||
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x - XDELTA, size.y - YDELTA);
|
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x - XDELTA, size.y - YDELTA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,16 +1,17 @@
|
|||||||
#include "InputManager.hpp"
|
#include "InputManager.hpp"
|
||||||
#include "../Compositor.hpp"
|
#include "../../Compositor.hpp"
|
||||||
|
|
||||||
void CInputManager::onMouseMoved(wlr_pointer_motion_event* e) {
|
void CInputManager::onMouseMoved(wlr_pointer_motion_event* e) {
|
||||||
|
|
||||||
float sensitivity = g_pConfigManager->getFloat("general:sensitivity");
|
float sensitivity = g_pConfigManager->getFloat("general:sensitivity");
|
||||||
|
|
||||||
if (g_pConfigManager->getInt("general:apply_sens_to_raw") == 1)
|
const auto DELTA = g_pConfigManager->getInt("input:force_no_accel") == 1 ? Vector2D(e->unaccel_dx, e->unaccel_dy) : Vector2D(e->delta_x, e->delta_y);
|
||||||
wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, e->delta_x * sensitivity, e->delta_y * sensitivity, e->unaccel_dx * sensitivity, e->unaccel_dy * sensitivity);
|
|
||||||
else
|
|
||||||
wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, e->delta_x, e->delta_y, e->unaccel_dx, e->unaccel_dy);
|
|
||||||
|
|
||||||
wlr_cursor_move(g_pCompositor->m_sWLRCursor, &e->pointer->base, e->delta_x * sensitivity, e->delta_y * sensitivity);
|
if (g_pConfigManager->getInt("general:apply_sens_to_raw") == 1)
|
||||||
|
wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x * sensitivity, DELTA.y * sensitivity, e->unaccel_dx * sensitivity, e->unaccel_dy * sensitivity);
|
||||||
|
else
|
||||||
|
wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x, DELTA.y, e->unaccel_dx, e->unaccel_dy);
|
||||||
|
|
||||||
|
wlr_cursor_move(g_pCompositor->m_sWLRCursor, &e->pointer->base, DELTA.x * sensitivity, DELTA.y * sensitivity);
|
||||||
|
|
||||||
mouseMoveUnified(e->time_msec);
|
mouseMoveUnified(e->time_msec);
|
||||||
}
|
}
|
||||||
@@ -236,28 +237,24 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
|||||||
|
|
||||||
PNEWKEYBOARD->keyboard = keyboard;
|
PNEWKEYBOARD->keyboard = keyboard;
|
||||||
|
|
||||||
xkb_rule_names rules;
|
|
||||||
|
|
||||||
const auto CONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
|
||||||
const auto KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
||||||
|
|
||||||
const auto REPEATRATE = g_pConfigManager->getInt("input:repeat_rate");
|
const auto REPEATRATE = g_pConfigManager->getInt("input:repeat_rate");
|
||||||
const auto REPEATDELAY = g_pConfigManager->getInt("input:repeat_delay");
|
const auto REPEATDELAY = g_pConfigManager->getInt("input:repeat_delay");
|
||||||
|
|
||||||
wlr_keyboard_set_keymap(keyboard->keyboard, KEYMAP);
|
|
||||||
xkb_keymap_unref(KEYMAP);
|
|
||||||
xkb_context_unref(CONTEXT);
|
|
||||||
wlr_keyboard_set_repeat_info(keyboard->keyboard, std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
|
wlr_keyboard_set_repeat_info(keyboard->keyboard, std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
|
||||||
|
|
||||||
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&keyboard->keyboard->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
|
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&keyboard->keyboard->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
|
||||||
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&keyboard->keyboard->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
|
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&keyboard->keyboard->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
|
||||||
PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "Keyboard");
|
PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "Keyboard");
|
||||||
|
|
||||||
|
if (m_pActiveKeyboard)
|
||||||
|
m_pActiveKeyboard->active = false;
|
||||||
|
m_pActiveKeyboard = PNEWKEYBOARD;
|
||||||
|
|
||||||
|
setKeyboardLayout();
|
||||||
|
|
||||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keyboard->keyboard);
|
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keyboard->keyboard);
|
||||||
|
|
||||||
Debug::log(LOG, "New keyboard created, pointers Hypr: %x and WLR: %x", PNEWKEYBOARD, keyboard);
|
Debug::log(LOG, "New keyboard created, pointers Hypr: %x and WLR: %x", PNEWKEYBOARD, keyboard);
|
||||||
|
|
||||||
setKeyboardLayout();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInputManager::setKeyboardLayout() {
|
void CInputManager::setKeyboardLayout() {
|
||||||
@@ -285,9 +282,31 @@ void CInputManager::setKeyboardLayout() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: configure devices one by one
|
const auto PLASTKEEB = m_pActiveKeyboard->keyboard->keyboard;
|
||||||
for (auto& k : m_lKeyboards)
|
|
||||||
wlr_keyboard_set_keymap(k.keyboard->keyboard, KEYMAP);
|
if (!PLASTKEEB) {
|
||||||
|
xkb_keymap_unref(KEYMAP);
|
||||||
|
xkb_context_unref(CONTEXT);
|
||||||
|
|
||||||
|
Debug::log(ERR, "No Seat Keyboard???");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_keyboard_set_keymap(PLASTKEEB, KEYMAP);
|
||||||
|
|
||||||
|
wlr_keyboard_modifiers wlrMods = {0};
|
||||||
|
|
||||||
|
if (g_pConfigManager->getInt("input:numlock_by_default") == 1) {
|
||||||
|
// lock numlock
|
||||||
|
const auto IDX = xkb_map_mod_get_index(KEYMAP, XKB_MOD_NAME_NUM);
|
||||||
|
|
||||||
|
if (IDX != XKB_MOD_INVALID)
|
||||||
|
wlrMods.locked |= (uint32_t)1 << IDX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wlrMods.locked != 0) {
|
||||||
|
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &wlrMods);
|
||||||
|
}
|
||||||
|
|
||||||
xkb_keymap_unref(KEYMAP);
|
xkb_keymap_unref(KEYMAP);
|
||||||
xkb_context_unref(CONTEXT);
|
xkb_context_unref(CONTEXT);
|
||||||
@@ -330,6 +349,17 @@ void CInputManager::destroyKeyboard(SKeyboard* pKeyboard) {
|
|||||||
pKeyboard->hyprListener_keyboardMod.removeCallback();
|
pKeyboard->hyprListener_keyboardMod.removeCallback();
|
||||||
pKeyboard->hyprListener_keyboardKey.removeCallback();
|
pKeyboard->hyprListener_keyboardKey.removeCallback();
|
||||||
|
|
||||||
|
if (pKeyboard->active) {
|
||||||
|
m_lKeyboards.remove(*pKeyboard);
|
||||||
|
|
||||||
|
if (m_lKeyboards.size() > 0) {
|
||||||
|
m_pActiveKeyboard = &m_lKeyboards.back();
|
||||||
|
m_pActiveKeyboard->active = true;
|
||||||
|
} else {
|
||||||
|
m_pActiveKeyboard = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_lKeyboards.remove(*pKeyboard);
|
m_lKeyboards.remove(*pKeyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,3 +499,23 @@ void CInputManager::constrainMouse(SMouse* pMouse, wlr_pointer_constraint_v1* co
|
|||||||
void Events::listener_commitConstraint(void* owner, void* data) {
|
void Events::listener_commitConstraint(void* owner, void* data) {
|
||||||
//g_pInputManager->recheckConstraint((SMouse*)owner);
|
//g_pInputManager->recheckConstraint((SMouse*)owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CInputManager::updateCapabilities(wlr_input_device* pDev) {
|
||||||
|
// TODO: this is dumb
|
||||||
|
|
||||||
|
switch (pDev->type) {
|
||||||
|
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||||
|
m_uiCapabilities |= WL_SEAT_CAPABILITY_KEYBOARD;
|
||||||
|
break;
|
||||||
|
case WLR_INPUT_DEVICE_POINTER:
|
||||||
|
m_uiCapabilities |= WL_SEAT_CAPABILITY_POINTER;
|
||||||
|
break;
|
||||||
|
case WLR_INPUT_DEVICE_TOUCH:
|
||||||
|
m_uiCapabilities |= WL_SEAT_CAPABILITY_TOUCH;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_seat_set_capabilities(g_pCompositor->m_sSeat.seat, m_uiCapabilities);
|
||||||
|
}
|
@@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../../defines.hpp"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "../helpers/WLClasses.hpp"
|
#include "../../helpers/WLClasses.hpp"
|
||||||
#include "../Window.hpp"
|
#include "../../Window.hpp"
|
||||||
|
|
||||||
class CInputManager {
|
class CInputManager {
|
||||||
public:
|
public:
|
||||||
@@ -28,6 +28,7 @@ public:
|
|||||||
void setKeyboardLayout();
|
void setKeyboardLayout();
|
||||||
|
|
||||||
void updateDragIcon();
|
void updateDragIcon();
|
||||||
|
void updateCapabilities(wlr_input_device*);
|
||||||
|
|
||||||
|
|
||||||
// for dragging floating windows
|
// for dragging floating windows
|
||||||
@@ -36,14 +37,28 @@ public:
|
|||||||
|
|
||||||
SDrag m_sDrag;
|
SDrag m_sDrag;
|
||||||
|
|
||||||
std::list<SConstraint> m_lConstraints;
|
std::list<SConstraint> m_lConstraints;
|
||||||
|
std::list<SKeyboard> m_lKeyboards;
|
||||||
|
std::list<SMouse> m_lMice;
|
||||||
|
|
||||||
private:
|
// tablets
|
||||||
|
std::list<STablet> m_lTablets;
|
||||||
|
std::list<STabletTool> m_lTabletTools;
|
||||||
|
std::list<STabletPad> m_lTabletPads;
|
||||||
|
|
||||||
std::list<SKeyboard> m_lKeyboards;
|
void newTabletTool(wlr_input_device*);
|
||||||
std::list<SMouse> m_lMice;
|
void newTabletPad(wlr_input_device*);
|
||||||
|
void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false);
|
||||||
|
|
||||||
|
SKeyboard* m_pActiveKeyboard = nullptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint32_t m_uiCapabilities = 0;
|
||||||
|
|
||||||
void mouseMoveUnified(uint32_t, bool refocus = false);
|
void mouseMoveUnified(uint32_t, bool refocus = false);
|
||||||
|
|
||||||
|
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CInputManager> g_pInputManager;
|
inline std::unique_ptr<CInputManager> g_pInputManager;
|
229
src/managers/input/Tablets.cpp
Normal file
229
src/managers/input/Tablets.cpp
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
#include "InputManager.hpp"
|
||||||
|
#include "../../Compositor.hpp"
|
||||||
|
|
||||||
|
void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||||
|
const auto PNEWTABLET = &m_lTablets.emplace_back();
|
||||||
|
|
||||||
|
PNEWTABLET->wlrTablet = pDevice->tablet;
|
||||||
|
PNEWTABLET->wlrDevice = pDevice;
|
||||||
|
PNEWTABLET->wlrTabletV2 = wlr_tablet_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice);
|
||||||
|
PNEWTABLET->wlrTablet->data = PNEWTABLET;
|
||||||
|
|
||||||
|
Debug::log(LOG, "Attaching tablet to cursor!");
|
||||||
|
|
||||||
|
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, pDevice);
|
||||||
|
|
||||||
|
PNEWTABLET->hyprListener_Destroy.initCallback(&pDevice->events.destroy, [](void* owner, void* data) {
|
||||||
|
const auto PTAB = (STablet*)owner;
|
||||||
|
|
||||||
|
g_pInputManager->m_lTablets.remove(*PTAB);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Removed a tablet");
|
||||||
|
}, PNEWTABLET, "Tablet");
|
||||||
|
|
||||||
|
PNEWTABLET->hyprListener_Axis.initCallback(&pDevice->tablet->events.axis, [](void* owner, void* data) {
|
||||||
|
|
||||||
|
const auto EVENT = (wlr_tablet_tool_axis_event*)data;
|
||||||
|
const auto PTAB = (STablet*)owner;
|
||||||
|
|
||||||
|
switch (EVENT->tool->type) {
|
||||||
|
case WLR_TABLET_TOOL_TYPE_MOUSE:
|
||||||
|
wlr_cursor_move(g_pCompositor->m_sWLRCursor, PTAB->wlrDevice, EVENT->dx, EVENT->dy);
|
||||||
|
g_pInputManager->refocus();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
double x = (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_X) ? EVENT->x : NAN;
|
||||||
|
double y = (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_Y) ? EVENT->y : NAN;
|
||||||
|
wlr_cursor_warp_absolute(g_pCompositor->m_sWLRCursor, PTAB->wlrDevice, x, y);
|
||||||
|
g_pInputManager->refocus();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool);
|
||||||
|
|
||||||
|
// TODO: this might be wrong
|
||||||
|
if (PTOOL->active) {
|
||||||
|
g_pInputManager->refocus();
|
||||||
|
|
||||||
|
g_pInputManager->focusTablet(PTAB, EVENT->tool, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_PRESSURE)
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_pressure(PTOOL->wlrTabletToolV2, EVENT->pressure);
|
||||||
|
|
||||||
|
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_DISTANCE)
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_distance(PTOOL->wlrTabletToolV2, EVENT->distance);
|
||||||
|
|
||||||
|
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_ROTATION)
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_rotation(PTOOL->wlrTabletToolV2, EVENT->rotation);
|
||||||
|
|
||||||
|
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_SLIDER)
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_slider(PTOOL->wlrTabletToolV2, EVENT->slider);
|
||||||
|
|
||||||
|
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_WHEEL)
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_wheel(PTOOL->wlrTabletToolV2, EVENT->wheel_delta, 0);
|
||||||
|
|
||||||
|
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_TILT_X)
|
||||||
|
PTOOL->tiltX = EVENT->tilt_x;
|
||||||
|
|
||||||
|
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_TILT_Y)
|
||||||
|
PTOOL->tiltY = EVENT->tilt_y;
|
||||||
|
|
||||||
|
if (EVENT->updated_axes & (WLR_TABLET_TOOL_AXIS_TILT_X | WLR_TABLET_TOOL_AXIS_TILT_Y))
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_tilt(PTOOL->wlrTabletToolV2, PTOOL->tiltX, PTOOL->tiltY);
|
||||||
|
|
||||||
|
}, PNEWTABLET, "Tablet");
|
||||||
|
|
||||||
|
PNEWTABLET->hyprListener_Tip.initCallback(&pDevice->tablet->events.tip, [](void* owner, void* data) {
|
||||||
|
const auto EVENT = (wlr_tablet_tool_tip_event*)data;
|
||||||
|
const auto PTAB = (STablet*)owner;
|
||||||
|
|
||||||
|
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool);
|
||||||
|
|
||||||
|
// TODO: this might be wrong
|
||||||
|
if (EVENT->state == WLR_TABLET_TOOL_TIP_DOWN) {
|
||||||
|
g_pInputManager->refocus();
|
||||||
|
g_pInputManager->focusTablet(PTAB, EVENT->tool);
|
||||||
|
wlr_send_tablet_v2_tablet_tool_down(PTOOL->wlrTabletToolV2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wlr_send_tablet_v2_tablet_tool_up(PTOOL->wlrTabletToolV2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, PNEWTABLET, "Tablet");
|
||||||
|
|
||||||
|
PNEWTABLET->hyprListener_Button.initCallback(&pDevice->tablet->events.button, [](void* owner, void* data) {
|
||||||
|
const auto EVENT = (wlr_tablet_tool_button_event*)data;
|
||||||
|
|
||||||
|
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool);
|
||||||
|
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_button(PTOOL->wlrTabletToolV2, (zwp_tablet_pad_v2_button_state)EVENT->button, (zwp_tablet_pad_v2_button_state)EVENT->state);
|
||||||
|
|
||||||
|
}, PNEWTABLET, "Tablet");
|
||||||
|
|
||||||
|
PNEWTABLET->hyprListener_Proximity.initCallback(&pDevice->tablet->events.proximity, [](void* owner, void* data) {
|
||||||
|
const auto EVENT = (wlr_tablet_tool_proximity_event*)data;
|
||||||
|
const auto PTAB = (STablet*)owner;
|
||||||
|
|
||||||
|
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool);
|
||||||
|
|
||||||
|
if (EVENT->state == WLR_TABLET_TOOL_PROXIMITY_OUT) {
|
||||||
|
PTOOL->active = false;
|
||||||
|
|
||||||
|
if (PTOOL->pSurface) {
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_proximity_out(PTOOL->wlrTabletToolV2);
|
||||||
|
PTOOL->pSurface = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
PTOOL->active = true;
|
||||||
|
g_pInputManager->refocus();
|
||||||
|
g_pInputManager->focusTablet(PTAB, EVENT->tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, PNEWTABLET, "Tablet");
|
||||||
|
}
|
||||||
|
|
||||||
|
STabletTool* CInputManager::ensureTabletToolPresent(wlr_tablet_tool* pTool) {
|
||||||
|
if (pTool->data == nullptr) {
|
||||||
|
const auto PTOOL = &m_lTabletTools.emplace_back();
|
||||||
|
|
||||||
|
Debug::log(LOG, "Creating tablet tool v2 for %x", pTool);
|
||||||
|
|
||||||
|
PTOOL->wlrTabletTool = pTool;
|
||||||
|
pTool->data = PTOOL;
|
||||||
|
|
||||||
|
PTOOL->wlrTabletToolV2 = wlr_tablet_tool_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pTool);
|
||||||
|
|
||||||
|
PTOOL->hyprListener_TabletToolDestroy.initCallback(&pTool->events.destroy, [](void* owner, void* data) {
|
||||||
|
const auto PTOOL = (STabletTool*)owner;
|
||||||
|
|
||||||
|
PTOOL->wlrTabletTool->data = nullptr;
|
||||||
|
g_pInputManager->m_lTabletTools.remove(*PTOOL);
|
||||||
|
}, PTOOL, "Tablet Tool V1");
|
||||||
|
|
||||||
|
//TODO: set cursor request
|
||||||
|
}
|
||||||
|
|
||||||
|
return (STabletTool*)pTool->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||||
|
const auto PNEWPAD = &m_lTabletPads.emplace_back();
|
||||||
|
|
||||||
|
PNEWPAD->wlrTabletPadV2 = wlr_tablet_pad_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice);
|
||||||
|
|
||||||
|
PNEWPAD->hyprListener_Button.initCallback(&pDevice->tablet_pad->events.button, [](void* owner, void* data) {
|
||||||
|
|
||||||
|
const auto EVENT = (wlr_tablet_pad_button_event*)data;
|
||||||
|
const auto PPAD = (STabletPad*)owner;
|
||||||
|
|
||||||
|
wlr_tablet_v2_tablet_pad_notify_mode(PPAD->wlrTabletPadV2, EVENT->group, EVENT->mode, EVENT->time_msec);
|
||||||
|
wlr_tablet_v2_tablet_pad_notify_button(PPAD->wlrTabletPadV2, EVENT->button, EVENT->time_msec, (zwp_tablet_pad_v2_button_state)EVENT->state);
|
||||||
|
|
||||||
|
}, PNEWPAD, "Tablet Pad");
|
||||||
|
|
||||||
|
PNEWPAD->hyprListener_Strip.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
|
||||||
|
|
||||||
|
const auto EVENT = (wlr_tablet_pad_strip_event*)data;
|
||||||
|
const auto PPAD = (STabletPad*)owner;
|
||||||
|
|
||||||
|
wlr_tablet_v2_tablet_pad_notify_strip(PPAD->wlrTabletPadV2, EVENT->strip, EVENT->position, EVENT->source == WLR_TABLET_PAD_STRIP_SOURCE_FINGER, EVENT->time_msec);
|
||||||
|
|
||||||
|
}, PNEWPAD, "Tablet Pad");
|
||||||
|
|
||||||
|
PNEWPAD->hyprListener_Ring.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
|
||||||
|
|
||||||
|
const auto EVENT = (wlr_tablet_pad_ring_event*)data;
|
||||||
|
const auto PPAD = (STabletPad*)owner;
|
||||||
|
|
||||||
|
wlr_tablet_v2_tablet_pad_notify_ring(PPAD->wlrTabletPadV2, EVENT->ring, EVENT->position, EVENT->source == WLR_TABLET_PAD_RING_SOURCE_FINGER, EVENT->time_msec);
|
||||||
|
|
||||||
|
}, PNEWPAD, "Tablet Pad");
|
||||||
|
|
||||||
|
PNEWPAD->hyprListener_Attach.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
|
||||||
|
|
||||||
|
const auto TABLET = (wlr_tablet_tool*)data;
|
||||||
|
const auto PPAD = (STabletPad*)owner;
|
||||||
|
|
||||||
|
PPAD->pTabletParent = (STablet*)TABLET->data;
|
||||||
|
|
||||||
|
if (!PPAD->pTabletParent)
|
||||||
|
Debug::log(ERR, "tabletpad got attached to a nullptr tablet!! this might be bad.");
|
||||||
|
|
||||||
|
}, PNEWPAD, "Tablet Pad");
|
||||||
|
|
||||||
|
PNEWPAD->hyprListener_Destroy.initCallback(&pDevice->events.destroy, [](void* owner, void* data) {
|
||||||
|
|
||||||
|
const auto PPAD = (STabletPad*)owner;
|
||||||
|
|
||||||
|
g_pInputManager->m_lTabletPads.remove(*PPAD);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Removed a tablet pad");
|
||||||
|
|
||||||
|
}, PNEWPAD, "Tablet Pad");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInputManager::focusTablet(STablet* pTab, wlr_tablet_tool* pTool, bool motion) {
|
||||||
|
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(pTool);
|
||||||
|
|
||||||
|
if (const auto PWINDOW = g_pCompositor->m_pLastWindow; g_pCompositor->windowValidMapped(PWINDOW)) {
|
||||||
|
const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal();
|
||||||
|
|
||||||
|
const auto LOCAL = CURSORPOS - PWINDOW->m_vRealPosition.goalv();
|
||||||
|
|
||||||
|
if (PTOOL->pSurface != g_pCompositor->m_pLastFocus)
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_proximity_out(PTOOL->wlrTabletToolV2);
|
||||||
|
|
||||||
|
if (g_pCompositor->m_pLastFocus) {
|
||||||
|
PTOOL->pSurface = g_pCompositor->m_pLastFocus;
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_proximity_in(PTOOL->wlrTabletToolV2, pTab->wlrTabletV2, g_pCompositor->m_pLastFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (motion)
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_motion(PTOOL->wlrTabletToolV2, LOCAL.x, LOCAL.y);
|
||||||
|
} else {
|
||||||
|
if (PTOOL->pSurface)
|
||||||
|
wlr_tablet_v2_tablet_tool_notify_proximity_out(PTOOL->wlrTabletToolV2);
|
||||||
|
}
|
||||||
|
}
|
@@ -264,11 +264,14 @@ void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
|
|||||||
const auto BOTTOMRIGHT = Vector2D(box->width - round, box->height - round);
|
const auto BOTTOMRIGHT = Vector2D(box->width - round, box->height - round);
|
||||||
const auto FULLSIZE = Vector2D(box->width, box->height);
|
const auto FULLSIZE = Vector2D(box->width, box->height);
|
||||||
|
|
||||||
|
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||||
|
|
||||||
// Rounded corners
|
// Rounded corners
|
||||||
glUniform2f(glGetUniformLocation(m_shQUAD.program, "topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
glUniform2f(glGetUniformLocation(m_shQUAD.program, "topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||||
glUniform2f(glGetUniformLocation(m_shQUAD.program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
glUniform2f(glGetUniformLocation(m_shQUAD.program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||||
glUniform2f(glGetUniformLocation(m_shQUAD.program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
glUniform2f(glGetUniformLocation(m_shQUAD.program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||||
glUniform1f(glGetUniformLocation(m_shQUAD.program, "radius"), round);
|
glUniform1f(glGetUniformLocation(m_shQUAD.program, "radius"), round);
|
||||||
|
glUniform1i(glGetUniformLocation(m_shQUAD.program, "primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 1 && round != 0));
|
||||||
|
|
||||||
glVertexAttribPointer(m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
glVertexAttribPointer(m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
glVertexAttribPointer(m_shQUAD.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
glVertexAttribPointer(m_shQUAD.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
@@ -304,7 +307,7 @@ void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float al
|
|||||||
scissor((wlr_box*)nullptr);
|
scissor((wlr_box*)nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool border) {
|
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool border, bool noAA) {
|
||||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||||
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||||
|
|
||||||
@@ -356,12 +359,14 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
|||||||
const auto TOPLEFT = Vector2D(round, round);
|
const auto TOPLEFT = Vector2D(round, round);
|
||||||
const auto BOTTOMRIGHT = Vector2D(tex.m_vSize.x - round, tex.m_vSize.y - round);
|
const auto BOTTOMRIGHT = Vector2D(tex.m_vSize.x - round, tex.m_vSize.y - round);
|
||||||
const auto FULLSIZE = tex.m_vSize;
|
const auto FULLSIZE = tex.m_vSize;
|
||||||
|
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||||
|
|
||||||
// Rounded corners
|
// Rounded corners
|
||||||
glUniform2f(glGetUniformLocation(shader->program, "topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
glUniform2f(glGetUniformLocation(shader->program, "topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||||
glUniform2f(glGetUniformLocation(shader->program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
glUniform2f(glGetUniformLocation(shader->program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||||
glUniform2f(glGetUniformLocation(shader->program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
glUniform2f(glGetUniformLocation(shader->program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||||
glUniform1f(glGetUniformLocation(shader->program, "radius"), round);
|
glUniform1f(glGetUniformLocation(shader->program, "radius"), round);
|
||||||
|
glUniform1i(glGetUniformLocation(shader->program, "primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !border && !noAA));
|
||||||
|
|
||||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
@@ -403,8 +408,9 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
|||||||
// some other func might be using it.
|
// some other func might be using it.
|
||||||
if (border) {
|
if (border) {
|
||||||
auto BORDERCOL = m_pCurrentWindow->m_cRealBorderColor.col();
|
auto BORDERCOL = m_pCurrentWindow->m_cRealBorderColor.col();
|
||||||
|
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||||
BORDERCOL.a *= alpha / 255.f;
|
BORDERCOL.a *= alpha / 255.f;
|
||||||
renderBorder(pBox, BORDERCOL, g_pConfigManager->getInt("general:border_size"), round);
|
renderBorder(pBox, BORDERCOL, *PBORDERSIZE, round);
|
||||||
glStencilMask(-1);
|
glStencilMask(-1);
|
||||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
@@ -432,14 +438,14 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||||
|
|
||||||
// get the config settings
|
// get the config settings
|
||||||
const auto BLURSIZE = g_pConfigManager->getInt("decoration:blur_size");
|
static auto *const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_size")->intValue;
|
||||||
const auto BLURPASSES = g_pConfigManager->getInt("decoration:blur_passes");
|
static auto *const PBLURPASSES = &g_pConfigManager->getConfigValuePtr("decoration:blur_passes")->intValue;
|
||||||
|
|
||||||
// prep damage
|
// prep damage
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
pixman_region32_init(&damage);
|
pixman_region32_init(&damage);
|
||||||
pixman_region32_copy(&damage, originalDamage);
|
pixman_region32_copy(&damage, originalDamage);
|
||||||
wlr_region_expand(&damage, &damage, pow(2, BLURPASSES) * BLURSIZE);
|
wlr_region_expand(&damage, &damage, pow(2, *PBLURPASSES) * *PBLURSIZE);
|
||||||
|
|
||||||
// helper
|
// helper
|
||||||
const auto PMIRRORFB = &m_mMonitorRenderResources[m_RenderData.pMonitor].mirrorFB;
|
const auto PMIRRORFB = &m_mMonitorRenderResources[m_RenderData.pMonitor].mirrorFB;
|
||||||
@@ -464,7 +470,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||||||
|
|
||||||
// prep two shaders
|
// prep two shaders
|
||||||
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
|
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
|
||||||
glUniform1f(glGetUniformLocation(pShader->program, "radius"), BLURSIZE * (a / 255.f)); // this makes the blursize change with a
|
glUniform1f(glGetUniformLocation(pShader->program, "radius"), *PBLURSIZE * (a / 255.f)); // this makes the blursize change with a
|
||||||
if (pShader == &m_shBLUR1)
|
if (pShader == &m_shBLUR1)
|
||||||
glUniform2f(glGetUniformLocation(m_shBLUR1.program, "halfpixel"), 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
|
glUniform2f(glGetUniformLocation(m_shBLUR1.program, "halfpixel"), 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
|
||||||
else
|
else
|
||||||
@@ -508,12 +514,12 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||||||
drawPass(&m_shBLUR1, &tempDamage);
|
drawPass(&m_shBLUR1, &tempDamage);
|
||||||
|
|
||||||
// and draw
|
// and draw
|
||||||
for (int i = 1; i < BLURPASSES; ++i) {
|
for (int i = 1; i < *PBLURPASSES; ++i) {
|
||||||
wlr_region_scale(&tempDamage, &damage, 1.f / (1 << (i + 1)));
|
wlr_region_scale(&tempDamage, &damage, 1.f / (1 << (i + 1)));
|
||||||
drawPass(&m_shBLUR1, &tempDamage); // down
|
drawPass(&m_shBLUR1, &tempDamage); // down
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = BLURPASSES - 1; i >= 0; --i) {
|
for (int i = *PBLURPASSES - 1; i >= 0; --i) {
|
||||||
wlr_region_scale(&tempDamage, &damage, 1.f / (1 << i)); // when upsampling we make the region twice as big
|
wlr_region_scale(&tempDamage, &damage, 1.f / (1 << i)); // when upsampling we make the region twice as big
|
||||||
drawPass(&m_shBLUR2, &tempDamage); // up
|
drawPass(&m_shBLUR2, &tempDamage); // up
|
||||||
}
|
}
|
||||||
@@ -533,7 +539,9 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||||||
void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, wlr_surface* pSurface, int round, bool border) {
|
void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, wlr_surface* pSurface, int round, bool border) {
|
||||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
|
||||||
|
|
||||||
if (g_pConfigManager->getInt("decoration:blur") == 0) {
|
static auto *const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
|
||||||
|
|
||||||
|
if (*PBLURENABLED == 0) {
|
||||||
renderTexture(tex, pBox, a, round, false, border);
|
renderTexture(tex, pBox, a, round, false, border);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -556,8 +564,10 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||||||
pixman_region32_copy(&inverseOpaque, &damage);
|
pixman_region32_copy(&inverseOpaque, &damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pixman_region32_not_empty(&damage))
|
if (!pixman_region32_not_empty(&inverseOpaque)) {
|
||||||
return; // if its empty, reject.
|
renderTexture(tex, pBox, a, round, false, border); // reject blurring a fully opaque window
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// blur the main FB, it will be rendered onto the mirror
|
// blur the main FB, it will be rendered onto the mirror
|
||||||
const auto POUTFB = blurMainFramebufferWithDamage(a, pBox, &inverseOpaque);
|
const auto POUTFB = blurMainFramebufferWithDamage(a, pBox, &inverseOpaque);
|
||||||
@@ -588,7 +598,8 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||||||
wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||||
if (pixman_region32_not_empty(&damage)) {
|
if (pixman_region32_not_empty(&damage)) {
|
||||||
// render our great blurred FB
|
// render our great blurred FB
|
||||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, g_pConfigManager->getInt("decoration:blur_ignore_opacity") ? 255.f : a, &damage);
|
static auto *const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur_ignore_opacity")->intValue;
|
||||||
|
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 255.f : a, &damage);
|
||||||
|
|
||||||
// render the window, but clear stencil
|
// render the window, but clear stencil
|
||||||
glClearStencil(0);
|
glClearStencil(0);
|
||||||
@@ -598,7 +609,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||||||
glStencilFunc(GL_ALWAYS, 1, -1);
|
glStencilFunc(GL_ALWAYS, 1, -1);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
|
|
||||||
renderTextureInternalWithDamage(tex, pBox, a, &damage, round);
|
renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true);
|
||||||
|
|
||||||
// then stop
|
// then stop
|
||||||
glStencilFunc(GL_EQUAL, 1, -1);
|
glStencilFunc(GL_EQUAL, 1, -1);
|
||||||
@@ -612,7 +623,8 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||||||
} else {
|
} else {
|
||||||
auto BORDERCOL = m_pCurrentWindow->m_cRealBorderColor.col();
|
auto BORDERCOL = m_pCurrentWindow->m_cRealBorderColor.col();
|
||||||
BORDERCOL.a *= a / 255.f;
|
BORDERCOL.a *= a / 255.f;
|
||||||
renderBorder(pBox, BORDERCOL, g_pConfigManager->getInt("general:border_size"), round);
|
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||||
|
renderBorder(pBox, BORDERCOL, *PBORDERSIZE, round);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
@@ -110,7 +110,7 @@ private:
|
|||||||
// returns the out FB, can be either Mirror or MirrorSwap
|
// returns the out FB, can be either Mirror or MirrorSwap
|
||||||
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
||||||
|
|
||||||
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool border = false);
|
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool border = false, bool noAA = false);
|
||||||
void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0);
|
void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -19,7 +19,9 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
|||||||
}
|
}
|
||||||
scaleBox(&windowBox, RDATA->output->scale);
|
scaleBox(&windowBox, RDATA->output->scale);
|
||||||
|
|
||||||
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? g_pConfigManager->getInt("decoration:rounding") : RDATA->rounding;
|
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||||
|
|
||||||
|
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
|
||||||
|
|
||||||
if (RDATA->surface && surface == RDATA->surface)
|
if (RDATA->surface && surface == RDATA->surface)
|
||||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding, RDATA->decorate);
|
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding, RDATA->decorate);
|
||||||
@@ -533,7 +535,9 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) {
|
|||||||
|
|
||||||
pixman_region32_fini(&damageBox);
|
pixman_region32_fini(&damageBox);
|
||||||
|
|
||||||
if (g_pConfigManager->getInt("debug:log_damage"))
|
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||||
|
|
||||||
|
if (*PLOGDAMAGE)
|
||||||
Debug::log(LOG, "Damage: Surface (extents): xy: %d, %d wh: %d, %d", damageBox.extents.x1, damageBox.extents.y1, damageBox.extents.x2 - damageBox.extents.x1, damageBox.extents.y2 - damageBox.extents.y1);
|
Debug::log(LOG, "Damage: Surface (extents): xy: %d, %d wh: %d, %d", damageBox.extents.x1, damageBox.extents.y1, damageBox.extents.x2 - damageBox.extents.x1, damageBox.extents.y2 - damageBox.extents.y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,12 +555,14 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
|||||||
wlr_output_damage_add_box(m.damage, &fixedDamageBox);
|
wlr_output_damage_add_box(m.damage, &fixedDamageBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_pConfigManager->getInt("debug:log_damage"))
|
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||||
|
|
||||||
|
if (*PLOGDAMAGE)
|
||||||
Debug::log(LOG, "Damage: Window floated (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
Debug::log(LOG, "Damage: Window floated (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
||||||
} else {
|
} else {
|
||||||
// damage by real size & pos + border size * 2 (JIC)
|
// damage by real size & pos + border size * 2 (JIC)
|
||||||
const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size");
|
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||||
wlr_box damageBox = { pWindow->m_vRealPosition.vec().x - BORDERSIZE - 1, pWindow->m_vRealPosition.vec().y - BORDERSIZE - 1, pWindow->m_vRealSize.vec().x + 2 * BORDERSIZE + 2, pWindow->m_vRealSize.vec().y + 2 * BORDERSIZE + 2};
|
wlr_box damageBox = { pWindow->m_vRealPosition.vec().x - *PBORDERSIZE - 1, pWindow->m_vRealPosition.vec().y - *PBORDERSIZE - 1, pWindow->m_vRealSize.vec().x + 2 * *PBORDERSIZE + 2, pWindow->m_vRealSize.vec().y + 2 * *PBORDERSIZE + 2};
|
||||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||||
wlr_box fixedDamageBox = damageBox;
|
wlr_box fixedDamageBox = damageBox;
|
||||||
fixedDamageBox.x -= m.vecPosition.x;
|
fixedDamageBox.x -= m.vecPosition.x;
|
||||||
@@ -565,7 +571,9 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
|||||||
wlr_output_damage_add_box(m.damage, &fixedDamageBox);
|
wlr_output_damage_add_box(m.damage, &fixedDamageBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_pConfigManager->getInt("debug:log_damage"))
|
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||||
|
|
||||||
|
if (*PLOGDAMAGE)
|
||||||
Debug::log(LOG, "Damage: Window tiled (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
Debug::log(LOG, "Damage: Window tiled (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -574,7 +582,9 @@ void CHyprRenderer::damageMonitor(SMonitor* pMonitor) {
|
|||||||
wlr_box damageBox = {0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y};
|
wlr_box damageBox = {0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y};
|
||||||
wlr_output_damage_add_box(pMonitor->damage, &damageBox);
|
wlr_output_damage_add_box(pMonitor->damage, &damageBox);
|
||||||
|
|
||||||
if (g_pConfigManager->getInt("debug:log_damage"))
|
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||||
|
|
||||||
|
if (*PLOGDAMAGE)
|
||||||
Debug::log(LOG, "Damage: Monitor %s", pMonitor->szName.c_str());
|
Debug::log(LOG, "Damage: Monitor %s", pMonitor->szName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,7 +595,9 @@ void CHyprRenderer::damageBox(wlr_box* pBox) {
|
|||||||
wlr_output_damage_add_box(m.damage, &damageBox);
|
wlr_output_damage_add_box(m.damage, &damageBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_pConfigManager->getInt("debug:log_damage"))
|
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||||
|
|
||||||
|
if (*PLOGDAMAGE)
|
||||||
Debug::log(LOG, "Damage: Box: xy: %d, %d wh: %d, %d", pBox->x, pBox->y, pBox->width, pBox->height);
|
Debug::log(LOG, "Damage: Box: xy: %d, %d wh: %d, %d", pBox->x, pBox->y, pBox->width, pBox->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,5 +729,5 @@ void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
|||||||
arrangeLayersForMonitor(pMonitor->ID);
|
arrangeLayersForMonitor(pMonitor->ID);
|
||||||
|
|
||||||
// frame skip
|
// frame skip
|
||||||
pMonitor->needsFrameSkip = true;
|
pMonitor->framesToSkip = 1;
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,147 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVarName) -> std::string {
|
||||||
|
return R"#(
|
||||||
|
if (pixCoord[0] < topLeft[0]) {
|
||||||
|
// we're close left
|
||||||
|
if (pixCoord[1] < topLeft[1]) {
|
||||||
|
// top
|
||||||
|
|
||||||
|
if (ignoreCorners == 1) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float topLeftDistance = distance(topLeft, pixCoord);
|
||||||
|
|
||||||
|
if (topLeftDistance > radius - 1.0) {
|
||||||
|
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
} else if (primitiveMultisample == 1) {
|
||||||
|
float distances = 0.0;
|
||||||
|
if (distance(topLeft, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(topLeft, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(topLeft, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(topLeft, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
|
||||||
|
if (distances == 0.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distances = distances / 4.0;
|
||||||
|
|
||||||
|
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pixCoord[1] > bottomRight[1]) {
|
||||||
|
// bottom
|
||||||
|
|
||||||
|
if (ignoreCorners == 1) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
|
||||||
|
|
||||||
|
if (topLeftDistance > radius - 1.0) {
|
||||||
|
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
} else if (primitiveMultisample == 1) {
|
||||||
|
float distances = 0.0;
|
||||||
|
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
|
||||||
|
if (distances == 0.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distances = distances / 4.0;
|
||||||
|
|
||||||
|
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pixCoord[0] > bottomRight[0]) {
|
||||||
|
// we're close right
|
||||||
|
if (pixCoord[1] < topLeft[1]) {
|
||||||
|
// top
|
||||||
|
|
||||||
|
if (ignoreCorners == 1) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
|
||||||
|
|
||||||
|
if (topLeftDistance > radius - 1.0) {
|
||||||
|
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
} else if (primitiveMultisample == 1) {
|
||||||
|
float distances = 0.0;
|
||||||
|
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
|
||||||
|
if (distances == 0.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distances = distances / 4.0;
|
||||||
|
|
||||||
|
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pixCoord[1] > bottomRight[1]) {
|
||||||
|
// bottom
|
||||||
|
|
||||||
|
if (ignoreCorners == 1) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float topLeftDistance = distance(bottomRight, pixCoord);
|
||||||
|
|
||||||
|
if (topLeftDistance > radius - 1.0) {
|
||||||
|
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
} else if (primitiveMultisample == 1) {
|
||||||
|
float distances = 0.0;
|
||||||
|
if (distance(bottomRight, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(bottomRight, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(bottomRight, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(bottomRight, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
|
||||||
|
if (distances == 0.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distances = distances / 4.0;
|
||||||
|
|
||||||
|
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)#";
|
||||||
|
};
|
||||||
|
|
||||||
inline const std::string QUADVERTSRC = R"#(
|
inline const std::string QUADVERTSRC = R"#(
|
||||||
uniform mat3 proj;
|
uniform mat3 proj;
|
||||||
uniform vec4 color;
|
uniform vec4 color;
|
||||||
@@ -26,6 +167,9 @@ uniform vec2 bottomRight;
|
|||||||
uniform vec2 fullSize;
|
uniform vec2 fullSize;
|
||||||
uniform float radius;
|
uniform float radius;
|
||||||
|
|
||||||
|
uniform int primitiveMultisample;
|
||||||
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
if (radius == 0.0) {
|
if (radius == 0.0) {
|
||||||
gl_FragColor = v_color;
|
gl_FragColor = v_color;
|
||||||
@@ -34,38 +178,7 @@ void main() {
|
|||||||
|
|
||||||
vec2 pixCoord = fullSize * v_texcoord;
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
if (pixCoord[0] < topLeft[0]) {
|
)#" + ROUNDED_SHADER_FUNC("v_color") + R"#(
|
||||||
// we're close left
|
|
||||||
if (pixCoord[1] < topLeft[1]) {
|
|
||||||
// top
|
|
||||||
if (distance(topLeft, pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (pixCoord[1] > bottomRight[1]) {
|
|
||||||
// bottom
|
|
||||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pixCoord[0] > bottomRight[0]) {
|
|
||||||
// we're close right
|
|
||||||
if (pixCoord[1] < topLeft[1]) {
|
|
||||||
// top
|
|
||||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (pixCoord[1] > bottomRight[1]) {
|
|
||||||
// bottom
|
|
||||||
if (distance(bottomRight, pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gl_FragColor = v_color;
|
gl_FragColor = v_color;
|
||||||
})#";
|
})#";
|
||||||
@@ -94,6 +207,9 @@ uniform float radius;
|
|||||||
|
|
||||||
uniform int discardOpaque;
|
uniform int discardOpaque;
|
||||||
|
|
||||||
|
uniform int primitiveMultisample;
|
||||||
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||||
@@ -105,38 +221,8 @@ void main() {
|
|||||||
|
|
||||||
vec2 pixCoord = fullSize * v_texcoord;
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
if (pixCoord[0] < topLeft[0]) {
|
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||||
// we're close left
|
R"#(
|
||||||
if (pixCoord[1] < topLeft[1]) {
|
|
||||||
// top
|
|
||||||
if (distance(topLeft, pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (pixCoord[1] > bottomRight[1]) {
|
|
||||||
// bottom
|
|
||||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pixCoord[0] > bottomRight[0]) {
|
|
||||||
// we're close right
|
|
||||||
if (pixCoord[1] < topLeft[1]) {
|
|
||||||
// top
|
|
||||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (pixCoord[1] > bottomRight[1]) {
|
|
||||||
// bottom
|
|
||||||
if (distance(bottomRight, pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gl_FragColor = pixColor * alpha;
|
gl_FragColor = pixColor * alpha;
|
||||||
})#";
|
})#";
|
||||||
@@ -154,49 +240,23 @@ uniform float radius;
|
|||||||
|
|
||||||
uniform int discardOpaque;
|
uniform int discardOpaque;
|
||||||
|
|
||||||
|
uniform int primitiveMultisample;
|
||||||
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
if (discardOpaque == 1 && alpha == 1.0) {
|
if (discardOpaque == 1 && alpha == 1.0) {
|
||||||
discard;
|
discard;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||||
|
|
||||||
vec2 pixCoord = fullSize * v_texcoord;
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
if (pixCoord[0] < topLeft[0]) {
|
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||||
// we're close left
|
|
||||||
if (pixCoord[1] < topLeft[1]) {
|
|
||||||
// top
|
|
||||||
if (distance(topLeft, pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (pixCoord[1] > bottomRight[1]) {
|
|
||||||
// bottom
|
|
||||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pixCoord[0] > bottomRight[0]) {
|
|
||||||
// we're close right
|
|
||||||
if (pixCoord[1] < topLeft[1]) {
|
|
||||||
// top
|
|
||||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (pixCoord[1] > bottomRight[1]) {
|
|
||||||
// bottom
|
|
||||||
if (distance(bottomRight, pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0) * alpha;
|
gl_FragColor = pixColor * alpha;
|
||||||
})#";
|
})#";
|
||||||
|
|
||||||
inline const std::string FRAGBLUR1 = R"#(
|
inline const std::string FRAGBLUR1 = R"#(
|
||||||
@@ -261,6 +321,9 @@ uniform float radius;
|
|||||||
|
|
||||||
uniform int discardOpaque;
|
uniform int discardOpaque;
|
||||||
|
|
||||||
|
uniform int primitiveMultisample;
|
||||||
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||||
@@ -272,38 +335,7 @@ void main() {
|
|||||||
|
|
||||||
vec2 pixCoord = fullSize * v_texcoord;
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
if (pixCoord[0] < topLeft[0]) {
|
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||||
// we're close left
|
|
||||||
if (pixCoord[1] < topLeft[1]) {
|
|
||||||
// top
|
|
||||||
if (distance(topLeft, pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (pixCoord[1] > bottomRight[1]) {
|
|
||||||
// bottom
|
|
||||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pixCoord[0] > bottomRight[0]) {
|
|
||||||
// we're close right
|
|
||||||
if (pixCoord[1] < topLeft[1]) {
|
|
||||||
// top
|
|
||||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (pixCoord[1] > bottomRight[1]) {
|
|
||||||
// bottom
|
|
||||||
if (distance(bottomRight, pixCoord) > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gl_FragColor = pixColor * alpha;
|
gl_FragColor = pixColor * alpha;
|
||||||
})#";
|
})#";
|
||||||
|
2
wlroots
2
wlroots
Submodule wlroots updated: 75d31509db...b89ed9015c
Reference in New Issue
Block a user