mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-07-27 18:21:54 -07:00
Compare commits
69 Commits
v0.12.0bet
...
v0.13.1bet
Author | SHA1 | Date | |
---|---|---|---|
|
928158bbfb | ||
|
bacfae3084 | ||
|
0d95a0174c | ||
|
0eb5ecafb9 | ||
|
49a55f136e | ||
|
64be57b780 | ||
|
6e195a6b8c | ||
|
8d3f6c5d84 | ||
|
5c470d2e54 | ||
|
26910a8b63 | ||
|
44a2d755c6 | ||
|
cf5426f2d8 | ||
|
1d631c8a23 | ||
|
789eedd115 | ||
|
4a8274e5f0 | ||
|
4b7d28d2cb | ||
|
5fdd1dd60f | ||
|
e71a4d75de | ||
|
f002bd1603 | ||
|
16f1d1b99b | ||
|
c1bc8d46e9 | ||
|
94ca386a8c | ||
|
2ba7cb2414 | ||
|
5b5f36f494 | ||
|
a74b8033ca | ||
|
41883e0522 | ||
|
3ea89e6171 | ||
|
d6c06318af | ||
|
cb839c9dcc | ||
|
3dd514a452 | ||
|
6afab12b91 | ||
|
7a3b57c99c | ||
|
ba0c5fe0bb | ||
|
f6ecef0959 | ||
|
ff26531e11 | ||
|
fbd2b4799d | ||
|
1664f81cae | ||
|
c425e620af | ||
|
f4add0ac6d | ||
|
3c3f80c2fe | ||
|
eee0cad4d0 | ||
|
0ea96e87c0 | ||
|
5d09bb647b | ||
|
f5697095bc | ||
|
56203b1757 | ||
|
c0a7dffcdc | ||
|
8581e71789 | ||
|
bb90ff0461 | ||
|
1d4d2f4793 | ||
|
7f62cbc48a | ||
|
f2d84a7e3a | ||
|
095185cfe7 | ||
|
f77fac9df9 | ||
|
dacaf72e02 | ||
|
0ad261aa9c | ||
|
7610c20761 | ||
|
4103bca056 | ||
|
21a1b62b6a | ||
|
7f483dfdb0 | ||
|
1cf46fd6a2 | ||
|
eb658dcb61 | ||
|
195ec2b092 | ||
|
dd6aba07e9 | ||
|
d35d949bc5 | ||
|
48eb2e0d6f | ||
|
179562b646 | ||
|
20c050e890 | ||
|
bdd20c401d | ||
|
6865660e51 |
2
.github/workflows/man-update.yaml
vendored
2
.github/workflows/man-update.yaml
vendored
@@ -5,6 +5,8 @@ on:
|
||||
push:
|
||||
paths:
|
||||
- docs/**
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
jobs:
|
||||
main:
|
||||
|
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
|
||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1660908602,
|
||||
"narHash": "sha256-SwZ85IPWvC4NxxFhWhRMTJpApSHbY1u4YK2UFWEBWvY=",
|
||||
"lastModified": 1661931183,
|
||||
"narHash": "sha256-0+2KzcexiJCB3Il5t7cZAM2RXNRfm5/gMCwhcZJxLuQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "495b19d5b3e62b4ec7e846bdfb6ef3d9c3b83492",
|
||||
"rev": "97747d3209efde533f7b1b28f1be11619f556a06",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -26,11 +26,11 @@
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"host": "gitlab.freedesktop.org",
|
||||
"lastModified": 1660930713,
|
||||
"narHash": "sha256-bY7q1NqG/sjCUAWPn/Ne9NCigLlPlH5Lk1WCMqv3rTU=",
|
||||
"lastModified": 1661882030,
|
||||
"narHash": "sha256-Kw0MG4rXdTnbndVLLCNwkXDmNszwdQZmm7pwI1R3Kds=",
|
||||
"owner": "wlroots",
|
||||
"repo": "wlroots",
|
||||
"rev": "7c575922c05e4d5fd9a403c2aa631a54c7531d44",
|
||||
"rev": "fd0b0276c9ecc159549acff48b932b83ec3b4f12",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
12
flake.nix
12
flake.nix
@@ -28,16 +28,18 @@
|
||||
]);
|
||||
in {
|
||||
overlays.default = _: prev: rec {
|
||||
wlroots-hyprland = prev.wlroots.overrideAttrs (__: {
|
||||
version = mkDate (inputs.wlroots.lastModifiedDate or "19700101");
|
||||
wlroots-hyprland = prev.callPackage ./nix/wlroots.nix {
|
||||
version = mkDate (inputs.wlroots.lastModifiedDate or "19700101") + "_" + (inputs.wlroots.shortRev or "dirty");
|
||||
src = inputs.wlroots;
|
||||
});
|
||||
};
|
||||
hyprland = prev.callPackage ./nix/default.nix {
|
||||
stdenv = prev.gcc12Stdenv;
|
||||
version = "0.11.1beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
version = "0.12.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"];
|
||||
});
|
||||
@@ -63,8 +65,6 @@
|
||||
|
||||
nixosModules.default = import ./nix/module.nix self;
|
||||
homeManagerModules.default = import ./nix/hm-module.nix self;
|
||||
|
||||
overlay = throw "Hyprland: .overlay output is deprecated, please use the .overlays.default output";
|
||||
};
|
||||
|
||||
nixConfig = {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
project('Hyprland', 'cpp', 'c',
|
||||
version : '0.11.1beta',
|
||||
version : '0.12.1beta',
|
||||
default_options : [
|
||||
'warning_level=2',
|
||||
'default_library=static',
|
||||
|
148
nix/default.nix
148
nix/default.nix
@@ -2,6 +2,7 @@
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
fetchpatch,
|
||||
pkg-config,
|
||||
meson,
|
||||
ninja,
|
||||
@@ -21,78 +22,85 @@
|
||||
xwayland,
|
||||
debug ? false,
|
||||
enableXWayland ? true,
|
||||
hidpiXWayland ? true,
|
||||
legacyRenderer ? false,
|
||||
nvidiaPatches ? 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) "-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
|
||||
}: 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
|
||||
(wlroots.override {inherit enableXWayland hidpiXWayland nvidiaPatches;})
|
||||
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";
|
||||
};
|
||||
}
|
||||
|
@@ -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,39 @@ 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;
|
||||
|
||||
home.sessionVariables = {
|
||||
CLUTTER_BACKEND = "wayland";
|
||||
GDK_BACKEND = "wayland";
|
||||
_JAVA_AWT_WM_NONREPARENTING = "1";
|
||||
MOZ_ENABLE_WAYLAND = "1";
|
||||
NIXOS_OZONE_WL = "1";
|
||||
QT_QPA_PLATFORM = "wayland;xcb";
|
||||
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
|
||||
XCURSOR_SIZE = toString config.home.pointerCursor.size or "24";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
};
|
||||
|
||||
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=${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
|
||||
|
@@ -8,6 +8,10 @@ self: {
|
||||
with lib; let
|
||||
cfg = config.programs.hyprland;
|
||||
in {
|
||||
imports = [
|
||||
(mkRemovedOptionModule ["programs" "hyprland" "extraPackages"] "extraPackages has been removed. Use environment.systemPackages instead.")
|
||||
];
|
||||
|
||||
options.programs.hyprland = {
|
||||
enable = mkEnableOption ''
|
||||
Hyprland, the dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
|
||||
@@ -26,21 +30,34 @@ in {
|
||||
Hyprland package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule ["programs" "hyprland" "extraPackages"] "extraPackages has been removed. Use environment.systemPackages instead.")
|
||||
];
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = lib.optional (cfg.package != null) cfg.package;
|
||||
security.polkit.enable = true;
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
environment = {
|
||||
systemPackages = lib.optional (cfg.package != null) cfg.package;
|
||||
sessionVariables = {
|
||||
CLUTTER_BACKEND = lib.mkDefault "wayland";
|
||||
GDK_BACKEND = lib.mkDefault "wayland";
|
||||
_JAVA_AWT_WM_NONREPARENTING = lib.mkDefault "1";
|
||||
MOZ_ENABLE_WAYLAND = lib.mkDefault "1";
|
||||
NIXOS_OZONE_WL = lib.mkDefault "1";
|
||||
QT_QPA_PLATFORM = lib.mkDefault "wayland;xcb";
|
||||
QT_WAYLAND_DISABLE_WINDOWDECORATION = lib.mkDefault "1";
|
||||
XCURSOR_SIZE = lib.mkDefault "24";
|
||||
XDG_SESSION_TYPE = lib.mkDefault "wayland";
|
||||
};
|
||||
};
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
programs.dconf.enable = mkDefault true;
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
programs = {
|
||||
dconf.enable = mkDefault true;
|
||||
xwayland.enable = mkDefault true;
|
||||
};
|
||||
security.polkit.enable = true;
|
||||
services.xserver.displayManager.sessionPackages = lib.optional (cfg.package != null) cfg.package;
|
||||
programs.xwayland.enable = mkDefault true;
|
||||
xdg.portal.enable = mkDefault true;
|
||||
xdg.portal.extraPortals = [pkgs.xdg-desktop-portal-wlr];
|
||||
xdg.portal = {
|
||||
enable = mkDefault true;
|
||||
extraPortals = [pkgs.xdg-desktop-portal-wlr];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
64
nix/wlroots.nix
Normal file
64
nix/wlroots.nix
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
version,
|
||||
src,
|
||||
#
|
||||
wlroots,
|
||||
xwayland,
|
||||
fetchpatch,
|
||||
lib,
|
||||
hidpiXWayland ? true,
|
||||
enableXWayland ? true,
|
||||
nvidiaPatches ? false,
|
||||
}:
|
||||
assert (lib.assertMsg (hidpiXWayland -> enableXWayland) ''
|
||||
wlroots-hyprland: cannot have hidpiXWayland when enableXWayland is false.
|
||||
'');
|
||||
(wlroots.overrideAttrs
|
||||
(old: {
|
||||
inherit version src;
|
||||
pname =
|
||||
old.pname
|
||||
+ "-hyprland"
|
||||
+ (
|
||||
if hidpiXWayland
|
||||
then "-hidpi"
|
||||
else ""
|
||||
)
|
||||
+ (
|
||||
if nvidiaPatches
|
||||
then "-nvidia"
|
||||
else ""
|
||||
);
|
||||
patches =
|
||||
(old.patches or [])
|
||||
++ (lib.optionals (enableXWayland && hidpiXWayland) [
|
||||
(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;
|
||||
})
|
||||
]);
|
||||
postPatch =
|
||||
(old.postPatch or "")
|
||||
+ (
|
||||
if nvidiaPatches
|
||||
then ''
|
||||
substituteInPlace render/gles2/renderer.c --replace "glFlush();" "glFinish();"
|
||||
''
|
||||
else ""
|
||||
);
|
||||
}))
|
||||
.override {
|
||||
xwayland = xwayland.overrideAttrs (old: {
|
||||
patches =
|
||||
(old.patches or [])
|
||||
++ (lib.optionals hidpiXWayland [
|
||||
./xwayland-vsync.patch
|
||||
./xwayland-hidpi.patch
|
||||
]);
|
||||
});
|
||||
}
|
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;
|
@@ -237,7 +237,8 @@ void CCompositor::cleanup() {
|
||||
|
||||
// accumulate all PIDs for killing, also request closing.
|
||||
for (auto& w : m_vWindows) {
|
||||
m_dProcessPIDsOnShutdown.push_back(w->getPID());
|
||||
if (w->m_bIsMapped || !w->m_bIsX11)
|
||||
m_dProcessPIDsOnShutdown.push_back(w->getPID());
|
||||
|
||||
closeWindow(w.get());
|
||||
}
|
||||
@@ -1295,6 +1296,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);
|
||||
@@ -1323,6 +1325,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) {
|
||||
@@ -1684,6 +1693,10 @@ void CCompositor::warpCursorTo(const Vector2D& pos) {
|
||||
return;
|
||||
|
||||
wlr_cursor_warp(m_sWLRCursor, m_sSeat.mouse->mouse, pos.x, pos.y);
|
||||
|
||||
const auto PMONITORNEW = getMonitorFromVector(pos);
|
||||
if (PMONITORNEW != m_pLastMonitor)
|
||||
m_pLastMonitor = PMONITORNEW;
|
||||
}
|
||||
|
||||
SLayerSurface* CCompositor::getLayerSurfaceFromWlr(wlr_layer_surface_v1* pLS) {
|
||||
@@ -1763,4 +1776,15 @@ void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) {
|
||||
g_pXWaylandManager->setWindowSize(w.get(), w->m_vRealSize.vec(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CCompositor::cursorOnReservedArea() {
|
||||
const auto PMONITOR = getMonitorFromCursor();
|
||||
|
||||
const auto XY1 = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
||||
const auto XY2 = PMONITOR->vecPosition + PMONITOR->vecSize - PMONITOR->vecReservedBottomRight;
|
||||
|
||||
const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal();
|
||||
|
||||
return !VECINRECT(CURSORPOS, XY1.x, XY1.y, XY2.x, XY2.y);
|
||||
}
|
||||
|
@@ -164,6 +164,7 @@ public:
|
||||
void closeWindow(CWindow*);
|
||||
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
||||
void forceReportSizesToWindowsOnWorkspace(const int&);
|
||||
bool cursorOnReservedArea();
|
||||
|
||||
|
||||
std::string explicitConfigPath;
|
||||
|
@@ -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)
|
||||
}
|
||||
@@ -227,9 +228,21 @@ CWindow* CWindow::X11TransientFor() {
|
||||
|
||||
auto PPARENT = g_pCompositor->getWindowFromSurface(m_uSurface.xwayland->parent->surface);
|
||||
|
||||
while (PPARENT->m_uSurface.xwayland->parent) {
|
||||
while (g_pCompositor->windowValidMapped(PPARENT) && PPARENT->m_uSurface.xwayland->parent) {
|
||||
PPARENT = g_pCompositor->getWindowFromSurface(PPARENT->m_uSurface.xwayland->parent->surface);
|
||||
}
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PPARENT))
|
||||
return nullptr;
|
||||
|
||||
return PPARENT;
|
||||
}
|
||||
|
||||
void CWindow::removeDecorationByType(eDecorationType type) {
|
||||
for (auto& wd : m_dWindowDecorations) {
|
||||
if (wd->getDecorationType() == type)
|
||||
m_vDecosToRemove.push_back(wd.get());
|
||||
}
|
||||
|
||||
updateWindowDecos();
|
||||
}
|
||||
|
@@ -139,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;
|
||||
@@ -154,6 +157,7 @@ public:
|
||||
void updateWindowDecos();
|
||||
pid_t getPID();
|
||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||
void removeDecorationByType(eDecorationType);
|
||||
void createToplevelHandle();
|
||||
void destroyToplevelHandle();
|
||||
void updateToplevel();
|
||||
|
@@ -65,7 +65,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["debug:disable_logs"].intValue = 0;
|
||||
configValues["debug:disable_time"].intValue = 1;
|
||||
|
||||
configValues["decoration:rounding"].intValue = 1;
|
||||
configValues["decoration:rounding"].intValue = 0;
|
||||
configValues["decoration:blur"].intValue = 1;
|
||||
configValues["decoration:blur_size"].intValue = 8;
|
||||
configValues["decoration:blur_passes"].intValue = 1;
|
||||
@@ -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,6 +197,7 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||
INITANIMCFG("fadeOut");
|
||||
INITANIMCFG("fadeSwitch");
|
||||
INITANIMCFG("fadeShadow");
|
||||
INITANIMCFG("fadeDim");
|
||||
|
||||
// border
|
||||
|
||||
@@ -226,6 +229,7 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||
CREATEANIMCFG("fadeOut", "fade");
|
||||
CREATEANIMCFG("fadeSwitch", "fade");
|
||||
CREATEANIMCFG("fadeShadow", "fade");
|
||||
CREATEANIMCFG("fadeDim", "fade");
|
||||
|
||||
CREATEANIMCFG("specialWorkspace", "workspaces");
|
||||
}
|
||||
@@ -721,17 +725,8 @@ void CConfigManager::handleUnbind(const std::string& command, const std::string&
|
||||
g_pKeybindManager->removeKeybind(MOD, KEY);
|
||||
}
|
||||
|
||||
void CConfigManager::handleWindowRule(const std::string& command, const std::string& value) {
|
||||
const auto RULE = value.substr(0, value.find_first_of(","));
|
||||
const auto VALUE = value.substr(value.find_first_of(",") + 1);
|
||||
|
||||
// check rule and value
|
||||
if (RULE == "" || VALUE == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
// verify we support a rule
|
||||
if (RULE != "float"
|
||||
bool windowRuleValid(const std::string& RULE) {
|
||||
return !(RULE != "float"
|
||||
&& RULE != "tile"
|
||||
&& RULE.find("opacity") != 0
|
||||
&& RULE.find("move") != 0
|
||||
@@ -746,14 +741,90 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str
|
||||
&& RULE != "fullscreen"
|
||||
&& RULE.find("animation") != 0
|
||||
&& RULE.find("rounding") != 0
|
||||
&& RULE.find("workspace") != 0) {
|
||||
Debug::log(ERR, "Invalid rule found: %s", RULE.c_str());
|
||||
parseError = "Invalid rule found: " + RULE;
|
||||
return;
|
||||
}
|
||||
&& RULE.find("workspace") != 0);
|
||||
}
|
||||
|
||||
void CConfigManager::handleWindowRule(const std::string& command, const std::string& value) {
|
||||
const auto RULE = value.substr(0, value.find_first_of(","));
|
||||
const auto VALUE = value.substr(value.find_first_of(",") + 1);
|
||||
|
||||
// check rule and value
|
||||
if (RULE == "" || VALUE == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
// verify we support a rule
|
||||
if (!windowRuleValid(RULE)) {
|
||||
Debug::log(ERR, "Invalid rule found: %s", RULE.c_str());
|
||||
parseError = "Invalid rule found: " + RULE;
|
||||
return;
|
||||
}
|
||||
|
||||
m_dWindowRules.push_back({RULE, VALUE});
|
||||
}
|
||||
|
||||
void CConfigManager::handleWindowRuleV2(const std::string& command, const std::string& value) {
|
||||
const auto RULE = value.substr(0, value.find_first_of(","));
|
||||
const auto VALUE = value.substr(value.find_first_of(",") + 1);
|
||||
|
||||
if (!windowRuleValid(RULE)) {
|
||||
Debug::log(ERR, "Invalid rulev2 found: %s", RULE.c_str());
|
||||
parseError = "Invalid rulev2 found: " + RULE;
|
||||
return;
|
||||
}
|
||||
|
||||
// now we estract shit from the value
|
||||
SWindowRule rule;
|
||||
rule.v2 = true;
|
||||
rule.szRule = RULE;
|
||||
rule.szValue = VALUE;
|
||||
|
||||
const auto TITLEPOS = VALUE.find("title:");
|
||||
const auto CLASSPOS = VALUE.find("class:");
|
||||
const auto X11POS = VALUE.find("xwayland:");
|
||||
const auto FLOATPOS = VALUE.find("floating:");
|
||||
|
||||
if (TITLEPOS == std::string::npos && CLASSPOS == std::string::npos && X11POS == std::string::npos && FLOATPOS == std::string::npos) {
|
||||
Debug::log(ERR, "Invalid rulev2 syntax: %s", VALUE.c_str());
|
||||
parseError = "Invalid rulev2 syntax: " + VALUE;
|
||||
return;
|
||||
}
|
||||
|
||||
auto extract = [&](size_t pos) -> std::string {
|
||||
std::string result;
|
||||
result = VALUE.substr(pos);
|
||||
|
||||
size_t min = 999999;
|
||||
if (TITLEPOS > pos && TITLEPOS < min) min = TITLEPOS;
|
||||
if (CLASSPOS > pos && CLASSPOS < min) min = CLASSPOS;
|
||||
if (X11POS > pos && X11POS < min) min = X11POS;
|
||||
if (FLOATPOS > pos && FLOATPOS < min) min = FLOATPOS;
|
||||
|
||||
result = result.substr(0, min - pos);
|
||||
|
||||
if (result.back() == ',')
|
||||
result.pop_back();
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
if (CLASSPOS != std::string::npos) {
|
||||
rule.szClass = extract(CLASSPOS + 6);
|
||||
}
|
||||
|
||||
if (TITLEPOS != std::string::npos) {
|
||||
rule.szTitle = extract(TITLEPOS + 6);
|
||||
}
|
||||
|
||||
if (X11POS != std::string::npos) {
|
||||
rule.bX11 = extract(X11POS + 9) == "1" ? 1 : 0;
|
||||
}
|
||||
|
||||
if (FLOATPOS != std::string::npos) {
|
||||
rule.bFloating = extract(FLOATPOS + 9) == "1" ? 1 : 0;
|
||||
}
|
||||
|
||||
m_dWindowRules.push_back(rule);
|
||||
}
|
||||
|
||||
void CConfigManager::handleBlurLS(const std::string& command, const std::string& value) {
|
||||
@@ -862,6 +933,7 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
||||
else if (COMMAND == "unbind") handleUnbind(COMMAND, VALUE);
|
||||
else if (COMMAND == "workspace") handleDefaultWorkspace(COMMAND, VALUE);
|
||||
else if (COMMAND == "windowrule") handleWindowRule(COMMAND, VALUE);
|
||||
else if (COMMAND == "windowrulev2") handleWindowRuleV2(COMMAND, VALUE);
|
||||
else if (COMMAND == "bezier") handleBezier(COMMAND, VALUE);
|
||||
else if (COMMAND == "animation") handleAnimation(COMMAND, VALUE);
|
||||
else if (COMMAND == "source") handleSource(COMMAND, VALUE);
|
||||
@@ -1100,13 +1172,13 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
// update layout
|
||||
g_pLayoutManager->switchToLayout(configValues["general:layout"].strValue);
|
||||
|
||||
// mark blur dirty
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
// mark blur dirty
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(m.get());
|
||||
|
||||
// Force the compositor to fully re-render all monitors
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
// Force the compositor to fully re-render all monitors
|
||||
m->forceFullFrames = 2;
|
||||
}
|
||||
|
||||
// Reset no monitor reload
|
||||
m_bNoMonitorReload = false;
|
||||
@@ -1275,22 +1347,53 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow) {
|
||||
|
||||
for (auto& rule : m_dWindowRules) {
|
||||
// check if we have a matching rule
|
||||
try {
|
||||
if (rule.szValue.find("title:") == 0) {
|
||||
// we have a title rule.
|
||||
std::regex RULECHECK(rule.szValue.substr(6));
|
||||
if (!rule.v2) {
|
||||
try {
|
||||
if (rule.szValue.find("title:") == 0) {
|
||||
// we have a title rule.
|
||||
std::regex RULECHECK(rule.szValue.substr(6));
|
||||
|
||||
if (!std::regex_search(title, RULECHECK))
|
||||
continue;
|
||||
} else {
|
||||
std::regex classCheck(rule.szValue);
|
||||
if (!std::regex_search(title, RULECHECK))
|
||||
continue;
|
||||
} else {
|
||||
std::regex classCheck(rule.szValue);
|
||||
|
||||
if (!std::regex_search(appidclass, classCheck))
|
||||
continue;
|
||||
if (!std::regex_search(appidclass, classCheck))
|
||||
continue;
|
||||
}
|
||||
} catch (...) {
|
||||
Debug::log(ERR, "Regex error at %s", rule.szValue.c_str());
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (rule.szClass != "") {
|
||||
std::regex RULECHECK(rule.szClass);
|
||||
|
||||
if (!std::regex_search(appidclass, RULECHECK))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rule.szTitle != "") {
|
||||
std::regex RULECHECK(rule.szTitle);
|
||||
|
||||
if (!std::regex_search(title, RULECHECK))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rule.bX11 != -1) {
|
||||
if (pWindow->m_bIsX11 != rule.bX11)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rule.bFloating != -1) {
|
||||
if (pWindow->m_bIsFloating != rule.bFloating)
|
||||
continue;
|
||||
}
|
||||
} catch (...) {
|
||||
Debug::log(ERR, "Regex error at %s", rule.szValue.c_str());
|
||||
continue;
|
||||
}
|
||||
} catch (...) {
|
||||
Debug::log(ERR, "Regex error at %s", rule.szValue.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// applies. Read the rule and behave accordingly
|
||||
@@ -1334,6 +1437,8 @@ void CConfigManager::performMonitorReload() {
|
||||
overAgain = true;
|
||||
break;
|
||||
}
|
||||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(m->ID);
|
||||
}
|
||||
|
||||
if (overAgain)
|
||||
|
@@ -48,6 +48,12 @@ struct SMonitorAdditionalReservedArea {
|
||||
struct SWindowRule {
|
||||
std::string szRule;
|
||||
std::string szValue;
|
||||
|
||||
bool v2 = false;
|
||||
std::string szTitle;
|
||||
std::string szClass;
|
||||
int bX11 = -1; // -1 means "ANY"
|
||||
int bFloating = -1;
|
||||
};
|
||||
|
||||
struct SAnimationPropertyConfig {
|
||||
@@ -151,6 +157,7 @@ private:
|
||||
void handleBind(const std::string&, const std::string&);
|
||||
void handleUnbind(const std::string&, const std::string&);
|
||||
void handleWindowRule(const std::string&, const std::string&);
|
||||
void handleWindowRuleV2(const std::string&, const std::string&);
|
||||
void handleDefaultWorkspace(const std::string&, const std::string&);
|
||||
void handleBezier(const std::string&, const std::string&);
|
||||
void handleAnimation(const std::string&, const std::string&);
|
||||
|
@@ -124,19 +124,25 @@ std::string workspacesRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
result += "[";
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
const auto PLASTW = w->getLastFocusedWindow();
|
||||
|
||||
result += getFormat(
|
||||
R"#({
|
||||
"id": %i,
|
||||
"name": "%s",
|
||||
"monitor": "%s",
|
||||
"windows": %i,
|
||||
"hasfullscreen": %s
|
||||
"hasfullscreen": %s,
|
||||
"lastwindow": "0x%x",
|
||||
"lastwindowtitle": "%s"
|
||||
},)#",
|
||||
w->m_iID,
|
||||
escapeJSONStrings(w->m_szName).c_str(),
|
||||
escapeJSONStrings(g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName).c_str(),
|
||||
g_pCompositor->getWindowsOnWorkspace(w->m_iID),
|
||||
((int)w->m_bHasFullscreenWindow == 1 ? "true" : "false")
|
||||
((int)w->m_bHasFullscreenWindow == 1 ? "true" : "false"),
|
||||
PLASTW,
|
||||
PLASTW ? escapeJSONStrings(PLASTW->m_szTitle).c_str() : ""
|
||||
);
|
||||
}
|
||||
|
||||
@@ -146,8 +152,9 @@ R"#({
|
||||
result += "]";
|
||||
} else {
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
result += getFormat("workspace ID %i (%s) on monitor %s:\n\twindows: %i\n\thasfullscreen: %i\n\n",
|
||||
w->m_iID, w->m_szName.c_str(), g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName.c_str(), g_pCompositor->getWindowsOnWorkspace(w->m_iID), (int)w->m_bHasFullscreenWindow);
|
||||
const auto PLASTW = w->getLastFocusedWindow();
|
||||
result += getFormat("workspace ID %i (%s) on monitor %s:\n\twindows: %i\n\thasfullscreen: %i\n\tlastwindow: 0x%x\n\tlastwindowtitle: %s\n\n",
|
||||
w->m_iID, w->m_szName.c_str(), g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName.c_str(), g_pCompositor->getWindowsOnWorkspace(w->m_iID), (int)w->m_bHasFullscreenWindow, PLASTW, PLASTW ? PLASTW->m_szTitle.c_str() : "");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@@ -158,7 +158,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
||||
|
||||
Debug::log(LOG, "LayerSurface %x unmapped", layersurface->layerSurface);
|
||||
|
||||
if (!g_pCompositor->getMonitorFromID(layersurface->monitorID)) {
|
||||
if (!g_pCompositor->getMonitorFromID(layersurface->monitorID) || g_pCompositor->m_bUnsafeState) {
|
||||
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
|
||||
|
||||
g_pCompositor->addToFadingOutSafe(layersurface);
|
||||
|
@@ -124,6 +124,9 @@ void Events::listener_startDrag(wl_listener* listener, void* data) {
|
||||
void Events::listener_destroyDrag(void* owner, void* data) {
|
||||
Debug::log(LOG, "Drag destroyed.");
|
||||
|
||||
if (g_pInputManager->m_sDrag.drag && g_pInputManager->m_sDrag.dragIcon && g_pInputManager->m_sDrag.dragIcon->surface)
|
||||
g_pHyprRenderer->damageBox(g_pInputManager->m_sDrag.pos.x - 2, g_pInputManager->m_sDrag.pos.y - 2, g_pInputManager->m_sDrag.dragIcon->surface->current.width + 4, g_pInputManager->m_sDrag.dragIcon->surface->current.height + 4);
|
||||
|
||||
g_pInputManager->m_sDrag.drag = nullptr;
|
||||
g_pInputManager->m_sDrag.dragIcon = nullptr;
|
||||
g_pInputManager->m_sDrag.hyprListener_destroy.removeCallback();
|
||||
|
@@ -191,7 +191,7 @@ 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 {
|
||||
@@ -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) {
|
||||
|
@@ -32,6 +32,12 @@ void addPopupGlobalCoords(void* pPopup, int* x, int* y) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (curPopup->parentPopup) {
|
||||
curPopup = curPopup->parentPopup;
|
||||
} else {
|
||||
|
@@ -48,8 +48,9 @@ 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 PMONITOR = g_pCompositor->m_pLastMonitor;
|
||||
const auto PWORKSPACE = PMONITOR->specialWorkspaceOpen ? g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
PWINDOW->m_bMappedX11 = true;
|
||||
@@ -282,8 +283,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
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);
|
||||
|
||||
@@ -316,6 +320,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
if (workspaceSilent) {
|
||||
// move the window
|
||||
const auto OLDWORKSPACE = PWINDOW->m_iWorkspaceID;
|
||||
|
||||
if (g_pCompositor->m_pLastWindow == PWINDOW) {
|
||||
if (requestedWorkspace != "special")
|
||||
g_pKeybindManager->m_mDispatchers["movetoworkspacesilent"](requestedWorkspace);
|
||||
@@ -324,6 +330,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
} else {
|
||||
Debug::log(ERR, "Tried to set workspace silent rule to a nofocus window!");
|
||||
}
|
||||
|
||||
g_pCompositor->forceReportSizesToWindowsOnWorkspace(OLDWORKSPACE);
|
||||
}
|
||||
|
||||
if (requestsFullscreen) {
|
||||
@@ -394,6 +402,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
if (PWINDOW->m_bIsFullscreen) {
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL, false);
|
||||
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||
g_pCompositor->forceReportSizesToWindowsOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
}
|
||||
|
||||
// Allow the renderer to catch the last frame.
|
||||
|
@@ -90,8 +90,6 @@ void CMonitor::onConnect(bool noRule) {
|
||||
wlr_xcursor_manager_load(g_pCompositor->m_sWLRXCursorMgr, monitorRule.scale);
|
||||
wlr_output_set_transform(output, WL_OUTPUT_TRANSFORM_NORMAL); // TODO: support other transforms
|
||||
|
||||
wlr_output_enable_adaptive_sync(output, 1);
|
||||
|
||||
// create it in the arr
|
||||
vecPosition = monitorRule.offset;
|
||||
vecSize = monitorRule.resolution;
|
||||
|
@@ -119,4 +119,11 @@ void CWorkspace::moveToMonitor(const int& id) {
|
||||
wlr_ext_workspace_handle_v1_set_urgent(m_pWlrHandle, false);
|
||||
|
||||
wlr_ext_workspace_handle_v1_set_name(m_pWlrHandle, m_szName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
CWindow* CWorkspace::getLastFocusedWindow() {
|
||||
if (!g_pCompositor->windowValidMapped(m_pLastFocusedWindow) || m_pLastFocusedWindow->m_iWorkspaceID != m_iID)
|
||||
return nullptr;
|
||||
|
||||
return m_pLastFocusedWindow;
|
||||
}
|
||||
|
@@ -8,6 +8,8 @@ enum eFullscreenMode : uint8_t {
|
||||
FULLSCREEN_MAXIMIZED
|
||||
};
|
||||
|
||||
class CWindow;
|
||||
|
||||
class CWorkspace {
|
||||
public:
|
||||
CWorkspace(int monitorID, std::string name, bool special = false);
|
||||
@@ -36,6 +38,9 @@ public:
|
||||
// "scratchpad"
|
||||
bool m_bIsSpecialWorkspace = false;
|
||||
|
||||
// last window
|
||||
CWindow* m_pLastFocusedWindow = nullptr;
|
||||
|
||||
// user-set
|
||||
bool m_bDefaultFloating = false;
|
||||
bool m_bDefaultPseudo = false;
|
||||
@@ -44,4 +49,6 @@ public:
|
||||
void setActive(bool on);
|
||||
|
||||
void moveToMonitor(const int&);
|
||||
|
||||
CWindow* getLastFocusedWindow();
|
||||
};
|
@@ -90,6 +90,19 @@ void SDwindleNodeData::setGroupFocusedNode(SDwindleNodeData* pMember) {
|
||||
this->pWindow->m_bHidden = pMember != this;
|
||||
}
|
||||
|
||||
int SDwindleNodeData::getGroupMemberCount() {
|
||||
SDwindleNodeData* current = this->pNextGroupMember;
|
||||
|
||||
int no = 1;
|
||||
|
||||
while (current != this) {
|
||||
current = current->pNextGroupMember;
|
||||
no++;
|
||||
}
|
||||
|
||||
return no;
|
||||
}
|
||||
|
||||
int CHyprDwindleLayout::getNodesOnWorkspace(const int& id) {
|
||||
int no = 0;
|
||||
for (auto& n : m_lDwindleNodesData) {
|
||||
@@ -153,14 +166,15 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
const bool DISPLAYTOP = STICKS(pNode->position.y, PMONITOR->vecPosition.y + PMONITOR->vecReservedTopLeft.y);
|
||||
const bool DISPLAYBOTTOM = STICKS(pNode->position.y + pNode->size.y, PMONITOR->vecPosition.y + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y);
|
||||
|
||||
const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size");
|
||||
const auto GAPSIN = g_pConfigManager->getInt("general:gaps_in");
|
||||
const auto GAPSOUT = g_pConfigManager->getInt("general:gaps_out");
|
||||
const auto PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
const auto PGAPSIN = &g_pConfigManager->getConfigValuePtr("general:gaps_in")->intValue;
|
||||
const auto PGAPSOUT = &g_pConfigManager->getConfigValuePtr("general:gaps_out")->intValue;
|
||||
|
||||
const auto PWINDOW = pNode->pWindow;
|
||||
|
||||
if (!g_pCompositor->windowExists(PWINDOW) || !PWINDOW->m_bIsMapped) {
|
||||
Debug::log(ERR, "Node %x holding invalid window %x!!", pNode, PWINDOW);
|
||||
onWindowRemovedTiling(PWINDOW);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -169,12 +183,14 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
|
||||
static auto *const PNOGAPSWHENONLY = &g_pConfigManager->getConfigValuePtr("dwindle:no_gaps_when_only")->intValue;
|
||||
|
||||
auto calcPos = PWINDOW->m_vPosition + Vector2D(BORDERSIZE, BORDERSIZE);
|
||||
auto calcSize = PWINDOW->m_vSize - Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE);
|
||||
auto calcPos = PWINDOW->m_vPosition + Vector2D(*PBORDERSIZE, *PBORDERSIZE);
|
||||
auto calcSize = PWINDOW->m_vSize - Vector2D(2 * *PBORDERSIZE, 2 * *PBORDERSIZE);
|
||||
|
||||
if (*PNOGAPSWHENONLY && PWINDOW->m_iWorkspaceID != SPECIAL_WORKSPACE_ID && getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1) {
|
||||
PWINDOW->m_vRealPosition = calcPos - Vector2D(BORDERSIZE, BORDERSIZE);
|
||||
PWINDOW->m_vRealSize = calcSize + Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE);
|
||||
const auto NODESONWORKSPACE = getNodesOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
|
||||
if (*PNOGAPSWHENONLY && PWINDOW->m_iWorkspaceID != SPECIAL_WORKSPACE_ID && (NODESONWORKSPACE == 1 || (pNode->isGroupMember() && pNode->getGroupMemberCount() == NODESONWORKSPACE))) {
|
||||
PWINDOW->m_vRealPosition = calcPos - Vector2D(*PBORDERSIZE, *PBORDERSIZE);
|
||||
PWINDOW->m_vRealSize = calcSize + Vector2D(2 * *PBORDERSIZE, 2 * *PBORDERSIZE);
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
|
||||
@@ -187,11 +203,11 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
PWINDOW->m_sSpecialRenderData.rounding = true;
|
||||
PWINDOW->m_sSpecialRenderData.border = true;
|
||||
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? GAPSOUT : GAPSIN,
|
||||
DISPLAYTOP ? GAPSOUT : GAPSIN);
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? *PGAPSOUT : *PGAPSIN,
|
||||
DISPLAYTOP ? *PGAPSOUT : *PGAPSIN);
|
||||
|
||||
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? GAPSOUT : GAPSIN,
|
||||
DISPLAYBOTTOM ? GAPSOUT : GAPSIN);
|
||||
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? *PGAPSOUT : *PGAPSIN,
|
||||
DISPLAYBOTTOM ? *PGAPSOUT : *PGAPSIN);
|
||||
|
||||
calcPos = calcPos + OFFSETTOPLEFT;
|
||||
calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT;
|
||||
@@ -340,6 +356,8 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
|
||||
applyNodeDataToWindow(PNODE);
|
||||
|
||||
pWindow->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -355,19 +373,19 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
NEWPARENT->pParent = OPENINGON->pParent;
|
||||
NEWPARENT->isNode = true; // it is a node
|
||||
|
||||
const auto WIDTHMULTIPLIER = g_pConfigManager->getFloat("dwindle:split_width_multiplier");
|
||||
const auto PWIDTHMULTIPLIER = &g_pConfigManager->getConfigValuePtr("dwindle:split_width_multiplier")->floatValue;
|
||||
|
||||
// if cursor over first child, make it first, etc
|
||||
const auto SIDEBYSIDE = NEWPARENT->size.x > NEWPARENT->size.y * WIDTHMULTIPLIER;
|
||||
const auto SIDEBYSIDE = NEWPARENT->size.x > NEWPARENT->size.y * *PWIDTHMULTIPLIER;
|
||||
NEWPARENT->splitTop = !SIDEBYSIDE;
|
||||
|
||||
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
|
||||
|
||||
const auto FORCESPLIT = g_pConfigManager->getInt("dwindle:force_split");
|
||||
const auto PFORCESPLIT = &g_pConfigManager->getConfigValuePtr("dwindle:force_split")->intValue;
|
||||
|
||||
if (FORCESPLIT == 0) {
|
||||
if ((SIDEBYSIDE && VECINRECT(MOUSECOORDS, NEWPARENT->position.x, NEWPARENT->position.y / WIDTHMULTIPLIER, NEWPARENT->position.x + NEWPARENT->size.x / 2.f, NEWPARENT->position.y + NEWPARENT->size.y))
|
||||
|| (!SIDEBYSIDE && VECINRECT(MOUSECOORDS, NEWPARENT->position.x, NEWPARENT->position.y / WIDTHMULTIPLIER, NEWPARENT->position.x + NEWPARENT->size.x, NEWPARENT->position.y + NEWPARENT->size.y / 2.f))) {
|
||||
if (*PFORCESPLIT == 0) {
|
||||
if ((SIDEBYSIDE && VECINRECT(MOUSECOORDS, NEWPARENT->position.x, NEWPARENT->position.y / *PWIDTHMULTIPLIER, NEWPARENT->position.x + NEWPARENT->size.x / 2.f, NEWPARENT->position.y + NEWPARENT->size.y))
|
||||
|| (!SIDEBYSIDE && VECINRECT(MOUSECOORDS, NEWPARENT->position.x, NEWPARENT->position.y / *PWIDTHMULTIPLIER, NEWPARENT->position.x + NEWPARENT->size.x, NEWPARENT->position.y + NEWPARENT->size.y / 2.f))) {
|
||||
// we are hovering over the first node, make PNODE first.
|
||||
NEWPARENT->children[1] = OPENINGON;
|
||||
NEWPARENT->children[0] = PNODE;
|
||||
@@ -377,7 +395,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
NEWPARENT->children[1] = PNODE;
|
||||
}
|
||||
} else {
|
||||
if (FORCESPLIT == 1) {
|
||||
if (*PFORCESPLIT == 1) {
|
||||
NEWPARENT->children[1] = OPENINGON;
|
||||
NEWPARENT->children[0] = PNODE;
|
||||
} else {
|
||||
@@ -398,7 +416,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
// Update the children
|
||||
|
||||
|
||||
if (NEWPARENT->size.x * WIDTHMULTIPLIER > NEWPARENT->size.y) {
|
||||
if (NEWPARENT->size.x * *PWIDTHMULTIPLIER > NEWPARENT->size.y) {
|
||||
// split left/right
|
||||
OPENINGON->position = NEWPARENT->position;
|
||||
OPENINGON->size = Vector2D(NEWPARENT->size.x / 2.f, NEWPARENT->size.y);
|
||||
@@ -453,21 +471,25 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
|
||||
PNEXT->position = PNODE->position;
|
||||
PNEXT->size = PNODE->size;
|
||||
|
||||
applyNodeDataToWindow(PNEXT);
|
||||
} else {
|
||||
const auto PHEAD = PNODE->getGroupHead();
|
||||
|
||||
PNEXT->position = PHEAD->position;
|
||||
PNEXT->size = PHEAD->size;
|
||||
|
||||
applyNodeDataToWindow(PNEXT);
|
||||
}
|
||||
|
||||
PNEXT->setGroupFocusedNode(PNEXT);
|
||||
PNEXT->pWindow->m_bHidden = false;
|
||||
|
||||
m_lDwindleNodesData.remove(*PNODE);
|
||||
|
||||
applyNodeDataToWindow(PNEXT);
|
||||
|
||||
if (!PNEXT->isGroupMember()) {
|
||||
// means we dissolved the group
|
||||
recalculateMonitor(PNEXT->pWindow->m_iMonitorID);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -803,6 +825,7 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
|
||||
for (auto& pw : toAddWindows) {
|
||||
onWindowCreated(pw);
|
||||
pw->removeDecorationByType(DECORATION_GROUPBAR);
|
||||
}
|
||||
|
||||
recalculateMonitor(PWORKSPACE->m_iMonitorID);
|
||||
@@ -862,10 +885,16 @@ 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
|
||||
PNODE->setGroupFocusedNode(PNODE);
|
||||
|
||||
// required for no_gaps_when_only to work
|
||||
applyNodeDataToWindow(PNODE);
|
||||
}
|
||||
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
@@ -883,14 +912,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;
|
||||
}
|
||||
@@ -939,6 +969,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) {
|
||||
@@ -946,6 +979,9 @@ SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow
|
||||
|
||||
SWindowRenderLayoutHints hints;
|
||||
|
||||
static auto *const PGROUPCOLACTIVE = &g_pConfigManager->getConfigValuePtr("dwindle:col.group_border_active")->intValue;
|
||||
static auto *const PGROUPCOLINACTIVE = &g_pConfigManager->getConfigValuePtr("dwindle:col.group_border")->intValue;
|
||||
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
if (!PNODE)
|
||||
return hints; // left for the future, maybe floating funkiness
|
||||
@@ -954,9 +990,9 @@ SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow
|
||||
hints.isBorderColor = true;
|
||||
|
||||
if (pWindow == g_pCompositor->m_pLastWindow)
|
||||
hints.borderColor = CColor(g_pConfigManager->getInt("dwindle:col.group_border_active"));
|
||||
hints.borderColor = CColor(*PGROUPCOLACTIVE);
|
||||
else
|
||||
hints.borderColor = CColor(g_pConfigManager->getInt("dwindle:col.group_border"));
|
||||
hints.borderColor = CColor(*PGROUPCOLINACTIVE);
|
||||
}
|
||||
|
||||
return hints;
|
||||
|
@@ -41,6 +41,7 @@ struct SDwindleNodeData {
|
||||
bool isGroupMember();
|
||||
SDwindleNodeData* getGroupHead();
|
||||
SDwindleNodeData* getGroupVisible();
|
||||
int getGroupMemberCount();
|
||||
void setGroupFocusedNode(SDwindleNodeData*);
|
||||
CHyprDwindleLayout* layout = nullptr;
|
||||
};
|
||||
|
@@ -215,9 +215,9 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
const bool DISPLAYTOP = STICKS(pNode->position.y, PMONITOR->vecPosition.y + PMONITOR->vecReservedTopLeft.y);
|
||||
const bool DISPLAYBOTTOM = STICKS(pNode->position.y + pNode->size.y, PMONITOR->vecPosition.y + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y);
|
||||
|
||||
const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size");
|
||||
const auto GAPSIN = g_pConfigManager->getInt("general:gaps_in");
|
||||
const auto GAPSOUT = g_pConfigManager->getInt("general:gaps_out");
|
||||
const auto PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
const auto PGAPSIN = &g_pConfigManager->getConfigValuePtr("general:gaps_in")->intValue;
|
||||
const auto PGAPSOUT = &g_pConfigManager->getConfigValuePtr("general:gaps_out")->intValue;
|
||||
|
||||
const auto PWINDOW = pNode->pWindow;
|
||||
|
||||
@@ -231,12 +231,12 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
PWINDOW->m_vSize = pNode->size;
|
||||
PWINDOW->m_vPosition = pNode->position;
|
||||
|
||||
auto calcPos = PWINDOW->m_vPosition + Vector2D(BORDERSIZE, BORDERSIZE);
|
||||
auto calcSize = PWINDOW->m_vSize - Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE);
|
||||
auto calcPos = PWINDOW->m_vPosition + Vector2D(*PBORDERSIZE, *PBORDERSIZE);
|
||||
auto calcSize = PWINDOW->m_vSize - Vector2D(2 * *PBORDERSIZE, 2 * *PBORDERSIZE);
|
||||
|
||||
if (*PNOGAPSWHENONLY && PWINDOW->m_iWorkspaceID != SPECIAL_WORKSPACE_ID && getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1) {
|
||||
PWINDOW->m_vRealPosition = calcPos - Vector2D(BORDERSIZE, BORDERSIZE);
|
||||
PWINDOW->m_vRealSize = calcSize + Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE);
|
||||
PWINDOW->m_vRealPosition = calcPos - Vector2D(*PBORDERSIZE, *PBORDERSIZE);
|
||||
PWINDOW->m_vRealSize = calcSize + Vector2D(2 * *PBORDERSIZE, 2 * *PBORDERSIZE);
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
|
||||
@@ -249,11 +249,11 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
PWINDOW->m_sSpecialRenderData.rounding = true;
|
||||
PWINDOW->m_sSpecialRenderData.border = true;
|
||||
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? GAPSOUT : GAPSIN,
|
||||
DISPLAYTOP ? GAPSOUT : GAPSIN);
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? *PGAPSOUT : *PGAPSIN,
|
||||
DISPLAYTOP ? *PGAPSOUT : *PGAPSIN);
|
||||
|
||||
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? GAPSOUT : GAPSIN,
|
||||
DISPLAYBOTTOM ? GAPSOUT : GAPSIN);
|
||||
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? *PGAPSOUT : *PGAPSIN,
|
||||
DISPLAYBOTTOM ? *PGAPSOUT : *PGAPSIN);
|
||||
|
||||
calcPos = calcPos + OFFSETTOPLEFT;
|
||||
calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT;
|
||||
|
@@ -7,6 +7,7 @@ CKeybindManager::CKeybindManager() {
|
||||
|
||||
m_mDispatchers["exec"] = spawn;
|
||||
m_mDispatchers["killactive"] = killActive;
|
||||
m_mDispatchers["closewindow"] = kill;
|
||||
m_mDispatchers["togglefloating"] = toggleActiveFloating;
|
||||
m_mDispatchers["workspace"] = changeworkspace;
|
||||
m_mDispatchers["fullscreen"] = fullscreenActive;
|
||||
@@ -475,6 +476,17 @@ void CKeybindManager::killActive(std::string args) {
|
||||
g_pCompositor->closeWindow(g_pCompositor->m_pLastWindow);
|
||||
}
|
||||
|
||||
void CKeybindManager::kill(std::string args) {
|
||||
const auto PWINDOW = g_pCompositor->getWindowByRegex(args);
|
||||
|
||||
if (!PWINDOW) {
|
||||
Debug::log(ERR, "kill: no window found");
|
||||
return;
|
||||
}
|
||||
|
||||
g_pCompositor->closeWindow(PWINDOW);
|
||||
}
|
||||
|
||||
void CKeybindManager::clearKeybinds() {
|
||||
m_lKeybinds.clear();
|
||||
}
|
||||
@@ -495,11 +507,10 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
|
||||
// remove drag status
|
||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||
|
||||
PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating;
|
||||
if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
return;
|
||||
|
||||
if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PWINDOW == g_pCompositor->m_pLastWindow) {
|
||||
moveActiveToWorkspace(std::to_string(g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeWorkspace));
|
||||
}
|
||||
PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW);
|
||||
}
|
||||
@@ -566,10 +577,7 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(
|
||||
g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
static auto *const PBACKANDFORTH = &g_pConfigManager->getConfigValuePtr("binds:workspace_back_and_forth")->intValue;
|
||||
if (*PBACKANDFORTH
|
||||
&& PCURRENTWORKSPACE->m_iID == workspaceToChangeTo
|
||||
&& PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1
|
||||
&& !internal) {
|
||||
if (*PBACKANDFORTH && PCURRENTWORKSPACE->m_iID == workspaceToChangeTo && PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1 && !internal) {
|
||||
|
||||
workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID;
|
||||
isSwitchingToPrevious = true;
|
||||
@@ -625,7 +633,8 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
}
|
||||
|
||||
// If the monitor is not the one our cursor's at, warp to it.
|
||||
if (PMONITOR != g_pCompositor->getMonitorFromCursor()) {
|
||||
const bool anotherMonitor = PMONITOR != g_pCompositor->getMonitorFromCursor();
|
||||
if (anotherMonitor) {
|
||||
Vector2D middle = PMONITOR->vecPosition + PMONITOR->vecSize / 2.f;
|
||||
g_pCompositor->warpCursorTo(middle);
|
||||
}
|
||||
@@ -640,7 +649,20 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
Debug::log(LOG, "Changed to workspace %i", workspaceToChangeTo);
|
||||
|
||||
// focus
|
||||
g_pInputManager->refocus();
|
||||
if (const auto PWINDOW = PWORKSPACETOCHANGETO->getLastFocusedWindow(); PWINDOW) {
|
||||
// warp and focus
|
||||
if (anotherMonitor)
|
||||
g_pCompositor->warpCursorTo(PWINDOW->m_vRealPosition.vec() + PWINDOW->m_vRealSize.vec() / 2.f);
|
||||
|
||||
g_pCompositor->focusWindow(PWINDOW, g_pXWaylandManager->getWindowSurface(PWINDOW));
|
||||
|
||||
if (g_pCompositor->cursorOnReservedArea()) // fix focus on bars etc
|
||||
g_pInputManager->refocus();
|
||||
} else if (g_pCompositor->getWindowsOnWorkspace(PWORKSPACETOCHANGETO->m_iID) > 0)
|
||||
g_pInputManager->refocus();
|
||||
|
||||
// set the new monitor as the last (no warps would bug otherwise)
|
||||
g_pCompositor->m_pLastMonitor = g_pCompositor->getMonitorFromID(PWORKSPACETOCHANGETO->m_iMonitorID);
|
||||
|
||||
// mark the monitor dirty
|
||||
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||
@@ -705,6 +727,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);
|
||||
}
|
||||
|
||||
@@ -894,6 +919,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
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1116,18 +1142,7 @@ void CKeybindManager::exitHyprland(std::string argz) {
|
||||
}
|
||||
|
||||
void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
|
||||
try {
|
||||
if (!isNumber(args) && !isDirection(args)) {
|
||||
PMONITOR = g_pCompositor->getMonitorFromName(args);
|
||||
} else {
|
||||
PMONITOR = isDirection(args) ? g_pCompositor->getMonitorInDirection(args[0]) : g_pCompositor->getMonitorFromID(std::stoi(args));
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(LOG, "moveCurrentWorkspaceToMonitor: caught exception in monitor", e.what());
|
||||
return;
|
||||
}
|
||||
CMonitor* PMONITOR = g_pCompositor->getMonitorFromString(args);
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
@@ -1148,19 +1163,7 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
||||
std::string workspace = args.substr(0, args.find_first_of(' '));
|
||||
std::string monitor = args.substr(args.find_first_of(' ') + 1);
|
||||
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
|
||||
try {
|
||||
if (!isNumber(monitor) && !isDirection(monitor)) {
|
||||
PMONITOR = g_pCompositor->getMonitorFromName(monitor);
|
||||
} else {
|
||||
PMONITOR = isDirection(monitor) ? g_pCompositor->getMonitorInDirection(monitor[0]) : g_pCompositor->getMonitorFromID(std::stoi(monitor));
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(LOG, "moveWorkspaceToMonitor: caught exception in monitor", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromString(monitor);
|
||||
|
||||
if (!PMONITOR){
|
||||
Debug::log(ERR, "Ignoring moveWorkspaceToMonitor: monitor doesnt exist");
|
||||
@@ -1215,6 +1218,11 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
||||
g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID)->startAnim(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto PWINDOW = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace)->getLastFocusedWindow(); PWINDOW)
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
else
|
||||
g_pInputManager->refocus();
|
||||
} else {
|
||||
auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID);
|
||||
|
||||
@@ -1228,9 +1236,12 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
||||
|
||||
PSPECIALWORKSPACE->startAnim(true, true);
|
||||
PSPECIALWORKSPACE->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID;
|
||||
}
|
||||
|
||||
g_pInputManager->refocus();
|
||||
if (const auto PWINDOW = PSPECIALWORKSPACE->getLastFocusedWindow(); PWINDOW)
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
else
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
}
|
||||
|
||||
void CKeybindManager::forceRendererReload(std::string args) {
|
||||
@@ -1343,8 +1354,6 @@ void CKeybindManager::focusWindow(std::string regexp) {
|
||||
|
||||
Debug::log(LOG, "Focusing to window name: %s", PWINDOW->m_szTitle.c_str());
|
||||
|
||||
changeworkspace("[internal]" + std::to_string(PWINDOW->m_iWorkspaceID));
|
||||
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
|
||||
const auto MIDPOINT = PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f;
|
||||
@@ -1356,6 +1365,7 @@ void CKeybindManager::setSubmap(std::string submap) {
|
||||
if (submap == "reset" || submap == "") {
|
||||
m_szCurrentSelectedSubmap = "";
|
||||
Debug::log(LOG, "Reset active submap to the default one.");
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"submap", ""});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1363,6 +1373,7 @@ void CKeybindManager::setSubmap(std::string submap) {
|
||||
if (k.submap == submap) {
|
||||
m_szCurrentSelectedSubmap = submap;
|
||||
Debug::log(LOG, "Changed keybind submap to %s", submap.c_str());
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"submap", submap});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -78,6 +78,7 @@ private:
|
||||
|
||||
// -------------- Dispatchers -------------- //
|
||||
static void killActive(std::string);
|
||||
static void kill(std::string);
|
||||
static void spawn(std::string);
|
||||
static void toggleActiveFloating(std::string);
|
||||
static void toggleActivePseudo(std::string);
|
||||
|
@@ -32,9 +32,12 @@ wlr_surface* CHyprXWaylandManager::getWindowSurface(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate) {
|
||||
if (!pSurface)
|
||||
return;
|
||||
|
||||
if (wlr_surface_is_xdg_surface(pSurface)) {
|
||||
const auto PSURF = wlr_xdg_surface_from_wlr_surface(pSurface);
|
||||
if (PSURF->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
||||
if (PSURF && PSURF->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
||||
wlr_xdg_toplevel_set_activated(PSURF->toplevel, activate);
|
||||
}
|
||||
} else if (wlr_surface_is_xwayland_surface(pSurface)) {
|
||||
@@ -59,6 +62,8 @@ void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
|
||||
|
||||
g_pCompositor->m_pLastFocus = getWindowSurface(pWindow);
|
||||
g_pCompositor->m_pLastWindow = pWindow;
|
||||
|
||||
g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_pLastFocusedWindow = pWindow;
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::getGeometryForWindow(CWindow* pWindow, wlr_box* pbox) {
|
||||
|
@@ -2,16 +2,18 @@
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
void CInputManager::onMouseMoved(wlr_pointer_motion_event* e) {
|
||||
float sensitivity = g_pConfigManager->getFloat("general:sensitivity");
|
||||
static auto *const PSENS = &g_pConfigManager->getConfigValuePtr("general:sensitivity")->floatValue;
|
||||
static auto *const PNOACCEL = &g_pConfigManager->getConfigValuePtr("input:force_no_accel")->intValue;
|
||||
static auto* const PSENSTORAW = &g_pConfigManager->getConfigValuePtr("general:apply_sens_to_raw")->intValue;
|
||||
|
||||
const auto DELTA = g_pConfigManager->getInt("input:force_no_accel") == 1 ? Vector2D(e->unaccel_dx, e->unaccel_dy) : Vector2D(e->delta_x, e->delta_y);
|
||||
const auto DELTA = *PNOACCEL == 1 ? Vector2D(e->unaccel_dx, e->unaccel_dy) : Vector2D(e->delta_x, e->delta_y);
|
||||
|
||||
if (g_pConfigManager->getInt("general:apply_sens_to_raw") == 1)
|
||||
wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x * sensitivity, DELTA.y * sensitivity, e->unaccel_dx * sensitivity, e->unaccel_dy * sensitivity);
|
||||
if (*PSENSTORAW == 1)
|
||||
wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x * *PSENS, DELTA.y * *PSENS, e->unaccel_dx * *PSENS, e->unaccel_dy * *PSENS);
|
||||
else
|
||||
wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x, DELTA.y, e->unaccel_dx, e->unaccel_dy);
|
||||
|
||||
wlr_cursor_move(g_pCompositor->m_sWLRCursor, &e->pointer->base, DELTA.x * sensitivity, DELTA.y * sensitivity);
|
||||
wlr_cursor_move(g_pCompositor->m_sWLRCursor, &e->pointer->base, DELTA.x * *PSENS, DELTA.y * *PSENS);
|
||||
|
||||
mouseMoveUnified(e->time_msec);
|
||||
|
||||
@@ -142,6 +144,13 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !foundSurface && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) {
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
|
||||
if (!pFoundWindow) {
|
||||
// what the fuck, somehow happens occasionally??
|
||||
PWORKSPACE->m_bHasFullscreenWindow = false;
|
||||
return;
|
||||
}
|
||||
|
||||
foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow);
|
||||
surfacePos = pFoundWindow->m_vRealPosition.vec();
|
||||
|
||||
@@ -267,9 +276,11 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
}
|
||||
|
||||
if (pFoundWindow == g_pCompositor->m_pLastWindow && foundSurface != g_pCompositor->m_pLastFocus) {
|
||||
// we changed the subsurface
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
if (pFoundWindow == g_pCompositor->m_pLastWindow) {
|
||||
if (foundSurface != g_pCompositor->m_pLastFocus || m_bLastFocusOnLS) {
|
||||
// ^^^ changed the subsurface ^^^ came back from a LS
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
}
|
||||
}
|
||||
|
||||
if (*PFOLLOWONDND && m_sDrag.dragIcon) {
|
||||
@@ -277,16 +288,22 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
}
|
||||
|
||||
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
|
||||
m_bLastFocusOnLS = false;
|
||||
return; // don't enter any new surfaces
|
||||
} else {
|
||||
if ((*PFOLLOWMOUSE != 3 && allowKeyboardRefocus) || refocus)
|
||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||
}
|
||||
|
||||
m_bLastFocusOnLS = false;
|
||||
} else {
|
||||
if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive && *PFOLLOWMOUSE != 3 && allowKeyboardRefocus) {
|
||||
g_pCompositor->focusSurface(foundSurface);
|
||||
g_pCompositor->m_pLastWindow = nullptr; // reset last window as we have a full focus on a LS
|
||||
}
|
||||
|
||||
if (pFoundLayerSurface)
|
||||
m_bLastFocusOnLS = true;
|
||||
}
|
||||
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
@@ -367,6 +384,7 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
|
||||
|
||||
// notify the keybind manager
|
||||
static auto *const PPASSMOUSE = &g_pConfigManager->getConfigValuePtr("binds:pass_mouse_when_bound")->intValue;
|
||||
static auto *const PMAINMODINTERNAL = &g_pConfigManager->getConfigValuePtr("general:main_mod_internal")->intValue;
|
||||
const auto PASS = g_pKeybindManager->onMouseEvent(e);
|
||||
|
||||
if (!PASS && !*PPASSMOUSE)
|
||||
@@ -381,7 +399,7 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
|
||||
if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_bIsFloating)
|
||||
g_pCompositor->moveWindowToTop(g_pCompositor->m_pLastWindow);
|
||||
|
||||
if ((e->button == BTN_LEFT || e->button == BTN_RIGHT) && wlr_keyboard_get_modifiers(PKEYBOARD) == (uint32_t)g_pConfigManager->getInt("general:main_mod_internal")) {
|
||||
if ((e->button == BTN_LEFT || e->button == BTN_RIGHT) && wlr_keyboard_get_modifiers(PKEYBOARD) == (uint32_t)*PMAINMODINTERNAL) {
|
||||
currentlyDraggedWindow = g_pCompositor->windowFromCursor();
|
||||
dragButton = e->button;
|
||||
|
||||
@@ -783,12 +801,17 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
|
||||
void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
||||
const auto PIMEGRAB = m_sIMERelay.getIMEKeyboardGrab(pKeyboard);
|
||||
|
||||
const auto ALLMODS = accumulateModsFromAllKBs();
|
||||
|
||||
auto MODS = wlr_keyboard_from_input_device(pKeyboard->keyboard)->modifiers;
|
||||
MODS.depressed = ALLMODS;
|
||||
|
||||
if (PIMEGRAB && PIMEGRAB->pWlrKbGrab && PIMEGRAB->pWlrKbGrab->input_method) {
|
||||
wlr_input_method_keyboard_grab_v2_set_keyboard(PIMEGRAB->pWlrKbGrab, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_input_method_keyboard_grab_v2_send_modifiers(PIMEGRAB->pWlrKbGrab, &wlr_keyboard_from_input_device(pKeyboard->keyboard)->modifiers);
|
||||
wlr_input_method_keyboard_grab_v2_send_modifiers(PIMEGRAB->pWlrKbGrab, &MODS);
|
||||
} else {
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &wlr_keyboard_from_input_device(pKeyboard->keyboard)->modifiers);
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &MODS);
|
||||
}
|
||||
|
||||
const auto PWLRKB = wlr_keyboard_from_input_device(pKeyboard->keyboard);
|
||||
@@ -900,11 +923,7 @@ void CInputManager::unconstrainMouse() {
|
||||
const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
|
||||
|
||||
if (CONSTRAINTWINDOW) {
|
||||
if (CONSTRAINTWINDOW->m_bIsX11) {
|
||||
wlr_xwayland_surface_activate(CONSTRAINTWINDOW->m_uSurface.xwayland, false);
|
||||
} else {
|
||||
wlr_xdg_toplevel_set_activated(CONSTRAINTWINDOW->m_uSurface.xdg->toplevel, false);
|
||||
}
|
||||
g_pXWaylandManager->activateSurface(g_pXWaylandManager->getWindowSurface(CONSTRAINTWINDOW), false);
|
||||
}
|
||||
|
||||
wlr_pointer_constraint_v1_send_deactivated(g_pCompositor->m_sSeat.mouse->currentConstraint);
|
||||
@@ -945,6 +964,9 @@ uint32_t CInputManager::accumulateModsFromAllKBs() {
|
||||
uint32_t finalMask = 0;
|
||||
|
||||
for (auto& kb : m_lKeyboards) {
|
||||
if (kb.isVirtual)
|
||||
continue;
|
||||
|
||||
finalMask |= wlr_keyboard_get_modifiers(wlr_keyboard_from_input_device(kb.keyboard));
|
||||
}
|
||||
|
||||
|
@@ -105,6 +105,9 @@ private:
|
||||
bool m_bEmptyFocusCursorSet = false;
|
||||
Vector2D m_vLastCursorPosFloored = Vector2D();
|
||||
|
||||
// for some bugs in follow mouse 0
|
||||
bool m_bLastFocusOnLS = false;
|
||||
|
||||
void processMouseDownNormal(wlr_pointer_button_event* e);
|
||||
void processMouseDownKill(wlr_pointer_button_event* e);
|
||||
|
||||
|
@@ -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;
|
||||
@@ -262,7 +268,7 @@ void CHyprOpenGLImpl::clear(const CColor& color) {
|
||||
scissor((wlr_box*)nullptr);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::scissor(const wlr_box* pBox) {
|
||||
void CHyprOpenGLImpl::scissor(const wlr_box* pBox, bool transform) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to scissor without begin()!");
|
||||
|
||||
if (!pBox) {
|
||||
@@ -272,17 +278,19 @@ void CHyprOpenGLImpl::scissor(const wlr_box* pBox) {
|
||||
|
||||
wlr_box newBox = *pBox;
|
||||
|
||||
int w, h;
|
||||
wlr_output_transformed_resolution(m_RenderData.pMonitor->output, &w, &h);
|
||||
if (transform) {
|
||||
int w, h;
|
||||
wlr_output_transformed_resolution(m_RenderData.pMonitor->output, &w, &h);
|
||||
|
||||
const auto TR = wlr_output_transform_invert(m_RenderData.pMonitor->transform);
|
||||
wlr_box_transform(&newBox, &newBox, TR, w, h);
|
||||
const auto TR = wlr_output_transform_invert(m_RenderData.pMonitor->transform);
|
||||
wlr_box_transform(&newBox, &newBox, TR, w, h);
|
||||
}
|
||||
|
||||
glScissor(newBox.x, newBox.y, newBox.width, newBox.height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::scissor(const pixman_box32* pBox) {
|
||||
void CHyprOpenGLImpl::scissor(const pixman_box32* pBox, bool transform) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to scissor without begin()!");
|
||||
|
||||
if (!pBox) {
|
||||
@@ -292,12 +300,12 @@ void CHyprOpenGLImpl::scissor(const pixman_box32* pBox) {
|
||||
|
||||
wlr_box newBox = {pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1};
|
||||
|
||||
scissor(&newBox);
|
||||
scissor(&newBox, transform);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h) {
|
||||
void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h, bool transform) {
|
||||
wlr_box box = {x,y,w,h};
|
||||
scissor(&box);
|
||||
scissor(&box, transform);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
|
||||
@@ -367,15 +375,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 +443,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[] = {
|
||||
@@ -475,9 +493,9 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
// get transforms for the full monitor
|
||||
const auto TRANSFORM = wlr_output_transform_invert(WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
const auto TRANSFORM = wlr_output_transform_invert(m_RenderData.pMonitor->transform);
|
||||
float matrix[9];
|
||||
wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
||||
wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
wlr_matrix_project_box(matrix, &MONITORBOX, TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
||||
|
||||
float glMatrix[9];
|
||||
@@ -493,8 +511,9 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||
pixman_region32_t damage;
|
||||
pixman_region32_init(&damage);
|
||||
pixman_region32_copy(&damage, originalDamage);
|
||||
wlr_region_transform(&damage, &damage, wlr_output_transform_invert(m_RenderData.pMonitor->transform), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
wlr_region_expand(&damage, &damage, pow(2, *PBLURPASSES) * *PBLURSIZE);
|
||||
|
||||
|
||||
// helper
|
||||
const auto PMIRRORFB = &m_RenderData.pCurrentMonData->mirrorFB;
|
||||
const auto PMIRRORSWAPFB = &m_RenderData.pCurrentMonData->mirrorSwapFB;
|
||||
@@ -534,7 +553,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||
if (pixman_region32_not_empty(pDamage)) {
|
||||
PIXMAN_DAMAGE_FOREACH(pDamage) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
scissor(&RECT);
|
||||
scissor(&RECT, false /* this region is already transformed */);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
@@ -557,8 +576,8 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||
// damage region will be scaled, make a temp
|
||||
pixman_region32_t tempDamage;
|
||||
pixman_region32_init(&tempDamage);
|
||||
wlr_region_scale(&tempDamage, &damage, 1.f / 2.f); // when DOWNscaling, we make the region twice as small because it's the TARGET
|
||||
|
||||
wlr_region_scale(&tempDamage, &damage, 1.f / 2.f); // when DOWNscaling, we make the region twice as small because it's the TARGET
|
||||
|
||||
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage);
|
||||
|
||||
// and draw
|
||||
@@ -621,7 +640,9 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() {
|
||||
|
||||
clear(CColor(0,0,0,0));
|
||||
|
||||
m_bEndFrame = true; // fix transformed
|
||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 255, &fakeDamage, 0, false, true, false);
|
||||
m_bEndFrame = false;
|
||||
|
||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
||||
|
||||
@@ -719,7 +740,9 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
if (pixman_region32_not_empty(&damage)) {
|
||||
// render our great blurred FB
|
||||
static auto *const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur_ignore_opacity")->intValue;
|
||||
m_bEndFrame = true; // fix transformed
|
||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 255.f : a, &damage, 0, false, false, false);
|
||||
m_bEndFrame = false;
|
||||
|
||||
// render the window, but clear stencil
|
||||
glClearStencil(0);
|
||||
@@ -727,7 +750,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 +873,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 +971,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 +979,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;
|
||||
@@ -1080,7 +1099,7 @@ void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const
|
||||
cairo_text_extents_t textExtents;
|
||||
cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &textExtents);
|
||||
|
||||
cairo_move_to(CAIRO, m_RenderData.pMonitor->vecTransformedSize.x / 2.f - textExtents.width / 2.f, m_RenderData.pMonitor->vecTransformedSize.y - textExtents.height - 1);
|
||||
cairo_move_to(CAIRO, m_RenderData.pMonitor->vecPixelSize.x / 2.f - textExtents.width / 2.f, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height - 1);
|
||||
cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str());
|
||||
|
||||
cairo_surface_flush(CAIROSURFACE);
|
||||
|
@@ -91,9 +91,9 @@ public:
|
||||
|
||||
void clear(const CColor&);
|
||||
void clearWithTex();
|
||||
void scissor(const wlr_box*);
|
||||
void scissor(const pixman_box32*);
|
||||
void scissor(const int x, const int y, const int w, const int h);
|
||||
void scissor(const wlr_box*, bool transform = true);
|
||||
void scissor(const pixman_box32*, bool transform = true);
|
||||
void scissor(const int x, const int y, const int w, const int h, bool transform = true);
|
||||
|
||||
void destroyMonitorResources(CMonitor*);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
@@ -703,6 +703,8 @@ void CHyprRenderer::arrangeLayersForMonitor(const int& monitor) {
|
||||
if (PMONITOR->damage)
|
||||
damageMonitor(PMONITOR);
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(monitor);
|
||||
|
||||
Debug::log(LOG, "Monitor %s layers arranged: reserved: %f %f %f %f", PMONITOR->szName.c_str(), PMONITOR->vecReservedTopLeft.x, PMONITOR->vecReservedTopLeft.y, PMONITOR->vecReservedBottomRight.x, PMONITOR->vecReservedBottomRight.y);
|
||||
}
|
||||
|
||||
@@ -984,6 +986,14 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
|
||||
pMonitor->vecPixelSize = pMonitor->vecSize;
|
||||
|
||||
// Adaptive sync (VRR)
|
||||
wlr_output_enable_adaptive_sync(pMonitor->output, 1);
|
||||
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
Debug::log(LOG, "Pending output %s does not accept VRR.", pMonitor->output->name);
|
||||
wlr_output_enable_adaptive_sync(pMonitor->output, 0);
|
||||
}
|
||||
|
||||
// update renderer
|
||||
g_pHyprOpenGL->destroyMonitorResources(pMonitor);
|
||||
|
||||
|
@@ -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() {
|
||||
@@ -27,9 +26,9 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
||||
|
||||
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
||||
// we draw 3px above the window's border with 3px
|
||||
const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size");
|
||||
const auto PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
|
||||
m_seExtents.topLeft = Vector2D(0, BORDERSIZE + 3 + 3);
|
||||
m_seExtents.topLeft = Vector2D(0, *PBORDERSIZE + 3 + 3);
|
||||
m_seExtents.bottomRight = Vector2D();
|
||||
|
||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
|
||||
@@ -83,7 +82,10 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
if (rect.width <= 0 || rect.height <= 0)
|
||||
break;
|
||||
|
||||
CColor color = m_dwGroupMembers[i] == g_pCompositor->m_pLastWindow ? CColor(g_pConfigManager->getInt("dwindle:col.group_border_active")) : CColor(g_pConfigManager->getInt("dwindle:col.group_border"));
|
||||
static auto *const PGROUPCOLACTIVE = &g_pConfigManager->getConfigValuePtr("dwindle:col.group_border_active")->intValue;
|
||||
static auto *const PGROUPCOLINACTIVE = &g_pConfigManager->getConfigValuePtr("dwindle:col.group_border")->intValue;
|
||||
|
||||
CColor color = m_dwGroupMembers[i] == g_pCompositor->m_pLastWindow ? CColor(*PGROUPCOLACTIVE) : CColor(*PGROUPCOLINACTIVE);
|
||||
color.a *= a;
|
||||
g_pHyprOpenGL->renderRect(&rect, color);
|
||||
|
||||
|
@@ -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;
|
||||
})#";
|
||||
|
Submodule subprojects/wlroots updated: 7c575922c0...fd0b0276c9
Reference in New Issue
Block a user