mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-11 18:21:54 -07:00
Compare commits
147 Commits
v0.10.2bet
...
v0.12.0bet
Author | SHA1 | Date | |
---|---|---|---|
|
6c8ce734fb | ||
|
09495375b5 | ||
|
3c20ecb04d | ||
|
5da114477f | ||
|
c757fa54e1 | ||
|
16f8d46391 | ||
|
5726f394b1 | ||
|
f5f99c6700 | ||
|
cfa6c01df0 | ||
|
d413388761 | ||
|
4203a61b69 | ||
|
80b3a436d2 | ||
|
5d9d55a245 | ||
|
52c0ba544c | ||
|
8b5c64c8fd | ||
|
2ea5f50f40 | ||
|
1d97ad9856 | ||
|
1d43bb70d4 | ||
|
573cb0d4e0 | ||
|
59d7cfcd02 | ||
|
ed2cacc5d5 | ||
|
df4c1c02a6 | ||
|
8122505825 | ||
|
0964448f93 | ||
|
5d63152219 | ||
|
aaa834d0c3 | ||
|
28966d85ae | ||
|
a648b452dd | ||
|
d53b0a6491 | ||
|
80d522cb26 | ||
|
dbd774fedb | ||
|
bf00bf7963 | ||
|
949655005a | ||
|
56caba5f01 | ||
|
b09f157b93 | ||
|
10f529ada7 | ||
|
f7c741317f | ||
|
b16a57ceeb | ||
|
0eb86f4b0d | ||
|
7b01c3d028 | ||
|
89018bfa95 | ||
|
0d1a9e4ba9 | ||
|
e327b0a835 | ||
|
de477a6ff5 | ||
|
e92469121d | ||
|
a9761cb1c8 | ||
|
6c2175ed52 | ||
|
00ef40dda1 | ||
|
9c3aeda9f9 | ||
|
a4f7bd4bc2 | ||
|
3fd903ee74 | ||
|
83ef951c21 | ||
|
8bbb790d87 | ||
|
ffaf14c19e | ||
|
9366c187dc | ||
|
29696d046e | ||
|
09f3999b1e | ||
|
fba7ed97fb | ||
|
fd70a9184b | ||
|
0a9ac47030 | ||
|
e2450247c0 | ||
|
973540bbc5 | ||
|
f9b2aa5468 | ||
|
451659ec34 | ||
|
a9e34cba93 | ||
|
48c9e9d83d | ||
|
23c5760538 | ||
|
9bfa3ebc50 | ||
|
8feb6f7da1 | ||
|
fb0e81c18e | ||
|
359df96d53 | ||
|
63493b5736 | ||
|
6565c31dbf | ||
|
575bfa40e5 | ||
|
429b2bffed | ||
|
c83948ea9a | ||
|
8a6e29974b | ||
|
4c6d9b7d5a | ||
|
9f5e099cd1 | ||
|
8b39a1cf9b | ||
|
e9551731f0 | ||
|
39a9980fb1 | ||
|
d0ec2b72ae | ||
|
e97fa4e26b | ||
|
52318692f0 | ||
|
86be6c3884 | ||
|
21bea0fcb4 | ||
|
83f7fee3f5 | ||
|
f273ebed9c | ||
|
3cb30e7fb0 | ||
|
3e9a8a7bc8 | ||
|
7ca50d7566 | ||
|
ebe07c6656 | ||
|
ce62a98470 | ||
|
8faac0c9ac | ||
|
fea6d7deb0 | ||
|
463bc7ab13 | ||
|
c4ba11729f | ||
|
5569e1f69c | ||
|
da725d7aa5 | ||
|
f7f3446882 | ||
|
0f63077a07 | ||
|
0f25f3aee3 | ||
|
5e1f2539cb | ||
|
9dbdd66da4 | ||
|
6ec932d11f | ||
|
3c8c605541 | ||
|
9ee42836d5 | ||
|
d6ff7e40cf | ||
|
04f0efadc3 | ||
|
12cdca7422 | ||
|
7ce2c91673 | ||
|
aaba11b7a2 | ||
|
9513031da3 | ||
|
08e874bcf9 | ||
|
61aa4ff70e | ||
|
cc3f0ff9e7 | ||
|
7af193d921 | ||
|
132c96f867 | ||
|
45a0e69286 | ||
|
0ebef9a8ae | ||
|
185f93ae64 | ||
|
776750ee34 | ||
|
37e1450a4d | ||
|
1b1a0259a8 | ||
|
223ca6e286 | ||
|
f0ad77251b | ||
|
c2a3896cc9 | ||
|
e749331f30 | ||
|
69d17bf424 | ||
|
946222f4a7 | ||
|
504d07a87d | ||
|
81b27be6bb | ||
|
f9e30e985c | ||
|
6cae44e2c0 | ||
|
43aea417b0 | ||
|
4af95d4253 | ||
|
844c33c980 | ||
|
ece3ac97f9 | ||
|
9b62328b22 | ||
|
c1a64a2b9d | ||
|
b078a12eed | ||
|
eca6e53bd7 | ||
|
f2d3aecf00 | ||
|
f3c597bfb7 | ||
|
c5a4c83f78 | ||
|
f4d11d2d43 |
26
.github/workflows/man-update.yaml
vendored
Normal file
26
.github/workflows/man-update.yaml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Build man pages
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- docs/**
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Build man pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: sudo apt install pandoc
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
# Not needed
|
||||
# with:
|
||||
# submodules: recursive
|
||||
- name: Build man pages
|
||||
run: make man
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||
name: Commit
|
||||
with:
|
||||
commit_message: "[gha] build man pages"
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -10,7 +10,7 @@ CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
build/
|
||||
result
|
||||
result*
|
||||
/.vscode/
|
||||
.envrc
|
||||
.cache
|
||||
@@ -24,4 +24,4 @@ hyprctl/hyprctl
|
||||
|
||||
gmon.out
|
||||
*.out
|
||||
*.tar.gz
|
||||
*.tar.gz
|
||||
|
31
Makefile
31
Makefile
@@ -126,8 +126,8 @@ install:
|
||||
make release
|
||||
cd hyprctl && make all && cd ..
|
||||
|
||||
mkdir -p ${PREFIX}/share/wayland-sessions
|
||||
cp ./example/hyprland.desktop ${PREFIX}/share/wayland-sessions/
|
||||
mkdir -p /usr/share/wayland-sessions
|
||||
cp ./example/hyprland.desktop /usr/share/wayland-sessions/
|
||||
mkdir -p ${PREFIX}/bin
|
||||
cp ./build/Hyprland ${PREFIX}/bin
|
||||
cp ./hyprctl/hyprctl ${PREFIX}/bin
|
||||
@@ -136,12 +136,35 @@ install:
|
||||
cp ./assets/wall_4K.png ${PREFIX}/share/hyprland
|
||||
cp ./assets/wall_8K.png ${PREFIX}/share/hyprland
|
||||
|
||||
install -Dm644 -t ${PREFIX}/share/man/man1 ./docs/*.1
|
||||
|
||||
cleaninstall:
|
||||
make clear
|
||||
make fixwlr
|
||||
cd ./subprojects/wlroots && meson build/ --buildtype=release && ninja -C build/ && cp ./build/libwlroots.so.11032 /usr/lib/ && cd ../..
|
||||
make protocols
|
||||
make release
|
||||
cd hyprctl && make all && cd ..
|
||||
|
||||
mkdir -p /usr/share/wayland-sessions
|
||||
mkdir -p ${PREFIX}/bin
|
||||
cp ./build/Hyprland ${PREFIX}/bin
|
||||
cp ./hyprctl/hyprctl ${PREFIX}/bin
|
||||
mkdir -p ${PREFIX}/share/hyprland
|
||||
cp ./assets/wall_2K.png ${PREFIX}/share/hyprland
|
||||
cp ./assets/wall_4K.png ${PREFIX}/share/hyprland
|
||||
cp ./assets/wall_8K.png ${PREFIX}/share/hyprland
|
||||
|
||||
install -Dm644 -t ${PREFIX}/share/man/man1 ./docs/*.1
|
||||
|
||||
uninstall:
|
||||
rm -f ${PREFIX}/share/wayland-sessions/hyprland.desktop
|
||||
rm -f ${PREFIX}/bin/Hyprland
|
||||
rm -f ${PREFIX}/bin/hyprctl
|
||||
rm -f /usr/lib/libwlroots.so.11032
|
||||
rm -rf ${PREFIX}/share/hyprland
|
||||
rm -f ${PREFIX}/share/man/man1/Hyprland.1
|
||||
rm -f ${PREFIX}/share/man/man1/hyprctl.1
|
||||
|
||||
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 wlr-output-power-management-unstable-v1-protocol.o
|
||||
|
||||
@@ -167,7 +190,7 @@ man:
|
||||
--variable=date:"${DATE}" \
|
||||
--variable=section:1 \
|
||||
--from rst \
|
||||
--to man | gzip -c > /usr/share/man/man1/Hyprland.1.gz
|
||||
--to man > ./docs/Hyprland.1
|
||||
|
||||
pandoc ./docs/hyprctl.1.rst \
|
||||
--standalone \
|
||||
@@ -175,4 +198,4 @@ man:
|
||||
--variable=date:"${DATE}" \
|
||||
--variable=section:1 \
|
||||
--from rst \
|
||||
--to man | gzip -c > /usr/share/man/man1/hyprctl.1.gz
|
||||
--to man > ./docs/hyprctl.1
|
||||
|
12
README.md
12
README.md
@@ -123,7 +123,7 @@ Try it out and report bugs / suggestions!
|
||||
|
||||
<!----------------------------------------------------------------------------->
|
||||
|
||||
[Configure]: https://github.com/hyprwm/Hyprland/wiki/Configuring-Hyprland
|
||||
[Configure]: https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
||||
[Discord]: https://discord.gg/hQ9XvMUjjr
|
||||
[Stars]: https://starchart.cc/hyprwm/Hyprland
|
||||
[Hypr]: https://github.com/hyprwm/Hypr
|
||||
@@ -132,9 +132,9 @@ Try it out and report bugs / suggestions!
|
||||
[Issues]: https://github.com/hyprwm/Hyprland/issues
|
||||
[Todo]: https://github.com/hyprwm/Hyprland/projects?type=beta
|
||||
|
||||
[Contribute]: https://github.com/hyprwm/Hyprland/wiki/Contributing-&-Debugging
|
||||
[Install]: https://github.com/hyprwm/Hyprland/wiki/Installation
|
||||
[Quick Start]: https://github.com/hyprwm/Hyprland/wiki/Quick-start
|
||||
[Contribute]: https://wiki.hyprland.org/Contributing-and-Debugging/
|
||||
[Install]: https://wiki.hyprland.org/Getting-Started/Installation/
|
||||
[Quick Start]: https://wiki.hyprland.org/Getting-Started/Quick-start/
|
||||
[License]: LICENSE
|
||||
|
||||
|
||||
@@ -150,9 +150,9 @@ Try it out and report bugs / suggestions!
|
||||
<!----------------------------------{ Images }--------------------------------->
|
||||
|
||||
[Stars Preview]: https://starchart.cc/vaxerski/Hyprland.svg
|
||||
[Preview A]: https://i.imgur.com/sCafdKQ.png
|
||||
[Preview A]: https://i.imgur.com/pC6YF1Y.png
|
||||
[Preview B]: https://i.imgur.com/NbrTnZH.png
|
||||
[Preview C]: https://i.imgur.com/ZA4Fa8R.png
|
||||
[Preview C]: https://i.imgur.com/sCafdKQ.png
|
||||
|
||||
|
||||
<!----------------------------------{ Badges }--------------------------------->
|
||||
|
46
docs/Hyprland.1
Normal file
46
docs/Hyprland.1
Normal file
@@ -0,0 +1,46 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\"
|
||||
.TH "Hyprland" "1" "24 Aug 2022" "" "Hyprland User Manual"
|
||||
.hy
|
||||
.SH NAME
|
||||
.PP
|
||||
Hyprland \- Dynamic tiling Wayland compositor
|
||||
.SH SYNOPSIS
|
||||
.PP
|
||||
\f[B]Hyprland\f[R] [\f[I]arg [...]\f[R]].
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\f[B]Hyprland\f[R] is a dynamic tiling Wayland compositor based on
|
||||
wlroots that doesn\[aq]t sacrifice on its looks.
|
||||
.PP
|
||||
You can launch Hyprland by either going into a TTY and executing
|
||||
\f[B]Hyprland\f[R], or with a login manager.
|
||||
.SH NOTICE
|
||||
.PP
|
||||
Hyprland is still in pretty early development compared to some other
|
||||
Wayland compositors.
|
||||
.PP
|
||||
Although Hyprland is pretty stable, it may have some bugs.
|
||||
.SH CONFIGURATION
|
||||
.PP
|
||||
For configuration information please see
|
||||
<\f[I]https://github.com/hyprwm/Hyprland/wiki\f[R]>.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \f[B]\-h\f[R], \f[B]\-\-help\f[R]
|
||||
Show command usage.
|
||||
.TP
|
||||
.B \f[B]\-c\f[R], \f[B]\-\-config\f[R]
|
||||
Specify config file to use.
|
||||
.SH BUGS
|
||||
.TP
|
||||
.B Submit bug reports and request features online at:
|
||||
<\f[I]https://github.com/hyprwm/Hyprland/issues\f[R]>
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
Sources at: <\f[I]https://github.com/hyprwm/Hyprland\f[R]>
|
||||
.SH COPYRIGHT
|
||||
.PP
|
||||
Copyright (c) 2022, vaxerski
|
||||
.SH AUTHORS
|
||||
Vaxerski <\f[I]https://github.com/vaxerski\f[R]>.
|
145
docs/hyprctl.1
Normal file
145
docs/hyprctl.1
Normal file
@@ -0,0 +1,145 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\"
|
||||
.TH "hyprctl" "1" "24 Aug 2022" "" "hyprctl User Manual"
|
||||
.hy
|
||||
.SH NAME
|
||||
.PP
|
||||
hyprctl \- Utility for controlling parts of Hyprland from a CLI or a
|
||||
script
|
||||
.SH SYNOPSIS
|
||||
.PP
|
||||
\f[B]hyprctl\f[R] [\f[I](opt)flags\f[R]] [\f[B]command\f[R]]
|
||||
[\f[I](opt)args\f[R]]
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\f[B]hyprctl\f[R] is a utility for controlling some parts of the
|
||||
compositor from a CLI or a script.
|
||||
.SH CONTROL COMMANDS
|
||||
.PP
|
||||
\f[B]dispatch\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Call a dispatcher with an argument.
|
||||
.PP
|
||||
An argument must be present.
|
||||
For dispatchers without parameters it can be anything.
|
||||
.PP
|
||||
Returns: \f[I]ok\f[R] on success, and an error message on failure.
|
||||
.TP
|
||||
.B Examples:
|
||||
\f[B]hyprctl\f[R] \f[I]dispatch exec kitty\f[R]
|
||||
.RS
|
||||
.PP
|
||||
\f[B]hyprctl\f[R] \f[I]dispatch pseudo x\f[R]
|
||||
.RE
|
||||
.RE
|
||||
.PP
|
||||
\f[B]keyword\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Set a config keyword dynamically.
|
||||
.PP
|
||||
Returns: \f[I]ok\f[R] on success, and an error message on failure.
|
||||
.TP
|
||||
.B Examples:
|
||||
\f[B]hyprctl\f[R] \f[I]keyword bind SUPER,0,pseudo\f[R]
|
||||
.RS
|
||||
.PP
|
||||
\f[B]hyprctl\f[R] \f[I]keyword general:border_size 10\f[R]
|
||||
.RE
|
||||
.RE
|
||||
.PP
|
||||
\f[B]reload\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Force a reload of the config file.
|
||||
.RE
|
||||
.PP
|
||||
\f[B]kill\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Enter kill mode, where you can kill an app by clicking on it.
|
||||
You can exit by pressing ESCAPE.
|
||||
.RE
|
||||
.SH INFO COMMANDS
|
||||
.PP
|
||||
\f[B]version\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Prints the Hyprland version, flags, commit and branch of build.
|
||||
.RE
|
||||
.PP
|
||||
\f[B]monitors\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Lists all the outputs with their properties.
|
||||
.RE
|
||||
.PP
|
||||
\f[B]workspaces\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Lists all workspaces with their properties.
|
||||
.RE
|
||||
.PP
|
||||
\f[B]clients\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Lists all windows with their properties.
|
||||
.RE
|
||||
.PP
|
||||
\f[B]devices\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Lists all connected input devices.
|
||||
.RE
|
||||
.PP
|
||||
\f[B]activewindow\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Returns the active window name.
|
||||
.RE
|
||||
.PP
|
||||
\f[B]layers\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Lists all the layers.
|
||||
.RE
|
||||
.PP
|
||||
\f[B]splash\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Returns the current random splash.
|
||||
.RE
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\f[B]\-\-batch\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Specify a batch of commands to execute.
|
||||
.TP
|
||||
.B Example:
|
||||
\f[B]hyprctl\f[R] \f[I]\-\-batch \[dq]keyword general:border_size 2 ;
|
||||
keyword general:gaps_out 20\[dq]\f[R]
|
||||
.RS
|
||||
.PP
|
||||
\f[I];\f[R] separates the commands.
|
||||
.RE
|
||||
.RE
|
||||
.PP
|
||||
\f[B]\-j\f[R]
|
||||
.RS
|
||||
.PP
|
||||
Outputs information in JSON.
|
||||
.RE
|
||||
.SH BUGS
|
||||
.TP
|
||||
.B Submit bug reports and request features online at:
|
||||
<\f[I]https://github.com/hyprwm/Hyprland/issues\f[R]>
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
Sources at: <\f[I]https://github.com/hyprwm/Hyprland\f[R]>
|
||||
.SH COPYRIGHT
|
||||
.PP
|
||||
Copyright (c) 2022, vaxerski
|
||||
.SH AUTHORS
|
||||
Vaxerski <\f[I]https://github.com/vaxerski\f[R]>.
|
2
docs/meson.build
Normal file
2
docs/meson.build
Normal file
@@ -0,0 +1,2 @@
|
||||
install_man ('Hyprland.1')
|
||||
install_man ('hyprctl.1')
|
@@ -12,6 +12,7 @@ monitor=,preferred,auto,1
|
||||
workspace=DP-1,1
|
||||
|
||||
input {
|
||||
kb_file=
|
||||
kb_layout=
|
||||
kb_variant=
|
||||
kb_model=
|
||||
@@ -23,10 +24,11 @@ input {
|
||||
touchpad {
|
||||
natural_scroll=no
|
||||
}
|
||||
|
||||
sensitivity=0 # -1.0 - 1.0, 0 means no modification.
|
||||
}
|
||||
|
||||
general {
|
||||
sensitivity=1.0 # for mouse cursor
|
||||
main_mod=SUPER
|
||||
|
||||
gaps_in=5
|
||||
@@ -44,10 +46,8 @@ decoration {
|
||||
rounding=10
|
||||
blur=1
|
||||
blur_size=3 # minimum 1
|
||||
blur_passes=1 # minimum 1, more passes = more resource intensive.
|
||||
# Your blur "amount" is blur_size * blur_passes, but high blur_size (over around 5-ish) will produce artifacts.
|
||||
# if you want heavy blur, you need to up the blur_passes.
|
||||
# the more passes, the more you can up the blur_size without noticing artifacts.
|
||||
blur_passes=1 # minimum 1
|
||||
blur_new_optimizations=1
|
||||
}
|
||||
|
||||
animations {
|
||||
@@ -112,4 +112,4 @@ bind=ALT,9,movetoworkspace,9
|
||||
bind=ALT,0,movetoworkspace,10
|
||||
|
||||
bind=SUPER,mouse_down,workspace,e+1
|
||||
bind=SUPER,mouse_up,workspace,e-1
|
||||
bind=SUPER,mouse_up,workspace,e-1
|
||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1659522808,
|
||||
"narHash": "sha256-HBcM19nGhI3IWwPNVlYb0MZ8VW6iKp4JbAVkeIHVykc=",
|
||||
"lastModified": 1660908602,
|
||||
"narHash": "sha256-SwZ85IPWvC4NxxFhWhRMTJpApSHbY1u4YK2UFWEBWvY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "168d1c578909dc143ba52dbed661c36e76b12b36",
|
||||
"rev": "495b19d5b3e62b4ec7e846bdfb6ef3d9c3b83492",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -26,11 +26,11 @@
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"host": "gitlab.freedesktop.org",
|
||||
"lastModified": 1659738224,
|
||||
"narHash": "sha256-bV3TLiCgptpKoUKLiH/5RMtiIsfn0hawdaCEHQFB6WY=",
|
||||
"lastModified": 1660930713,
|
||||
"narHash": "sha256-bY7q1NqG/sjCUAWPn/Ne9NCigLlPlH5Lk1WCMqv3rTU=",
|
||||
"owner": "wlroots",
|
||||
"repo": "wlroots",
|
||||
"rev": "3baf2a6bcfc4cb86c364f5724aaec80f28715a01",
|
||||
"rev": "7c575922c05e4d5fd9a403c2aa631a54c7531d44",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
@@ -34,7 +34,7 @@
|
||||
});
|
||||
hyprland = prev.callPackage ./nix/default.nix {
|
||||
stdenv = prev.gcc12Stdenv;
|
||||
version = "0.10.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
|
||||
version = "0.11.1beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
wlroots = wlroots-hyprland;
|
||||
};
|
||||
hyprland-debug = hyprland.override {debug = true;};
|
||||
@@ -66,4 +66,9 @@
|
||||
|
||||
overlay = throw "Hyprland: .overlay output is deprecated, please use the .overlays.default output";
|
||||
};
|
||||
|
||||
nixConfig = {
|
||||
extra-substituters = ["https://hyprland.cachix.org"];
|
||||
extra-trusted-public-keys = ["hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="];
|
||||
};
|
||||
}
|
||||
|
@@ -50,12 +50,6 @@ void request(std::string arg) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto SERVER = gethostbyname("localhost");
|
||||
|
||||
if (!SERVER) {
|
||||
std::cout << "Couldn't get host (2)";
|
||||
return;
|
||||
}
|
||||
|
||||
// get the instance signature
|
||||
auto instanceSig = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||
@@ -158,7 +152,10 @@ void dispatchRequest(int argc, char** argv) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string rq = "/dispatch " + std::string(argv[2]) + " " + std::string(argv[3]);
|
||||
std::string rq = "/dispatch";
|
||||
|
||||
for(int i = 2; i < argc; i++)
|
||||
rq += " " + std::string(argv[i]);
|
||||
|
||||
request(rq);
|
||||
}
|
||||
@@ -169,7 +166,10 @@ void keywordRequest(int argc, char** argv) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string rq = "keyword " + std::string(argv[2]) + " " + std::string(argv[3]);
|
||||
std::string rq = "/keyword";
|
||||
|
||||
for(int i = 2; i < argc; i++)
|
||||
rq += " " + std::string(argv[i]);
|
||||
|
||||
request(rq);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
project('Hyprland', 'cpp', 'c',
|
||||
version : '0.10.0beta',
|
||||
version : '0.11.1beta',
|
||||
default_options : [
|
||||
'warning_level=2',
|
||||
'default_library=static',
|
||||
@@ -15,7 +15,7 @@ if cpp_compiler.has_argument('-std=c++23')
|
||||
elif cpp_compiler.has_argument('-std=c++2b')
|
||||
add_global_arguments('-std=c++2b', language: 'cpp')
|
||||
else
|
||||
error('Could not configure current C++ compiler (' + cpp_compiler.get_id() + ' ' + cpp_compiler.get_version() + ') with required C++ standard (C++23)')
|
||||
error('Could not configure current C++ compiler (' + cpp_compiler.get_id() + ' ' + cpp_compiler.version() + ') with required C++ standard (C++23)')
|
||||
endif
|
||||
|
||||
GIT_BRANCH = run_command('git', 'rev-parse', '--abbrev-ref', 'HEAD', check: false).stdout().strip()
|
||||
@@ -59,3 +59,4 @@ subdir('src')
|
||||
subdir('hyprctl')
|
||||
subdir('assets')
|
||||
subdir('example')
|
||||
subdir('docs')
|
||||
|
@@ -44,6 +44,11 @@ stdenv.mkDerivation {
|
||||
pkg-config
|
||||
];
|
||||
|
||||
outputs = [
|
||||
"out"
|
||||
"man"
|
||||
];
|
||||
|
||||
buildInputs =
|
||||
[
|
||||
git
|
||||
@@ -67,7 +72,7 @@ stdenv.mkDerivation {
|
||||
else "release";
|
||||
|
||||
mesonFlags = builtins.concatLists [
|
||||
(lib.optional (!enableXWayland) "-DNO_XWAYLAND=true")
|
||||
(lib.optional (!enableXWayland) "-Dxwayland=disabled")
|
||||
(lib.optional legacyRenderer "-DLEGACY_RENDERER:STRING=true")
|
||||
];
|
||||
|
||||
|
@@ -16,6 +16,8 @@ int handleCritSignal(int signo, void* data) {
|
||||
CCompositor::CCompositor() {
|
||||
wlr_log_init(WLR_INFO, NULL);
|
||||
|
||||
m_iHyprlandPID = getpid();
|
||||
|
||||
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
|
||||
|
||||
setenv("HYPRLAND_INSTANCE_SIGNATURE", m_szInstanceSignature.c_str(), true);
|
||||
@@ -27,6 +29,8 @@ CCompositor::CCompositor() {
|
||||
|
||||
Debug::log(LOG, "Instance Signature: %s", m_szInstanceSignature.c_str());
|
||||
|
||||
Debug::log(LOG, "Hyprland PID: %i", m_iHyprlandPID);
|
||||
|
||||
Debug::log(LOG, "===== SYSTEM INFO: =====");
|
||||
|
||||
logSystemInfo();
|
||||
@@ -94,7 +98,7 @@ CCompositor::CCompositor() {
|
||||
wlr_data_control_manager_v1_create(m_sWLDisplay);
|
||||
wlr_gamma_control_manager_v1_create(m_sWLDisplay);
|
||||
wlr_primary_selection_v1_device_manager_create(m_sWLDisplay);
|
||||
// wlr_viewporter_create(m_sWLDisplay); // TODO: support wl_viewporter
|
||||
wlr_viewporter_create(m_sWLDisplay);
|
||||
|
||||
m_sWLROutputLayout = wlr_output_layout_create();
|
||||
|
||||
@@ -141,6 +145,12 @@ CCompositor::CCompositor() {
|
||||
|
||||
m_sWLRToplevelMgr = wlr_foreign_toplevel_manager_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend);
|
||||
if (!m_sWRLDRMLeaseMgr) {
|
||||
Debug::log(INFO, "Failed to create wlr_drm_lease_v1_manager");
|
||||
Debug::log(INFO, "VR will not be available");
|
||||
}
|
||||
|
||||
m_sWLRTabletManager = wlr_tablet_v2_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRForeignRegistry = wlr_xdg_foreign_registry_create(m_sWLDisplay);
|
||||
@@ -211,20 +221,41 @@ void CCompositor::initAllSignals() {
|
||||
addWLSignal(&m_sWLRIMEMgr->events.input_method, &Events::listen_newIME, m_sWLRIMEMgr, "IMEMgr");
|
||||
addWLSignal(&m_sWLRTextInputMgr->events.text_input, &Events::listen_newTextInput, m_sWLRTextInputMgr, "TextInputMgr");
|
||||
|
||||
if(m_sWRLDRMLeaseMgr)
|
||||
addWLSignal(&m_sWRLDRMLeaseMgr->events.request, &Events::listen_leaseRequest, &m_sWRLDRMLeaseMgr, "DRM");
|
||||
|
||||
if (m_sWLRSession)
|
||||
addWLSignal(&m_sWLRSession->events.active, &Events::listen_sessionActive, m_sWLRSession, "Session");
|
||||
}
|
||||
|
||||
void CCompositor::cleanup() {
|
||||
if (!m_sWLDisplay)
|
||||
if (!m_sWLDisplay || m_bIsShuttingDown)
|
||||
return;
|
||||
|
||||
m_pLastFocus = nullptr;
|
||||
m_pLastWindow = nullptr;
|
||||
|
||||
// accumulate all PIDs for killing, also request closing.
|
||||
for (auto& w : m_vWindows) {
|
||||
m_dProcessPIDsOnShutdown.push_back(w->getPID());
|
||||
|
||||
closeWindow(w.get());
|
||||
}
|
||||
|
||||
// end threads
|
||||
g_pEventManager->m_tThread = std::thread();
|
||||
HyprCtl::tThread = std::thread();
|
||||
|
||||
m_vWorkspaces.clear();
|
||||
m_vWindows.clear();
|
||||
|
||||
for (auto& m : m_vMonitors) {
|
||||
g_pHyprOpenGL->destroyMonitorResources(m.get());
|
||||
|
||||
wlr_output_enable(m->output, false);
|
||||
wlr_output_commit(m->output);
|
||||
}
|
||||
|
||||
if (g_pXWaylandManager->m_sWLRXWayland) {
|
||||
wlr_xwayland_destroy(g_pXWaylandManager->m_sWLRXWayland);
|
||||
g_pXWaylandManager->m_sWLRXWayland = nullptr;
|
||||
@@ -232,7 +263,10 @@ void CCompositor::cleanup() {
|
||||
|
||||
wl_display_terminate(m_sWLDisplay);
|
||||
|
||||
m_sWLDisplay = nullptr;
|
||||
m_bIsShuttingDown = true;
|
||||
|
||||
g_pKeybindManager->spawn("sleep 5 && kill -9 " + std::to_string(m_iHyprlandPID)); // this is to prevent that random "freezing"
|
||||
// the PID should not be reused.
|
||||
}
|
||||
|
||||
void CCompositor::startCompositor() {
|
||||
@@ -627,6 +661,8 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
|
||||
wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat);
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
|
||||
|
||||
m_pLastFocus = nullptr;
|
||||
return;
|
||||
}
|
||||
@@ -710,7 +746,7 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
|
||||
.old_surface = m_pLastFocus,
|
||||
.new_surface = pSurface,
|
||||
};
|
||||
wlr_signal_emit_safe(&m_sSeat.seat->keyboard_state.events.focus_change, &event);
|
||||
wl_signal_emit_mutable(&m_sSeat.seat->keyboard_state.events.focus_change, &event);
|
||||
|
||||
if (pWindowOwner)
|
||||
Debug::log(LOG, "Set keyboard focus to surface %x, with window name: %s", pSurface, pWindowOwner->m_szTitle.c_str());
|
||||
@@ -868,11 +904,34 @@ void CCompositor::moveWindowToTop(CWindow* pWindow) {
|
||||
if (!windowValidMapped(pWindow))
|
||||
return;
|
||||
|
||||
for (auto it = m_vWindows.begin(); it != m_vWindows.end(); ++it) {
|
||||
if (it->get() == pWindow) {
|
||||
std::rotate(it, it + 1, m_vWindows.end());
|
||||
break;
|
||||
auto moveToTop = [&](CWindow* pw) -> void {
|
||||
for (auto it = m_vWindows.begin(); it != m_vWindows.end(); ++it) {
|
||||
if (it->get() == pw) {
|
||||
std::rotate(it, it + 1, m_vWindows.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
moveToTop(pWindow);
|
||||
|
||||
if (!pWindow->m_bIsX11)
|
||||
return;
|
||||
|
||||
// move all children
|
||||
|
||||
std::deque<CWindow*> toMove;
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_bIsMapped && w->m_bMappedX11 && !w->m_bHidden && w->m_bIsX11 && w->X11TransientFor() == pWindow) {
|
||||
toMove.emplace_back(w.get());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& pw : toMove) {
|
||||
moveToTop(pw);
|
||||
|
||||
moveWindowToTop(pw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1276,13 +1335,6 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::moveWindowToWorkspace(CWindow* pWindow, const std::string& work) {
|
||||
m_pLastWindow = pWindow;
|
||||
g_pKeybindManager->moveActiveToWorkspace(work);
|
||||
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
int CCompositor::getNextAvailableMonitorID() {
|
||||
int64_t topID = -1;
|
||||
for (auto& m : m_vRealMonitors) {
|
||||
@@ -1293,6 +1345,100 @@ int CCompositor::getNextAvailableMonitorID() {
|
||||
return topID + 1;
|
||||
}
|
||||
|
||||
void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) {
|
||||
|
||||
const auto PWORKSPACEA = g_pCompositor->getWorkspaceByID(pMonitorA->activeWorkspace);
|
||||
const auto PWORKSPACEB = g_pCompositor->getWorkspaceByID(pMonitorB->activeWorkspace);
|
||||
|
||||
PWORKSPACEA->m_iMonitorID = pMonitorB->ID;
|
||||
PWORKSPACEA->moveToMonitor(pMonitorB->ID);
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == PWORKSPACEA->m_iID) {
|
||||
w->m_iMonitorID = pMonitorB->ID;
|
||||
|
||||
// additionally, move floating and fs windows manually
|
||||
if (w->m_bIsFloating)
|
||||
w->m_vRealPosition = w->m_vRealPosition.vec() - pMonitorA->vecPosition + pMonitorB->vecPosition;
|
||||
|
||||
if (w->m_bIsFullscreen) {
|
||||
w->m_vRealPosition = pMonitorB->vecPosition;
|
||||
w->m_vRealSize = pMonitorB->vecSize;
|
||||
}
|
||||
|
||||
w->updateToplevel();
|
||||
}
|
||||
}
|
||||
|
||||
PWORKSPACEB->m_iMonitorID = pMonitorA->ID;
|
||||
PWORKSPACEB->moveToMonitor(pMonitorA->ID);
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == PWORKSPACEB->m_iID) {
|
||||
w->m_iMonitorID = pMonitorA->ID;
|
||||
|
||||
// additionally, move floating and fs windows manually
|
||||
if (w->m_bIsFloating)
|
||||
w->m_vRealPosition = w->m_vRealPosition.vec() - pMonitorB->vecPosition + pMonitorA->vecPosition;
|
||||
|
||||
if (w->m_bIsFullscreen) {
|
||||
w->m_vRealPosition = pMonitorA->vecPosition;
|
||||
w->m_vRealSize = pMonitorA->vecSize;
|
||||
}
|
||||
|
||||
w->updateToplevel();
|
||||
}
|
||||
}
|
||||
|
||||
pMonitorA->activeWorkspace = PWORKSPACEB->m_iID;
|
||||
pMonitorB->activeWorkspace = PWORKSPACEA->m_iID;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitorA->ID);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitorB->ID);
|
||||
|
||||
g_pInputManager->refocus();
|
||||
|
||||
// event
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEA->m_szName + "," + pMonitorB->szName});
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEB->m_szName + "," + pMonitorA->szName});
|
||||
}
|
||||
|
||||
CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
|
||||
if (isNumber(name)) {
|
||||
// change by ID
|
||||
int monID = -1;
|
||||
try {
|
||||
monID = std::stoi(name);
|
||||
} catch (std::exception& e) {
|
||||
// shouldn't happen but jic
|
||||
Debug::log(ERR, "Error in getMonitorFromString: invalid num");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (monID > -1 && monID < (int)g_pCompositor->m_vMonitors.size()) {
|
||||
return g_pCompositor->getMonitorFromID(monID);
|
||||
} else {
|
||||
Debug::log(ERR, "Error in getMonitorFromString: invalid arg 1");
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
if (isDirection(name)) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorInDirection(name[0]);
|
||||
return PMONITOR;
|
||||
} else {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->szName == name) {
|
||||
return m.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Debug::log(ERR, "Error in getMonitorFromString: no such monitor");
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMonitor) {
|
||||
|
||||
// We trust the workspace and monitor to be correct.
|
||||
@@ -1338,9 +1484,15 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
|
||||
if (w->m_iWorkspaceID == pWorkspace->m_iID) {
|
||||
w->m_iMonitorID = pMonitor->ID;
|
||||
|
||||
// additionally, move floating windows manually
|
||||
if (w->m_bIsFloating && w->m_bIsMapped && !w->m_bHidden) {
|
||||
w->m_vRealPosition = w->m_vRealPosition.vec() - POLDMON->vecPosition + pMonitor->vecPosition;
|
||||
// additionally, move floating and fs windows manually
|
||||
if (w->m_bIsMapped && !w->m_bHidden) {
|
||||
if (w->m_bIsFloating)
|
||||
w->m_vRealPosition = w->m_vRealPosition.vec() - POLDMON->vecPosition + pMonitor->vecPosition;
|
||||
|
||||
if (w->m_bIsFullscreen) {
|
||||
w->m_vRealPosition = pMonitor->vecPosition;
|
||||
w->m_vRealSize = pMonitor->vecSize;
|
||||
}
|
||||
}
|
||||
|
||||
w->updateToplevel();
|
||||
@@ -1365,6 +1517,9 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(POLDMON->ID);
|
||||
|
||||
g_pInputManager->refocus();
|
||||
|
||||
// event
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", pWorkspace->m_szName + "," + pMonitor->szName});
|
||||
}
|
||||
|
||||
bool CCompositor::workspaceIDOutOfBounds(const int& id) {
|
||||
@@ -1399,6 +1554,8 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
|
||||
}
|
||||
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv(), true);
|
||||
|
||||
forceReportSizesToWindowsOnWorkspace(pWindow->m_iWorkspaceID);
|
||||
}
|
||||
|
||||
void CCompositor::moveUnmanagedX11ToWindows(CWindow* pWindow) {
|
||||
@@ -1545,13 +1702,6 @@ SLayerSurface* CCompositor::getLayerSurfaceFromWlr(wlr_layer_surface_v1* pLS) {
|
||||
void CCompositor::closeWindow(CWindow* pWindow) {
|
||||
if (pWindow && windowValidMapped(pWindow)) {
|
||||
g_pXWaylandManager->sendCloseWindow(pWindow);
|
||||
|
||||
if (pWindow == m_pLastWindow) {
|
||||
m_pLastFocus = nullptr;
|
||||
m_pLastWindow = nullptr;
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // post an activewindow event to empty, as we are currently unfocused
|
||||
focusWindow(windowFromCursor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1605,4 +1755,12 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con
|
||||
const int Y = std::stoi(y);
|
||||
|
||||
return Vector2D(X + relativeTo.x, Y + relativeTo.y);
|
||||
}
|
||||
|
||||
void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == wid && w->m_bIsMapped && !w->m_bHidden) {
|
||||
g_pXWaylandManager->setWindowSize(w.get(), w->m_vRealSize.vec(), true);
|
||||
}
|
||||
}
|
||||
}
|
@@ -38,6 +38,8 @@ public:
|
||||
wlr_compositor* m_sWLRCompositor;
|
||||
wlr_subcompositor* m_sWLRSubCompositor;
|
||||
wlr_data_device_manager* m_sWLRDataDevMgr;
|
||||
wlr_drm* m_sWRLDRM;
|
||||
wlr_drm_lease_v1_manager* m_sWRLDRMLeaseMgr;
|
||||
wlr_xdg_activation_v1* m_sWLRXDGActivation;
|
||||
wlr_output_layout* m_sWLROutputLayout;
|
||||
wlr_idle* m_sWLRIdle;
|
||||
@@ -54,7 +56,6 @@ public:
|
||||
wlr_egl* m_sWLREGL;
|
||||
int m_iDRMFD;
|
||||
wlr_ext_workspace_manager_v1* m_sWLREXTWorkspaceMgr;
|
||||
wlr_linux_dmabuf_v1* m_sWLRDmabuf;
|
||||
wlr_pointer_constraints_v1* m_sWLRPointerConstraints;
|
||||
wlr_relative_pointer_manager_v1* m_sWLRRelPointerMgr;
|
||||
wlr_server_decoration_manager* m_sWLRServerDecoMgr;
|
||||
@@ -98,6 +99,8 @@ public:
|
||||
bool m_bSessionActive = true;
|
||||
bool m_bDPMSStateON = true;
|
||||
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
|
||||
bool m_bIsShuttingDown = false;
|
||||
std::deque<uint64_t> m_dProcessPIDsOnShutdown; // stores PIDs of apps to kill later when shutting down
|
||||
|
||||
// ------------------------------------------------- //
|
||||
|
||||
@@ -143,9 +146,10 @@ public:
|
||||
CMonitor* getMonitorInDirection(const char&);
|
||||
void updateAllWindowsAnimatedDecorationValues();
|
||||
void updateWindowAnimatedDecorationValues(CWindow*);
|
||||
void moveWindowToWorkspace(CWindow*, const std::string&);
|
||||
int getNextAvailableMonitorID();
|
||||
void moveWorkspaceToMonitor(CWorkspace*, CMonitor*);
|
||||
void swapActiveWorkspaces(CMonitor*, CMonitor*);
|
||||
CMonitor* getMonitorFromString(const std::string&);
|
||||
bool workspaceIDOutOfBounds(const int&);
|
||||
void setWindowFullscreen(CWindow*, bool, eFullscreenMode);
|
||||
void moveUnmanagedX11ToWindows(CWindow*);
|
||||
@@ -159,6 +163,7 @@ public:
|
||||
SLayerSurface* getLayerSurfaceFromSurface(wlr_surface*);
|
||||
void closeWindow(CWindow*);
|
||||
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
||||
void forceReportSizesToWindowsOnWorkspace(const int&);
|
||||
|
||||
|
||||
std::string explicitConfigPath;
|
||||
@@ -167,7 +172,9 @@ public:
|
||||
|
||||
private:
|
||||
void initAllSignals();
|
||||
void setRandomSplash();
|
||||
void setRandomSplash();
|
||||
|
||||
uint64_t m_iHyprlandPID = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -21,9 +21,9 @@ CWindow::~CWindow() {
|
||||
}
|
||||
|
||||
wlr_box CWindow::getFullWindowBoundingBox() {
|
||||
static auto* const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
|
||||
SWindowDecorationExtents maxExtents = {{*PBORDERSIZE + 1, *PBORDERSIZE + 1}, {*PBORDERSIZE + 1, *PBORDERSIZE + 1}};
|
||||
SWindowDecorationExtents maxExtents = {{*PBORDERSIZE + 2, *PBORDERSIZE + 2}, {*PBORDERSIZE + 2, *PBORDERSIZE + 2}};
|
||||
|
||||
for (auto& wd : m_dWindowDecorations) {
|
||||
|
||||
@@ -205,4 +205,31 @@ void CWindow::updateSurfaceOutputs() {
|
||||
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(this), sendLeaveIter, PLASTMONITOR->output);
|
||||
|
||||
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(this), sendEnterIter, PNEWMONITOR->output);
|
||||
}
|
||||
}
|
||||
|
||||
void CWindow::moveToWorkspace(int workspaceID) {
|
||||
if (m_iWorkspaceID != workspaceID) {
|
||||
m_iWorkspaceID = workspaceID;
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID);
|
||||
if (PWORKSPACE) {
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", this, PWORKSPACE->m_szName.c_str())});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CWindow* CWindow::X11TransientFor() {
|
||||
if (!m_bIsX11)
|
||||
return nullptr;
|
||||
|
||||
if (!m_uSurface.xwayland->parent)
|
||||
return nullptr;
|
||||
|
||||
auto PPARENT = g_pCompositor->getWindowFromSurface(m_uSurface.xwayland->parent->surface);
|
||||
|
||||
while (PPARENT->m_uSurface.xwayland->parent) {
|
||||
PPARENT = g_pCompositor->getWindowFromSurface(PPARENT->m_uSurface.xwayland->parent->surface);
|
||||
}
|
||||
|
||||
return PPARENT;
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ struct SWindowAdditionalConfigData {
|
||||
int rounding = -1; // -1 means no
|
||||
bool forceNoBlur = false;
|
||||
bool forceOpaque = false;
|
||||
bool forceAllowsInput = false;
|
||||
};
|
||||
|
||||
class CWindow {
|
||||
@@ -100,6 +101,9 @@ public:
|
||||
bool m_bNoFocus = false;
|
||||
bool m_bNoInitialFocus = false;
|
||||
|
||||
// initial fullscreen
|
||||
bool m_bWantsInitialFullscreen = false;
|
||||
|
||||
SSurfaceTreeNode* m_pSurfaceTree = nullptr;
|
||||
|
||||
// Animated border
|
||||
@@ -115,6 +119,9 @@ public:
|
||||
// For hidden windows and stuff
|
||||
bool m_bHidden = false;
|
||||
|
||||
// for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
|
||||
CWindow* m_pLastCycledWindow = nullptr;
|
||||
|
||||
// Foreign Toplevel proto
|
||||
wlr_foreign_toplevel_handle_v1* m_phForeignToplevel = nullptr;
|
||||
|
||||
@@ -151,4 +158,6 @@ public:
|
||||
void destroyToplevelHandle();
|
||||
void updateToplevel();
|
||||
void updateSurfaceOutputs();
|
||||
void moveToWorkspace(int);
|
||||
CWindow* X11TransientFor();
|
||||
};
|
||||
|
@@ -92,6 +92,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["dwindle:special_scale_factor"].floatValue = 0.8f;
|
||||
configValues["dwindle:split_width_multiplier"].floatValue = 1.0f;
|
||||
configValues["dwindle:no_gaps_when_only"].intValue = 0;
|
||||
configValues["dwindle:use_active_for_splits"].intValue = 1;
|
||||
|
||||
configValues["master:special_scale_factor"].floatValue = 0.8f;
|
||||
configValues["master:new_is_master"].intValue = 1;
|
||||
@@ -119,6 +120,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["animations:workspaces"].intValue = 1;
|
||||
|
||||
configValues["input:sensitivity"].floatValue = 0.f;
|
||||
configValues["input:kb_file"].strValue = STRVAL_EMPTY;
|
||||
configValues["input:kb_layout"].strValue = "us";
|
||||
configValues["input:kb_variant"].strValue = STRVAL_EMPTY;
|
||||
configValues["input:kb_options"].strValue = STRVAL_EMPTY;
|
||||
@@ -129,6 +131,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["input:natural_scroll"].intValue = 0;
|
||||
configValues["input:numlock_by_default"].intValue = 0;
|
||||
configValues["input:force_no_accel"].intValue = 0;
|
||||
configValues["input:float_switch_override_focus"].intValue = 1;
|
||||
configValues["input:touchpad:natural_scroll"].intValue = 0;
|
||||
configValues["input:touchpad:disable_while_typing"].intValue = 1;
|
||||
configValues["input:touchpad:clickfinger_behavior"].intValue = 0;
|
||||
@@ -138,6 +141,8 @@ void CConfigManager::setDefaultVars() {
|
||||
|
||||
configValues["binds:pass_mouse_when_bound"].intValue = 1;
|
||||
configValues["binds:scroll_event_delay"].intValue = 300;
|
||||
configValues["binds:workspace_back_and_forth"].intValue = 0;
|
||||
configValues["binds:allow_workspace_cycles"].intValue = 0;
|
||||
|
||||
configValues["gestures:workspace_swipe"].intValue = 0;
|
||||
configValues["gestures:workspace_swipe_fingers"].intValue = 3;
|
||||
@@ -155,6 +160,7 @@ void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
|
||||
auto& cfgValues = deviceConfigs[dev];
|
||||
|
||||
cfgValues["sensitivity"].floatValue = 0.f;
|
||||
cfgValues["kb_file"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["kb_layout"].strValue = "us";
|
||||
cfgValues["kb_variant"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["kb_options"].strValue = STRVAL_EMPTY;
|
||||
@@ -193,6 +199,7 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||
// border
|
||||
|
||||
// workspaces
|
||||
INITANIMCFG("specialWorkspace");
|
||||
}
|
||||
|
||||
// init the values
|
||||
@@ -219,6 +226,8 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||
CREATEANIMCFG("fadeOut", "fade");
|
||||
CREATEANIMCFG("fadeSwitch", "fade");
|
||||
CREATEANIMCFG("fadeShadow", "fade");
|
||||
|
||||
CREATEANIMCFG("specialWorkspace", "workspaces");
|
||||
}
|
||||
|
||||
void CConfigManager::init() {
|
||||
@@ -687,6 +696,11 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
||||
return;
|
||||
}
|
||||
|
||||
if (KEY == "exclam" || KEY == "asciicircum" || KEY == "at") { // just some
|
||||
parseError = "Your config contains (probably) wrong keys. The SHIFT keysym behavior has changed after v0.10.3beta. Please consult the wiki (Advanced configuring -> binds)";
|
||||
return;
|
||||
}
|
||||
|
||||
if (KEY != "") {
|
||||
if (isNumber(KEY) && std::stoi(KEY) > 9)
|
||||
g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat});
|
||||
@@ -728,6 +742,7 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str
|
||||
&& RULE != "noblur"
|
||||
&& RULE != "center"
|
||||
&& RULE != "opaque"
|
||||
&& RULE != "forceinput"
|
||||
&& RULE != "fullscreen"
|
||||
&& RULE.find("animation") != 0
|
||||
&& RULE.find("rounding") != 0
|
||||
@@ -772,30 +787,13 @@ void CConfigManager::handleSubmap(const std::string& command, const std::string&
|
||||
}
|
||||
|
||||
void CConfigManager::handleSource(const std::string& command, const std::string& rawpath) {
|
||||
static const char* const ENVHOME = getenv("HOME");
|
||||
|
||||
auto value = rawpath;
|
||||
|
||||
if (value.length() < 2) {
|
||||
if (rawpath.length() < 2) {
|
||||
Debug::log(ERR, "source= path garbage");
|
||||
parseError = "source path " + value + " bogus!";
|
||||
parseError = "source path " + rawpath + " bogus!";
|
||||
return;
|
||||
}
|
||||
|
||||
if (value[0] == '.') {
|
||||
auto currentDir = configCurrentPath.substr(0, configCurrentPath.find_last_of('/'));
|
||||
|
||||
if (value[1] == '.') {
|
||||
auto parentDir = currentDir.substr(0, currentDir.find_last_of('/'));
|
||||
value.replace(0, 2, parentDir);
|
||||
} else {
|
||||
value.replace(0, 1, currentDir);
|
||||
}
|
||||
}
|
||||
|
||||
if (value[0] == '~') {
|
||||
value.replace(0, 1, std::string(ENVHOME));
|
||||
}
|
||||
auto value = absolutePath(rawpath, configCurrentPath);
|
||||
|
||||
if (!std::filesystem::exists(value)) {
|
||||
Debug::log(ERR, "source= file doesnt exist");
|
||||
@@ -924,6 +922,7 @@ void CConfigManager::parseLine(std::string& line) {
|
||||
if (line.contains(" {")) {
|
||||
auto cat = line.substr(0, line.find(" {"));
|
||||
transform(cat.begin(), cat.end(), cat.begin(), ::tolower);
|
||||
std::replace(cat.begin(), cat.end(), ' ', '-');
|
||||
if (currentCategory.length() != 0) {
|
||||
currentCategory.push_back(':');
|
||||
currentCategory.append(cat);
|
||||
@@ -936,7 +935,14 @@ void CConfigManager::parseLine(std::string& line) {
|
||||
}
|
||||
|
||||
if (line.contains("}") && currentCategory != "") {
|
||||
currentCategory = "";
|
||||
|
||||
const auto LASTSEP = currentCategory.find_last_of(':');
|
||||
|
||||
if (LASTSEP == std::string::npos || currentCategory.contains("device"))
|
||||
currentCategory = "";
|
||||
else
|
||||
currentCategory = currentCategory.substr(0, LASTSEP);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1152,9 +1158,13 @@ SConfigValue CConfigManager::getConfigValueSafe(const std::string& val) {
|
||||
SConfigValue CConfigManager::getConfigValueSafeDevice(const std::string& dev, const std::string& val) {
|
||||
std::lock_guard<std::mutex> lg(configmtx);
|
||||
|
||||
const auto it = deviceConfigs.find(dev);
|
||||
auto devcopy = dev;
|
||||
std::replace(devcopy.begin(), devcopy.end(), ' ', '-');
|
||||
|
||||
const auto it = deviceConfigs.find(devcopy);
|
||||
|
||||
if (it == deviceConfigs.end()) {
|
||||
Debug::log(ERR, "getConfigValueSafeDevice: No device config for %s found???", devcopy.c_str());
|
||||
return SConfigValue();
|
||||
}
|
||||
|
||||
@@ -1167,7 +1177,7 @@ SConfigValue CConfigManager::getConfigValueSafeDevice(const std::string& dev, co
|
||||
if (foundIt == std::string::npos)
|
||||
continue;
|
||||
|
||||
if (foundIt == cv.first.length() - val.length()) {
|
||||
if (cv.first == "input:" + val || cv.first == "input:touchpad:" + cv.first) {
|
||||
copy = cv.second;
|
||||
}
|
||||
}
|
||||
@@ -1346,7 +1356,10 @@ SConfigValue* CConfigManager::getConfigValuePtrSafe(std::string val) {
|
||||
}
|
||||
|
||||
bool CConfigManager::deviceConfigExists(const std::string& dev) {
|
||||
const auto it = deviceConfigs.find(dev);
|
||||
auto copy = dev;
|
||||
std::replace(copy.begin(), copy.end(), ' ', '-');
|
||||
|
||||
const auto it = deviceConfigs.find(copy);
|
||||
|
||||
return it != deviceConfigs.end();
|
||||
}
|
||||
@@ -1379,4 +1392,4 @@ SAnimationPropertyConfig* CConfigManager::getAnimationPropertyConfig(const std::
|
||||
void CConfigManager::addParseError(const std::string& err) {
|
||||
if (parseError == "")
|
||||
parseError = err;
|
||||
}
|
||||
}
|
||||
|
@@ -106,6 +106,8 @@ public:
|
||||
|
||||
SAnimationPropertyConfig* getAnimationPropertyConfig(const std::string&);
|
||||
|
||||
std::string configCurrentPath;
|
||||
|
||||
private:
|
||||
std::deque<std::string> configPaths; // stores all the config paths
|
||||
std::unordered_map<std::string, time_t> configModifyTimes; // stores modify times
|
||||
@@ -115,8 +117,6 @@ private:
|
||||
|
||||
std::unordered_map<std::string, SAnimationPropertyConfig> animationConfig; // stores all the animations with their set values
|
||||
|
||||
std::string configCurrentPath;
|
||||
|
||||
std::string currentCategory = ""; // For storing the category of the current item
|
||||
|
||||
std::string parseError = ""; // For storing a parse error to display later
|
||||
@@ -159,4 +159,4 @@ private:
|
||||
void handleBlurLS(const std::string&, const std::string&);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
||||
|
@@ -20,6 +20,7 @@ autogenerated=1 # remove this line to get rid of the warning on top.
|
||||
monitor=,preferred,auto,1
|
||||
|
||||
input {
|
||||
kb_file=
|
||||
kb_layout=
|
||||
kb_variant=
|
||||
kb_model=
|
||||
@@ -31,10 +32,11 @@ input {
|
||||
touchpad {
|
||||
natural_scroll=no
|
||||
}
|
||||
|
||||
sensitivity=0 # -1.0 - 1.0, 0 means no modification.
|
||||
}
|
||||
|
||||
general {
|
||||
sensitivity=1.0 # for mouse cursor
|
||||
main_mod=SUPER
|
||||
|
||||
gaps_in=5
|
||||
@@ -52,10 +54,8 @@ decoration {
|
||||
rounding=10
|
||||
blur=1
|
||||
blur_size=3 # minimum 1
|
||||
blur_passes=1 # minimum 1, more passes = more resource intensive.
|
||||
# Your blur "amount" is blur_size * blur_passes, but high blur_size (over around 5-ish) will produce artifacts.
|
||||
# if you want heavy blur, you need to up the blur_passes.
|
||||
# the more passes, the more you can up the blur_size without noticing artifacts.
|
||||
blur_passes=1 # minimum 1
|
||||
blur_new_optimizations=1
|
||||
}
|
||||
|
||||
animations {
|
||||
@@ -122,4 +122,4 @@ bind=ALT,0,movetoworkspace,10
|
||||
|
||||
bind=SUPER,mouse_down,workspace,e+1
|
||||
bind=SUPER,mouse_up,workspace,e-1
|
||||
)#";
|
||||
)#";
|
||||
|
@@ -310,7 +310,8 @@ R"#( {
|
||||
"layout": "%s",
|
||||
"variant": "%s",
|
||||
"options": "%s",
|
||||
"active_keymap": "%s"
|
||||
"active_keymap": "%s",
|
||||
"main": %s
|
||||
},)#",
|
||||
&k,
|
||||
escapeJSONStrings(k.keyboard->name).c_str(),
|
||||
@@ -319,7 +320,8 @@ R"#( {
|
||||
escapeJSONStrings(k.currentRules.layout).c_str(),
|
||||
escapeJSONStrings(k.currentRules.variant).c_str(),
|
||||
escapeJSONStrings(k.currentRules.options).c_str(),
|
||||
escapeJSONStrings(KM).c_str()
|
||||
escapeJSONStrings(KM).c_str(),
|
||||
(k.active ? "true" : "false")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -386,7 +388,7 @@ R"#( {
|
||||
|
||||
for (auto& k : g_pInputManager->m_lKeyboards) {
|
||||
const auto KM = g_pInputManager->getActiveLayoutForKeyboard(&k);
|
||||
result += getFormat("\tKeyboard at %x:\n\t\t%s\n\t\t\trules: r \"%s\", m \"%s\", l \"%s\", v \"%s\", o \"%s\"\n\t\t\tactive keymap: %s\n", &k, k.keyboard->name, k.currentRules.rules.c_str(), k.currentRules.model.c_str(), k.currentRules.layout.c_str(), k.currentRules.variant.c_str(), k.currentRules.options.c_str(), KM.c_str());
|
||||
result += getFormat("\tKeyboard at %x:\n\t\t%s\n\t\t\trules: r \"%s\", m \"%s\", l \"%s\", v \"%s\", o \"%s\"\n\t\t\tactive keymap: %s\n\t\t\tmain: %s\n", &k, k.keyboard->name, k.currentRules.rules.c_str(), k.currentRules.model.c_str(), k.currentRules.layout.c_str(), k.currentRules.variant.c_str(), k.currentRules.options.c_str(), KM.c_str(), (k.active ? "yes" : "no"));
|
||||
}
|
||||
|
||||
result += "\n\nTablets:\n";
|
||||
@@ -491,8 +493,10 @@ std::string dispatchKeyword(std::string in) {
|
||||
if (COMMAND == "monitor")
|
||||
g_pConfigManager->m_bWantsMonitorReload = true; // for monitor keywords
|
||||
|
||||
if (COMMAND.contains("input"))
|
||||
if (COMMAND.contains("input") || COMMAND.contains("device:")) {
|
||||
g_pInputManager->setKeyboardLayout(); // update kb layout
|
||||
g_pInputManager->setMouseConfigs(); // update mouse cfgs
|
||||
}
|
||||
|
||||
if (COMMAND.contains("general:layout"))
|
||||
g_pLayoutManager->switchToLayout(g_pConfigManager->getString("general:layout")); // update layout
|
||||
@@ -755,7 +759,7 @@ std::string getRequestFromThread(std::string rq) {
|
||||
}
|
||||
|
||||
void HyprCtl::startHyprCtlSocket() {
|
||||
std::thread([&]() {
|
||||
tThread = std::thread([&]() {
|
||||
const auto SOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (SOCKET < 0) {
|
||||
@@ -802,5 +806,7 @@ void HyprCtl::startHyprCtlSocket() {
|
||||
}
|
||||
|
||||
close(SOCKET);
|
||||
}).detach();
|
||||
});
|
||||
|
||||
tThread.detach();
|
||||
}
|
||||
|
@@ -15,6 +15,8 @@ namespace HyprCtl {
|
||||
|
||||
inline std::ifstream requestStream;
|
||||
|
||||
inline std::thread tThread;
|
||||
|
||||
enum eHyprCtlOutputFormat {
|
||||
FORMAT_NORMAL = 0,
|
||||
FORMAT_JSON
|
||||
|
@@ -6,10 +6,23 @@
|
||||
#include <iostream>
|
||||
|
||||
void Debug::init(std::string IS) {
|
||||
if (ISDEBUG)
|
||||
logFile = "/tmp/hypr/" + IS + "/hyprlandd.log";
|
||||
else
|
||||
logFile = "/tmp/hypr/" + IS + "/hyprland.log";
|
||||
logFile = "/tmp/hypr/" + IS + (ISDEBUG ? "/hyprlandd.log" : "/hyprland.log");
|
||||
}
|
||||
|
||||
void Debug::wlrLog(wlr_log_importance level, const char* fmt, va_list args) {
|
||||
char* outputStr = nullptr;
|
||||
|
||||
std::ofstream ofs;
|
||||
ofs.open(logFile, std::ios::out | std::ios::app);
|
||||
|
||||
vasprintf(&outputStr, fmt, args);
|
||||
|
||||
std::string output = std::string(outputStr);
|
||||
free(outputStr);
|
||||
|
||||
ofs << "[wlr] " << output << "\n";
|
||||
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
void Debug::log(LogLevel level, const char* fmt, ...) {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
#define LOGMESSAGESIZE 1024
|
||||
|
||||
@@ -15,6 +16,7 @@ enum LogLevel {
|
||||
namespace Debug {
|
||||
void init(std::string IS);
|
||||
void log(LogLevel level, const char* fmt, ...);
|
||||
void wlrLog(wlr_log_importance level, const char* fmt, va_list args);
|
||||
|
||||
inline std::string logFile;
|
||||
inline int64_t* disableLogs = nullptr;
|
||||
|
@@ -12,6 +12,9 @@ namespace Events {
|
||||
LISTENER(change);
|
||||
LISTENER(newOutput);
|
||||
|
||||
// DRM events
|
||||
LISTENER(leaseRequest);
|
||||
|
||||
// Layer events
|
||||
LISTENER(newLayerSurface);
|
||||
DYNLISTENFUNC(destroyLayerSurface);
|
||||
|
@@ -25,6 +25,15 @@ void Events::listener_outputMgrTest(wl_listener* listener, void* data) {
|
||||
g_pHyprRenderer->outputMgrApplyTest(CONFIG, true);
|
||||
}
|
||||
|
||||
void Events::listener_leaseRequest(wl_listener* listener, void* data) {
|
||||
const auto REQUEST = (wlr_drm_lease_request_v1*)data;
|
||||
struct wlr_drm_lease_v1* lease = wlr_drm_lease_request_v1_grant(REQUEST);
|
||||
if (!lease) {
|
||||
Debug::log(ERR, "Failed to grant lease request!");
|
||||
wlr_drm_lease_request_v1_reject(REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
void Events::listener_requestSetPrimarySel(wl_listener* listener, void* data) {
|
||||
const auto EVENT = (wlr_seat_request_set_primary_selection_event*)data;
|
||||
wlr_seat_set_primary_selection(g_pCompositor->m_sSeat.seat, EVENT->source, EVENT->serial);
|
||||
|
@@ -195,13 +195,13 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
|
||||
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
||||
} else {
|
||||
static auto* const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
|
||||
static auto *const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
|
||||
|
||||
// if we use blur we need to expand the damage for proper blurring
|
||||
if (*PBLURENABLED == 1) {
|
||||
// TODO: can this be optimized?
|
||||
static auto* const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_size")->intValue;
|
||||
static auto* const PBLURPASSES = &g_pConfigManager->getConfigValuePtr("decoration:blur_passes")->intValue;
|
||||
static auto *const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_size")->intValue;
|
||||
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.
|
||||
|
||||
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
||||
|
@@ -18,20 +18,18 @@
|
||||
void addPopupGlobalCoords(void* pPopup, int* x, int* y) {
|
||||
SXDGPopup *const PPOPUP = (SXDGPopup*)pPopup;
|
||||
|
||||
auto curPopup = PPOPUP;
|
||||
|
||||
int px = 0;
|
||||
int py = 0;
|
||||
|
||||
auto curPopup = PPOPUP;
|
||||
while (true) {
|
||||
px += curPopup->popup->current.geometry.x;
|
||||
py += curPopup->popup->current.geometry.y;
|
||||
|
||||
// fix oversized fucking popups
|
||||
// kill me
|
||||
if (curPopup->pSurfaceTree && curPopup->pSurfaceTree->pSurface && !curPopup->parentPopup) {
|
||||
const auto EXTENTSSURFACE = pixman_region32_extents(&curPopup->pSurfaceTree->pSurface->input_region);
|
||||
px -= EXTENTSSURFACE->x1;
|
||||
py -= EXTENTSSURFACE->y1;
|
||||
if (curPopup == PPOPUP && PPOPUP->parentWindow) {
|
||||
px -= curPopup->popup->base->current.geometry.x;
|
||||
py -= curPopup->popup->base->current.geometry.y;
|
||||
}
|
||||
|
||||
if (curPopup->parentPopup) {
|
||||
@@ -104,12 +102,9 @@ void Events::listener_newPopupXDG(void* owner, void* data) {
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(PWINDOW->m_uSurface.xdg, &geom);
|
||||
|
||||
PNEWPOPUP->popup = WLRPOPUP;
|
||||
PNEWPOPUP->lx = PWINDOW->m_vRealPosition.goalv().x - geom.x;
|
||||
PNEWPOPUP->ly = PWINDOW->m_vRealPosition.goalv().y - geom.y;
|
||||
PNEWPOPUP->lx = PWINDOW->m_vRealPosition.goalv().x;
|
||||
PNEWPOPUP->ly = PWINDOW->m_vRealPosition.goalv().y;
|
||||
PNEWPOPUP->parentWindow = PWINDOW;
|
||||
PNEWPOPUP->monitor = PMONITOR;
|
||||
createNewPopup(WLRPOPUP, PNEWPOPUP);
|
||||
@@ -154,7 +149,7 @@ void Events::listener_mapPopupXDG(void* owner, void* data) {
|
||||
wlr_box extents;
|
||||
wlr_surface_get_extends(PPOPUP->popup->base->surface, &extents);
|
||||
|
||||
g_pHyprRenderer->damageBox(lx, ly, extents.width + 2, extents.height + 2);
|
||||
g_pHyprRenderer->damageBox(lx - extents.x, ly - extents.y, extents.width + 2, extents.height + 2);
|
||||
|
||||
Debug::log(LOG, "XDG Popup got assigned a surfaceTreeNode %x", PPOPUP->pSurfaceTree);
|
||||
}
|
||||
@@ -173,7 +168,7 @@ void Events::listener_unmapPopupXDG(void* owner, void* data) {
|
||||
wlr_box extents;
|
||||
wlr_surface_get_extends(PPOPUP->popup->base->surface, &extents);
|
||||
|
||||
g_pHyprRenderer->damageBox(lx, ly, extents.width + 2, extents.height + 2);
|
||||
g_pHyprRenderer->damageBox(lx - extents.x, ly - extents.y, extents.width + 2, extents.height + 2);
|
||||
|
||||
PPOPUP->pSurfaceTree = nullptr;
|
||||
}
|
||||
|
@@ -85,6 +85,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_bRequestsFloat = true;
|
||||
}
|
||||
|
||||
PWINDOW->m_bX11ShouldntFocus = PWINDOW->m_bX11ShouldntFocus || (PWINDOW->m_bIsX11 && PWINDOW->m_iX11Type == 2);
|
||||
|
||||
if (PWORKSPACE->m_bDefaultFloating)
|
||||
PWINDOW->m_bIsFloating = true;
|
||||
|
||||
@@ -95,17 +97,20 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_vPseudoSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
|
||||
}
|
||||
|
||||
CWindow* pFullscreenWindow = nullptr;
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !PWINDOW->m_bIsFloating) {
|
||||
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PFULLWINDOW, FULLSCREEN_FULL, false);
|
||||
g_pXWaylandManager->setWindowFullscreen(PFULLWINDOW, PFULLWINDOW->m_bIsFullscreen);
|
||||
pFullscreenWindow = PFULLWINDOW;
|
||||
g_pCompositor->setWindowFullscreen(PFULLWINDOW, false, PWORKSPACE->m_efFullscreenMode);
|
||||
}
|
||||
|
||||
// window rules
|
||||
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(PWINDOW);
|
||||
std::string requestedWorkspace = "";
|
||||
bool workspaceSilent = false;
|
||||
bool requestsFullscreen = false;
|
||||
bool requestsFullscreen = PWINDOW->m_bWantsInitialFullscreen || (!PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xdg->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL && PWINDOW->m_uSurface.xdg->toplevel->requested.fullscreen);
|
||||
bool shouldFocus = true;
|
||||
|
||||
for (auto& r : WINDOWRULES) {
|
||||
if (r.szRule.find("monitor") == 0) {
|
||||
@@ -154,6 +159,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
requestsFullscreen = true;
|
||||
} else if (r.szRule == "opaque") {
|
||||
PWINDOW->m_sAdditionalConfigData.forceOpaque = true;
|
||||
} else if (r.szRule == "forceinput") {
|
||||
PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true;
|
||||
} else if (r.szRule.find("rounding") == 0) {
|
||||
try {
|
||||
PWINDOW->m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
||||
@@ -186,10 +193,14 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
// check for silent
|
||||
if (requestedWorkspace.contains("silent")) {
|
||||
workspaceSilent = true;
|
||||
shouldFocus = false;
|
||||
}
|
||||
|
||||
requestedWorkspace = requestedWorkspace.substr(0, requestedWorkspace.find_first_of(' '));
|
||||
|
||||
if (!shouldFocus && requestedWorkspace == std::to_string(PMONITOR->activeWorkspace))
|
||||
shouldFocus = true;
|
||||
|
||||
if (requestedWorkspace == "special") {
|
||||
workspaceSilent = true;
|
||||
}
|
||||
@@ -260,6 +271,14 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv() - Vector2D(10,10);
|
||||
}
|
||||
|
||||
const auto PFOCUSEDWINDOWPREV = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (PWINDOW->m_sAdditionalConfigData.forceAllowsInput) {
|
||||
PWINDOW->m_bNoFocus = false;
|
||||
PWINDOW->m_bNoInitialFocus = false;
|
||||
PWINDOW->m_bX11ShouldntFocus = false;
|
||||
}
|
||||
|
||||
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && PWINDOW->m_iX11Type != 2) {
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
|
||||
@@ -270,13 +289,13 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
if (!PWINDOW->m_bIsX11) {
|
||||
PWINDOW->hyprListener_commitWindow.initCallback(&PWINDOW->m_uSurface.xdg->surface->events.commit, &Events::listener_commitWindow, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_fullscreenWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_fullscreen, &Events::listener_fullscreenWindow, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_newPopupXDG.initCallback(&PWINDOW->m_uSurface.xdg->events.new_popup, &Events::listener_newPopupXDG, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_requestMaximize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_maximize, &Events::listener_requestMaximize, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_requestMinimize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_minimize, &Events::listener_requestMinimize, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_requestMove.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_move, &Events::listener_requestMove, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_requestResize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_resize, &Events::listener_requestResize, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_fullscreenWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_fullscreen, &Events::listener_fullscreenWindow, PWINDOW, "XDG Window Late");
|
||||
} else {
|
||||
PWINDOW->hyprListener_fullscreenWindow.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_fullscreen, &Events::listener_fullscreenWindow, PWINDOW, "XWayland Window Late");
|
||||
PWINDOW->hyprListener_activateX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_activate, &Events::listener_activateX11, PWINDOW, "XWayland Window Late");
|
||||
@@ -321,6 +340,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, true, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
if (pFullscreenWindow && workspaceSilent) {
|
||||
g_pCompositor->setWindowFullscreen(pFullscreenWindow, true, PWORKSPACE->m_efFullscreenMode);
|
||||
}
|
||||
|
||||
// recheck idle inhibitors
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
|
||||
@@ -328,24 +351,37 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
PWINDOW->updateToplevel();
|
||||
|
||||
if (!shouldFocus) {
|
||||
if (g_pCompositor->windowValidMapped(PFOCUSEDWINDOWPREV)) {
|
||||
g_pCompositor->focusWindow(PFOCUSEDWINDOWPREV);
|
||||
PFOCUSEDWINDOWPREV->updateWindowDecos(); // need to for some reason i cba to find out why
|
||||
} else if (!PFOCUSEDWINDOWPREV)
|
||||
g_pCompositor->focusWindow(nullptr);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName;
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"openwindow", getFormat("%x,%s,%s,%s", PWINDOW, workspaceID.c_str(), g_pXWaylandManager->getAppIDClass(PWINDOW).c_str(), PWINDOW->m_szTitle.c_str())});
|
||||
}
|
||||
|
||||
void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
Debug::log(LOG, "Window %x unmapped (class %s)", PWINDOW, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str());
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"closewindow", getFormat("%x", PWINDOW)});
|
||||
|
||||
if (!PWINDOW->m_bIsX11) {
|
||||
Debug::log(LOG, "Unregistered late callbacks XDG");
|
||||
PWINDOW->hyprListener_commitWindow.removeCallback();
|
||||
PWINDOW->hyprListener_setTitleWindow.removeCallback();
|
||||
PWINDOW->hyprListener_fullscreenWindow.removeCallback();
|
||||
PWINDOW->hyprListener_newPopupXDG.removeCallback();
|
||||
PWINDOW->hyprListener_requestMaximize.removeCallback();
|
||||
PWINDOW->hyprListener_requestMinimize.removeCallback();
|
||||
PWINDOW->hyprListener_requestMove.removeCallback();
|
||||
PWINDOW->hyprListener_requestResize.removeCallback();
|
||||
PWINDOW->hyprListener_fullscreenWindow.removeCallback();
|
||||
} else {
|
||||
Debug::log(LOG, "Unregistered late callbacks XWL");
|
||||
PWINDOW->hyprListener_fullscreenWindow.removeCallback();
|
||||
@@ -363,7 +399,10 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
// Allow the renderer to catch the last frame.
|
||||
g_pHyprOpenGL->makeWindowSnapshot(PWINDOW);
|
||||
|
||||
bool wasLastWindow = false;
|
||||
|
||||
if (PWINDOW == g_pCompositor->m_pLastWindow) {
|
||||
wasLastWindow = true;
|
||||
g_pCompositor->m_pLastWindow = nullptr;
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
}
|
||||
@@ -381,11 +420,26 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
// do this after onWindowRemoved because otherwise it'll think the window is invalid
|
||||
PWINDOW->m_bIsMapped = false;
|
||||
|
||||
// refocus on a new window
|
||||
g_pInputManager->refocus();
|
||||
// refocus on a new window if needed
|
||||
if (wasLastWindow) {
|
||||
auto PWINDOWCANDIDATE = g_pCompositor->vectorToWindowIdeal(PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f);
|
||||
|
||||
if (!g_pCompositor->m_pLastWindow) {
|
||||
g_pCompositor->focusWindow(g_pCompositor->getFirstWindowOnWorkspace(PWORKSPACE->m_iID));
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && ((!PWINDOWCANDIDATE || !PWINDOWCANDIDATE->m_bCreatedOverFullscreen) || !PWINDOW->m_bIsFloating))
|
||||
PWINDOWCANDIDATE = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
|
||||
if (!PWINDOWCANDIDATE || PWINDOW == PWINDOWCANDIDATE || !PWINDOWCANDIDATE->m_bIsMapped || PWINDOWCANDIDATE->m_bHidden || PWINDOWCANDIDATE->m_bX11ShouldntFocus || PWINDOWCANDIDATE->m_iX11Type == 2 || PWINDOWCANDIDATE->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)
|
||||
PWINDOWCANDIDATE = nullptr;
|
||||
|
||||
Debug::log(LOG, "On closed window, new focused candidate is %x", PWINDOWCANDIDATE);
|
||||
|
||||
if (PWINDOWCANDIDATE != g_pCompositor->m_pLastWindow) {
|
||||
if (!PWINDOWCANDIDATE)
|
||||
g_pInputManager->refocus();
|
||||
else
|
||||
g_pCompositor->focusWindow(PWINDOWCANDIDATE);
|
||||
}
|
||||
} else {
|
||||
Debug::log(LOG, "Unmapped was not focused, ignoring a refocus.");
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Destroying the SubSurface tree of unmapped window %x", PWINDOW);
|
||||
@@ -477,7 +531,12 @@ void Events::listener_setTitleWindow(void* owner, void* data) {
|
||||
void Events::listener_fullscreenWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
if (!PWINDOW->m_bIsMapped || PWINDOW->m_bHidden)
|
||||
if (!PWINDOW->m_bIsMapped) {
|
||||
PWINDOW->m_bWantsInitialFullscreen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bHidden)
|
||||
return;
|
||||
|
||||
if (!PWINDOW->m_bIsX11) {
|
||||
|
@@ -40,6 +40,28 @@ static const float transforms[][9] = {{
|
||||
},
|
||||
};
|
||||
|
||||
std::string absolutePath(const std::string& rawpath, const std::string& currentPath) {
|
||||
auto value = rawpath;
|
||||
|
||||
if (value[0] == '.') {
|
||||
auto currentDir = currentPath.substr(0, currentPath.find_last_of('/'));
|
||||
|
||||
if (value[1] == '.') {
|
||||
auto parentDir = currentDir.substr(0, currentDir.find_last_of('/'));
|
||||
value.replace(0, 2, parentDir);
|
||||
} else {
|
||||
value.replace(0, 1, currentDir);
|
||||
}
|
||||
}
|
||||
|
||||
if (value[0] == '~') {
|
||||
static const char* const ENVHOME = getenv("HOME");
|
||||
value.replace(0, 1, std::string(ENVHOME));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void addWLSignal(wl_signal* pSignal, wl_listener* pListener, void* pOwner, std::string ownerString) {
|
||||
ASSERT(pSignal);
|
||||
ASSERT(pListener);
|
||||
@@ -53,35 +75,6 @@ void handleNoop(struct wl_listener *listener, void *data) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void wlr_signal_emit_safe(struct wl_signal *signal, void *data) {
|
||||
struct wl_listener cursor;
|
||||
struct wl_listener end;
|
||||
|
||||
/* Add two special markers: one cursor and one end marker. This way, we know
|
||||
* that we've already called listeners on the left of the cursor and that we
|
||||
* don't want to call listeners on the right of the end marker. The 'it'
|
||||
* function can remove any element it wants from the list without troubles.
|
||||
* wl_list_for_each_safe tries to be safe but it fails: it works fine
|
||||
* if the current item is removed, but not if the next one is. */
|
||||
wl_list_insert(&signal->listener_list, &cursor.link);
|
||||
cursor.notify = handleNoop;
|
||||
wl_list_insert(signal->listener_list.prev, &end.link);
|
||||
end.notify = handleNoop;
|
||||
|
||||
while (cursor.link.next != &end.link) {
|
||||
struct wl_list *pos = cursor.link.next;
|
||||
struct wl_listener *l = wl_container_of(pos, l, link);
|
||||
|
||||
wl_list_remove(&cursor.link);
|
||||
wl_list_insert(pos, &cursor.link);
|
||||
|
||||
l->notify(l, data);
|
||||
}
|
||||
|
||||
wl_list_remove(&cursor.link);
|
||||
wl_list_remove(&end.link);
|
||||
}
|
||||
|
||||
std::string getFormat(const char *fmt, ...) {
|
||||
char* outputStr = nullptr;
|
||||
|
||||
|
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "../includes.hpp"
|
||||
|
||||
std::string absolutePath(const std::string&, const std::string&);
|
||||
void addWLSignal(wl_signal*, wl_listener*, void* pOwner, std::string ownerString);
|
||||
void wlr_signal_emit_safe(struct wl_signal *signal, void *data);
|
||||
std::string getFormat(const char *fmt, ...); // Basically Debug::log to a string
|
||||
std::string escapeJSONStrings(const std::string& str);
|
||||
void scaleBox(wlr_box*, float);
|
||||
@@ -17,4 +17,4 @@ std::string execAndGet(const char*);
|
||||
|
||||
float getPlusMinusKeywordResult(std::string in, float relative);
|
||||
|
||||
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr);
|
||||
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr);
|
||||
|
@@ -56,6 +56,14 @@ void CMonitor::onConnect(bool noRule) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (output->non_desktop) {
|
||||
Debug::log(LOG, "Not configuring non-desktop output");
|
||||
if (g_pCompositor->m_sWRLDRMLeaseMgr) {
|
||||
wlr_drm_lease_v1_manager_offer_output(g_pCompositor->m_sWRLDRMLeaseMgr, output);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_bRenderingInitPassed) {
|
||||
wlr_output_init_render(output, g_pCompositor->m_sWLRAllocator, g_pCompositor->m_sWLRRenderer);
|
||||
m_bRenderingInitPassed = true;
|
||||
@@ -232,3 +240,11 @@ void CMonitor::onDisconnect() {
|
||||
|
||||
g_pCompositor->m_vMonitors.erase(std::remove_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](std::shared_ptr<CMonitor>& el) { return el.get() == this; }));
|
||||
}
|
||||
|
||||
void CMonitor::addDamage(pixman_region32_t* rg) {
|
||||
wlr_output_damage_add(damage, rg);
|
||||
}
|
||||
|
||||
void CMonitor::addDamage(wlr_box* box) {
|
||||
wlr_output_damage_add_box(damage, box);
|
||||
}
|
||||
|
@@ -55,6 +55,8 @@ public:
|
||||
// methods
|
||||
void onConnect(bool noRule);
|
||||
void onDisconnect();
|
||||
void addDamage(pixman_region32_t* rg);
|
||||
void addDamage(wlr_box* box);
|
||||
|
||||
std::shared_ptr<CMonitor>* m_pThisWrap = nullptr;
|
||||
bool m_bEnabled = false;
|
||||
|
@@ -139,6 +139,9 @@ void Events::listener_newSubsurfaceNode(void* owner, void* data) {
|
||||
|
||||
PNEWSUBSURFACE->pWindowOwner = pNode->pWindowOwner;
|
||||
|
||||
if (PSUBSURFACE->mapped)
|
||||
listener_mapSubsurface(PNEWSUBSURFACE, nullptr);
|
||||
|
||||
wlr_subsurface* existingWlrSubsurface;
|
||||
wl_list_for_each(existingWlrSubsurface, &PSUBSURFACE->surface->current.subsurfaces_below, current.link) {
|
||||
listener_newSubsurfaceNode(pNode, existingWlrSubsurface);
|
||||
@@ -187,7 +190,7 @@ void Events::listener_commitSubsurface(void* owner, void* data) {
|
||||
|
||||
// no damaging if it's not visible
|
||||
if (!g_pHyprRenderer->shouldRenderWindow(pNode->pWindowOwner)) {
|
||||
static auto* const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
if (*PLOGDAMAGE)
|
||||
Debug::log(LOG, "Refusing to commit damage from %x because it's invisible.", pNode->pWindowOwner);
|
||||
return;
|
||||
|
@@ -35,6 +35,10 @@ class Vector2D {
|
||||
return a.x != x || a.y != y;
|
||||
}
|
||||
|
||||
Vector2D operator*(const Vector2D& a) const {
|
||||
return Vector2D(this->x * a.x, this->y * a.y);
|
||||
}
|
||||
|
||||
Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D());
|
||||
|
||||
Vector2D floor();
|
||||
|
@@ -73,6 +73,9 @@ struct SRenderData {
|
||||
|
||||
// only for windows, not popups
|
||||
bool squishOversized = true;
|
||||
|
||||
// for calculating UV
|
||||
CWindow* pWindow = nullptr;
|
||||
};
|
||||
|
||||
struct SExtensionFindingData {
|
||||
@@ -94,12 +97,16 @@ struct SKeyboard {
|
||||
|
||||
DYNLISTENER(keyboardMod);
|
||||
DYNLISTENER(keyboardKey);
|
||||
DYNLISTENER(keyboardKeymap);
|
||||
DYNLISTENER(keyboardDestroy);
|
||||
|
||||
bool isVirtual = false;
|
||||
bool active = false;
|
||||
|
||||
xkb_layout_index_t activeLayout = 0;
|
||||
|
||||
std::string name = "";
|
||||
std::string xkbFilePath = "";
|
||||
|
||||
SStringRuleNames currentRules;
|
||||
int repeatRate = 0;
|
||||
@@ -302,6 +309,7 @@ struct SIMEPopup {
|
||||
int x, y;
|
||||
int realX, realY;
|
||||
bool visible;
|
||||
Vector2D lastSize;
|
||||
|
||||
DYNLISTENER(mapPopup);
|
||||
DYNLISTENER(unmapPopup);
|
||||
@@ -313,4 +321,4 @@ struct SIMEPopup {
|
||||
bool operator==(const SIMEPopup& other) {
|
||||
return pSurface == other.pSurface;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@@ -26,9 +26,9 @@ CWorkspace::CWorkspace(int monitorID, std::string name, bool special) {
|
||||
}
|
||||
|
||||
m_vRenderOffset.m_pWorkspace = this;
|
||||
m_vRenderOffset.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("workspaces"), nullptr, AVARDAMAGE_ENTIRE);
|
||||
m_vRenderOffset.create(AVARTYPE_VECTOR, special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), nullptr, AVARDAMAGE_ENTIRE);
|
||||
m_fAlpha.m_pWorkspace = this;
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("workspaces"), nullptr, AVARDAMAGE_ENTIRE);
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), nullptr, AVARDAMAGE_ENTIRE);
|
||||
m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
g_pEventManager->postEvent({"createworkspace", m_szName}, true);
|
||||
|
@@ -18,6 +18,9 @@ public:
|
||||
int m_iID = -1;
|
||||
std::string m_szName = "";
|
||||
uint64_t m_iMonitorID = -1;
|
||||
// Previous workspace ID is stored during a workspace change, allowing travel
|
||||
// to the previous workspace.
|
||||
int m_iPrevWorkspaceID = -1;
|
||||
bool m_bHasFullscreenWindow = false;
|
||||
eFullscreenMode m_efFullscreenMode = FULLSCREEN_FULL;
|
||||
|
||||
|
@@ -37,12 +37,15 @@
|
||||
extern "C" {
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/backend/libinput.h>
|
||||
#include <wlr/backend/drm.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_data_control_v1.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_drm_lease_v1.h>
|
||||
#include <wlr/types/wlr_drm.h>
|
||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||
|
@@ -6,9 +6,11 @@ void SDwindleNodeData::recalcSizePosRecursive(bool force) {
|
||||
|
||||
const auto REVERSESPLITRATIO = 2.f - splitRatio;
|
||||
|
||||
if (g_pConfigManager->getInt("dwindle:preserve_split") == 0) {
|
||||
const auto WIDTHMULTIPLIER = g_pConfigManager->getFloat("dwindle:split_width_multiplier");
|
||||
splitTop = size.y * WIDTHMULTIPLIER > size.x;
|
||||
static auto *const PPRESERVESPLIT = &g_pConfigManager->getConfigValuePtr("dwindle:preserve_split")->intValue;
|
||||
static auto *const PFLMULT = &g_pConfigManager->getConfigValuePtr("dwindle:split_width_multiplier")->floatValue;
|
||||
|
||||
if (*PPRESERVESPLIT == 0) {
|
||||
splitTop = size.y * *PFLMULT > size.x;
|
||||
}
|
||||
|
||||
const auto SPLITSIDE = !splitTop;
|
||||
@@ -234,8 +236,12 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
}
|
||||
|
||||
if (force) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
|
||||
PWINDOW->m_vRealPosition.warp();
|
||||
PWINDOW->m_vRealSize.warp();
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
|
||||
if (pNode->isGroupMember() && pNode->groupHead) {
|
||||
@@ -258,6 +264,8 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
|
||||
static auto *const PUSEACTIVE = &g_pConfigManager->getConfigValuePtr("dwindle:use_active_for_splits")->intValue;
|
||||
|
||||
// Populate the node with our window's data
|
||||
PNODE->workspaceID = pWindow->m_iWorkspaceID;
|
||||
PNODE->pWindow = pWindow;
|
||||
@@ -267,13 +275,22 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
SDwindleNodeData* OPENINGON;
|
||||
const auto MONFROMCURSOR = g_pCompositor->getMonitorFromCursor();
|
||||
|
||||
if (PMONITOR->ID == MONFROMCURSOR->ID && (PNODE->workspaceID == PMONITOR->activeWorkspace || (PNODE->workspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen))) {
|
||||
if (PMONITOR->ID == MONFROMCURSOR->ID && (PNODE->workspaceID == PMONITOR->activeWorkspace || (PNODE->workspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && !*PUSEACTIVE) {
|
||||
OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal()));
|
||||
|
||||
// happens on reserved area
|
||||
if (!OPENINGON && g_pCompositor->getWindowsOnWorkspace(PNODE->workspaceID) > 0)
|
||||
OPENINGON = getFirstNodeOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
} else if (*PUSEACTIVE) {
|
||||
if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && !g_pCompositor->m_pLastWindow->m_bIsFloating && g_pCompositor->m_pLastWindow != pWindow && g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsMapped) {
|
||||
OPENINGON = getNodeFromWindow(g_pCompositor->m_pLastWindow);
|
||||
} else {
|
||||
OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal()));
|
||||
}
|
||||
|
||||
if (!OPENINGON && g_pCompositor->getWindowsOnWorkspace(PNODE->workspaceID) > 0)
|
||||
OPENINGON = getFirstNodeOnWorkspace(PMONITOR->activeWorkspace);
|
||||
} else
|
||||
OPENINGON = getFirstNodeOnWorkspace(pWindow->m_iWorkspaceID);
|
||||
|
||||
@@ -408,8 +425,10 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
|
||||
if (!PNODE)
|
||||
if (!PNODE) {
|
||||
Debug::log(ERR, "onWindowRemovedTiling node null?");
|
||||
return;
|
||||
}
|
||||
|
||||
// check if it was grouped
|
||||
if (PNODE->isGroupMember()) {
|
||||
@@ -455,6 +474,7 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
const auto PPARENT = PNODE->pParent;
|
||||
|
||||
if (!PPARENT) {
|
||||
Debug::log(LOG, "Removing last node (dwindle)");
|
||||
m_lDwindleNodesData.remove(*PNODE);
|
||||
return;
|
||||
}
|
||||
@@ -1055,4 +1075,4 @@ void CHyprDwindleLayout::onEnable() {
|
||||
|
||||
void CHyprDwindleLayout::onDisable() {
|
||||
m_lDwindleNodesData.clear();
|
||||
}
|
||||
}
|
||||
|
@@ -206,8 +206,8 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
|
||||
if (PMONITOR) {
|
||||
DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
DRAGGINGWINDOW->m_iWorkspaceID = PMONITOR->activeWorkspace;
|
||||
|
||||
DRAGGINGWINDOW->moveToWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
DRAGGINGWINDOW->updateToplevel();
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
||||
if (!TILED) {
|
||||
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.vec() + pWindow->m_vRealSize.vec() / 2.f);
|
||||
pWindow->m_iMonitorID = PNEWMON->ID;
|
||||
pWindow->m_iWorkspaceID = PNEWMON->activeWorkspace;
|
||||
pWindow->moveToWorkspace(PNEWMON->activeWorkspace);
|
||||
|
||||
// save real pos cuz the func applies the default 5,5 mid
|
||||
const auto PSAVEDPOS = pWindow->m_vRealPosition.vec();
|
||||
|
@@ -273,8 +273,12 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
}
|
||||
|
||||
if (m_bForceWarps) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
|
||||
PWINDOW->m_vRealPosition.warp();
|
||||
PWINDOW->m_vRealSize.warp();
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
@@ -448,8 +452,80 @@ void CHyprMasterLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
||||
recalculateMonitor(pWindow->m_iMonitorID);
|
||||
}
|
||||
|
||||
CWindow* CHyprMasterLayout::getNextWindow(CWindow* pWindow, bool next) {
|
||||
if (!isWindowTiled(pWindow))
|
||||
return nullptr;
|
||||
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
|
||||
if (next) {
|
||||
if (PNODE->isMaster) {
|
||||
// focus the first non master
|
||||
for (auto n : m_lMasterNodesData) {
|
||||
if (n.pWindow != pWindow && n.workspaceID == pWindow->m_iWorkspaceID) {
|
||||
return n.pWindow;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// focus next
|
||||
bool reached = false;
|
||||
bool found = false;
|
||||
for (auto n : m_lMasterNodesData) {
|
||||
if (n.pWindow == pWindow) {
|
||||
reached = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n.workspaceID == pWindow->m_iWorkspaceID && reached) {
|
||||
return n.pWindow;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const auto PMASTER = getMasterNodeOnWorkspace(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (PMASTER)
|
||||
return PMASTER->pWindow;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (PNODE->isMaster) {
|
||||
// focus the first non master
|
||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||
if (it->pWindow != pWindow && it->workspaceID == pWindow->m_iWorkspaceID) {
|
||||
return it->pWindow;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// focus next
|
||||
bool reached = false;
|
||||
bool found = false;
|
||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||
if (it->pWindow == pWindow) {
|
||||
reached = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (it->workspaceID == pWindow->m_iWorkspaceID && reached) {
|
||||
return it->pWindow;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const auto PMASTER = getMasterNodeOnWorkspace(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (PMASTER)
|
||||
return PMASTER->pWindow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
|
||||
auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) {
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO))
|
||||
return;
|
||||
|
||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||
Vector2D middle = PWINDOWTOCHANGETO->m_vRealPosition.goalv() + PWINDOWTOCHANGETO->m_vRealSize.goalv() / 2.f;
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, middle.x, middle.y);
|
||||
@@ -475,80 +551,40 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||
} else if (message == "cyclenext") {
|
||||
const auto PWINDOW = header.pWindow;
|
||||
|
||||
if (!isWindowTiled(PWINDOW))
|
||||
return 0;
|
||||
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
|
||||
if (PNODE->isMaster) {
|
||||
// focus the first non master
|
||||
for (auto n : m_lMasterNodesData) {
|
||||
if (n.pWindow != PWINDOW && n.workspaceID == PWINDOW->m_iWorkspaceID) {
|
||||
switchToWindow(n.pWindow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// focus next
|
||||
bool reached = false;
|
||||
bool found = false;
|
||||
for (auto n : m_lMasterNodesData) {
|
||||
if (n.pWindow == PWINDOW) {
|
||||
reached = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n.workspaceID == PWINDOW->m_iWorkspaceID && reached) {
|
||||
switchToWindow(n.pWindow);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
|
||||
if (PMASTER)
|
||||
switchToWindow(PMASTER->pWindow);
|
||||
}
|
||||
}
|
||||
switchToWindow(getNextWindow(PWINDOW, true));
|
||||
} else if (message == "cycleprev") {
|
||||
const auto PWINDOW = header.pWindow;
|
||||
|
||||
if (!isWindowTiled(PWINDOW))
|
||||
switchToWindow(getNextWindow(PWINDOW, false));
|
||||
} else if (message == "swapnext") {
|
||||
if (!g_pCompositor->windowValidMapped(header.pWindow))
|
||||
return 0;
|
||||
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
if (header.pWindow->m_bIsFloating) {
|
||||
g_pKeybindManager->m_mDispatchers["swapnext"]("");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (PNODE->isMaster) {
|
||||
// focus the first non master
|
||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||
if (it->pWindow != PWINDOW && it->workspaceID == PWINDOW->m_iWorkspaceID) {
|
||||
switchToWindow(it->pWindow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// focus next
|
||||
bool reached = false;
|
||||
bool found = false;
|
||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||
if (it->pWindow == PWINDOW) {
|
||||
reached = true;
|
||||
continue;
|
||||
}
|
||||
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true);
|
||||
|
||||
if (it->workspaceID == PWINDOW->m_iWorkspaceID && reached) {
|
||||
switchToWindow(it->pWindow);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
if (PWINDOWTOSWAPWITH) {
|
||||
switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
|
||||
g_pCompositor->focusWindow(header.pWindow);
|
||||
}
|
||||
} else if (message == "swapprev") {
|
||||
if (!g_pCompositor->windowValidMapped(header.pWindow))
|
||||
return 0;
|
||||
|
||||
if (PMASTER)
|
||||
switchToWindow(PMASTER->pWindow);
|
||||
}
|
||||
if (header.pWindow->m_bIsFloating) {
|
||||
g_pKeybindManager->m_mDispatchers["swapnext"]("prev");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false);
|
||||
|
||||
if (PWINDOWTOSWAPWITH) {
|
||||
switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
|
||||
g_pCompositor->focusWindow(header.pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -51,6 +51,7 @@ private:
|
||||
SMasterNodeData* getNodeFromWindow(CWindow*);
|
||||
SMasterNodeData* getMasterNodeOnWorkspace(const int&);
|
||||
void calculateWorkspace(const int&);
|
||||
CWindow* getNextWindow(CWindow*, bool);
|
||||
|
||||
friend struct SMasterNodeData;
|
||||
};
|
12
src/main.cpp
12
src/main.cpp
@@ -44,6 +44,10 @@ int main(int argc, char** argv) {
|
||||
|
||||
std::cout << "Welcome to Hyprland!\n";
|
||||
|
||||
const auto LOGWLR = getenv("HYPRLAND_LOG_WLR");
|
||||
if (LOGWLR && std::string(LOGWLR) == "1")
|
||||
wlr_log_init(WLR_DEBUG, Debug::wlrLog);
|
||||
|
||||
// let's init the compositor.
|
||||
// it initializes basic Wayland stuff in the constructor.
|
||||
g_pCompositor = std::make_unique<CCompositor>();
|
||||
@@ -57,7 +61,13 @@ int main(int argc, char** argv) {
|
||||
// If we are here it means we got yote.
|
||||
Debug::log(LOG, "Hyprland reached the end.");
|
||||
|
||||
g_pCompositor->cleanup();
|
||||
wl_display_destroy_clients(g_pCompositor->m_sWLDisplay);
|
||||
|
||||
// kill all clients
|
||||
for (auto& c : g_pCompositor->m_dProcessPIDsOnShutdown)
|
||||
kill(c, SIGKILL);
|
||||
|
||||
wl_display_destroy(g_pCompositor->m_sWLDisplay);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@@ -190,7 +190,7 @@ void CAnimationManager::tick() {
|
||||
} case AVARDAMAGE_SHADOW: {
|
||||
RASSERT(PWINDOW, "Tried to AVARDAMAGE_SHADOW a non-window AVAR!");
|
||||
|
||||
static auto* const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
|
||||
static auto *const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
|
||||
|
||||
const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW);
|
||||
|
||||
@@ -428,7 +428,7 @@ std::string CAnimationManager::styleValidInConfigVar(const std::string& config,
|
||||
}
|
||||
|
||||
return "unknown style";
|
||||
} else if (config == "workspaces") {
|
||||
} else if (config == "workspaces" || config == "specialWorkspace") {
|
||||
if (style == "slide" || style == "slidevert" || style == "fade")
|
||||
return "";
|
||||
|
||||
|
@@ -19,7 +19,7 @@ CEventManager::CEventManager() {
|
||||
}
|
||||
|
||||
void CEventManager::startThread() {
|
||||
std::thread([&]() {
|
||||
m_tThread = std::thread([&]() {
|
||||
const auto SOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (SOCKET < 0) {
|
||||
@@ -101,13 +101,15 @@ void CEventManager::startThread() {
|
||||
}
|
||||
|
||||
close(SOCKET);
|
||||
}).detach();
|
||||
});
|
||||
|
||||
m_tThread.detach();
|
||||
}
|
||||
|
||||
void CEventManager::postEvent(const SHyprIPCEvent event, bool force) {
|
||||
|
||||
if (m_bIgnoreEvents && !force) {
|
||||
Debug::log(WARN, "Suppressed (ignoreevents true) event of type %s, content: %s",event.event.c_str(), event.data.c_str());
|
||||
if ((m_bIgnoreEvents && !force) || g_pCompositor->m_bIsShuttingDown) {
|
||||
Debug::log(WARN, "Suppressed (ignoreevents true / shutting down) event of type %s, content: %s",event.event.c_str(), event.data.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -21,6 +21,8 @@ public:
|
||||
|
||||
bool m_bIgnoreEvents = false;
|
||||
|
||||
std::thread m_tThread;
|
||||
|
||||
private:
|
||||
|
||||
std::mutex eventQueueMutex;
|
||||
|
@@ -39,6 +39,8 @@ CKeybindManager::CKeybindManager() {
|
||||
m_mDispatchers["dpms"] = dpms;
|
||||
m_mDispatchers["movewindowpixel"] = moveWindow;
|
||||
m_mDispatchers["resizewindowpixel"] = resizeWindow;
|
||||
m_mDispatchers["swapnext"] = swapnext;
|
||||
m_mDispatchers["swapactiveworkspaces"] = swapActiveWorkspaces;
|
||||
|
||||
m_tScrollTimer.reset();
|
||||
}
|
||||
@@ -94,18 +96,67 @@ uint32_t CKeybindManager::stringToModMask(std::string mods) {
|
||||
return modMask;
|
||||
}
|
||||
|
||||
void CKeybindManager::updateXKBTranslationState() {
|
||||
if (m_pXKBTranslationState) {
|
||||
xkb_keymap_unref(xkb_state_get_keymap(m_pXKBTranslationState));
|
||||
xkb_state_unref(m_pXKBTranslationState);
|
||||
|
||||
m_pXKBTranslationState = nullptr;
|
||||
}
|
||||
|
||||
const auto FILEPATH = g_pConfigManager->getString("input:kb_file");
|
||||
const auto RULES = g_pConfigManager->getString("input:kb_rules");
|
||||
const auto MODEL = g_pConfigManager->getString("input:kb_model");
|
||||
const auto LAYOUT = g_pConfigManager->getString("input:kb_layout");
|
||||
const auto VARIANT = g_pConfigManager->getString("input:kb_variant");
|
||||
const auto OPTIONS = g_pConfigManager->getString("input:kb_options");
|
||||
|
||||
xkb_rule_names rules = {
|
||||
.rules = RULES.c_str(),
|
||||
.model = MODEL.c_str(),
|
||||
.layout = LAYOUT.c_str(),
|
||||
.variant = VARIANT.c_str(),
|
||||
.options = OPTIONS.c_str()};
|
||||
|
||||
const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
const auto PKEYMAP = FILEPATH == "" ? xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS) : xkb_keymap_new_from_file(PCONTEXT, fopen(FILEPATH.c_str(), "r"), XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
xkb_context_unref(PCONTEXT);
|
||||
m_pXKBTranslationState = xkb_state_new(PKEYMAP);
|
||||
}
|
||||
|
||||
bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
|
||||
if (!g_pCompositor->m_bSessionActive) {
|
||||
m_dPressedKeycodes.clear();
|
||||
m_dPressedKeysyms.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pKeyboard->isVirtual)
|
||||
return true;
|
||||
|
||||
if (!m_pXKBTranslationState) {
|
||||
Debug::log(ERR, "BUG THIS: m_pXKBTranslationState NULL!");
|
||||
updateXKBTranslationState();
|
||||
|
||||
if (!m_pXKBTranslationState)
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto KEYCODE = e->keycode + 8; // Because to xkbcommon it's +8 from libinput
|
||||
|
||||
const xkb_keysym_t keysym = xkb_state_key_get_one_sym(wlr_keyboard_from_input_device(pKeyboard->keyboard)->xkb_state, KEYCODE);
|
||||
const xkb_keysym_t keysym = xkb_state_key_get_one_sym(m_pXKBTranslationState, KEYCODE);
|
||||
const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(wlr_keyboard_from_input_device(pKeyboard->keyboard)->xkb_state, KEYCODE);
|
||||
|
||||
if (handleInternalKeybinds(internalKeysym))
|
||||
return true;
|
||||
|
||||
const auto MODS = g_pInputManager->accumulateModsFromAllKBs();
|
||||
|
||||
m_uTimeLastMs = e->time_msec;
|
||||
m_uLastCode = KEYCODE;
|
||||
m_uLastMouseCode = 0;
|
||||
|
||||
bool found = false;
|
||||
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
@@ -178,6 +229,10 @@ bool CKeybindManager::onMouseEvent(wlr_pointer_button_event* e) {
|
||||
|
||||
bool found = false;
|
||||
|
||||
m_uLastMouseCode = e->button;
|
||||
m_uLastCode = 0;
|
||||
m_uTimeLastMs = e->time_msec;
|
||||
|
||||
if (e->state == WLR_BUTTON_PRESSED) {
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, true, 0);
|
||||
|
||||
@@ -211,9 +266,6 @@ int repeatKeyHandler(void* data) {
|
||||
bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string& key, const xkb_keysym_t& keysym, const int& keycode, bool pressed, uint32_t time) {
|
||||
bool found = false;
|
||||
|
||||
if (handleInternalKeybinds(keysym))
|
||||
return true;
|
||||
|
||||
if (g_pCompositor->m_sSeat.exclusiveClient)
|
||||
Debug::log(LOG, "Keybind handling only locked (inhibitor)");
|
||||
|
||||
@@ -224,7 +276,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
||||
}
|
||||
|
||||
for (auto& k : m_lKeybinds) {
|
||||
if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || (!pressed && !k.release) || k.shadowed)
|
||||
if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || (!pressed && !k.release && k.handler != "pass") || k.shadowed)
|
||||
continue;
|
||||
|
||||
if (!key.empty()) {
|
||||
@@ -261,8 +313,13 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
||||
} else {
|
||||
// call the dispatcher
|
||||
Debug::log(LOG, "Keybind triggered, calling dispatcher (%d, %s, %d)", modmask, key.c_str(), keysym);
|
||||
|
||||
m_iPassPressed = (int)pressed;
|
||||
|
||||
DISPATCHER->second(k.arg);
|
||||
|
||||
m_iPassPressed = -1;
|
||||
|
||||
if (k.handler == "submap") {
|
||||
found = true; // don't process keybinds on submap change.
|
||||
break;
|
||||
@@ -423,19 +480,28 @@ void CKeybindManager::clearKeybinds() {
|
||||
}
|
||||
|
||||
void CKeybindManager::toggleActiveFloating(std::string args) {
|
||||
const auto ACTIVEWINDOW = g_pCompositor->m_pLastWindow;
|
||||
CWindow* PWINDOW = nullptr;
|
||||
|
||||
if (g_pCompositor->windowValidMapped(ACTIVEWINDOW)) {
|
||||
if (args != "" && args != "active" && args.length() > 1) {
|
||||
PWINDOW = g_pCompositor->getWindowByRegex(args);
|
||||
} else {
|
||||
PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
}
|
||||
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
if (g_pCompositor->windowValidMapped(PWINDOW)) {
|
||||
// remove drag status
|
||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||
|
||||
ACTIVEWINDOW->m_bIsFloating = !ACTIVEWINDOW->m_bIsFloating;
|
||||
PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating;
|
||||
|
||||
if (ACTIVEWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) {
|
||||
moveActiveToWorkspace(std::to_string(g_pCompositor->getMonitorFromID(ACTIVEWINDOW->m_iMonitorID)->activeWorkspace));
|
||||
if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PWINDOW == g_pCompositor->m_pLastWindow) {
|
||||
moveActiveToWorkspace(std::to_string(g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeWorkspace));
|
||||
}
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(ACTIVEWINDOW);
|
||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,11 +520,38 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
int workspaceToChangeTo = 0;
|
||||
std::string workspaceName = "";
|
||||
|
||||
// Flag needed so that the previous workspace is not recorded when switching
|
||||
// to a previous workspace.
|
||||
bool isSwitchingToPrevious = false;
|
||||
|
||||
bool internal = false;
|
||||
|
||||
if (args.find("[internal]") == 0) {
|
||||
workspaceToChangeTo = std::stoi(args.substr(10));
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToChangeTo);
|
||||
if (PWORKSPACE)
|
||||
workspaceName = PWORKSPACE->m_szName;
|
||||
|
||||
internal = true;
|
||||
} else if (args.find("previous") == 0) {
|
||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(
|
||||
g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
|
||||
// Do nothing if there's no previous workspace, otherwise switch to it.
|
||||
if (PCURRENTWORKSPACE->m_iPrevWorkspaceID == -1) {
|
||||
Debug::log(LOG, "No previous workspace to change to");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID;
|
||||
isSwitchingToPrevious = true;
|
||||
|
||||
// If the previous workspace ID isn't reset, cycles can form when continually going
|
||||
// to the previous workspace again and again.
|
||||
static auto *const PALLOWWORKSPACECYCLES = &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue;
|
||||
if (!*PALLOWWORKSPACECYCLES)
|
||||
PCURRENTWORKSPACE->m_iPrevWorkspaceID = -1;
|
||||
}
|
||||
} else {
|
||||
workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName);
|
||||
}
|
||||
@@ -468,15 +561,43 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Workspace_back_and_forth being enabled means that an attempt to switch to
|
||||
// the current workspace will instead switch to the previous.
|
||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(
|
||||
g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
static auto *const PBACKANDFORTH = &g_pConfigManager->getConfigValuePtr("binds:workspace_back_and_forth")->intValue;
|
||||
if (*PBACKANDFORTH
|
||||
&& PCURRENTWORKSPACE->m_iID == workspaceToChangeTo
|
||||
&& PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1
|
||||
&& !internal) {
|
||||
|
||||
workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID;
|
||||
isSwitchingToPrevious = true;
|
||||
|
||||
// If the previous workspace ID isn't reset, cycles can form when continually going
|
||||
// to the previous workspace again and again.
|
||||
static auto *const PALLOWWORKSPACECYCLES = &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue;
|
||||
if (!*PALLOWWORKSPACECYCLES)
|
||||
PCURRENTWORKSPACE->m_iPrevWorkspaceID = -1;
|
||||
}
|
||||
|
||||
// remove constraints
|
||||
g_pInputManager->unconstrainMouse();
|
||||
|
||||
// if it's not internal, we will unfocus to prevent stuck focus
|
||||
if (!internal)
|
||||
g_pCompositor->focusWindow(nullptr);
|
||||
|
||||
// if it exists, we warp to it
|
||||
if (g_pCompositor->getWorkspaceByID(workspaceToChangeTo)) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(g_pCompositor->getWorkspaceByID(workspaceToChangeTo)->m_iMonitorID);
|
||||
|
||||
const auto PWORKSPACETOCHANGETO = g_pCompositor->getWorkspaceByID(workspaceToChangeTo);
|
||||
|
||||
if (!isSwitchingToPrevious && !internal)
|
||||
// Remember previous workspace.
|
||||
PWORKSPACETOCHANGETO->m_iPrevWorkspaceID = g_pCompositor->m_pLastMonitor->activeWorkspace;
|
||||
|
||||
if (workspaceToChangeTo == SPECIAL_WORKSPACE_ID)
|
||||
PWORKSPACETOCHANGETO->m_iMonitorID = PMONITOR->ID;
|
||||
|
||||
@@ -541,6 +662,10 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(PMONITOR->ID, workspaceName, workspaceToChangeTo == SPECIAL_WORKSPACE_ID)).get();
|
||||
|
||||
if (!isSwitchingToPrevious)
|
||||
// Remember previous workspace.
|
||||
PWORKSPACE->m_iPrevWorkspaceID = OLDWORKSPACE;
|
||||
|
||||
// start anim on new workspace
|
||||
PWORKSPACE->startAnim(true, ANIMTOLEFT);
|
||||
|
||||
@@ -629,7 +754,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
|
||||
OLDWORKSPACE->m_bHasFullscreenWindow = false;
|
||||
|
||||
PWINDOW->m_iWorkspaceID = PWORKSPACE->m_iID;
|
||||
PWINDOW->moveToWorkspace(PWORKSPACE->m_iID);
|
||||
PWINDOW->m_iMonitorID = PWORKSPACE->m_iMonitorID;
|
||||
PWINDOW->m_bIsFullscreen = false;
|
||||
|
||||
@@ -884,45 +1009,12 @@ void CKeybindManager::alterSplitRatio(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::focusMonitor(std::string arg) {
|
||||
if (isNumber(arg)) {
|
||||
// change by ID
|
||||
int monID = -1;
|
||||
try {
|
||||
monID = std::stoi(arg);
|
||||
} catch (std::exception& e) {
|
||||
// shouldn't happen but jic
|
||||
Debug::log(ERR, "Error in focusMonitor: invalid num");
|
||||
}
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromString(arg);
|
||||
|
||||
if (monID > -1 && monID < (int)g_pCompositor->m_vMonitors.size()) {
|
||||
changeworkspace("[internal]" + std::to_string(g_pCompositor->getMonitorFromID(monID)->activeWorkspace));
|
||||
} else {
|
||||
Debug::log(ERR, "Error in focusMonitor: invalid arg 1");
|
||||
}
|
||||
} else {
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
|
||||
if (isDirection(arg)) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorInDirection(arg[0]);
|
||||
if (PMONITOR) {
|
||||
if (PMONITOR->activeWorkspace < 0) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
changeworkspace("name:" + PWORKSPACE->m_szName);
|
||||
}
|
||||
else
|
||||
changeworkspace(std::to_string(PMONITOR->activeWorkspace));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->szName == arg) {
|
||||
changeworkspace("[internal]" + std::to_string(m->activeWorkspace));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Debug::log(ERR, "Error in focusMonitor: no such monitor");
|
||||
}
|
||||
changeworkspace("[internal]" + std::to_string(PMONITOR->activeWorkspace));
|
||||
}
|
||||
|
||||
void CKeybindManager::moveCursorToCorner(std::string arg) {
|
||||
@@ -1297,16 +1389,62 @@ void CKeybindManager::pass(std::string regexp) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto XWTOXW = PWINDOW->m_bIsX11 && g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_bIsX11;
|
||||
const auto SL = Vector2D(g_pCompositor->m_sSeat.seat->pointer_state.sx, g_pCompositor->m_sSeat.seat->pointer_state.sy);
|
||||
|
||||
// pass all mf shit
|
||||
wlr_seat_keyboard_notify_enter(g_pCompositor->m_sSeat.seat, g_pXWaylandManager->getWindowSurface(PWINDOW), KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers);
|
||||
if (!XWTOXW) {
|
||||
if (g_pKeybindManager->m_uLastCode != 0)
|
||||
wlr_seat_keyboard_enter(g_pCompositor->m_sSeat.seat, g_pXWaylandManager->getWindowSurface(PWINDOW), KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers);
|
||||
else
|
||||
wlr_seat_pointer_enter(g_pCompositor->m_sSeat.seat, g_pXWaylandManager->getWindowSurface(PWINDOW), 1, 1);
|
||||
}
|
||||
|
||||
|
||||
wlr_keyboard_modifiers kbmods = {g_pInputManager->accumulateModsFromAllKBs(), 0, 0, 0};
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &kbmods);
|
||||
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_PRESSED);
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_RELEASED);
|
||||
if (g_pKeybindManager->m_iPassPressed == 1) {
|
||||
if (g_pKeybindManager->m_uLastCode != 0)
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_PRESSED);
|
||||
else
|
||||
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WLR_BUTTON_PRESSED);
|
||||
} else if (g_pKeybindManager->m_iPassPressed == 0)
|
||||
if (g_pKeybindManager->m_uLastCode != 0)
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_RELEASED);
|
||||
else
|
||||
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WLR_BUTTON_RELEASED);
|
||||
else {
|
||||
// dynamic call of the dispatcher
|
||||
if (g_pKeybindManager->m_uLastCode != 0) {
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_PRESSED);
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_RELEASED);
|
||||
} else {
|
||||
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WLR_BUTTON_PRESSED);
|
||||
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WLR_BUTTON_RELEASED);
|
||||
}
|
||||
}
|
||||
|
||||
wlr_seat_keyboard_notify_enter(g_pCompositor->m_sSeat.seat, PLASTSRF, KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers);
|
||||
if (XWTOXW)
|
||||
return;
|
||||
|
||||
// Massive hack:
|
||||
// this will make wlroots NOT send the leave event to XWayland apps, provided we are not on an XWayland window already.
|
||||
// please kill me
|
||||
if (PWINDOW->m_bIsX11) {
|
||||
if (g_pKeybindManager->m_uLastCode != 0) {
|
||||
g_pCompositor->m_sSeat.seat->keyboard_state.focused_client = nullptr;
|
||||
g_pCompositor->m_sSeat.seat->keyboard_state.focused_surface = nullptr;
|
||||
} else {
|
||||
g_pCompositor->m_sSeat.seat->pointer_state.focused_client = nullptr;
|
||||
g_pCompositor->m_sSeat.seat->pointer_state.focused_surface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_pKeybindManager->m_uLastCode != 0)
|
||||
wlr_seat_keyboard_enter(g_pCompositor->m_sSeat.seat, PLASTSRF, KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers);
|
||||
else
|
||||
wlr_seat_pointer_enter(g_pCompositor->m_sSeat.seat, g_pXWaylandManager->getWindowSurface(PWINDOW), SL.x, SL.y);
|
||||
}
|
||||
|
||||
void CKeybindManager::layoutmsg(std::string msg) {
|
||||
@@ -1341,3 +1479,47 @@ void CKeybindManager::dpms(std::string arg) {
|
||||
|
||||
g_pCompositor->m_bDPMSStateON = enable;
|
||||
}
|
||||
|
||||
void CKeybindManager::swapnext(std::string arg) {
|
||||
|
||||
CWindow* toSwap = nullptr;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||
return;
|
||||
|
||||
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
const auto PLASTCYCLED = g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow->m_pLastCycledWindow) && g_pCompositor->m_pLastWindow->m_pLastCycledWindow->m_iWorkspaceID == PLASTWINDOW->m_iWorkspaceID ? g_pCompositor->m_pLastWindow->m_pLastCycledWindow : nullptr;
|
||||
|
||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW);
|
||||
else
|
||||
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW);
|
||||
|
||||
// sometimes we may come back to ourselves.
|
||||
if (toSwap == PLASTWINDOW) {
|
||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW);
|
||||
else
|
||||
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW);
|
||||
}
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, toSwap);
|
||||
|
||||
PLASTWINDOW->m_pLastCycledWindow = toSwap;
|
||||
|
||||
g_pCompositor->focusWindow(PLASTWINDOW);
|
||||
}
|
||||
|
||||
void CKeybindManager::swapActiveWorkspaces(std::string args) {
|
||||
const auto MON1 = args.substr(0, args.find_first_of(' '));
|
||||
const auto MON2 = args.substr(args.find_first_of(' ') + 1);
|
||||
|
||||
const auto PMON1 = g_pCompositor->getMonitorFromString(MON1);
|
||||
const auto PMON2 = g_pCompositor->getMonitorFromString(MON2);
|
||||
|
||||
if (!PMON1 || !PMON2)
|
||||
return;
|
||||
|
||||
g_pCompositor->swapActiveWorkspaces(PMON1, PMON2);
|
||||
}
|
||||
|
@@ -61,6 +61,9 @@ private:
|
||||
|
||||
uint32_t m_uTimeLastMs = 0;
|
||||
uint32_t m_uLastCode = 0;
|
||||
uint32_t m_uLastMouseCode = 0;
|
||||
|
||||
int m_iPassPressed = -1; // used for pass
|
||||
|
||||
CTimer m_tScrollTimer;
|
||||
|
||||
@@ -69,6 +72,10 @@ private:
|
||||
bool handleInternalKeybinds(xkb_keysym_t);
|
||||
bool handleVT(xkb_keysym_t);
|
||||
|
||||
xkb_state* m_pXKBTranslationState = nullptr;
|
||||
|
||||
void updateXKBTranslationState();
|
||||
|
||||
// -------------- Dispatchers -------------- //
|
||||
static void killActive(std::string);
|
||||
static void spawn(std::string);
|
||||
@@ -103,6 +110,8 @@ private:
|
||||
static void layoutmsg(std::string);
|
||||
static void toggleOpaque(std::string);
|
||||
static void dpms(std::string);
|
||||
static void swapnext(std::string);
|
||||
static void swapActiveWorkspaces(std::string);
|
||||
|
||||
friend class CCompositor;
|
||||
friend class CInputManager;
|
||||
|
@@ -32,9 +32,12 @@ wlr_surface* CHyprXWaylandManager::getWindowSurface(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate) {
|
||||
if (wlr_surface_is_xdg_surface(pSurface))
|
||||
wlr_xdg_toplevel_set_activated(wlr_xdg_surface_from_wlr_surface(pSurface)->toplevel, activate);
|
||||
else if (wlr_surface_is_xwayland_surface(pSurface)) {
|
||||
if (wlr_surface_is_xdg_surface(pSurface)) {
|
||||
const auto PSURF = wlr_xdg_surface_from_wlr_surface(pSurface);
|
||||
if (PSURF->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
||||
wlr_xdg_toplevel_set_activated(PSURF->toplevel, activate);
|
||||
}
|
||||
} else if (wlr_surface_is_xwayland_surface(pSurface)) {
|
||||
wlr_xwayland_surface_activate(wlr_xwayland_surface_from_wlr_surface(pSurface), activate);
|
||||
|
||||
if (activate)
|
||||
|
@@ -32,6 +32,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
static auto *const PMOUSEDPMS = &g_pConfigManager->getConfigValuePtr("misc:mouse_move_enables_dpms")->intValue;
|
||||
static auto *const PFOLLOWONDND = &g_pConfigManager->getConfigValuePtr("misc:always_follow_on_dnd")->intValue;
|
||||
static auto *const PHOGFOCUS = &g_pConfigManager->getConfigValuePtr("misc:layers_hog_keyboard_focus")->intValue;
|
||||
static auto *const PFLOATBEHAVIOR = &g_pConfigManager->getConfigValuePtr("input:float_switch_override_focus")->intValue;
|
||||
|
||||
if (!g_pCompositor->m_bReadyToProcess)
|
||||
return;
|
||||
@@ -182,9 +183,15 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
if (!(pFoundWindow && pFoundWindow->m_bIsFloating && pFoundWindow->m_bCreatedOverFullscreen))
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
|
||||
|
||||
// TODO: this causes crashes, sometimes. ???
|
||||
// if (refocus && !pFoundWindow) {
|
||||
// pFoundWindow = g_pCompositor->getFirstWindowOnWorkspace(PMONITOR->activeWorkspace);
|
||||
// }
|
||||
}
|
||||
|
||||
if (pFoundWindow) {
|
||||
if (!pFoundWindow->m_bIsX11) {
|
||||
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
|
||||
@@ -202,11 +209,18 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
if (!foundSurface)
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_pLastMonitor);
|
||||
|
||||
if (!foundSurface) {
|
||||
if (m_ecbClickBehavior == CLICKMODE_KILL)
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "crosshair", g_pCompositor->m_sWLRCursor);
|
||||
else
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", g_pCompositor->m_sWLRCursor);
|
||||
if (!m_bEmptyFocusCursorSet) {
|
||||
// TODO: maybe wrap?
|
||||
if (m_ecbClickBehavior == CLICKMODE_KILL)
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "crosshair", g_pCompositor->m_sWLRCursor);
|
||||
else
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", g_pCompositor->m_sWLRCursor);
|
||||
|
||||
m_bEmptyFocusCursorSet = true;
|
||||
}
|
||||
|
||||
wlr_seat_pointer_clear_focus(g_pCompositor->m_sSeat.seat);
|
||||
|
||||
@@ -217,6 +231,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_bEmptyFocusCursorSet = false;
|
||||
|
||||
if (time)
|
||||
wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat);
|
||||
|
||||
@@ -242,7 +258,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
if (pFoundWindow) {
|
||||
if (*PFOLLOWMOUSE != 1 && !refocus) {
|
||||
if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && (g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating)) {
|
||||
if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating && *PFLOATBEHAVIOR) {
|
||||
// enter if change floating style
|
||||
if (*PFOLLOWMOUSE != 3 && allowKeyboardRefocus)
|
||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||
@@ -263,12 +279,14 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
|
||||
return; // don't enter any new surfaces
|
||||
} else {
|
||||
if (*PFOLLOWMOUSE != 3 && allowKeyboardRefocus)
|
||||
if ((*PFOLLOWMOUSE != 3 && allowKeyboardRefocus) || refocus)
|
||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||
}
|
||||
} else {
|
||||
if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive && *PFOLLOWMOUSE != 3 && allowKeyboardRefocus)
|
||||
if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive && *PFOLLOWMOUSE != 3 && allowKeyboardRefocus) {
|
||||
g_pCompositor->focusSurface(foundSurface);
|
||||
g_pCompositor->m_pLastWindow = nullptr; // reset last window as we have a full focus on a LS
|
||||
}
|
||||
}
|
||||
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
@@ -441,10 +459,19 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
||||
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "Keyboard");
|
||||
|
||||
if (m_pActiveKeyboard)
|
||||
m_pActiveKeyboard->active = false;
|
||||
PNEWKEYBOARD->hyprListener_keyboardKeymap.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.keymap, [&](void* owner, void* data) {
|
||||
const auto PKEYBOARD = (SKeyboard*)owner;
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," +getActiveLayoutForKeyboard(PKEYBOARD)}, true); // force as this should ALWAYS be sent
|
||||
|
||||
}, PNEWKEYBOARD, "Keyboard");
|
||||
|
||||
disableAllKeyboards(false);
|
||||
|
||||
m_pActiveKeyboard = PNEWKEYBOARD;
|
||||
|
||||
PNEWKEYBOARD->active = true;
|
||||
|
||||
applyConfigToKeyboard(PNEWKEYBOARD);
|
||||
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(keyboard));
|
||||
@@ -467,11 +494,19 @@ void CInputManager::newVirtualKeyboard(wlr_input_device* keyboard) {
|
||||
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardKeymap.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.keymap, [&](void* owner, void* data) {
|
||||
const auto PKEYBOARD = (SKeyboard*)owner;
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," +getActiveLayoutForKeyboard(PKEYBOARD)}, true); // force as this should ALWAYS be sent
|
||||
|
||||
}, PNEWKEYBOARD, "Keyboard");
|
||||
|
||||
disableAllKeyboards(true);
|
||||
|
||||
if (m_pActiveKeyboard)
|
||||
m_pActiveKeyboard->active = false;
|
||||
m_pActiveKeyboard = PNEWKEYBOARD;
|
||||
|
||||
PNEWKEYBOARD->active = true;
|
||||
|
||||
applyConfigToKeyboard(PNEWKEYBOARD);
|
||||
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(keyboard));
|
||||
@@ -482,6 +517,8 @@ void CInputManager::newVirtualKeyboard(wlr_input_device* keyboard) {
|
||||
void CInputManager::setKeyboardLayout() {
|
||||
for (auto& k : m_lKeyboards)
|
||||
applyConfigToKeyboard(&k);
|
||||
|
||||
g_pKeybindManager->updateXKBTranslationState();
|
||||
}
|
||||
|
||||
void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
@@ -502,6 +539,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
|
||||
const auto NUMLOCKON = HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "numlock_by_default") : g_pConfigManager->getInt("input:numlock_by_default");
|
||||
|
||||
const auto FILEPATH = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "kb_file") : g_pConfigManager->getString("input:kb_file");
|
||||
const auto RULES = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "kb_rules") : g_pConfigManager->getString("input:kb_rules");
|
||||
const auto MODEL = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "kb_model") : g_pConfigManager->getString("input:kb_model");
|
||||
const auto LAYOUT = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "kb_layout") : g_pConfigManager->getString("input:kb_layout");
|
||||
@@ -509,7 +547,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
const auto OPTIONS = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "kb_options") : g_pConfigManager->getString("input:kb_options");
|
||||
|
||||
try {
|
||||
if (NUMLOCKON == pKeyboard->numlockOn && REPEATDELAY == pKeyboard->repeatDelay && REPEATRATE == pKeyboard->repeatRate && RULES != "" && RULES == pKeyboard->currentRules.rules && MODEL == pKeyboard->currentRules.model && LAYOUT == pKeyboard->currentRules.layout && VARIANT == pKeyboard->currentRules.variant && OPTIONS == pKeyboard->currentRules.options) {
|
||||
if (NUMLOCKON == pKeyboard->numlockOn && REPEATDELAY == pKeyboard->repeatDelay && REPEATRATE == pKeyboard->repeatRate && RULES != "" && RULES == pKeyboard->currentRules.rules && MODEL == pKeyboard->currentRules.model && LAYOUT == pKeyboard->currentRules.layout && VARIANT == pKeyboard->currentRules.variant && OPTIONS == pKeyboard->currentRules.options && FILEPATH == pKeyboard->xkbFilePath) {
|
||||
Debug::log(LOG, "Not applying config to keyboard, it did not change.");
|
||||
return;
|
||||
}
|
||||
@@ -523,6 +561,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
pKeyboard->repeatDelay = REPEATDELAY;
|
||||
pKeyboard->repeatRate = REPEATRATE;
|
||||
pKeyboard->numlockOn = NUMLOCKON;
|
||||
pKeyboard->xkbFilePath = FILEPATH.c_str();
|
||||
|
||||
xkb_rule_names rules = {
|
||||
.rules = RULES.c_str(),
|
||||
@@ -546,7 +585,21 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
|
||||
Debug::log(LOG, "Attempting to create a keymap for layout %s with variant %s (rules: %s, model: %s, options: %s)", rules.layout, rules.variant, rules.rules, rules.model, rules.options);
|
||||
|
||||
auto KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_keymap * KEYMAP = NULL;
|
||||
|
||||
if (!FILEPATH.empty()) {
|
||||
auto path = absolutePath(FILEPATH, g_pConfigManager->configCurrentPath);
|
||||
|
||||
if (!std::filesystem::exists(path)) {
|
||||
Debug::log(ERR, "input:kb_file= file doesnt exist");
|
||||
} else {
|
||||
KEYMAP = xkb_keymap_new_from_file(CONTEXT, fopen(path.c_str(), "r"), XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
}
|
||||
|
||||
if (!KEYMAP) {
|
||||
KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
|
||||
if (!KEYMAP) {
|
||||
g_pConfigManager->addParseError("Invalid keyboard layout passed. ( rules: " + RULES + ", model: " + MODEL + ", variant: " + VARIANT + ", options: " + OPTIONS + ", layout: " + LAYOUT + " )");
|
||||
@@ -582,6 +635,8 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
xkb_keymap_unref(KEYMAP);
|
||||
xkb_context_unref(CONTEXT);
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," +getActiveLayoutForKeyboard(pKeyboard)}, true); // force as this should ALWAYS be sent
|
||||
|
||||
Debug::log(LOG, "Set the keyboard layout to %s and variant to %s for keyboard \"%s\"", rules.layout, rules.variant, pKeyboard->keyboard->name);
|
||||
}
|
||||
|
||||
@@ -735,6 +790,14 @@ void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &wlr_keyboard_from_input_device(pKeyboard->keyboard)->modifiers);
|
||||
}
|
||||
|
||||
const auto PWLRKB = wlr_keyboard_from_input_device(pKeyboard->keyboard);
|
||||
|
||||
if (PWLRKB->modifiers.group != pKeyboard->activeLayout) {
|
||||
pKeyboard->activeLayout = PWLRKB->modifiers.group;
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + getActiveLayoutForKeyboard(pKeyboard)}, true); // force as this should ALWAYS be sent
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::refocus() {
|
||||
@@ -906,3 +969,13 @@ std::string CInputManager::getActiveLayoutForKeyboard(SKeyboard* pKeyboard) {
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
void CInputManager::disableAllKeyboards(bool virt) {
|
||||
|
||||
for (auto& k : m_lKeyboards) {
|
||||
if (k.isVirtual != virt)
|
||||
continue;
|
||||
|
||||
k.active = false;
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ enum eClickBehaviorMode {
|
||||
|
||||
struct STouchData {
|
||||
CWindow* touchFocusWindow = nullptr;
|
||||
Vector2D touchSurfaceOrigin;
|
||||
};
|
||||
|
||||
class CInputManager {
|
||||
@@ -101,11 +102,14 @@ private:
|
||||
|
||||
// for click behavior override
|
||||
eClickBehaviorMode m_ecbClickBehavior = CLICKMODE_DEFAULT;
|
||||
bool m_bEmptyFocusCursorSet = false;
|
||||
Vector2D m_vLastCursorPosFloored = Vector2D();
|
||||
|
||||
void processMouseDownNormal(wlr_pointer_button_event* e);
|
||||
void processMouseDownKill(wlr_pointer_button_event* e);
|
||||
|
||||
void disableAllKeyboards(bool virt = false);
|
||||
|
||||
uint32_t m_uiCapabilities = 0;
|
||||
|
||||
void mouseMoveUnified(uint32_t, bool refocus = false);
|
||||
|
@@ -125,6 +125,9 @@ void CInputMethodRelay::updateInputPopup(SIMEPopup* pPopup) {
|
||||
if (!pPopup->pSurface->mapped)
|
||||
return;
|
||||
|
||||
// damage last known pos & size
|
||||
g_pHyprRenderer->damageBox(pPopup->realX, pPopup->realY, pPopup->lastSize.x, pPopup->lastSize.y);
|
||||
|
||||
const auto PFOCUSEDTI = getFocusedTextInput();
|
||||
|
||||
if (!PFOCUSEDTI || !PFOCUSEDTI->pWlrInput->focused_surface)
|
||||
@@ -167,6 +170,8 @@ void CInputMethodRelay::updateInputPopup(SIMEPopup* pPopup) {
|
||||
pPopup->realX = finalBox.x + parentPos.x;
|
||||
pPopup->realY = finalBox.y + parentPos.y + finalBox.height;
|
||||
|
||||
pPopup->lastSize = Vector2D(pPopup->pSurface->surface->current.width, pPopup->pSurface->surface->current.height);
|
||||
|
||||
wlr_input_popup_surface_v2_send_text_input_rectangle(pPopup->pSurface, &finalBox);
|
||||
|
||||
damagePopup(pPopup);
|
||||
@@ -189,6 +194,8 @@ void Events::listener_unmapInputPopup(void* owner, void* data) {
|
||||
|
||||
Debug::log(LOG, "Unmapped an IME Popup");
|
||||
|
||||
g_pHyprRenderer->damageBox(PPOPUP->realX, PPOPUP->realY, PPOPUP->lastSize.x, PPOPUP->lastSize.y);
|
||||
|
||||
g_pInputManager->m_sIMERelay.updateInputPopup(PPOPUP);
|
||||
}
|
||||
|
||||
@@ -259,9 +266,6 @@ SIMEKbGrab* CInputMethodRelay::getIMEKeyboardGrab(SKeyboard* pKeyboard) {
|
||||
if (VIRTKB && (wl_resource_get_client(VIRTKB->resource) == wl_resource_get_client(m_pKeyboardGrab->pWlrKbGrab->resource)))
|
||||
return nullptr;
|
||||
|
||||
if (wlr_keyboard_from_input_device(pKeyboard->keyboard) != m_pKeyboardGrab->pKeyboard)
|
||||
return nullptr;
|
||||
|
||||
return m_pKeyboardGrab.get();
|
||||
}
|
||||
|
||||
|
@@ -6,7 +6,7 @@ void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
||||
static auto *const PSWIPE = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe")->intValue;
|
||||
static auto *const PSWIPEFINGERS = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_fingers")->intValue;
|
||||
|
||||
if (e->fingers != *PSWIPEFINGERS|| *PSWIPE == 0)
|
||||
if (e->fingers != *PSWIPEFINGERS || *PSWIPE == 0)
|
||||
return;
|
||||
|
||||
int onMonitor = 0;
|
||||
@@ -143,11 +143,13 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
PWORKSPACE->m_bForceRendering = true;
|
||||
PWORKSPACE->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
if (workspaceIDLeft != workspaceIDRight) {
|
||||
const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
|
||||
PWORKSPACER->m_bForceRendering = false;
|
||||
PWORKSPACER->m_fAlpha.setValueAndWarp(0.f);
|
||||
}
|
||||
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x - m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
@@ -163,11 +165,13 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
|
||||
PWORKSPACE->m_bForceRendering = true;
|
||||
PWORKSPACE->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
if (workspaceIDLeft != workspaceIDRight) {
|
||||
const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
PWORKSPACEL->m_bForceRendering = false;
|
||||
PWORKSPACEL->m_fAlpha.setValueAndWarp(0.f);
|
||||
}
|
||||
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x + m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
|
@@ -10,9 +10,16 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) {
|
||||
m_sTouchData.touchFocusWindow = nullptr;
|
||||
|
||||
if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow)) {
|
||||
wlr_seat_touch_notify_down(g_pCompositor->m_sSeat.seat, g_pCompositor->m_pLastFocus, e->time_msec, e->touch_id,
|
||||
e->x * g_pCompositor->m_pLastMonitor->vecSize.x + g_pCompositor->m_pLastMonitor->vecPosition.x - g_pCompositor->m_pLastWindow->m_vRealPosition.vec().x,
|
||||
e->y * g_pCompositor->m_pLastMonitor->vecSize.y + g_pCompositor->m_pLastMonitor->vecPosition.y - g_pCompositor->m_pLastWindow->m_vRealPosition.vec().y);
|
||||
Vector2D local;
|
||||
if (g_pCompositor->m_pLastWindow->m_bIsX11) {
|
||||
local = g_pInputManager->getMouseCoordsInternal() - g_pCompositor->m_pLastWindow->m_vRealPosition.goalv();
|
||||
} else {
|
||||
g_pCompositor->vectorWindowToSurface(g_pInputManager->getMouseCoordsInternal(), g_pCompositor->m_pLastWindow, local);
|
||||
}
|
||||
|
||||
m_sTouchData.touchSurfaceOrigin = g_pInputManager->getMouseCoordsInternal() - local;
|
||||
|
||||
wlr_seat_touch_notify_down(g_pCompositor->m_sSeat.seat, g_pCompositor->m_pLastFocus, e->time_msec, e->touch_id, local.x, local.y);
|
||||
|
||||
m_sTouchData.touchFocusWindow = g_pCompositor->m_pLastWindow;
|
||||
}
|
||||
@@ -29,10 +36,10 @@ void CInputManager::onTouchMove(wlr_touch_motion_event* e){
|
||||
if (g_pCompositor->windowValidMapped(m_sTouchData.touchFocusWindow)) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusWindow->m_iMonitorID);
|
||||
|
||||
wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id,
|
||||
e->x * PMONITOR->vecSize.x + PMONITOR->vecPosition.x - m_sTouchData.touchFocusWindow->m_vRealPosition.vec().x,
|
||||
e->y * PMONITOR->vecSize.y + PMONITOR->vecPosition.y - m_sTouchData.touchFocusWindow->m_vRealPosition.vec().y);
|
||||
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PMONITOR->vecPosition.x + e->x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e->y * PMONITOR->vecSize.y);
|
||||
|
||||
const auto local = g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchSurfaceOrigin;
|
||||
|
||||
wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id, local.x, local.y);
|
||||
}
|
||||
}
|
@@ -629,7 +629,7 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() {
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::preWindowPass() {
|
||||
static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
|
||||
static auto *const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
|
||||
|
||||
if (!m_RenderData.pCurrentMonData->blurFBDirty || !*PBLURNEWOPTIMIZE)
|
||||
return;
|
||||
@@ -654,7 +654,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
|
||||
static auto *const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
|
||||
static auto *const PNOBLUROVERSIZED = &g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized")->intValue;
|
||||
static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
|
||||
static auto *const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
|
||||
|
||||
if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) || (m_pCurrentWindow && m_pCurrentWindow->m_sAdditionalConfigData.forceNoBlur)) {
|
||||
renderTexture(tex, pBox, a, round, false, true);
|
||||
@@ -685,7 +685,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
}
|
||||
|
||||
// vvv TODO: layered blur fbs?
|
||||
const bool USENEWOPTIMIZE = (*PBLURNEWOPTIMIZE && m_pCurrentWindow && !m_pCurrentWindow->m_bIsFloating && m_RenderData.pCurrentMonData->blurFB.m_cTex.m_iTexID);
|
||||
const bool USENEWOPTIMIZE = (*PBLURNEWOPTIMIZE && m_pCurrentWindow && !m_pCurrentWindow->m_bIsFloating && m_RenderData.pCurrentMonData->blurFB.m_cTex.m_iTexID && m_pCurrentWindow->m_iWorkspaceID != SPECIAL_WORKSPACE_ID);
|
||||
|
||||
const auto POUTFB = USENEWOPTIMIZE ? &m_RenderData.pCurrentMonData->blurFB : blurMainFramebufferWithDamage(a, pBox, &inverseOpaque);
|
||||
|
||||
@@ -896,7 +896,7 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
|
||||
// this is temporary, doesnt mess with the actual wlr damage
|
||||
pixman_region32_t fakeDamage;
|
||||
pixman_region32_init(&fakeDamage);
|
||||
pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecPixelSize.x, (int)PMONITOR->vecPixelSize.y);
|
||||
pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||
|
||||
begin(PMONITOR, &fakeDamage, true);
|
||||
|
||||
@@ -916,8 +916,6 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
|
||||
// draw the layer
|
||||
g_pHyprRenderer->renderLayer(pLayer, PMONITOR, &now);
|
||||
|
||||
m_bEndFrame = false;
|
||||
|
||||
// TODO: WARN:
|
||||
// revise if any stencil-requiring rendering is done to the layers.
|
||||
|
||||
@@ -992,12 +990,16 @@ void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PLAYER->monitorID);
|
||||
|
||||
wlr_box windowBox = {0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
|
||||
wlr_box monbox = {0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
|
||||
|
||||
pixman_region32_t fakeDamage;
|
||||
pixman_region32_init_rect(&fakeDamage, 0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y);
|
||||
|
||||
renderTextureInternalWithDamage(it->second.m_cTex, &windowBox, PLAYER->alpha.fl(), &fakeDamage, 0);
|
||||
m_bEndFrame = true;
|
||||
|
||||
renderTextureInternalWithDamage(it->second.m_cTex, &monbox, PLAYER->alpha.fl(), &fakeDamage, 0);
|
||||
|
||||
m_bEndFrame = false;
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
|
||||
|
@@ -17,17 +17,15 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
else // here we clamp to 2, these might be some tiny specks
|
||||
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::clamp(surface->current.width, 2, 1337420), std::clamp(surface->current.height, 2, 1337420)};
|
||||
|
||||
// squish all oversized but dont in some cases, jesus christ this is a mess
|
||||
// TODO: this shouldn't be done this way. Custom UV here as well.
|
||||
// this is fucking horrible
|
||||
// Issue: will cause oversized apps with reserved area to overflow from the window box. (see chromium on ozone wayland)
|
||||
const auto PRESQUISHSIZE = Vector2D(windowBox.width, windowBox.height);
|
||||
if (RDATA->squishOversized) {
|
||||
if (x + windowBox.width > RDATA->w)
|
||||
windowBox.width = RDATA->w - x;
|
||||
if (y + windowBox.height > RDATA->h)
|
||||
windowBox.height = RDATA->h - y;
|
||||
}
|
||||
|
||||
if (RDATA->pWindow)
|
||||
g_pHyprRenderer->calculateUVForWindowSurface(RDATA->pWindow, surface, RDATA->squishOversized);
|
||||
|
||||
scaleBox(&windowBox, RDATA->output->scale);
|
||||
|
||||
@@ -36,6 +34,8 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
|
||||
rounding *= RDATA->output->scale;
|
||||
|
||||
rounding -= 1; // to fix a border issue
|
||||
|
||||
if (RDATA->surface && surface == RDATA->surface) {
|
||||
if (wlr_surface_is_xwayland_surface(surface) && !wlr_xwayland_surface_from_wlr_surface(surface)->has_alpha && RDATA->fadeAlpha * RDATA->alpha == 255.f) {
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
|
||||
@@ -47,26 +47,16 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (RDATA->surface && wlr_surface_is_xdg_surface(RDATA->surface)) {
|
||||
wlr_box geo;
|
||||
wlr_xdg_surface_get_geometry(wlr_xdg_surface_from_wlr_surface(RDATA->surface), &geo);
|
||||
|
||||
// TODO: continuation of the above madness.
|
||||
if (geo.x != 0 || geo.y != 0) {
|
||||
windowBox.width = PRESQUISHSIZE.x;
|
||||
windowBox.height = PRESQUISHSIZE.y;
|
||||
}
|
||||
|
||||
windowBox.x -= geo.x;
|
||||
windowBox.y -= geo.y;
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
|
||||
}
|
||||
|
||||
wlr_surface_send_frame_done(surface, RDATA->when);
|
||||
|
||||
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output);
|
||||
|
||||
// reset the UV, we might've set it above
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
|
||||
bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) {
|
||||
@@ -79,16 +69,22 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID) {
|
||||
if (!(!PWORKSPACE->m_bHasFullscreenWindow || pWindow->m_bIsFullscreen || (pWindow->m_bIsFloating && pWindow->m_bCreatedOverFullscreen)))
|
||||
return false;
|
||||
if (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated()) {
|
||||
return true;
|
||||
} else {
|
||||
if (!(!PWORKSPACE->m_bHasFullscreenWindow || pWindow->m_bIsFullscreen || (pWindow->m_bIsFloating && pWindow->m_bCreatedOverFullscreen)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (pWindow->m_iWorkspaceID == pMonitor->activeWorkspace)
|
||||
return true;
|
||||
|
||||
// if not, check if it maybe is active on a different monitor. vvv might be animation in progress
|
||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_bForceRendering) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
||||
return true;
|
||||
// if not, check if it maybe is active on a different monitor.
|
||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) ||
|
||||
(PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_bForceRendering) || // vvvv might be in animation progress vvvvv
|
||||
(PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
||||
return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors
|
||||
|
||||
if (pMonitor->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
return true;
|
||||
@@ -205,6 +201,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
|
||||
renderdata.blur = true; // if it shouldn't, it will be ignored later
|
||||
renderdata.pWindow = pWindow;
|
||||
|
||||
// apply window special data
|
||||
if (pWindow->m_sSpecialRenderData.alphaInactive == -1)
|
||||
@@ -224,38 +221,6 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||
if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
|
||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
|
||||
|
||||
if (!pWindow->m_bIsX11) {
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||
|
||||
// first, check for poorly sized windows.
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height);
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
|
||||
// No special UV mods needed
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
|
||||
// then, if the surface is too big, modify the pos UV
|
||||
if (geom.width > renderdata.w + 1 || geom.height > renderdata.h + 1) {
|
||||
const auto OFF = Vector2D(renderdata.w / (double)geom.width, renderdata.h / (double)geom.height);
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D(-1, -1))
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(0, 0);
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x * ((double)renderdata.w / ((double)geom.width / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x)),
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y * ((double)renderdata.h / ((double)geom.height / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y))
|
||||
);
|
||||
}
|
||||
} else {
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
|
||||
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
|
||||
|
||||
if (renderdata.decorate && pWindow->m_sSpecialRenderData.border) {
|
||||
@@ -273,14 +238,17 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||
|
||||
g_pHyprOpenGL->renderBorder(&windowBox, col, rounding);
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
|
||||
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_POPUP) {
|
||||
if (!pWindow->m_bIsX11) {
|
||||
renderdata.dontRound = false; // restore dontround
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||
|
||||
renderdata.x -= geom.x;
|
||||
renderdata.y -= geom.y;
|
||||
|
||||
renderdata.dontRound = true; // don't round popups
|
||||
renderdata.pMonitor = pMonitor;
|
||||
renderdata.squishOversized = false; // don't squish popups
|
||||
wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata);
|
||||
@@ -306,6 +274,7 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times
|
||||
wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata);
|
||||
|
||||
renderdata.squishOversized = false; // don't squish popups
|
||||
renderdata.dontRound = true;
|
||||
wlr_layer_surface_v1_for_each_popup_surface(pLayer->layerSurface, renderSurface, &renderdata);
|
||||
}
|
||||
|
||||
@@ -433,6 +402,72 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
renderDragIcon(PMONITOR, time);
|
||||
}
|
||||
|
||||
void CHyprRenderer::calculateUVForWindowSurface(CWindow* pWindow, wlr_surface* pSurface, bool main) {
|
||||
if (!pWindow->m_bIsX11) {
|
||||
Vector2D uvTL;
|
||||
Vector2D uvBR = Vector2D(1, 1);
|
||||
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||
|
||||
const auto SUBSURFACE = g_pXWaylandManager->getWindowSurface(pWindow) != pSurface && main;
|
||||
|
||||
// wp_viewporter_v1 implementation
|
||||
if (pSurface->current.viewport.has_src) {
|
||||
wlr_fbox bufferSource;
|
||||
wlr_surface_get_buffer_source_box(pSurface, &bufferSource);
|
||||
|
||||
Vector2D surfaceSize = Vector2D(pSurface->buffer->texture->width, pSurface->buffer->texture->height);
|
||||
|
||||
uvTL = Vector2D(bufferSource.x / surfaceSize.x, bufferSource.y / surfaceSize.y);
|
||||
uvBR = Vector2D((bufferSource.x + bufferSource.width) / surfaceSize.x, (bufferSource.y + bufferSource.height) / surfaceSize.y);
|
||||
|
||||
if (uvBR.x < 0.01f || uvBR.y < 0.01f) {
|
||||
uvTL = Vector2D();
|
||||
uvBR = Vector2D(1,1);
|
||||
}
|
||||
|
||||
// TODO: (example: chromium) this still has a tiny "bump" at the end.
|
||||
if (main) {
|
||||
uvTL = uvTL + (Vector2D((double)geom.x / ((double)pWindow->m_uSurface.xdg->surface->current.width), (double)geom.y / ((double)pWindow->m_uSurface.xdg->surface->current.height)) * (((uvBR.x - uvTL.x) * surfaceSize.x) / surfaceSize.x));
|
||||
uvBR = uvBR * Vector2D((double)(geom.width + geom.x) / ((double)pWindow->m_uSurface.xdg->surface->current.width), (double)(geom.y + geom.height) / ((double)pWindow->m_uSurface.xdg->surface->current.height));
|
||||
}
|
||||
} else if (main) {
|
||||
// oversized windows' UV adjusting
|
||||
uvTL = Vector2D((double)geom.x / ((double)pWindow->m_uSurface.xdg->surface->current.width), (double)geom.y / ((double)pWindow->m_uSurface.xdg->surface->current.height));
|
||||
uvBR = Vector2D((double)(geom.width + geom.x) / ((double)pWindow->m_uSurface.xdg->surface->current.width), (double)(geom.y + geom.height) / ((double)pWindow->m_uSurface.xdg->surface->current.height));
|
||||
}
|
||||
|
||||
// set UV
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = uvTL;
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = uvBR;
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
|
||||
// No special UV mods needed
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
|
||||
if (!main)
|
||||
return; // ignore the rest
|
||||
|
||||
// then, if the surface is too big, modify the pos UV
|
||||
if ((geom.width > pWindow->m_vRealSize.vec().x + 1 || geom.height > pWindow->m_vRealSize.vec().y + 1) && !SUBSURFACE) {
|
||||
const auto OFF = Vector2D(pWindow->m_vRealSize.vec().x / (double)geom.width, pWindow->m_vRealSize.vec().y / (double)geom.height);
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D(-1, -1))
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(0, 0);
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x * ((double)pWindow->m_vRealSize.vec().x / ((double)geom.width / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x)),
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y * ((double)pWindow->m_vRealSize.vec().y / ((double)geom.height / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y)));
|
||||
}
|
||||
} else {
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprRenderer::outputMgrApplyTest(wlr_output_configuration_v1* config, bool test) {
|
||||
wlr_output_configuration_head_v1* head;
|
||||
bool noError = true;
|
||||
@@ -704,7 +739,7 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) {
|
||||
wlr_region_scale(&damageBoxForEach, &damageBoxForEach, m->scale);
|
||||
pixman_region32_translate(&damageBoxForEach, lx + m->vecPosition.x, ly + m->vecPosition.y);
|
||||
|
||||
wlr_output_damage_add(m->damage, &damageBoxForEach);
|
||||
m->addDamage(&damageBoxForEach);
|
||||
}
|
||||
|
||||
pixman_region32_fini(&damageBoxForEach);
|
||||
@@ -725,10 +760,10 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
wlr_box fixedDamageBox = {damageBox.x - m->vecPosition.x, damageBox.y - m->vecPosition.y, damageBox.width, damageBox.height};
|
||||
scaleBox(&fixedDamageBox, m->scale);
|
||||
wlr_output_damage_add_box(m->damage, &fixedDamageBox);
|
||||
m->addDamage(&fixedDamageBox);
|
||||
}
|
||||
|
||||
static auto* const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
|
||||
if (*PLOGDAMAGE)
|
||||
Debug::log(LOG, "Damage: Window (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
||||
@@ -739,7 +774,7 @@ void CHyprRenderer::damageMonitor(CMonitor* pMonitor) {
|
||||
return;
|
||||
|
||||
wlr_box damageBox = {0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y};
|
||||
wlr_output_damage_add_box(pMonitor->damage, &damageBox);
|
||||
pMonitor->addDamage(&damageBox);
|
||||
|
||||
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
|
||||
@@ -754,7 +789,7 @@ void CHyprRenderer::damageBox(wlr_box* pBox) {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
wlr_box damageBox = {pBox->x - m->vecPosition.x, pBox->y - m->vecPosition.y, pBox->width, pBox->height};
|
||||
scaleBox(&damageBox, m->scale);
|
||||
wlr_output_damage_add_box(m->damage, &damageBox);
|
||||
m->addDamage(&damageBox);
|
||||
}
|
||||
|
||||
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
|
@@ -40,6 +40,7 @@ public:
|
||||
bool shouldRenderWindow(CWindow*);
|
||||
void ensureCursorRenderingMode();
|
||||
bool shouldRenderCursor();
|
||||
void calculateUVForWindowSurface(CWindow*, wlr_surface*, bool main = false);
|
||||
|
||||
bool m_bWindowRequestedCursorHide = false;
|
||||
|
||||
|
@@ -14,7 +14,7 @@ GLint CShader::getUniformLocation(const std::string& unif) {
|
||||
|
||||
CShader::~CShader() {
|
||||
// destroy shader
|
||||
if (program != 0) {
|
||||
if (program) {
|
||||
glDeleteProgram(program);
|
||||
}
|
||||
}
|
@@ -80,6 +80,8 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
return; // cannot parse
|
||||
}
|
||||
|
||||
const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ? 0 : (m_pWindow->m_sAdditionalConfigData.rounding == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding);
|
||||
|
||||
// update the extents
|
||||
m_seExtents = {{*PSHADOWSIZE + 2 - offset.x, *PSHADOWSIZE + 2 - offset.y}, {*PSHADOWSIZE + 2 + offset.x, *PSHADOWSIZE + 2 + offset.y}};
|
||||
|
||||
@@ -113,15 +115,15 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
return; // prevent assert failed
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->renderRect(&windowBox, CColor(0,0,0,0), *PROUNDING * pMonitor->scale);
|
||||
|
||||
g_pHyprOpenGL->renderRect(&windowBox, CColor(0, 0, 0, 0), ROUNDING * pMonitor->scale);
|
||||
|
||||
glStencilFunc(GL_NOTEQUAL, 1, -1);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
}
|
||||
|
||||
scaleBox(&fullBox, pMonitor->scale);
|
||||
g_pHyprOpenGL->renderRoundedShadow(&fullBox, *PROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, a);
|
||||
g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, a);
|
||||
|
||||
if (*PSHADOWIGNOREWINDOW) {
|
||||
// cleanup
|
||||
|
@@ -112,7 +112,7 @@ static void workspace_handle_remove(struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_signal_emit_safe(&workspace->events.remove_request, NULL);
|
||||
wl_signal_emit_mutable(&workspace->events.remove_request, NULL);
|
||||
}
|
||||
|
||||
static void workspace_handle_deactivate(struct wl_client *client,
|
||||
@@ -312,7 +312,7 @@ void wlr_ext_workspace_handle_v1_destroy(
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_signal_emit_safe(&workspace->events.destroy, workspace);
|
||||
wl_signal_emit_mutable(&workspace->events.destroy, workspace);
|
||||
|
||||
workspace_manager_update_idle_source(workspace->group->manager);
|
||||
|
||||
@@ -338,7 +338,7 @@ static void workspace_group_handle_handle_create_workspace(struct wl_client *cli
|
||||
struct wlr_ext_workspace_group_handle_v1_create_workspace_event event;
|
||||
event.workspace_group = group;
|
||||
event.name = arg;
|
||||
wlr_signal_emit_safe(&group->events.create_workspace_request, &event);
|
||||
wl_signal_emit_mutable(&group->events.create_workspace_request, &event);
|
||||
}
|
||||
|
||||
static void workspace_group_handle_handle_destroy(struct wl_client *client,
|
||||
@@ -513,7 +513,7 @@ void wlr_ext_workspace_group_handle_v1_destroy(
|
||||
wlr_ext_workspace_handle_v1_destroy(workspace);
|
||||
}
|
||||
|
||||
wlr_signal_emit_safe(&group->events.destroy, group);
|
||||
wl_signal_emit_mutable(&group->events.destroy, group);
|
||||
workspace_manager_update_idle_source(group->manager);
|
||||
|
||||
struct wlr_ext_workspace_group_handle_v1_output *output, *tmp2;
|
||||
@@ -556,7 +556,7 @@ static void workspace_manager_commit(struct wl_client *client,
|
||||
}
|
||||
}
|
||||
|
||||
wlr_signal_emit_safe(&manager->events.commit, manager);
|
||||
wl_signal_emit_mutable(&manager->events.commit, manager);
|
||||
}
|
||||
|
||||
static void workspace_manager_stop(struct wl_client *client,
|
||||
@@ -602,7 +602,7 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_ext_workspace_manager_v1 *manager =
|
||||
wl_container_of(listener, manager, display_destroy);
|
||||
|
||||
wlr_signal_emit_safe(&manager->events.destroy, manager);
|
||||
wl_signal_emit_mutable(&manager->events.destroy, manager);
|
||||
wl_list_remove(&manager->display_destroy.link);
|
||||
wl_global_destroy(manager->global);
|
||||
|
||||
|
Submodule subprojects/wlroots updated: 3baf2a6bcf...7c575922c0
Reference in New Issue
Block a user