mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-07-27 02:01:55 -07:00
Compare commits
66 Commits
v0.11.1bet
...
v0.12.1bet
Author | SHA1 | Date | |
---|---|---|---|
|
eb658dcb61 | ||
|
195ec2b092 | ||
|
dd6aba07e9 | ||
|
d35d949bc5 | ||
|
48eb2e0d6f | ||
|
179562b646 | ||
|
20c050e890 | ||
|
bdd20c401d | ||
|
6865660e51 | ||
|
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 |
7
.github/workflows/nix-build.yaml
vendored
7
.github/workflows/nix-build.yaml
vendored
@@ -5,6 +5,11 @@ jobs:
|
||||
nix:
|
||||
name: "Build Hyprland (Nix)"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
package:
|
||||
- default
|
||||
- hyprland-no-hidpi
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
@@ -22,4 +27,4 @@ jobs:
|
||||
name: hyprland
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
- name: Build Hyprland with default settings
|
||||
run: nix build --print-build-logs
|
||||
run: nix build .#${{ matrix.package }} --print-build-logs
|
||||
|
19
Makefile
19
Makefile
@@ -137,6 +137,25 @@ install:
|
||||
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
|
||||
|
@@ -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 }--------------------------------->
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\"
|
||||
.TH "Hyprland" "1" "22 Aug 2022" "" "Hyprland User Manual"
|
||||
.TH "Hyprland" "1" "24 Aug 2022" "" "Hyprland User Manual"
|
||||
.hy
|
||||
.SH NAME
|
||||
.PP
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.\" Automatically generated by Pandoc 2.5
|
||||
.\"
|
||||
.TH "hyprctl" "1" "22 Aug 2022" "" "hyprctl User Manual"
|
||||
.TH "hyprctl" "1" "24 Aug 2022" "" "hyprctl User Manual"
|
||||
.hy
|
||||
.SH NAME
|
||||
.PP
|
||||
|
@@ -24,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
|
||||
|
10
flake.nix
10
flake.nix
@@ -32,12 +32,15 @@
|
||||
version = mkDate (inputs.wlroots.lastModifiedDate or "19700101");
|
||||
src = inputs.wlroots;
|
||||
});
|
||||
|
||||
hyprland = prev.callPackage ./nix/default.nix {
|
||||
stdenv = prev.gcc12Stdenv;
|
||||
version = "0.11.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
version = "0.11.1beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
wlroots = wlroots-hyprland;
|
||||
};
|
||||
hyprland-debug = hyprland.override {debug = true;};
|
||||
hyprland-no-hidpi = hyprland.override {hidpiXWayland = false;};
|
||||
|
||||
waybar-hyprland = prev.waybar.overrideAttrs (oldAttrs: {
|
||||
mesonFlags = oldAttrs.mesonFlags ++ ["-Dexperimental=true"];
|
||||
});
|
||||
@@ -66,4 +69,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="];
|
||||
};
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
project('Hyprland', 'cpp', 'c',
|
||||
version : '0.10.0beta',
|
||||
version : '0.11.1beta',
|
||||
default_options : [
|
||||
'warning_level=2',
|
||||
'default_library=static',
|
||||
|
151
nix/default.nix
151
nix/default.nix
@@ -2,6 +2,7 @@
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
fetchpatch,
|
||||
pkg-config,
|
||||
meson,
|
||||
ninja,
|
||||
@@ -21,78 +22,88 @@
|
||||
xwayland,
|
||||
debug ? false,
|
||||
enableXWayland ? true,
|
||||
hidpiXWayland ? true,
|
||||
legacyRenderer ? false,
|
||||
version ? "git",
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "hyprland" + lib.optionalString debug "-debug";
|
||||
inherit version;
|
||||
|
||||
src = lib.cleanSourceWith {
|
||||
filter = name: type: let
|
||||
baseName = baseNameOf (toString name);
|
||||
in
|
||||
! (
|
||||
lib.hasSuffix ".nix" baseName
|
||||
);
|
||||
src = lib.cleanSource ../.;
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
outputs = [
|
||||
"out"
|
||||
"man"
|
||||
];
|
||||
|
||||
buildInputs =
|
||||
[
|
||||
git
|
||||
libdrm
|
||||
libinput
|
||||
libxcb
|
||||
libxkbcommon
|
||||
mesa
|
||||
pango
|
||||
wayland
|
||||
wayland-protocols
|
||||
wayland-scanner
|
||||
(wlroots.override {inherit enableXWayland;})
|
||||
xcbutilwm
|
||||
]
|
||||
++ lib.optional enableXWayland xwayland;
|
||||
|
||||
mesonBuildType =
|
||||
if debug
|
||||
then "debug"
|
||||
else "release";
|
||||
|
||||
mesonFlags = builtins.concatLists [
|
||||
(lib.optional (!enableXWayland) "-DNO_XWAYLAND=true")
|
||||
(lib.optional legacyRenderer "-DLEGACY_RENDERER:STRING=true")
|
||||
];
|
||||
|
||||
patches = [
|
||||
# make meson use the provided wlroots instead of the git submodule
|
||||
./meson-build.patch
|
||||
];
|
||||
|
||||
# Fix hardcoded paths to /usr installation
|
||||
postPatch = ''
|
||||
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
|
||||
}: let
|
||||
assertXWayland = lib.assertMsg (hidpiXWayland -> enableXWayland) ''
|
||||
Hyprland: cannot have hidpiXWayland when enableXWayland is false.
|
||||
'';
|
||||
in
|
||||
assert assertXWayland;
|
||||
stdenv.mkDerivation {
|
||||
pname = "hyprland" + lib.optionalString debug "-debug";
|
||||
inherit version;
|
||||
|
||||
passthru.providedSessions = ["hyprland"];
|
||||
src = lib.cleanSourceWith {
|
||||
filter = name: type: let
|
||||
baseName = baseNameOf (toString name);
|
||||
in
|
||||
! (
|
||||
lib.hasSuffix ".nix" baseName
|
||||
);
|
||||
src = lib.cleanSource ../.;
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://github.com/vaxerski/Hyprland";
|
||||
description = "A dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
|
||||
license = licenses.bsd3;
|
||||
platforms = platforms.linux;
|
||||
mainProgram = "Hyprland";
|
||||
};
|
||||
}
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
outputs = [
|
||||
"out"
|
||||
"man"
|
||||
];
|
||||
|
||||
buildInputs =
|
||||
[
|
||||
git
|
||||
libdrm
|
||||
libinput
|
||||
libxcb
|
||||
libxkbcommon
|
||||
mesa
|
||||
pango
|
||||
wayland
|
||||
wayland-protocols
|
||||
wayland-scanner
|
||||
(
|
||||
if hidpiXWayland
|
||||
then (import ./hidpi_wlroots.nix {inherit wlroots xwayland fetchpatch;})
|
||||
else wlroots.override {inherit enableXWayland;}
|
||||
)
|
||||
xcbutilwm
|
||||
]
|
||||
++ lib.optional enableXWayland xwayland;
|
||||
|
||||
mesonBuildType =
|
||||
if debug
|
||||
then "debug"
|
||||
else "release";
|
||||
|
||||
mesonFlags = builtins.concatLists [
|
||||
(lib.optional (!enableXWayland) "-Dxwayland=disabled")
|
||||
(lib.optional legacyRenderer "-DLEGACY_RENDERER:STRING=true")
|
||||
];
|
||||
|
||||
patches = [
|
||||
# make meson use the provided wlroots instead of the git submodule
|
||||
./meson-build.patch
|
||||
];
|
||||
|
||||
# Fix hardcoded paths to /usr installation
|
||||
postPatch = ''
|
||||
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
|
||||
'';
|
||||
|
||||
passthru.providedSessions = ["hyprland"];
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://github.com/vaxerski/Hyprland";
|
||||
description = "A dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
|
||||
license = licenses.bsd3;
|
||||
platforms = platforms.linux;
|
||||
mainProgram = "Hyprland";
|
||||
};
|
||||
}
|
||||
|
31
nix/hidpi_wlroots.nix
Normal file
31
nix/hidpi_wlroots.nix
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
wlroots,
|
||||
xwayland,
|
||||
fetchpatch,
|
||||
}:
|
||||
(wlroots.overrideAttrs
|
||||
(old: {
|
||||
patches =
|
||||
(old.patches or [])
|
||||
++ [
|
||||
(fetchpatch {
|
||||
url = "https://gitlab.freedesktop.org/lilydjwg/wlroots/-/commit/6c5ffcd1fee9e44780a6a8792f74ecfbe24a1ca7.diff";
|
||||
sha256 = "sha256-Eo1pTa/PIiJsRZwIUnHGTIFFIedzODVf0ZeuXb0a3TQ=";
|
||||
})
|
||||
(fetchpatch {
|
||||
url = "https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/18595000f3a21502fd60bf213122859cc348f9af.diff";
|
||||
sha256 = "sha256-jvfkAMh3gzkfuoRhB4E9T5X1Hu62wgUjj4tZkJm0mrI=";
|
||||
revert = true;
|
||||
})
|
||||
];
|
||||
}))
|
||||
.override {
|
||||
xwayland = xwayland.overrideAttrs (old: {
|
||||
patches =
|
||||
(old.patches or [])
|
||||
++ [
|
||||
./xwayland-vsync.patch
|
||||
./xwayland-hidpi.patch
|
||||
];
|
||||
});
|
||||
}
|
@@ -6,7 +6,8 @@ self: {
|
||||
}: let
|
||||
cfg = config.wayland.windowManager.hyprland;
|
||||
defaultHyprlandPackage = self.packages.${pkgs.system}.default.override {
|
||||
enableXWayland = cfg.xwayland;
|
||||
enableXWayland = cfg.xwayland.enable;
|
||||
hidpiXWayland = cfg.xwayland.hidpi;
|
||||
};
|
||||
in {
|
||||
options.wayland.windowManager.hyprland = {
|
||||
@@ -41,12 +42,21 @@ in {
|
||||
</itemizedlist>
|
||||
'';
|
||||
};
|
||||
xwayland = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable xwayland.
|
||||
'';
|
||||
xwayland = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable XWayland.
|
||||
'';
|
||||
};
|
||||
hidpi = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable HiDPI XWayland.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
extraConfig = lib.mkOption {
|
||||
@@ -56,20 +66,28 @@ in {
|
||||
Extra configuration lines to add to ~/.config/hypr/hyprland.conf.
|
||||
'';
|
||||
};
|
||||
|
||||
imports = [
|
||||
(
|
||||
lib.mkRenamedOptionModule
|
||||
["wayland" "windowManager" "hyprland" "xwayland"]
|
||||
["wayland" "windowManager" "hyprland" "xwayland" "enable"]
|
||||
)
|
||||
];
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages =
|
||||
lib.optional (cfg.package != null) cfg.package
|
||||
++ lib.optional cfg.xwayland pkgs.xwayland;
|
||||
++ lib.optional cfg.xwayland.enable pkgs.xwayland;
|
||||
|
||||
xdg.configFile."hypr/hyprland.conf" = {
|
||||
text =
|
||||
(lib.optionalString cfg.systemdIntegration ''
|
||||
exec-once=export XDG_SESSION_TYPE=wayland
|
||||
exec-once=${pkgs.dbus}/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP
|
||||
exec-once=systemctl --user start hyprland-session.target
|
||||
'')
|
||||
exec-once=export XDG_SESSION_TYPE=wayland
|
||||
exec-once=${pkgs.dbus}/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP
|
||||
exec-once=systemctl --user start hyprland-session.target
|
||||
'')
|
||||
+ cfg.extraConfig;
|
||||
|
||||
onChange = let
|
||||
|
498
nix/xwayland-hidpi.patch
Normal file
498
nix/xwayland-hidpi.patch
Normal file
@@ -0,0 +1,498 @@
|
||||
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
|
||||
index c4457cc2a61b2103b47f996b51dbbe9eb87bd715..4a33e1f33e73c35c1691564ef4852e7501b02245 100644
|
||||
--- a/hw/xwayland/xwayland-cursor.c
|
||||
+++ b/hw/xwayland/xwayland-cursor.c
|
||||
@@ -171,6 +171,8 @@ xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
|
||||
}
|
||||
|
||||
wl_surface_attach(xwl_cursor->surface, buffer, 0, 0);
|
||||
+ wl_surface_set_buffer_scale(xwl_cursor->surface,
|
||||
+ xwl_seat->xwl_screen->global_output_scale);
|
||||
xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0,
|
||||
xwl_seat->x_cursor->bits->width,
|
||||
xwl_seat->x_cursor->bits->height);
|
||||
@@ -190,6 +192,7 @@ xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
|
||||
void
|
||||
xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
|
||||
{
|
||||
+ struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
struct xwl_cursor *xwl_cursor = &xwl_seat->cursor;
|
||||
PixmapPtr pixmap;
|
||||
CursorPtr cursor;
|
||||
@@ -220,8 +223,8 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
|
||||
wl_pointer_set_cursor(xwl_seat->wl_pointer,
|
||||
xwl_seat->pointer_enter_serial,
|
||||
xwl_cursor->surface,
|
||||
- xwl_seat->x_cursor->bits->xhot,
|
||||
- xwl_seat->x_cursor->bits->yhot);
|
||||
+ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->xhot),
|
||||
+ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->yhot));
|
||||
|
||||
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
|
||||
}
|
||||
@@ -230,6 +233,7 @@ void
|
||||
xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
|
||||
+ struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
struct xwl_cursor *xwl_cursor = &xwl_tablet_tool->cursor;
|
||||
PixmapPtr pixmap;
|
||||
CursorPtr cursor;
|
||||
@@ -258,9 +262,9 @@ xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
|
||||
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
|
||||
xwl_tablet_tool->proximity_in_serial,
|
||||
xwl_cursor->surface,
|
||||
- xwl_seat->x_cursor->bits->xhot,
|
||||
- xwl_seat->x_cursor->bits->yhot);
|
||||
-
|
||||
+ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->xhot),
|
||||
+ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->yhot));
|
||||
+ wl_surface_set_buffer_scale(xwl_cursor->surface, xwl_screen->global_output_scale);
|
||||
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
|
||||
}
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
|
||||
index 26b3630c73b62514fe3ba7824371f79868e953f3..55cd8d466a55db03948abe93ffa03bf129b5e17a 100644
|
||||
--- a/hw/xwayland/xwayland-input.c
|
||||
+++ b/hw/xwayland/xwayland-input.c
|
||||
@@ -412,8 +412,8 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
|
||||
DeviceIntPtr dev = get_pointer_device(xwl_seat);
|
||||
DeviceIntPtr master;
|
||||
int i;
|
||||
- int sx = wl_fixed_to_int(sx_w);
|
||||
- int sy = wl_fixed_to_int(sy_w);
|
||||
+ int sx = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale;
|
||||
+ int sy = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale;
|
||||
int dx, dy;
|
||||
ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
|
||||
ValuatorMask mask;
|
||||
@@ -592,13 +592,14 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer,
|
||||
uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = data;
|
||||
+ int32_t scale = xwl_seat->xwl_screen->global_output_scale;
|
||||
|
||||
if (!xwl_seat->focus_window)
|
||||
return;
|
||||
|
||||
xwl_seat->pending_pointer_event.has_absolute = TRUE;
|
||||
- xwl_seat->pending_pointer_event.x = sx_w;
|
||||
- xwl_seat->pending_pointer_event.y = sy_w;
|
||||
+ xwl_seat->pending_pointer_event.x = sx_w * scale;
|
||||
+ xwl_seat->pending_pointer_event.y = sy_w * scale;
|
||||
|
||||
if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5)
|
||||
dispatch_pointer_motion_event(xwl_seat);
|
||||
@@ -672,7 +673,8 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
|
||||
xorg_list_del(&pending->l);
|
||||
free(pending);
|
||||
} else {
|
||||
- valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor);
|
||||
+ double scaled_value = wl_fixed_to_double(value);
|
||||
+ valuator_mask_set_double(&mask, index, scaled_value / divisor);
|
||||
}
|
||||
|
||||
QueuePointerEvents(get_pointer_device(xwl_seat),
|
||||
@@ -740,12 +742,13 @@ relative_pointer_handle_relative_motion(void *data,
|
||||
wl_fixed_t dy_unaccelf)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = data;
|
||||
+ int32_t scale = xwl_seat->xwl_screen->global_output_scale;
|
||||
|
||||
xwl_seat->pending_pointer_event.has_relative = TRUE;
|
||||
- xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf);
|
||||
- xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf);
|
||||
- xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf);
|
||||
- xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf);
|
||||
+ xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf) * scale;
|
||||
+ xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf) * scale;
|
||||
+ xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf) * scale;
|
||||
+ xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf) * scale;
|
||||
|
||||
if (!xwl_seat->focus_window)
|
||||
return;
|
||||
@@ -1057,8 +1060,8 @@ touch_handle_down(void *data, struct wl_touch *wl_touch,
|
||||
|
||||
xwl_touch->window = wl_surface_get_user_data(surface);
|
||||
xwl_touch->id = id;
|
||||
- xwl_touch->x = wl_fixed_to_int(sx_w);
|
||||
- xwl_touch->y = wl_fixed_to_int(sy_w);
|
||||
+ xwl_touch->x = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale;
|
||||
+ xwl_touch->y = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale;
|
||||
xorg_list_add(&xwl_touch->link_touch, &xwl_seat->touches);
|
||||
|
||||
xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchBegin);
|
||||
@@ -1094,8 +1097,8 @@ touch_handle_motion(void *data, struct wl_touch *wl_touch,
|
||||
if (!xwl_touch)
|
||||
return;
|
||||
|
||||
- xwl_touch->x = wl_fixed_to_int(sx_w);
|
||||
- xwl_touch->y = wl_fixed_to_int(sy_w);
|
||||
+ xwl_touch->x = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale;;
|
||||
+ xwl_touch->y = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale;;
|
||||
xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchUpdate);
|
||||
}
|
||||
|
||||
@@ -1726,8 +1729,8 @@ tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool,
|
||||
struct xwl_tablet_tool *xwl_tablet_tool = data;
|
||||
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
|
||||
int32_t dx, dy;
|
||||
- double sx = wl_fixed_to_double(x);
|
||||
- double sy = wl_fixed_to_double(y);
|
||||
+ double sx = wl_fixed_to_double(x) * xwl_seat->xwl_screen->global_output_scale;
|
||||
+ double sy = wl_fixed_to_double(y) * xwl_seat->xwl_screen->global_output_scale;
|
||||
|
||||
if (!xwl_seat->tablet_focus_window)
|
||||
return;
|
||||
@@ -2714,6 +2717,7 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
+ struct xwl_screen *xwl_screen;
|
||||
struct zwp_locked_pointer_v1 *locked_pointer =
|
||||
warp_emulator->locked_pointer;
|
||||
WindowPtr window;
|
||||
@@ -2725,6 +2729,7 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em
|
||||
if (!warp_emulator->xwl_seat->focus_window)
|
||||
return;
|
||||
|
||||
+ xwl_screen = warp_emulator->xwl_seat->xwl_screen;
|
||||
window = warp_emulator->xwl_seat->focus_window->window;
|
||||
if (x >= window->drawable.x ||
|
||||
y >= window->drawable.y ||
|
||||
@@ -2733,8 +2738,8 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em
|
||||
sx = x - window->drawable.x;
|
||||
sy = y - window->drawable.y;
|
||||
zwp_locked_pointer_v1_set_cursor_position_hint(locked_pointer,
|
||||
- wl_fixed_from_int(sx),
|
||||
- wl_fixed_from_int(sy));
|
||||
+ wl_fixed_from_int(xwl_scale_to(xwl_screen, sx)),
|
||||
+ wl_fixed_from_int(xwl_scale_to(xwl_screen, sy)));
|
||||
wl_surface_commit(warp_emulator->xwl_seat->focus_window->surface);
|
||||
}
|
||||
}
|
||||
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
|
||||
index ef705bc01bf8c2d2f170cda9ba21ed8293f50559..b8f6cd51bd240ed5e16271eb4749db18868bea7b 100644
|
||||
--- a/hw/xwayland/xwayland-output.c
|
||||
+++ b/hw/xwayland/xwayland-output.c
|
||||
@@ -191,6 +191,9 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||
|
||||
+ width *= xwl_screen->global_output_scale;
|
||||
+ height *= xwl_screen->global_output_scale;
|
||||
+
|
||||
if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL)
|
||||
SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE);
|
||||
|
||||
@@ -497,14 +500,15 @@ xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
|
||||
xwl_output_set_randr_emu_props(xwl_output->xwl_screen, client);
|
||||
}
|
||||
|
||||
-static void
|
||||
-apply_output_change(struct xwl_output *xwl_output)
|
||||
+void
|
||||
+xwl_output_apply_changes(struct xwl_output *xwl_output)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||
struct xwl_output *it;
|
||||
int mode_width, mode_height, count;
|
||||
int width = 0, height = 0, has_this_output = 0;
|
||||
RRModePtr *randr_modes;
|
||||
+ int32_t scale = xwl_screen->global_output_scale;
|
||||
|
||||
/* Clear out the "done" received flags */
|
||||
xwl_output->wl_output_done = FALSE;
|
||||
@@ -523,10 +527,10 @@ apply_output_change(struct xwl_output *xwl_output)
|
||||
}
|
||||
|
||||
/* Build a fresh modes array using the current refresh rate */
|
||||
- randr_modes = output_get_rr_modes(xwl_output, mode_width, mode_height, &count);
|
||||
+ randr_modes = output_get_rr_modes(xwl_output, mode_width * scale, mode_height * scale, &count);
|
||||
RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1);
|
||||
RRCrtcNotify(xwl_output->randr_crtc, randr_modes[0],
|
||||
- xwl_output->x, xwl_output->y,
|
||||
+ xwl_output->x * scale, xwl_output->y * scale,
|
||||
xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
|
||||
/* RROutputSetModes takes ownership of the passed in modes, so we only
|
||||
* have to free the pointer array.
|
||||
@@ -567,7 +571,7 @@ output_handle_done(void *data, struct wl_output *wl_output)
|
||||
*/
|
||||
if (xwl_output->xdg_output_done || !xwl_output->xdg_output ||
|
||||
zxdg_output_v1_get_version(xwl_output->xdg_output) >= 3)
|
||||
- apply_output_change(xwl_output);
|
||||
+ xwl_output_apply_changes(xwl_output);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -610,7 +614,7 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output)
|
||||
xwl_output->xdg_output_done = TRUE;
|
||||
if (xwl_output->wl_output_done &&
|
||||
zxdg_output_v1_get_version(xdg_output) < 3)
|
||||
- apply_output_change(xwl_output);
|
||||
+ xwl_output_apply_changes(xwl_output);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -678,6 +682,8 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
|
||||
RROutputSetConnection(xwl_output->randr_output, RR_Connected);
|
||||
RRTellChanged(xwl_screen->screen);
|
||||
|
||||
+ xwl_output->scale = 1;
|
||||
+
|
||||
/* We want the output to be in the list as soon as created so we can
|
||||
* use it when binding to the xdg-output protocol...
|
||||
*/
|
||||
diff --git a/hw/xwayland/xwayland-output.h b/hw/xwayland/xwayland-output.h
|
||||
index 02b9831083e82a33d85d4404e39d00f06f6c56fd..ec089757f44178dcd7f9c48907f790ce1b2a2729 100644
|
||||
--- a/hw/xwayland/xwayland-output.h
|
||||
+++ b/hw/xwayland/xwayland-output.h
|
||||
@@ -53,7 +53,7 @@ struct xwl_output {
|
||||
struct wl_output *output;
|
||||
struct zxdg_output_v1 *xdg_output;
|
||||
uint32_t server_output_id;
|
||||
- int32_t x, y, width, height, refresh;
|
||||
+ int32_t x, y, width, height, refresh, scale;
|
||||
Rotation rotation;
|
||||
Bool wl_output_done;
|
||||
Bool xdg_output_done;
|
||||
@@ -100,6 +100,8 @@ void xwl_output_set_emulated_mode(struct xwl_output *xwl_output,
|
||||
void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
|
||||
WindowPtr window);
|
||||
|
||||
+void xwl_output_apply_changes(struct xwl_output *xwl_output);
|
||||
+
|
||||
void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
|
||||
|
||||
#endif /* XWAYLAND_OUTPUT_H */
|
||||
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
|
||||
index c9cf8c2f569a319034e0789e7587414e50237065..5be0c208ca46b1a53a136885fdc8ab44251fe7ff 100644
|
||||
--- a/hw/xwayland/xwayland-present.c
|
||||
+++ b/hw/xwayland/xwayland-present.c
|
||||
@@ -680,6 +680,8 @@ xwl_present_flip(WindowPtr present_window,
|
||||
|
||||
/* We can flip directly to the main surface (full screen window without clips) */
|
||||
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
|
||||
+ wl_surface_set_buffer_scale(xwl_window->surface,
|
||||
+ xwl_window->xwl_screen->global_output_scale);
|
||||
|
||||
if (!xwl_window->frame_callback)
|
||||
xwl_window_create_frame_callback(xwl_window);
|
||||
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
|
||||
index bb18e5c94fbc7134c801e4e1979e8184079d352e..4ec2de7d123dd36315df07a1e95b1f417925f0f8 100644
|
||||
--- a/hw/xwayland/xwayland-screen.c
|
||||
+++ b/hw/xwayland/xwayland-screen.c
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "xwayland-pixmap.h"
|
||||
#include "xwayland-present.h"
|
||||
#include "xwayland-shm.h"
|
||||
+#include "xwayland-window-buffers.h"
|
||||
|
||||
#ifdef MITSHM
|
||||
#include "shmint.h"
|
||||
@@ -110,6 +111,12 @@ xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen)
|
||||
return xwl_screen->rootless && xwl_screen_has_viewport_support(xwl_screen);
|
||||
}
|
||||
|
||||
+int
|
||||
+xwl_scale_to(struct xwl_screen *xwl_screen, int value)
|
||||
+{
|
||||
+ return value / (double)xwl_screen->global_output_scale + 0.5;
|
||||
+}
|
||||
+
|
||||
/* Return the output @ 0x0, falling back to the first output in the list */
|
||||
struct xwl_output *
|
||||
xwl_screen_get_first_output(struct xwl_screen *xwl_screen)
|
||||
@@ -127,6 +134,37 @@ xwl_screen_get_first_output(struct xwl_screen *xwl_screen)
|
||||
return xorg_list_first_entry(&xwl_screen->output_list, struct xwl_output, link);
|
||||
}
|
||||
|
||||
+static void
|
||||
+xwl_screen_set_global_scale_from_property(struct xwl_screen *screen,
|
||||
+ PropertyPtr prop)
|
||||
+{
|
||||
+ CARD32 *propdata;
|
||||
+
|
||||
+ if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) {
|
||||
+ // TODO: handle warnings more cleanly.
|
||||
+ LogMessageVerb(X_WARNING, 0, "Bad value for property %s.\n",
|
||||
+ NameForAtom(prop->propertyName));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ propdata = prop->data;
|
||||
+ xwl_screen_set_global_scale(screen, propdata[0]);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+xwl_screen_update_property(struct xwl_screen *screen,
|
||||
+ PropertyStateRec *propstate)
|
||||
+{
|
||||
+ switch (propstate->state) {
|
||||
+ case PropertyNewValue:
|
||||
+ xwl_screen_set_global_scale_from_property(screen, propstate->prop);
|
||||
+ break;
|
||||
+ case PropertyDelete:
|
||||
+ xwl_screen_set_global_scale(screen, 1);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
xwl_property_callback(CallbackListPtr *pcbl, void *closure,
|
||||
void *calldata)
|
||||
@@ -134,19 +172,24 @@ xwl_property_callback(CallbackListPtr *pcbl, void *closure,
|
||||
ScreenPtr screen = closure;
|
||||
PropertyStateRec *rec = calldata;
|
||||
struct xwl_screen *xwl_screen;
|
||||
- struct xwl_window *xwl_window;
|
||||
|
||||
if (rec->win->drawable.pScreen != screen)
|
||||
return;
|
||||
|
||||
- xwl_window = xwl_window_get(rec->win);
|
||||
- if (!xwl_window)
|
||||
- return;
|
||||
-
|
||||
xwl_screen = xwl_screen_get(screen);
|
||||
|
||||
- if (rec->prop->propertyName == xwl_screen->allow_commits_prop)
|
||||
+ if (rec->prop->propertyName == xwl_screen->allow_commits_prop) {
|
||||
+ struct xwl_window *xwl_window;
|
||||
+
|
||||
+ xwl_window = xwl_window_get(rec->win);
|
||||
+ if (!xwl_window)
|
||||
+ return;
|
||||
+
|
||||
xwl_window_update_property(xwl_window, rec);
|
||||
+ }
|
||||
+ else if (rec->prop->propertyName == xwl_screen->global_output_scale_prop) {
|
||||
+ xwl_screen_update_property(xwl_screen, rec);
|
||||
+ }
|
||||
}
|
||||
|
||||
Bool
|
||||
@@ -521,8 +564,14 @@ void xwl_surface_damage(struct xwl_screen *xwl_screen,
|
||||
{
|
||||
if (wl_surface_get_version(surface) >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
|
||||
wl_surface_damage_buffer(surface, x, y, width, height);
|
||||
- else
|
||||
+ else {
|
||||
+ x = xwl_scale_to(xwl_screen, x);
|
||||
+ y = xwl_scale_to(xwl_screen, y);
|
||||
+ width = xwl_scale_to(xwl_screen, width);
|
||||
+ height = xwl_scale_to(xwl_screen, height);
|
||||
+
|
||||
wl_surface_damage(surface, x, y, width, height);
|
||||
+ }
|
||||
}
|
||||
|
||||
void
|
||||
@@ -538,10 +587,34 @@ xwl_screen_roundtrip(struct xwl_screen *xwl_screen)
|
||||
xwl_give_up("could not connect to wayland server\n");
|
||||
}
|
||||
|
||||
+void
|
||||
+xwl_screen_set_global_scale(struct xwl_screen *xwl_screen, int32_t scale)
|
||||
+{
|
||||
+ struct xwl_output *it;
|
||||
+ struct xwl_window *xwl_window;
|
||||
+
|
||||
+ xwl_screen->global_output_scale = scale;
|
||||
+
|
||||
+ /* change randr resolutions and positions */
|
||||
+ xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
|
||||
+ xwl_output_apply_changes(it);
|
||||
+ }
|
||||
+
|
||||
+ if (!xwl_screen->rootless && xwl_screen->screen->root) {
|
||||
+ /* Clear all the buffers, so that they'll be remade with the new sizes
|
||||
+ * (this doesn't occur automatically because as far as Xorg is
|
||||
+ * concerned, the window's size is the same) */
|
||||
+ xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window) {
|
||||
+ xwl_window_buffers_recycle(xwl_window);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
Bool
|
||||
xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
||||
{
|
||||
static const char allow_commits[] = "_XWAYLAND_ALLOW_COMMITS";
|
||||
+ static const char global_output_scale[] = "_XWAYLAND_GLOBAL_OUTPUT_SCALE";
|
||||
struct xwl_screen *xwl_screen;
|
||||
Pixel red_mask, blue_mask, green_mask;
|
||||
int ret, bpc, green_bpc, i;
|
||||
@@ -573,6 +646,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
||||
#ifdef XWL_HAS_GLAMOR
|
||||
xwl_screen->glamor = 1;
|
||||
#endif
|
||||
+ xwl_screen->global_output_scale = 1;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-rootless") == 0) {
|
||||
@@ -743,6 +817,12 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
||||
if (xwl_screen->allow_commits_prop == BAD_RESOURCE)
|
||||
return FALSE;
|
||||
|
||||
+ xwl_screen->global_output_scale_prop = MakeAtom(global_output_scale,
|
||||
+ strlen(global_output_scale),
|
||||
+ TRUE);
|
||||
+ if (xwl_screen->global_output_scale_prop == BAD_RESOURCE)
|
||||
+ return FALSE;
|
||||
+
|
||||
AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen);
|
||||
|
||||
xwl_screen_roundtrip(xwl_screen);
|
||||
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
|
||||
index b965dddd7f964b1d100bbb9d10da1c35ab39810e..7446829d098fbe235e605084a016daff1a8eaea2 100644
|
||||
--- a/hw/xwayland/xwayland-screen.h
|
||||
+++ b/hw/xwayland/xwayland-screen.h
|
||||
@@ -72,6 +72,8 @@ struct xwl_screen {
|
||||
struct xorg_list damage_window_list;
|
||||
struct xorg_list window_list;
|
||||
|
||||
+ int32_t global_output_scale;
|
||||
+
|
||||
int wayland_fd;
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
@@ -107,6 +109,7 @@ struct xwl_screen {
|
||||
struct glamor_context *glamor_ctx;
|
||||
|
||||
Atom allow_commits_prop;
|
||||
+ Atom global_output_scale_prop;
|
||||
|
||||
/* The preferred GLVND vendor. If NULL, "mesa" is assumed. */
|
||||
const char *glvnd_vendor;
|
||||
@@ -134,5 +137,7 @@ void xwl_screen_roundtrip (struct xwl_screen *xwl_screen);
|
||||
void xwl_surface_damage(struct xwl_screen *xwl_screen,
|
||||
struct wl_surface *surface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height);
|
||||
+int xwl_scale_to(struct xwl_screen *xwl_screen, int value);
|
||||
+void xwl_screen_set_global_scale(struct xwl_screen *xwl_screen, int32_t scale);
|
||||
|
||||
#endif /* XWAYLAND_SCREEN_H */
|
||||
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
|
||||
index 00f161eda084e335ac07471a2198176d75d9fcf0..ed3903853f0dab1dad390cd8429639541546157d 100644
|
||||
--- a/hw/xwayland/xwayland-window.c
|
||||
+++ b/hw/xwayland/xwayland-window.c
|
||||
@@ -470,7 +470,8 @@ ensure_surface_for_window(WindowPtr window)
|
||||
}
|
||||
|
||||
wl_region_add(region, 0, 0,
|
||||
- window->drawable.width, window->drawable.height);
|
||||
+ xwl_scale_to(xwl_screen, window->drawable.width),
|
||||
+ xwl_scale_to(xwl_screen, window->drawable.height));
|
||||
wl_surface_set_opaque_region(xwl_window->surface, region);
|
||||
wl_region_destroy(region);
|
||||
}
|
||||
@@ -820,6 +821,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
|
||||
#endif
|
||||
|
||||
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
|
||||
+ wl_surface_set_buffer_scale(xwl_window->surface, xwl_screen->global_output_scale);
|
||||
|
||||
/* Arbitrary limit to try to avoid flooding the Wayland
|
||||
* connection. If we flood it too much anyway, this could
|
||||
|
12
nix/xwayland-vsync.patch
Normal file
12
nix/xwayland-vsync.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
--- a/hw/xwayland/xwayland-present.c
|
||||
+++ b/hw/xwayland/xwayland-present.c
|
||||
@@ -824,7 +824,8 @@
|
||||
dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);
|
||||
vblank->pixmap = NULL;
|
||||
|
||||
- if (xwl_present_queue_vblank(screen, window, vblank->crtc,
|
||||
+ if (vblank->target_msc > crtc_msc &&
|
||||
+ xwl_present_queue_vblank(screen, window, vblank->crtc,
|
||||
vblank->event_id, crtc_msc + 1)
|
||||
== Success)
|
||||
return;
|
@@ -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,23 +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)
|
||||
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;
|
||||
@@ -235,15 +263,10 @@ void CCompositor::cleanup() {
|
||||
|
||||
wl_display_terminate(m_sWLDisplay);
|
||||
|
||||
m_sWLDisplay = nullptr;
|
||||
m_bIsShuttingDown = true;
|
||||
|
||||
// kill the PID with a sigkill after 2 seconds
|
||||
const auto PID = getpid();
|
||||
|
||||
std::string call = "sleep 2 && kill -9 " + std::to_string(PID);
|
||||
|
||||
execl("/bin/sh", "/bin/sh", "-c", call.c_str(), ">", "/dev/null", nullptr); // this is to prevent that random "freezing"
|
||||
// the PID should not be reused.
|
||||
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() {
|
||||
@@ -881,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1249,6 +1295,7 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
|
||||
static auto *const PFULLSCREENALPHA = &g_pConfigManager->getConfigValuePtr("decoration:fullscreen_opacity")->floatValue;
|
||||
static auto *const PSHADOWCOL = &g_pConfigManager->getConfigValuePtr("decoration:col.shadow")->intValue;
|
||||
static auto *const PSHADOWCOLINACTIVE = &g_pConfigManager->getConfigValuePtr("decoration:col.shadow_inactive")->intValue;
|
||||
static auto *const PDIMSTRENGTH = &g_pConfigManager->getConfigValuePtr("decoration:dim_strength")->floatValue;
|
||||
|
||||
// border
|
||||
const auto RENDERDATA = g_pLayoutManager->getCurrentLayout()->requestRenderHints(pWindow);
|
||||
@@ -1277,6 +1324,13 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? pWindow->m_sSpecialRenderData.alphaInactive * *PINACTIVEALPHA : *PINACTIVEALPHA;
|
||||
}
|
||||
|
||||
// dim
|
||||
if (pWindow == m_pLastWindow) {
|
||||
pWindow->m_fDimPercent = 0;
|
||||
} else {
|
||||
pWindow->m_fDimPercent = *PDIMSTRENGTH;
|
||||
}
|
||||
|
||||
// shadow
|
||||
if (pWindow->m_iX11Type != 2 && !pWindow->m_bX11DoesntWantBorders) {
|
||||
if (pWindow == m_pLastWindow) {
|
||||
@@ -1299,6 +1353,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.
|
||||
@@ -1344,9 +1492,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();
|
||||
@@ -1371,6 +1525,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) {
|
||||
|
@@ -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
|
||||
|
||||
// ------------------------------------------------- //
|
||||
|
||||
@@ -145,6 +148,8 @@ public:
|
||||
void updateWindowAnimatedDecorationValues(CWindow*);
|
||||
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*);
|
||||
@@ -167,7 +172,9 @@ public:
|
||||
|
||||
private:
|
||||
void initAllSignals();
|
||||
void setRandomSplash();
|
||||
void setRandomSplash();
|
||||
|
||||
uint64_t m_iHyprlandPID = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -9,6 +9,7 @@ CWindow::CWindow() {
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_fActiveInactiveAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_cRealShadowColor.create(AVARTYPE_COLOR, g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), (void*)this, AVARDAMAGE_SHADOW);
|
||||
m_fDimPercent.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeDim"), (void*)this, AVARDAMAGE_ENTIRE);
|
||||
|
||||
m_dWindowDecorations.emplace_back(std::make_unique<CHyprDropShadowDecoration>(this)); // put the shadow so it's the first deco (has to be rendered first)
|
||||
}
|
||||
@@ -21,9 +22,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) {
|
||||
|
||||
@@ -216,4 +217,29 @@ void CWindow::moveToWorkspace(int workspaceID) {
|
||||
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;
|
||||
}
|
||||
|
||||
void CWindow::removeDecorationByType(eDecorationType type) {
|
||||
for (auto& wd : m_dWindowDecorations) {
|
||||
if (wd->getDecorationType() == type)
|
||||
m_vDecosToRemove.push_back(wd.get());
|
||||
}
|
||||
|
||||
updateWindowDecos();
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ struct SWindowAdditionalConfigData {
|
||||
int rounding = -1; // -1 means no
|
||||
bool forceNoBlur = false;
|
||||
bool forceOpaque = false;
|
||||
bool forceAllowsInput = false;
|
||||
};
|
||||
|
||||
class CWindow {
|
||||
@@ -118,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;
|
||||
|
||||
@@ -135,6 +139,9 @@ public:
|
||||
// animated shadow color
|
||||
CAnimatedVariable m_cRealShadowColor;
|
||||
|
||||
// animated tint
|
||||
CAnimatedVariable m_fDimPercent;
|
||||
|
||||
// for toplevel monitor events
|
||||
uint64_t m_iLastToplevelMonitorID = -1;
|
||||
uint64_t m_iLastSurfaceMonitorID = -1;
|
||||
@@ -150,9 +157,11 @@ public:
|
||||
void updateWindowDecos();
|
||||
pid_t getPID();
|
||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||
void removeDecorationByType(eDecorationType);
|
||||
void createToplevelHandle();
|
||||
void destroyToplevelHandle();
|
||||
void updateToplevel();
|
||||
void updateSurfaceOutputs();
|
||||
void moveToWorkspace(int);
|
||||
CWindow* X11TransientFor();
|
||||
};
|
||||
|
@@ -83,6 +83,8 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["decoration:shadow_offset"].strValue = "0 0";
|
||||
configValues["decoration:col.shadow"].intValue = 0xee1a1a1a;
|
||||
configValues["decoration:col.shadow_inactive"].intValue = INT_MAX;
|
||||
configValues["decoration:dim_inactive"].intValue = 0;
|
||||
configValues["decoration:dim_strength"].floatValue = 0.5f;
|
||||
|
||||
configValues["dwindle:pseudotile"].intValue = 0;
|
||||
configValues["dwindle:col.group_border"].intValue = 0x66777700;
|
||||
@@ -195,10 +197,12 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||
INITANIMCFG("fadeOut");
|
||||
INITANIMCFG("fadeSwitch");
|
||||
INITANIMCFG("fadeShadow");
|
||||
INITANIMCFG("fadeDim");
|
||||
|
||||
// border
|
||||
|
||||
// workspaces
|
||||
INITANIMCFG("specialWorkspace");
|
||||
}
|
||||
|
||||
// init the values
|
||||
@@ -225,6 +229,9 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||
CREATEANIMCFG("fadeOut", "fade");
|
||||
CREATEANIMCFG("fadeSwitch", "fade");
|
||||
CREATEANIMCFG("fadeShadow", "fade");
|
||||
CREATEANIMCFG("fadeDim", "fade");
|
||||
|
||||
CREATEANIMCFG("specialWorkspace", "workspaces");
|
||||
}
|
||||
|
||||
void CConfigManager::init() {
|
||||
@@ -739,6 +746,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
|
||||
@@ -931,7 +939,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;
|
||||
}
|
||||
|
||||
|
@@ -32,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
|
||||
|
@@ -759,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) {
|
||||
@@ -806,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,7 @@
|
||||
#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) {
|
||||
|
@@ -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);
|
||||
|
@@ -191,17 +191,17 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
|
||||
// if we have no tracking or full tracking, invalidate the entire monitor
|
||||
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || PMONITOR->forceFullFrames > 0 || damageBlinkCleanup > 0) {
|
||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x * 10, (int)PMONITOR->vecTransformedSize.y * 10); // wot?
|
||||
|
||||
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);
|
||||
@@ -241,7 +241,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
}
|
||||
|
||||
if (*PDAMAGEBLINK && damageBlinkCleanup == 0) {
|
||||
wlr_box monrect = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
||||
wlr_box monrect = {0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
|
||||
g_pHyprOpenGL->renderRect(&monrect, CColor(255,0,255,100), 0);
|
||||
damageBlinkCleanup = 1;
|
||||
} else if (*PDAMAGEBLINK) {
|
||||
|
@@ -18,17 +18,21 @@
|
||||
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) {
|
||||
if (curPopup == PPOPUP && PPOPUP->parentWindow) {
|
||||
px -= curPopup->popup->base->current.geometry.x;
|
||||
py -= curPopup->popup->base->current.geometry.y;
|
||||
}
|
||||
|
||||
if (curPopup->pSurfaceTree && curPopup->pSurfaceTree->pSurface && !curPopup->parentPopup && !curPopup->parentWindow) {
|
||||
const auto EXTENTSSURFACE = pixman_region32_extents(&curPopup->pSurfaceTree->pSurface->input_region);
|
||||
px -= EXTENTSSURFACE->x1;
|
||||
py -= EXTENTSSURFACE->y1;
|
||||
|
@@ -48,6 +48,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
static auto *const PINACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity")->floatValue;
|
||||
static auto *const PACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:active_opacity")->floatValue;
|
||||
static auto *const PDIMSTRENGTH = &g_pConfigManager->getConfigValuePtr("decoration:dim_strength")->floatValue;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||
const auto PWORKSPACE = PMONITOR->specialWorkspaceOpen ? g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
@@ -97,10 +98,12 @@ 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
|
||||
@@ -108,6 +111,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
std::string requestedWorkspace = "";
|
||||
bool workspaceSilent = 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) {
|
||||
@@ -156,6 +160,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));
|
||||
@@ -188,10 +194,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;
|
||||
}
|
||||
@@ -262,11 +272,22 @@ 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);
|
||||
} else
|
||||
PWINDOW->m_fDimPercent.setValueAndWarp(*PDIMSTRENGTH);
|
||||
} else {
|
||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PINACTIVEALPHA);
|
||||
PWINDOW->m_fDimPercent.setValueAndWarp(0);
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Window got assigned a surfaceTreeNode %x", PWINDOW->m_pSurfaceTree);
|
||||
|
||||
@@ -323,6 +344,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();
|
||||
|
||||
@@ -330,6 +355,14 @@ 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;
|
||||
@@ -370,7 +403,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;
|
||||
}
|
||||
@@ -388,22 +424,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
|
||||
auto PWINDOWCANDIDATE = g_pCompositor->vectorToWindowIdeal(PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f);
|
||||
// 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 (PWORKSPACE->m_bHasFullscreenWindow && (!PWINDOWCANDIDATE->m_bCreatedOverFullscreen || !PWINDOW->m_bIsFloating))
|
||||
PWINDOWCANDIDATE = g_pCompositor->getFullscreenWindowOnWorkspace(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;
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
@@ -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;
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
|
@@ -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,6 +236,8 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
}
|
||||
|
||||
if (force) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
|
||||
PWINDOW->m_vRealPosition.warp();
|
||||
PWINDOW->m_vRealSize.warp();
|
||||
|
||||
@@ -799,6 +803,7 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
|
||||
for (auto& pw : toAddWindows) {
|
||||
onWindowCreated(pw);
|
||||
pw->removeDecorationByType(DECORATION_GROUPBAR);
|
||||
}
|
||||
|
||||
recalculateMonitor(PWORKSPACE->m_iMonitorID);
|
||||
@@ -858,6 +863,9 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
|
||||
newGroupMembers[i]->pPreviousGroupMember = PREVMEMBER;
|
||||
newGroupMembers[i]->pNextGroupMember = NEXTMEMBER;
|
||||
|
||||
// add the deco
|
||||
newGroupMembers[i]->pWindow->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(newGroupMembers[i]->pWindow));
|
||||
}
|
||||
|
||||
// focus
|
||||
@@ -879,14 +887,15 @@ std::deque<CWindow*> CHyprDwindleLayout::getGroupMembers(CWindow* pWindow) {
|
||||
// get the node
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
|
||||
if (!PNODE)
|
||||
if (!PNODE || !PNODE->isGroupMember())
|
||||
return result; // reject with empty
|
||||
|
||||
SDwindleNodeData* current = PNODE->pNextGroupMember;
|
||||
const auto HEAD = PNODE->getGroupHead();
|
||||
SDwindleNodeData* current = HEAD->pNextGroupMember;
|
||||
|
||||
result.push_back(pWindow);
|
||||
result.push_back(HEAD->pWindow);
|
||||
|
||||
while (current != PNODE) {
|
||||
while (current != HEAD) {
|
||||
result.push_back(current->pWindow);
|
||||
current = current->pNextGroupMember;
|
||||
}
|
||||
@@ -935,6 +944,9 @@ void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward) {
|
||||
pNewNode->pWindow->m_vRealSize.warp();
|
||||
pNewNode->pWindow->m_vRealPosition.warp();
|
||||
}
|
||||
|
||||
pNewNode->pWindow->updateWindowDecos();
|
||||
PNODE->pWindow->updateWindowDecos();
|
||||
}
|
||||
|
||||
SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow) {
|
||||
|
@@ -273,6 +273,8 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
}
|
||||
|
||||
if (m_bForceWarps) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
|
||||
PWINDOW->m_vRealPosition.warp();
|
||||
PWINDOW->m_vRealSize.warp();
|
||||
|
||||
@@ -450,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);
|
||||
@@ -477,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;
|
||||
};
|
@@ -61,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();
|
||||
}
|
||||
@@ -125,6 +127,12 @@ void CKeybindManager::updateXKBTranslationState() {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -139,11 +147,16 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||
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(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) {
|
||||
@@ -216,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);
|
||||
|
||||
@@ -249,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)");
|
||||
|
||||
@@ -262,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()) {
|
||||
@@ -299,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;
|
||||
@@ -461,19 +480,27 @@ 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;
|
||||
if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
return;
|
||||
|
||||
if (ACTIVEWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) {
|
||||
moveActiveToWorkspace(std::to_string(g_pCompositor->getMonitorFromID(ACTIVEWINDOW->m_iMonitorID)->activeWorkspace));
|
||||
}
|
||||
PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(ACTIVEWINDOW);
|
||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,11 +523,15 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
// 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);
|
||||
@@ -536,7 +567,8 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
static auto *const PBACKANDFORTH = &g_pConfigManager->getConfigValuePtr("binds:workspace_back_and_forth")->intValue;
|
||||
if (*PBACKANDFORTH
|
||||
&& PCURRENTWORKSPACE->m_iID == workspaceToChangeTo
|
||||
&& PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1) {
|
||||
&& PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1
|
||||
&& !internal) {
|
||||
|
||||
workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID;
|
||||
isSwitchingToPrevious = true;
|
||||
@@ -551,13 +583,17 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
// 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)
|
||||
if (!isSwitchingToPrevious && !internal)
|
||||
// Remember previous workspace.
|
||||
PWORKSPACETOCHANGETO->m_iPrevWorkspaceID = g_pCompositor->m_pLastMonitor->activeWorkspace;
|
||||
|
||||
@@ -668,6 +704,9 @@ void CKeybindManager::fullscreenActive(std::string args) {
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return;
|
||||
|
||||
if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
return;
|
||||
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, !PWINDOW->m_bIsFullscreen, args == "1" ? FULLSCREEN_MAXIMIZED : FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
@@ -857,6 +896,7 @@ void CKeybindManager::moveFocusTo(std::string args) {
|
||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||
Vector2D middle = PWINDOWTOCHANGETO->m_vRealPosition.goalv() + PWINDOWTOCHANGETO->m_vRealSize.goalv() / 2.f;
|
||||
g_pCompositor->warpCursorTo(middle);
|
||||
g_pCompositor->m_pLastMonitor = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID); // update last monitor
|
||||
}
|
||||
};
|
||||
|
||||
@@ -972,45 +1012,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) {
|
||||
@@ -1385,16 +1392,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) {
|
||||
@@ -1429,3 +1482,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;
|
||||
|
||||
@@ -107,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;
|
||||
|
@@ -209,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);
|
||||
|
||||
@@ -224,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);
|
||||
|
||||
|
@@ -102,6 +102,7 @@ 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);
|
||||
|
@@ -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;
|
||||
|
@@ -165,6 +165,8 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.tint = glGetUniformLocation(prog, "tint");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBX);
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.program = prog;
|
||||
@@ -179,6 +181,8 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.tint = glGetUniformLocation(prog, "tint");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, TEXFRAGSRCEXT);
|
||||
m_RenderData.pCurrentMonData->m_shEXT.program = prog;
|
||||
@@ -193,6 +197,8 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shEXT.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.tint = glGetUniformLocation(prog, "tint");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, FRAGBLUR1);
|
||||
m_RenderData.pCurrentMonData->m_shBLUR1.program = prog;
|
||||
@@ -367,15 +373,17 @@ void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha
|
||||
void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool allowCustomUV) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
|
||||
renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, false, allowCustomUV);
|
||||
renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, false, allowCustomUV, true);
|
||||
|
||||
scissor((wlr_box*)nullptr);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool noAA, bool allowCustomUV) {
|
||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool noAA, bool allowCustomUV, bool allowDim) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||
|
||||
static auto *const PDIMINACTIVE = &g_pConfigManager->getConfigValuePtr("decoration:dim_inactive")->intValue;
|
||||
|
||||
// get transform
|
||||
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
||||
float matrix[9];
|
||||
@@ -433,6 +441,14 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
glUniform1f(shader->radius, round);
|
||||
glUniform1i(shader->primitiveMultisample, (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !noAA));
|
||||
|
||||
if (allowDim && m_pCurrentWindow && *PDIMINACTIVE && m_pCurrentWindow != g_pCompositor->m_pLastWindow) {
|
||||
glUniform1i(shader->applyTint, 1);
|
||||
const auto DIM = m_pCurrentWindow->m_fDimPercent.fl();
|
||||
glUniform3f(shader->tint, 1.f - DIM, 1.f - DIM, 1.f - DIM);
|
||||
} else {
|
||||
glUniform1i(shader->applyTint, 0);
|
||||
}
|
||||
|
||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
const float verts[] = {
|
||||
@@ -629,7 +645,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 +670,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);
|
||||
@@ -727,7 +743,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
|
||||
// draw window
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true);
|
||||
renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true, true);
|
||||
}
|
||||
|
||||
glStencilMask(-1);
|
||||
@@ -850,28 +866,22 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
|
||||
g_pConfigManager->setInt("decoration:blur", 0);
|
||||
|
||||
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL);
|
||||
|
||||
m_bEndFrame = true;
|
||||
|
||||
g_pConfigManager->setInt("decoration:blur", BLURVAL);
|
||||
|
||||
// render onto the window fb
|
||||
// we rendered onto the primary because it has a stencil, which we need for the borders etc
|
||||
const auto PFRAMEBUFFER = &m_mWindowFramebuffers[pWindow];
|
||||
|
||||
glViewport(0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y);
|
||||
|
||||
PFRAMEBUFFER->m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex;
|
||||
|
||||
PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
|
||||
PFRAMEBUFFER->bind();
|
||||
|
||||
clear(CColor(0, 0, 0, 0)); // JIC
|
||||
|
||||
wlr_box fullMonBox = {0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
|
||||
|
||||
renderTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex, &fullMonBox, 255.f, 0);
|
||||
m_bEndFrame = false;
|
||||
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL);
|
||||
|
||||
g_pConfigManager->setInt("decoration:blur", BLURVAL);
|
||||
|
||||
// restore original fb
|
||||
#ifndef GLES2
|
||||
@@ -954,8 +964,6 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
|
||||
// the originalClosedPos is relative to the monitor's pos
|
||||
Vector2D scaleXY = Vector2D((PMONITOR->scale * PWINDOW->m_vRealSize.vec().x / (PWINDOW->m_vOriginalClosedSize.x * PMONITOR->scale)), (PMONITOR->scale * PWINDOW->m_vRealSize.vec().y / (PWINDOW->m_vOriginalClosedSize.y * PMONITOR->scale)));
|
||||
|
||||
// TODO: this is wrong on scaled.
|
||||
|
||||
windowBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x;
|
||||
windowBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y;
|
||||
windowBox.x = ((PWINDOW->m_vRealPosition.vec().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x);
|
||||
@@ -964,8 +972,12 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
|
||||
pixman_region32_t fakeDamage;
|
||||
pixman_region32_init_rect(&fakeDamage, 0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y);
|
||||
|
||||
m_bEndFrame = true;
|
||||
|
||||
renderTextureInternalWithDamage(it->second.m_cTex, &windowBox, PWINDOW->m_fAlpha.fl(), &fakeDamage, 0);
|
||||
|
||||
m_bEndFrame = false;
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
|
||||
static auto *const PDAMAGEMON = &g_pConfigManager->getConfigValuePtr("misc:damage_entire_on_snapshot")->intValue;
|
||||
|
@@ -134,7 +134,7 @@ private:
|
||||
// returns the out FB, can be either Mirror or MirrorSwap
|
||||
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
||||
|
||||
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowCustomUV = false);
|
||||
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowCustomUV = false, bool allowDim = false);
|
||||
|
||||
void renderSplash(cairo_t *const, cairo_surface_t *const);
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
@@ -49,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) {
|
||||
@@ -213,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)
|
||||
@@ -232,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) {
|
||||
@@ -281,13 +238,16 @@ 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) {
|
||||
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
|
||||
@@ -442,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;
|
||||
@@ -737,7 +763,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
||||
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);
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -29,6 +29,9 @@ public:
|
||||
GLint range;
|
||||
GLint shadowPower;
|
||||
|
||||
GLint applyTint;
|
||||
GLint tint;
|
||||
|
||||
GLint getUniformLocation(const std::string&);
|
||||
|
||||
private:
|
||||
|
@@ -3,7 +3,6 @@
|
||||
|
||||
CHyprGroupBarDecoration::CHyprGroupBarDecoration(CWindow* pWindow) {
|
||||
m_pWindow = pWindow;
|
||||
updateWindow(pWindow);
|
||||
}
|
||||
|
||||
CHyprGroupBarDecoration::~CHyprGroupBarDecoration() {
|
||||
|
@@ -205,6 +205,9 @@ uniform float radius;
|
||||
|
||||
uniform int discardOpaque;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
@@ -217,6 +220,12 @@ void main() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||
@@ -238,6 +247,9 @@ uniform float radius;
|
||||
|
||||
uniform int discardOpaque;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
@@ -249,10 +261,17 @@ void main() {
|
||||
}
|
||||
|
||||
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||
R"#(
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
@@ -319,6 +338,9 @@ uniform float radius;
|
||||
|
||||
uniform int discardOpaque;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
@@ -331,9 +353,16 @@ void main() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||
R"#(
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
|
Reference in New Issue
Block a user