mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-14 19:45:45 -07:00
Compare commits
201 Commits
v0.12.0bet
...
v0.15.0bet
Author | SHA1 | Date | |
---|---|---|---|
|
ff5843bd85 | ||
|
3bb5971c2e | ||
|
a1d9404f9f | ||
|
ab82c4806d | ||
|
49ab3890aa | ||
|
85eea70be4 | ||
|
174b593438 | ||
|
0a08830375 | ||
|
a97621b1cb | ||
|
355366714e | ||
|
590fbf808b | ||
|
bbeed21e62 | ||
|
e6c9e3f81d | ||
|
7579e03b64 | ||
|
1ef23a304a | ||
|
3c27d1ab13 | ||
|
59a3c43913 | ||
|
2d73da1a79 | ||
|
45fe185cb9 | ||
|
da40bf823f | ||
|
caeb0636fa | ||
|
bdd9680adf | ||
|
ff4c22ca90 | ||
|
9f9129e536 | ||
|
ab42e4bccf | ||
|
2636abca2d | ||
|
ead0e74471 | ||
|
dcf5e34bfa | ||
|
10c4f4ba35 | ||
|
a1319e5110 | ||
|
5233746ac5 | ||
|
31cb4c49d9 | ||
|
11ee78f88b | ||
|
ec5ffe8839 | ||
|
e3b1d3c3c5 | ||
|
458ba3237b | ||
|
7a775c0584 | ||
|
87afc8c250 | ||
|
cd2b2c4fba | ||
|
c48336aac3 | ||
|
f70b57f360 | ||
|
bf3f519eb7 | ||
|
190229942f | ||
|
e476382d08 | ||
|
c885afcbc6 | ||
|
fad5fc587d | ||
|
73dbacd16d | ||
|
65fb0cf0f6 | ||
|
5101ddeff1 | ||
|
959557ecc3 | ||
|
bccc81d306 | ||
|
718de0d9fa | ||
|
fd6116c0cd | ||
|
00b16888bf | ||
|
abee2da5bd | ||
|
695411f1bd | ||
|
f9d8b3096a | ||
|
e5d143b238 | ||
|
37f2e1ddbe | ||
|
ef3eb37c7f | ||
|
db551b8970 | ||
|
c08218301b | ||
|
75aaf11a9c | ||
|
c4e782ca5d | ||
|
da2c2ddc21 | ||
|
5272588270 | ||
|
215125bd66 | ||
|
30d16373d0 | ||
|
c1feb683ce | ||
|
d3ffccd45f | ||
|
d49af1cc18 | ||
|
8b46d0b5a9 | ||
|
336883dda3 | ||
|
65ec8c7694 | ||
|
79c645f8cd | ||
|
d44cc9f112 | ||
|
1963da2d47 | ||
|
2b99dbb446 | ||
|
d24f31de51 | ||
|
d51c7ca135 | ||
|
8b11a2e1b1 | ||
|
b4bcba935d | ||
|
7f3750bd75 | ||
|
7a9423c782 | ||
|
6f98b3cbd8 | ||
|
2dd1661aec | ||
|
cde624ec6a | ||
|
b82621c4ec | ||
|
5b6c8d5b0f | ||
|
4dca2b945b | ||
|
a8943246a7 | ||
|
e42de0b778 | ||
|
5146165599 | ||
|
73e19aee6f | ||
|
3780361b95 | ||
|
ec6144e5da | ||
|
b6eaeffcf6 | ||
|
c24b45671a | ||
|
85c7aaf155 | ||
|
696253b348 | ||
|
abb6db9c37 | ||
|
18b483b8e1 | ||
|
7c809a3059 | ||
|
4070e1a148 | ||
|
dd61f88ed1 | ||
|
29626989e7 | ||
|
cf32d28082 | ||
|
5131a4acaf | ||
|
a72a39ebd5 | ||
|
151e013241 | ||
|
fa2d81b649 | ||
|
037d4ed422 | ||
|
9f82278d65 | ||
|
8e0f7b9b11 | ||
|
a96acc8fa4 | ||
|
5a146e9d90 | ||
|
da10022d84 | ||
|
e518adf1ac | ||
|
d8dbe26f31 | ||
|
e9f226797e | ||
|
7d4f0a3199 | ||
|
0062281092 | ||
|
81f267dff9 | ||
|
a09c614c2d | ||
|
b49d7007b5 | ||
|
864e227f5d | ||
|
82aa78916d | ||
|
f024d7114f | ||
|
8808d40008 | ||
|
d94fe3d063 | ||
|
f663fa209c | ||
|
9370c7aa8a | ||
|
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:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- docs/**
|
- docs/**
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
main:
|
main:
|
||||||
|
7
.github/workflows/nix-build.yaml
vendored
7
.github/workflows/nix-build.yaml
vendored
@@ -5,6 +5,11 @@ jobs:
|
|||||||
nix:
|
nix:
|
||||||
name: "Build Hyprland (Nix)"
|
name: "Build Hyprland (Nix)"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
package:
|
||||||
|
- default
|
||||||
|
- hyprland-no-hidpi
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@@ -22,4 +27,4 @@ jobs:
|
|||||||
name: hyprland
|
name: hyprland
|
||||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||||
- name: Build Hyprland with default settings
|
- name: Build Hyprland with default settings
|
||||||
run: nix build --print-build-logs
|
run: nix build .#${{ matrix.package }} --print-build-logs
|
||||||
|
@@ -29,8 +29,6 @@ input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
general {
|
general {
|
||||||
main_mod=SUPER
|
|
||||||
|
|
||||||
gaps_in=5
|
gaps_in=5
|
||||||
gaps_out=20
|
gaps_out=20
|
||||||
border_size=2
|
border_size=2
|
||||||
@@ -75,6 +73,10 @@ gestures {
|
|||||||
#windowrule=pseudo,abc
|
#windowrule=pseudo,abc
|
||||||
#windowrule=monitor 0,xyz
|
#windowrule=monitor 0,xyz
|
||||||
|
|
||||||
|
# some nice mouse binds
|
||||||
|
bindm=SUPER,mouse:272,movewindow
|
||||||
|
bindm=SUPER,mouse:273,resizewindow
|
||||||
|
|
||||||
# example binds
|
# example binds
|
||||||
bind=SUPER,Q,exec,kitty
|
bind=SUPER,Q,exec,kitty
|
||||||
bind=SUPER,C,killactive,
|
bind=SUPER,C,killactive,
|
||||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1660908602,
|
"lastModified": 1664687381,
|
||||||
"narHash": "sha256-SwZ85IPWvC4NxxFhWhRMTJpApSHbY1u4YK2UFWEBWvY=",
|
"narHash": "sha256-9czSuDzS+OGGwq2kC4KXBLXWfYaup+oLB+AA1Md25U4=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "495b19d5b3e62b4ec7e846bdfb6ef3d9c3b83492",
|
"rev": "59d2991d4256cdca1c0cda45d876c80a0fe45c31",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -26,11 +26,11 @@
|
|||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"host": "gitlab.freedesktop.org",
|
"host": "gitlab.freedesktop.org",
|
||||||
"lastModified": 1660930713,
|
"lastModified": 1664816798,
|
||||||
"narHash": "sha256-bY7q1NqG/sjCUAWPn/Ne9NCigLlPlH5Lk1WCMqv3rTU=",
|
"narHash": "sha256-oLJyFT1Fc4UNNaDSN+EYUAWL4CufCBpuS5AV4Z4XANo=",
|
||||||
"owner": "wlroots",
|
"owner": "wlroots",
|
||||||
"repo": "wlroots",
|
"repo": "wlroots",
|
||||||
"rev": "7c575922c05e4d5fd9a403c2aa631a54c7531d44",
|
"rev": "50cc1ef4d3791d86854dd83c15fff17e5ea1a5b6",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
38
flake.nix
38
flake.nix
@@ -20,7 +20,31 @@
|
|||||||
"aarch64-linux"
|
"aarch64-linux"
|
||||||
"x86_64-linux"
|
"x86_64-linux"
|
||||||
];
|
];
|
||||||
pkgsFor = nixpkgs.legacyPackages;
|
pkgsFor = genSystems (system:
|
||||||
|
import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = [
|
||||||
|
(_: prev: {
|
||||||
|
libdrm = prev.libdrm.overrideAttrs (old: rec {
|
||||||
|
version = "2.4.113";
|
||||||
|
src = prev.fetchurl {
|
||||||
|
url = "https://dri.freedesktop.org/${old.pname}/${old.pname}-${version}.tar.xz";
|
||||||
|
sha256 = "sha256-f9frKWf2O+tGBvItUOJ32ZNIDQXvdd2Iqb2OZ3Mj5eE=";
|
||||||
|
};
|
||||||
|
mesonFlags =
|
||||||
|
[
|
||||||
|
"-Dinstall-test-programs=true"
|
||||||
|
"-Domap=enabled"
|
||||||
|
"-Dcairo-tests=disabled"
|
||||||
|
]
|
||||||
|
++ lib.optionals prev.stdenv.hostPlatform.isAarch [
|
||||||
|
"-Dtegra=enabled"
|
||||||
|
"-Detnaviv=enabled"
|
||||||
|
];
|
||||||
|
});
|
||||||
|
})
|
||||||
|
];
|
||||||
|
});
|
||||||
mkDate = longDate: (lib.concatStringsSep "-" [
|
mkDate = longDate: (lib.concatStringsSep "-" [
|
||||||
(__substring 0 4 longDate)
|
(__substring 0 4 longDate)
|
||||||
(__substring 4 2 longDate)
|
(__substring 4 2 longDate)
|
||||||
@@ -28,16 +52,18 @@
|
|||||||
]);
|
]);
|
||||||
in {
|
in {
|
||||||
overlays.default = _: prev: rec {
|
overlays.default = _: prev: rec {
|
||||||
wlroots-hyprland = prev.wlroots.overrideAttrs (__: {
|
wlroots-hyprland = prev.callPackage ./nix/wlroots.nix {
|
||||||
version = mkDate (inputs.wlroots.lastModifiedDate or "19700101");
|
version = mkDate (inputs.wlroots.lastModifiedDate or "19700101") + "_" + (inputs.wlroots.shortRev or "dirty");
|
||||||
src = inputs.wlroots;
|
src = inputs.wlroots;
|
||||||
});
|
};
|
||||||
hyprland = prev.callPackage ./nix/default.nix {
|
hyprland = prev.callPackage ./nix/default.nix {
|
||||||
stdenv = prev.gcc12Stdenv;
|
stdenv = prev.gcc12Stdenv;
|
||||||
version = "0.11.1beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
version = "0.14.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||||
wlroots = wlroots-hyprland;
|
wlroots = wlroots-hyprland;
|
||||||
};
|
};
|
||||||
hyprland-debug = hyprland.override {debug = true;};
|
hyprland-debug = hyprland.override {debug = true;};
|
||||||
|
hyprland-no-hidpi = hyprland.override {hidpiXWayland = false;};
|
||||||
|
|
||||||
waybar-hyprland = prev.waybar.overrideAttrs (oldAttrs: {
|
waybar-hyprland = prev.waybar.overrideAttrs (oldAttrs: {
|
||||||
mesonFlags = oldAttrs.mesonFlags ++ ["-Dexperimental=true"];
|
mesonFlags = oldAttrs.mesonFlags ++ ["-Dexperimental=true"];
|
||||||
});
|
});
|
||||||
@@ -63,8 +89,6 @@
|
|||||||
|
|
||||||
nixosModules.default = import ./nix/module.nix self;
|
nixosModules.default = import ./nix/module.nix self;
|
||||||
homeManagerModules.default = import ./nix/hm-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 = {
|
nixConfig = {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
project('Hyprland', 'cpp', 'c',
|
project('Hyprland', 'cpp', 'c',
|
||||||
version : '0.11.1beta',
|
version : '0.14.0beta',
|
||||||
default_options : [
|
default_options : [
|
||||||
'warning_level=2',
|
'warning_level=2',
|
||||||
'default_library=static',
|
'default_library=static',
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
lib,
|
lib,
|
||||||
stdenv,
|
stdenv,
|
||||||
fetchFromGitHub,
|
fetchFromGitHub,
|
||||||
|
fetchpatch,
|
||||||
pkg-config,
|
pkg-config,
|
||||||
meson,
|
meson,
|
||||||
ninja,
|
ninja,
|
||||||
@@ -21,10 +22,17 @@
|
|||||||
xwayland,
|
xwayland,
|
||||||
debug ? false,
|
debug ? false,
|
||||||
enableXWayland ? true,
|
enableXWayland ? true,
|
||||||
|
hidpiXWayland ? true,
|
||||||
legacyRenderer ? false,
|
legacyRenderer ? false,
|
||||||
|
nvidiaPatches ? false,
|
||||||
version ? "git",
|
version ? "git",
|
||||||
}:
|
}: let
|
||||||
stdenv.mkDerivation {
|
assertXWayland = lib.assertMsg (hidpiXWayland -> enableXWayland) ''
|
||||||
|
Hyprland: cannot have hidpiXWayland when enableXWayland is false.
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
assert assertXWayland;
|
||||||
|
stdenv.mkDerivation {
|
||||||
pname = "hyprland" + lib.optionalString debug "-debug";
|
pname = "hyprland" + lib.optionalString debug "-debug";
|
||||||
inherit version;
|
inherit version;
|
||||||
|
|
||||||
@@ -61,7 +69,7 @@ stdenv.mkDerivation {
|
|||||||
wayland
|
wayland
|
||||||
wayland-protocols
|
wayland-protocols
|
||||||
wayland-scanner
|
wayland-scanner
|
||||||
(wlroots.override {inherit enableXWayland;})
|
(wlroots.override {inherit enableXWayland hidpiXWayland nvidiaPatches;})
|
||||||
xcbutilwm
|
xcbutilwm
|
||||||
]
|
]
|
||||||
++ lib.optional enableXWayland xwayland;
|
++ lib.optional enableXWayland xwayland;
|
||||||
@@ -95,4 +103,4 @@ stdenv.mkDerivation {
|
|||||||
platforms = platforms.linux;
|
platforms = platforms.linux;
|
||||||
mainProgram = "Hyprland";
|
mainProgram = "Hyprland";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,8 @@ self: {
|
|||||||
}: let
|
}: let
|
||||||
cfg = config.wayland.windowManager.hyprland;
|
cfg = config.wayland.windowManager.hyprland;
|
||||||
defaultHyprlandPackage = self.packages.${pkgs.system}.default.override {
|
defaultHyprlandPackage = self.packages.${pkgs.system}.default.override {
|
||||||
enableXWayland = cfg.xwayland;
|
enableXWayland = cfg.xwayland.enable;
|
||||||
|
hidpiXWayland = cfg.xwayland.hidpi;
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
options.wayland.windowManager.hyprland = {
|
options.wayland.windowManager.hyprland = {
|
||||||
@@ -41,13 +42,22 @@ in {
|
|||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
xwayland = lib.mkOption {
|
xwayland = {
|
||||||
|
enable = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = ''
|
description = ''
|
||||||
Enable xwayland.
|
Enable XWayland.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
hidpi = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Enable HiDPI XWayland.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
extraConfig = lib.mkOption {
|
extraConfig = lib.mkOption {
|
||||||
type = lib.types.lines;
|
type = lib.types.lines;
|
||||||
@@ -56,17 +66,42 @@ in {
|
|||||||
Extra configuration lines to add to ~/.config/hypr/hyprland.conf.
|
Extra configuration lines to add to ~/.config/hypr/hyprland.conf.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
recommendedEnvironment = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
defaultText = lib.literalExpression "true";
|
||||||
|
example = lib.literalExpression "false";
|
||||||
|
description = ''
|
||||||
|
Whether to set the recommended environment variables.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(
|
||||||
|
lib.mkRenamedOptionModule
|
||||||
|
["wayland" "windowManager" "hyprland" "xwayland"]
|
||||||
|
["wayland" "windowManager" "hyprland" "xwayland" "enable"]
|
||||||
|
)
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
home.packages =
|
home.packages =
|
||||||
lib.optional (cfg.package != null) cfg.package
|
lib.optional (cfg.package != null) cfg.package
|
||||||
++ lib.optional cfg.xwayland pkgs.xwayland;
|
++ lib.optional cfg.xwayland.enable pkgs.xwayland;
|
||||||
|
|
||||||
|
home.sessionVariables = lib.mkIf cfg.recommendedEnvironment {
|
||||||
|
GDK_BACKEND = "wayland";
|
||||||
|
_JAVA_AWT_WM_NONREPARENTING = "1";
|
||||||
|
NIXOS_OZONE_WL = "1";
|
||||||
|
XCURSOR_SIZE = toString config.home.pointerCursor.size or "24";
|
||||||
|
XDG_SESSION_TYPE = "wayland";
|
||||||
|
};
|
||||||
|
|
||||||
xdg.configFile."hypr/hyprland.conf" = {
|
xdg.configFile."hypr/hyprland.conf" = {
|
||||||
text =
|
text =
|
||||||
(lib.optionalString cfg.systemdIntegration ''
|
(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=${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=systemctl --user start hyprland-session.target
|
||||||
'')
|
'')
|
||||||
|
@@ -8,6 +8,10 @@ self: {
|
|||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.programs.hyprland;
|
cfg = config.programs.hyprland;
|
||||||
in {
|
in {
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule ["programs" "hyprland" "extraPackages"] "extraPackages has been removed. Use environment.systemPackages instead.")
|
||||||
|
];
|
||||||
|
|
||||||
options.programs.hyprland = {
|
options.programs.hyprland = {
|
||||||
enable = mkEnableOption ''
|
enable = mkEnableOption ''
|
||||||
Hyprland, the dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
|
Hyprland, the dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
|
||||||
@@ -27,20 +31,40 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
imports = [
|
recommendedEnvironment = mkOption {
|
||||||
(mkRemovedOptionModule ["programs" "hyprland" "extraPackages"] "extraPackages has been removed. Use environment.systemPackages instead.")
|
type = types.bool;
|
||||||
];
|
default = true;
|
||||||
|
defaultText = literalExpression "true";
|
||||||
|
example = literalExpression "false";
|
||||||
|
description = ''
|
||||||
|
Whether to set the recommended environment variables.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
environment.systemPackages = lib.optional (cfg.package != null) cfg.package;
|
environment = {
|
||||||
security.polkit.enable = true;
|
systemPackages = lib.optional (cfg.package != null) cfg.package;
|
||||||
hardware.opengl.enable = mkDefault true;
|
|
||||||
|
sessionVariables = mkIf cfg.recommendedEnvironment {
|
||||||
|
GDK_BACKEND = "wayland";
|
||||||
|
_JAVA_AWT_WM_NONREPARENTING = "1";
|
||||||
|
NIXOS_OZONE_WL = "1";
|
||||||
|
XCURSOR_SIZE = "24";
|
||||||
|
XDG_SESSION_TYPE = "wayland";
|
||||||
|
};
|
||||||
|
};
|
||||||
fonts.enableDefaultFonts = mkDefault true;
|
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;
|
services.xserver.displayManager.sessionPackages = lib.optional (cfg.package != null) cfg.package;
|
||||||
programs.xwayland.enable = mkDefault true;
|
xdg.portal = {
|
||||||
xdg.portal.enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
xdg.portal.extraPortals = [pkgs.xdg-desktop-portal-wlr];
|
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;
|
@@ -198,6 +198,9 @@ void CCompositor::initAllSignals() {
|
|||||||
addWLSignal(&m_sWLRCursor->events.touch_down, &Events::listen_touchBegin, m_sWLRCursor, "WLRCursor");
|
addWLSignal(&m_sWLRCursor->events.touch_down, &Events::listen_touchBegin, m_sWLRCursor, "WLRCursor");
|
||||||
addWLSignal(&m_sWLRCursor->events.touch_up, &Events::listen_touchEnd, m_sWLRCursor, "WLRCursor");
|
addWLSignal(&m_sWLRCursor->events.touch_up, &Events::listen_touchEnd, m_sWLRCursor, "WLRCursor");
|
||||||
addWLSignal(&m_sWLRCursor->events.touch_motion, &Events::listen_touchUpdate, m_sWLRCursor, "WLRCursor");
|
addWLSignal(&m_sWLRCursor->events.touch_motion, &Events::listen_touchUpdate, m_sWLRCursor, "WLRCursor");
|
||||||
|
addWLSignal(&m_sWLRCursor->events.touch_frame, &Events::listen_touchFrame, m_sWLRCursor, "WLRCursor");
|
||||||
|
addWLSignal(&m_sWLRCursor->events.hold_begin, &Events::listen_holdBegin, m_sWLRCursor, "WLRCursor");
|
||||||
|
addWLSignal(&m_sWLRCursor->events.hold_end, &Events::listen_holdEnd, m_sWLRCursor, "WLRCursor");
|
||||||
addWLSignal(&m_sWLRBackend->events.new_input, &Events::listen_newInput, m_sWLRBackend, "Backend");
|
addWLSignal(&m_sWLRBackend->events.new_input, &Events::listen_newInput, m_sWLRBackend, "Backend");
|
||||||
addWLSignal(&m_sSeat.seat->events.request_set_cursor, &Events::listen_requestMouse, &m_sSeat, "Seat");
|
addWLSignal(&m_sSeat.seat->events.request_set_cursor, &Events::listen_requestMouse, &m_sSeat, "Seat");
|
||||||
addWLSignal(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel, &m_sSeat, "Seat");
|
addWLSignal(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel, &m_sSeat, "Seat");
|
||||||
@@ -237,6 +240,7 @@ void CCompositor::cleanup() {
|
|||||||
|
|
||||||
// accumulate all PIDs for killing, also request closing.
|
// accumulate all PIDs for killing, also request closing.
|
||||||
for (auto& w : m_vWindows) {
|
for (auto& w : m_vWindows) {
|
||||||
|
if (w->m_bIsMapped || !w->m_bIsX11)
|
||||||
m_dProcessPIDsOnShutdown.push_back(w->getPID());
|
m_dProcessPIDsOnShutdown.push_back(w->getPID());
|
||||||
|
|
||||||
closeWindow(w.get());
|
closeWindow(w.get());
|
||||||
@@ -244,7 +248,6 @@ void CCompositor::cleanup() {
|
|||||||
|
|
||||||
// end threads
|
// end threads
|
||||||
g_pEventManager->m_tThread = std::thread();
|
g_pEventManager->m_tThread = std::thread();
|
||||||
HyprCtl::tThread = std::thread();
|
|
||||||
|
|
||||||
m_vWorkspaces.clear();
|
m_vWorkspaces.clear();
|
||||||
m_vWindows.clear();
|
m_vWindows.clear();
|
||||||
@@ -453,10 +456,17 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pinned
|
||||||
|
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||||
|
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||||
|
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && !(*w)->m_bHidden && (*w)->m_bPinned)
|
||||||
|
return w->get();
|
||||||
|
}
|
||||||
|
|
||||||
// first loop over floating cuz they're above, m_vWindows should be sorted bottom->top, for tiled it doesn't matter.
|
// first loop over floating cuz they're above, m_vWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden)
|
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bPinned)
|
||||||
return w->get();
|
return w->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,12 +526,43 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pinned windows on top of floating regardless
|
||||||
|
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||||
|
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||||
|
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && !(*w)->m_bHidden && !(*w)->m_bX11ShouldntFocus && (*w)->m_bPinned) {
|
||||||
|
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y))
|
||||||
|
return w->get();
|
||||||
|
|
||||||
|
if (!(*w)->m_bIsX11) {
|
||||||
|
wlr_surface* resultSurf = nullptr;
|
||||||
|
Vector2D origin = (*w)->m_vRealPosition.vec();
|
||||||
|
SExtensionFindingData data = {origin, pos, &resultSurf};
|
||||||
|
wlr_xdg_surface_for_each_popup_surface((*w)->m_uSurface.xdg, findExtensionForVector2D, &data);
|
||||||
|
|
||||||
|
if (resultSurf)
|
||||||
|
return w->get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bX11ShouldntFocus) {
|
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bPinned) {
|
||||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y))
|
// OR windows should add focus to parent
|
||||||
|
if ((*w)->m_bX11ShouldntFocus && (*w)->m_iX11Type != 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y)) {
|
||||||
|
|
||||||
|
if ((*w)->m_iX11Type == 2) {
|
||||||
|
// Override Redirect
|
||||||
|
return g_pCompositor->m_pLastWindow; // we kinda trick everything here.
|
||||||
|
// TODO: this is wrong, we should focus the parent, but idk how to get it considering it's nullptr in most cases.
|
||||||
|
}
|
||||||
|
|
||||||
return w->get();
|
return w->get();
|
||||||
|
}
|
||||||
|
|
||||||
if (!(*w)->m_bIsX11) {
|
if (!(*w)->m_bIsX11) {
|
||||||
wlr_surface* resultSurf = nullptr;
|
wlr_surface* resultSurf = nullptr;
|
||||||
@@ -573,10 +614,17 @@ CWindow* CCompositor::windowFromCursor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pinned
|
||||||
|
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||||
|
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||||
|
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && (*w)->m_bPinned)
|
||||||
|
return w->get();
|
||||||
|
}
|
||||||
|
|
||||||
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID))
|
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bPinned)
|
||||||
return w->get();
|
return w->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,7 +640,13 @@ CWindow* CCompositor::windowFromCursor() {
|
|||||||
CWindow* CCompositor::windowFloatingFromCursor() {
|
CWindow* CCompositor::windowFloatingFromCursor() {
|
||||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden)
|
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && !(*w)->m_bHidden && (*w)->m_bPinned)
|
||||||
|
return w->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||||
|
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||||
|
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bPinned)
|
||||||
return w->get();
|
return w->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,6 +729,9 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
|||||||
if (m_pLastWindow == pWindow && m_sSeat.seat->keyboard_state.focused_surface == pSurface)
|
if (m_pLastWindow == pWindow && m_sSeat.seat->keyboard_state.focused_surface == pSurface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (pWindow->m_bPinned)
|
||||||
|
pWindow->m_iWorkspaceID = m_pLastMonitor->activeWorkspace;
|
||||||
|
|
||||||
if (!isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
if (!isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
||||||
g_pKeybindManager->changeworkspace("[internal]" + std::to_string(pWindow->m_iWorkspaceID));
|
g_pKeybindManager->changeworkspace("[internal]" + std::to_string(pWindow->m_iWorkspaceID));
|
||||||
|
|
||||||
@@ -784,7 +841,7 @@ CWindow* CCompositor::getWindowForPopup(wlr_xdg_popup* popup) {
|
|||||||
|
|
||||||
wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<std::unique_ptr<SLayerSurface>>* layerSurfaces, Vector2D* sCoords, SLayerSurface** ppLayerSurfaceFound) {
|
wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<std::unique_ptr<SLayerSurface>>* layerSurfaces, Vector2D* sCoords, SLayerSurface** ppLayerSurfaceFound) {
|
||||||
for (auto it = layerSurfaces->rbegin(); it != layerSurfaces->rend(); it++) {
|
for (auto it = layerSurfaces->rbegin(); it != layerSurfaces->rend(); it++) {
|
||||||
if ((*it)->fadingOut || !(*it)->layerSurface || ((*it)->layerSurface && !(*it)->layerSurface->mapped))
|
if ((*it)->fadingOut || !(*it)->layerSurface || ((*it)->layerSurface && !(*it)->layerSurface->mapped) || (*it)->alpha.fl() == 0.f)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto SURFACEAT = wlr_layer_surface_v1_surface_at((*it)->layerSurface, pos.x - (*it)->geometry.x, pos.y - (*it)->geometry.y, &sCoords->x, &sCoords->y);
|
const auto SURFACEAT = wlr_layer_surface_v1_surface_at((*it)->layerSurface, pos.x - (*it)->geometry.x, pos.y - (*it)->geometry.y, &sCoords->x, &sCoords->y);
|
||||||
@@ -1057,7 +1114,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
|||||||
switch (dir) {
|
switch (dir) {
|
||||||
case 'l':
|
case 'l':
|
||||||
if (STICKS(POSA.x, POSB.x + SIZEB.x)) {
|
if (STICKS(POSA.x, POSB.x + SIZEB.x)) {
|
||||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||||
if (INTERSECTLEN > longestIntersect) {
|
if (INTERSECTLEN > longestIntersect) {
|
||||||
longestIntersect = INTERSECTLEN;
|
longestIntersect = INTERSECTLEN;
|
||||||
longestIntersectWindow = w.get();
|
longestIntersectWindow = w.get();
|
||||||
@@ -1066,7 +1123,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
|||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
if (STICKS(POSA.x + SIZEA.x, POSB.x)) {
|
if (STICKS(POSA.x + SIZEA.x, POSB.x)) {
|
||||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||||
if (INTERSECTLEN > longestIntersect) {
|
if (INTERSECTLEN > longestIntersect) {
|
||||||
longestIntersect = INTERSECTLEN;
|
longestIntersect = INTERSECTLEN;
|
||||||
longestIntersectWindow = w.get();
|
longestIntersectWindow = w.get();
|
||||||
@@ -1076,7 +1133,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
|||||||
case 't':
|
case 't':
|
||||||
case 'u':
|
case 'u':
|
||||||
if (STICKS(POSA.y, POSB.y + SIZEB.y)) {
|
if (STICKS(POSA.y, POSB.y + SIZEB.y)) {
|
||||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||||
if (INTERSECTLEN > longestIntersect) {
|
if (INTERSECTLEN > longestIntersect) {
|
||||||
longestIntersect = INTERSECTLEN;
|
longestIntersect = INTERSECTLEN;
|
||||||
longestIntersectWindow = w.get();
|
longestIntersectWindow = w.get();
|
||||||
@@ -1086,7 +1143,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
|||||||
case 'b':
|
case 'b':
|
||||||
case 'd':
|
case 'd':
|
||||||
if (STICKS(POSA.y + SIZEA.y, POSB.y)) {
|
if (STICKS(POSA.y + SIZEA.y, POSB.y)) {
|
||||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||||
if (INTERSECTLEN > longestIntersect) {
|
if (INTERSECTLEN > longestIntersect) {
|
||||||
longestIntersect = INTERSECTLEN;
|
longestIntersect = INTERSECTLEN;
|
||||||
longestIntersectWindow = w.get();
|
longestIntersectWindow = w.get();
|
||||||
@@ -1109,7 +1166,7 @@ void CCompositor::deactivateAllWLRWorkspaces(wlr_ext_workspace_handle_v1* exclud
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow) {
|
CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow, bool focusableOnly) {
|
||||||
bool gotToWindow = false;
|
bool gotToWindow = false;
|
||||||
for (auto& w : m_vWindows) {
|
for (auto& w : m_vWindows) {
|
||||||
if (w.get() != pWindow && !gotToWindow)
|
if (w.get() != pWindow && !gotToWindow)
|
||||||
@@ -1120,19 +1177,19 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden)
|
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden && (!focusableOnly || !w->m_bNoFocus))
|
||||||
return w.get();
|
return w.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& w : m_vWindows) {
|
for (auto& w : m_vWindows) {
|
||||||
if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden)
|
if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden && (!focusableOnly || !w->m_bNoFocus))
|
||||||
return w.get();
|
return w.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow) {
|
CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow, bool focusableOnly) {
|
||||||
bool gotToWindow = false;
|
bool gotToWindow = false;
|
||||||
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
||||||
if (it->get() != pWindow && !gotToWindow)
|
if (it->get() != pWindow && !gotToWindow)
|
||||||
@@ -1143,12 +1200,12 @@ CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden)
|
if ((*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden && (!focusableOnly || !(*it)->m_bNoFocus))
|
||||||
return it->get();
|
return it->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
||||||
if (it->get() != pWindow && (*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden)
|
if (it->get() != pWindow && (*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden && (!focusableOnly || !(*it)->m_bNoFocus))
|
||||||
return it->get();
|
return it->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1232,7 +1289,7 @@ CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
|||||||
switch (dir) {
|
switch (dir) {
|
||||||
case 'l':
|
case 'l':
|
||||||
if (STICKS(POSA.x, POSB.x + SIZEB.x)) {
|
if (STICKS(POSA.x, POSB.x + SIZEB.x)) {
|
||||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||||
if (INTERSECTLEN > longestIntersect) {
|
if (INTERSECTLEN > longestIntersect) {
|
||||||
longestIntersect = INTERSECTLEN;
|
longestIntersect = INTERSECTLEN;
|
||||||
longestIntersectMonitor = m.get();
|
longestIntersectMonitor = m.get();
|
||||||
@@ -1241,7 +1298,7 @@ CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
|||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
if (STICKS(POSA.x + SIZEA.x, POSB.x)) {
|
if (STICKS(POSA.x + SIZEA.x, POSB.x)) {
|
||||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||||
if (INTERSECTLEN > longestIntersect) {
|
if (INTERSECTLEN > longestIntersect) {
|
||||||
longestIntersect = INTERSECTLEN;
|
longestIntersect = INTERSECTLEN;
|
||||||
longestIntersectMonitor = m.get();
|
longestIntersectMonitor = m.get();
|
||||||
@@ -1251,7 +1308,7 @@ CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
|||||||
case 't':
|
case 't':
|
||||||
case 'u':
|
case 'u':
|
||||||
if (STICKS(POSA.y, POSB.y + SIZEB.y)) {
|
if (STICKS(POSA.y, POSB.y + SIZEB.y)) {
|
||||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||||
if (INTERSECTLEN > longestIntersect) {
|
if (INTERSECTLEN > longestIntersect) {
|
||||||
longestIntersect = INTERSECTLEN;
|
longestIntersect = INTERSECTLEN;
|
||||||
longestIntersectMonitor = m.get();
|
longestIntersectMonitor = m.get();
|
||||||
@@ -1261,7 +1318,7 @@ CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
|||||||
case 'b':
|
case 'b':
|
||||||
case 'd':
|
case 'd':
|
||||||
if (STICKS(POSA.y + SIZEA.y, POSB.y)) {
|
if (STICKS(POSA.y + SIZEA.y, POSB.y)) {
|
||||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||||
if (INTERSECTLEN > longestIntersect) {
|
if (INTERSECTLEN > longestIntersect) {
|
||||||
longestIntersect = INTERSECTLEN;
|
longestIntersect = INTERSECTLEN;
|
||||||
longestIntersectMonitor = m.get();
|
longestIntersectMonitor = m.get();
|
||||||
@@ -1295,6 +1352,7 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
|
|||||||
static auto *const PFULLSCREENALPHA = &g_pConfigManager->getConfigValuePtr("decoration:fullscreen_opacity")->floatValue;
|
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 PSHADOWCOL = &g_pConfigManager->getConfigValuePtr("decoration:col.shadow")->intValue;
|
||||||
static auto *const PSHADOWCOLINACTIVE = &g_pConfigManager->getConfigValuePtr("decoration:col.shadow_inactive")->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
|
// border
|
||||||
const auto RENDERDATA = g_pLayoutManager->getCurrentLayout()->requestRenderHints(pWindow);
|
const auto RENDERDATA = g_pLayoutManager->getCurrentLayout()->requestRenderHints(pWindow);
|
||||||
@@ -1323,6 +1381,13 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
|
|||||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? pWindow->m_sSpecialRenderData.alphaInactive * *PINACTIVEALPHA : *PINACTIVEALPHA;
|
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
|
// shadow
|
||||||
if (pWindow->m_iX11Type != 2 && !pWindow->m_bX11DoesntWantBorders) {
|
if (pWindow->m_iX11Type != 2 && !pWindow->m_bX11DoesntWantBorders) {
|
||||||
if (pWindow == m_pLastWindow) {
|
if (pWindow == m_pLastWindow) {
|
||||||
@@ -1390,6 +1455,17 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fix pinned windows
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
if (w->m_iWorkspaceID == pMonitorA->activeWorkspace && w->m_bPinned) {
|
||||||
|
w->m_iWorkspaceID = PWORKSPACEB->m_iID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w->m_iWorkspaceID == pMonitorB->activeWorkspace && w->m_bPinned) {
|
||||||
|
w->m_iWorkspaceID = PWORKSPACEA->m_iID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pMonitorA->activeWorkspace = PWORKSPACEB->m_iID;
|
pMonitorA->activeWorkspace = PWORKSPACEB->m_iID;
|
||||||
pMonitorB->activeWorkspace = PWORKSPACEA->m_iID;
|
pMonitorB->activeWorkspace = PWORKSPACEA->m_iID;
|
||||||
|
|
||||||
@@ -1422,6 +1498,9 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (name == "current")
|
||||||
|
return g_pCompositor->m_pLastMonitor;
|
||||||
|
|
||||||
if (isDirection(name)) {
|
if (isDirection(name)) {
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorInDirection(name[0]);
|
const auto PMONITOR = g_pCompositor->getMonitorInDirection(name[0]);
|
||||||
return PMONITOR;
|
return PMONITOR;
|
||||||
@@ -1527,6 +1606,9 @@ bool CCompositor::workspaceIDOutOfBounds(const int& id) {
|
|||||||
int highestID = -99999;
|
int highestID = -99999;
|
||||||
|
|
||||||
for (auto& w : m_vWorkspaces) {
|
for (auto& w : m_vWorkspaces) {
|
||||||
|
if (w->m_iID == SPECIAL_WORKSPACE_ID)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (w->m_iID < lowestID)
|
if (w->m_iID < lowestID)
|
||||||
lowestID = w->m_iID;
|
lowestID = w->m_iID;
|
||||||
|
|
||||||
@@ -1541,7 +1623,19 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
|
|||||||
if (!windowValidMapped(pWindow))
|
if (!windowValidMapped(pWindow))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
focusWindow(pWindow);
|
if (pWindow->m_bPinned) {
|
||||||
|
Debug::log(LOG, "Pinned windows cannot be fullscreen'd");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID);
|
||||||
|
|
||||||
|
const auto PWORKSPACE = getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (PWORKSPACE->m_bHasFullscreenWindow && on) {
|
||||||
|
Debug::log(LOG, "Rejecting fullscreen ON on a fullscreen workspace");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(pWindow, mode, on);
|
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(pWindow, mode, on);
|
||||||
|
|
||||||
@@ -1549,8 +1643,16 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
|
|||||||
|
|
||||||
// make all windows on the same workspace under the fullscreen window
|
// make all windows on the same workspace under the fullscreen window
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID)
|
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID) {
|
||||||
w->m_bCreatedOverFullscreen = false;
|
w->m_bCreatedOverFullscreen = false;
|
||||||
|
if (w.get() != pWindow && !w->m_bFadingOut && !w->m_bPinned)
|
||||||
|
w->m_fAlpha = pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL ? 0.f : 255.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& ls : PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||||
|
if (!ls->fadingOut)
|
||||||
|
ls->alpha = pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL ? 0.f : 255.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv(), true);
|
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv(), true);
|
||||||
@@ -1654,25 +1756,6 @@ CWindow* CCompositor::getWindowByRegex(const std::string& regexp) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_event_source* hyprCtlTickSource = nullptr;
|
|
||||||
|
|
||||||
int hyprCtlTick(void* data) {
|
|
||||||
HyprCtl::tickHyprCtl(); // so that we dont get that race condition multithread bullshit
|
|
||||||
|
|
||||||
wl_event_source_timer_update(hyprCtlTickSource, 16); // tick it 60/s, should be enough.
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCompositor::startHyprCtlTick() {
|
|
||||||
if (hyprCtlTickSource)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hyprCtlTickSource = wl_event_loop_add_timer(m_sWLEventLoop, hyprCtlTick, nullptr);
|
|
||||||
|
|
||||||
wl_event_source_timer_update(hyprCtlTickSource, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCompositor::warpCursorTo(const Vector2D& pos) {
|
void CCompositor::warpCursorTo(const Vector2D& pos) {
|
||||||
|
|
||||||
// warpCursorTo should only be used for warps that
|
// warpCursorTo should only be used for warps that
|
||||||
@@ -1684,6 +1767,10 @@ void CCompositor::warpCursorTo(const Vector2D& pos) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
wlr_cursor_warp(m_sWLRCursor, m_sSeat.mouse->mouse, pos.x, pos.y);
|
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) {
|
SLayerSurface* CCompositor::getLayerSurfaceFromWlr(wlr_layer_surface_v1* pLS) {
|
||||||
@@ -1764,3 +1851,14 @@ void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
@@ -138,8 +138,8 @@ public:
|
|||||||
void cleanupFadingOut(const int& monid);
|
void cleanupFadingOut(const int& monid);
|
||||||
CWindow* getWindowInDirection(CWindow*, char);
|
CWindow* getWindowInDirection(CWindow*, char);
|
||||||
void deactivateAllWLRWorkspaces(wlr_ext_workspace_handle_v1* exclude = nullptr);
|
void deactivateAllWLRWorkspaces(wlr_ext_workspace_handle_v1* exclude = nullptr);
|
||||||
CWindow* getNextWindowOnWorkspace(CWindow*);
|
CWindow* getNextWindowOnWorkspace(CWindow*, bool focusableOnly = false);
|
||||||
CWindow* getPrevWindowOnWorkspace(CWindow*);
|
CWindow* getPrevWindowOnWorkspace(CWindow*, bool focusableOnly = false);
|
||||||
int getNextAvailableNamedWorkspace();
|
int getNextAvailableNamedWorkspace();
|
||||||
bool isPointOnAnyMonitor(const Vector2D&);
|
bool isPointOnAnyMonitor(const Vector2D&);
|
||||||
CWindow* getConstraintWindow(SMouse*);
|
CWindow* getConstraintWindow(SMouse*);
|
||||||
@@ -164,12 +164,10 @@ public:
|
|||||||
void closeWindow(CWindow*);
|
void closeWindow(CWindow*);
|
||||||
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
||||||
void forceReportSizesToWindowsOnWorkspace(const int&);
|
void forceReportSizesToWindowsOnWorkspace(const int&);
|
||||||
|
bool cursorOnReservedArea();
|
||||||
|
|
||||||
std::string explicitConfigPath;
|
std::string explicitConfigPath;
|
||||||
|
|
||||||
void startHyprCtlTick();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initAllSignals();
|
void initAllSignals();
|
||||||
void setRandomSplash();
|
void setRandomSplash();
|
||||||
|
@@ -9,6 +9,7 @@ CWindow::CWindow() {
|
|||||||
m_fAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), (void*)this, AVARDAMAGE_ENTIRE);
|
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_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_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)
|
m_dWindowDecorations.emplace_back(std::make_unique<CHyprDropShadowDecoration>(this)); // put the shadow so it's the first deco (has to be rendered first)
|
||||||
}
|
}
|
||||||
@@ -96,8 +97,7 @@ void CWindow::updateWindowDecos() {
|
|||||||
pid_t CWindow::getPID() {
|
pid_t CWindow::getPID() {
|
||||||
pid_t PID = -1;
|
pid_t PID = -1;
|
||||||
if (!m_bIsX11) {
|
if (!m_bIsX11) {
|
||||||
const auto CLIENT = wl_resource_get_client(m_uSurface.xdg->resource);
|
wl_client_get_credentials(wl_resource_get_client(m_uSurface.xdg->resource), &PID, nullptr, nullptr);
|
||||||
wl_client_get_credentials(CLIENT, &PID, nullptr, nullptr);
|
|
||||||
} else {
|
} else {
|
||||||
PID = m_uSurface.xwayland->pid;
|
PID = m_uSurface.xwayland->pid;
|
||||||
}
|
}
|
||||||
@@ -211,8 +211,7 @@ void CWindow::moveToWorkspace(int workspaceID) {
|
|||||||
if (m_iWorkspaceID != workspaceID) {
|
if (m_iWorkspaceID != workspaceID) {
|
||||||
m_iWorkspaceID = workspaceID;
|
m_iWorkspaceID = workspaceID;
|
||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID);
|
if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); PWORKSPACE) {
|
||||||
if (PWORKSPACE) {
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", this, PWORKSPACE->m_szName.c_str())});
|
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", this, PWORKSPACE->m_szName.c_str())});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,9 +226,21 @@ CWindow* CWindow::X11TransientFor() {
|
|||||||
|
|
||||||
auto PPARENT = g_pCompositor->getWindowFromSurface(m_uSurface.xwayland->parent->surface);
|
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);
|
PPARENT = g_pCompositor->getWindowFromSurface(PPARENT->m_uSurface.xwayland->parent->surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!g_pCompositor->windowValidMapped(PPARENT))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
return PPARENT;
|
return PPARENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWindow::removeDecorationByType(eDecorationType type) {
|
||||||
|
for (auto& wd : m_dWindowDecorations) {
|
||||||
|
if (wd->getDecorationType() == type)
|
||||||
|
m_vDecosToRemove.push_back(wd.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
updateWindowDecos();
|
||||||
|
}
|
||||||
|
@@ -14,6 +14,7 @@ struct SWindowSpecialRenderData {
|
|||||||
// set by the layout
|
// set by the layout
|
||||||
bool rounding = true;
|
bool rounding = true;
|
||||||
bool border = true;
|
bool border = true;
|
||||||
|
bool decorate = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SWindowAdditionalConfigData {
|
struct SWindowAdditionalConfigData {
|
||||||
@@ -119,6 +120,9 @@ public:
|
|||||||
// For hidden windows and stuff
|
// For hidden windows and stuff
|
||||||
bool m_bHidden = false;
|
bool m_bHidden = false;
|
||||||
|
|
||||||
|
// For pinned (sticky) windows
|
||||||
|
bool m_bPinned = false;
|
||||||
|
|
||||||
// for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
|
// for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
|
||||||
CWindow* m_pLastCycledWindow = nullptr;
|
CWindow* m_pLastCycledWindow = nullptr;
|
||||||
|
|
||||||
@@ -139,6 +143,12 @@ public:
|
|||||||
// animated shadow color
|
// animated shadow color
|
||||||
CAnimatedVariable m_cRealShadowColor;
|
CAnimatedVariable m_cRealShadowColor;
|
||||||
|
|
||||||
|
// animated tint
|
||||||
|
CAnimatedVariable m_fDimPercent;
|
||||||
|
|
||||||
|
// swallowing
|
||||||
|
CWindow* m_pSwallowed = nullptr;
|
||||||
|
|
||||||
// for toplevel monitor events
|
// for toplevel monitor events
|
||||||
uint64_t m_iLastToplevelMonitorID = -1;
|
uint64_t m_iLastToplevelMonitorID = -1;
|
||||||
uint64_t m_iLastSurfaceMonitorID = -1;
|
uint64_t m_iLastSurfaceMonitorID = -1;
|
||||||
@@ -154,6 +164,7 @@ public:
|
|||||||
void updateWindowDecos();
|
void updateWindowDecos();
|
||||||
pid_t getPID();
|
pid_t getPID();
|
||||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||||
|
void removeDecorationByType(eDecorationType);
|
||||||
void createToplevelHandle();
|
void createToplevelHandle();
|
||||||
void destroyToplevelHandle();
|
void destroyToplevelHandle();
|
||||||
void updateToplevel();
|
void updateToplevel();
|
||||||
|
@@ -57,6 +57,9 @@ void CConfigManager::setDefaultVars() {
|
|||||||
configValues["misc:always_follow_on_dnd"].intValue = 1;
|
configValues["misc:always_follow_on_dnd"].intValue = 1;
|
||||||
configValues["misc:layers_hog_keyboard_focus"].intValue = 1;
|
configValues["misc:layers_hog_keyboard_focus"].intValue = 1;
|
||||||
configValues["misc:animate_manual_resizes"].intValue = 0;
|
configValues["misc:animate_manual_resizes"].intValue = 0;
|
||||||
|
configValues["misc:disable_autoreload"].intValue = 0;
|
||||||
|
configValues["misc:enable_swallow"].intValue = 0;
|
||||||
|
configValues["misc:swallow_regex"].strValue = STRVAL_EMPTY;
|
||||||
|
|
||||||
configValues["debug:int"].intValue = 0;
|
configValues["debug:int"].intValue = 0;
|
||||||
configValues["debug:log_damage"].intValue = 0;
|
configValues["debug:log_damage"].intValue = 0;
|
||||||
@@ -65,7 +68,7 @@ void CConfigManager::setDefaultVars() {
|
|||||||
configValues["debug:disable_logs"].intValue = 0;
|
configValues["debug:disable_logs"].intValue = 0;
|
||||||
configValues["debug:disable_time"].intValue = 1;
|
configValues["debug:disable_time"].intValue = 1;
|
||||||
|
|
||||||
configValues["decoration:rounding"].intValue = 1;
|
configValues["decoration:rounding"].intValue = 0;
|
||||||
configValues["decoration:blur"].intValue = 1;
|
configValues["decoration:blur"].intValue = 1;
|
||||||
configValues["decoration:blur_size"].intValue = 8;
|
configValues["decoration:blur_size"].intValue = 8;
|
||||||
configValues["decoration:blur_passes"].intValue = 1;
|
configValues["decoration:blur_passes"].intValue = 1;
|
||||||
@@ -80,9 +83,11 @@ void CConfigManager::setDefaultVars() {
|
|||||||
configValues["decoration:shadow_range"].intValue = 4;
|
configValues["decoration:shadow_range"].intValue = 4;
|
||||||
configValues["decoration:shadow_render_power"].intValue = 3;
|
configValues["decoration:shadow_render_power"].intValue = 3;
|
||||||
configValues["decoration:shadow_ignore_window"].intValue = 1;
|
configValues["decoration:shadow_ignore_window"].intValue = 1;
|
||||||
configValues["decoration:shadow_offset"].strValue = "0 0";
|
configValues["decoration:shadow_offset"].vecValue = Vector2D();
|
||||||
configValues["decoration:col.shadow"].intValue = 0xee1a1a1a;
|
configValues["decoration:col.shadow"].intValue = 0xee1a1a1a;
|
||||||
configValues["decoration:col.shadow_inactive"].intValue = INT_MAX;
|
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:pseudotile"].intValue = 0;
|
||||||
configValues["dwindle:col.group_border"].intValue = 0x66777700;
|
configValues["dwindle:col.group_border"].intValue = 0x66777700;
|
||||||
@@ -139,7 +144,7 @@ void CConfigManager::setDefaultVars() {
|
|||||||
configValues["input:touchpad:tap-to-click"].intValue = 1;
|
configValues["input:touchpad:tap-to-click"].intValue = 1;
|
||||||
configValues["input:touchpad:drag_lock"].intValue = 0;
|
configValues["input:touchpad:drag_lock"].intValue = 0;
|
||||||
|
|
||||||
configValues["binds:pass_mouse_when_bound"].intValue = 1;
|
configValues["binds:pass_mouse_when_bound"].intValue = 0;
|
||||||
configValues["binds:scroll_event_delay"].intValue = 300;
|
configValues["binds:scroll_event_delay"].intValue = 300;
|
||||||
configValues["binds:workspace_back_and_forth"].intValue = 0;
|
configValues["binds:workspace_back_and_forth"].intValue = 0;
|
||||||
configValues["binds:allow_workspace_cycles"].intValue = 0;
|
configValues["binds:allow_workspace_cycles"].intValue = 0;
|
||||||
@@ -195,6 +200,7 @@ void CConfigManager::setDefaultAnimationVars() {
|
|||||||
INITANIMCFG("fadeOut");
|
INITANIMCFG("fadeOut");
|
||||||
INITANIMCFG("fadeSwitch");
|
INITANIMCFG("fadeSwitch");
|
||||||
INITANIMCFG("fadeShadow");
|
INITANIMCFG("fadeShadow");
|
||||||
|
INITANIMCFG("fadeDim");
|
||||||
|
|
||||||
// border
|
// border
|
||||||
|
|
||||||
@@ -226,6 +232,7 @@ void CConfigManager::setDefaultAnimationVars() {
|
|||||||
CREATEANIMCFG("fadeOut", "fade");
|
CREATEANIMCFG("fadeOut", "fade");
|
||||||
CREATEANIMCFG("fadeSwitch", "fade");
|
CREATEANIMCFG("fadeSwitch", "fade");
|
||||||
CREATEANIMCFG("fadeShadow", "fade");
|
CREATEANIMCFG("fadeShadow", "fade");
|
||||||
|
CREATEANIMCFG("fadeDim", "fade");
|
||||||
|
|
||||||
CREATEANIMCFG("specialWorkspace", "workspaces");
|
CREATEANIMCFG("specialWorkspace", "workspaces");
|
||||||
}
|
}
|
||||||
@@ -287,7 +294,7 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
|||||||
|
|
||||||
CONFIGENTRY->set = true;
|
CONFIGENTRY->set = true;
|
||||||
|
|
||||||
if (CONFIGENTRY->intValue != -1) {
|
if (CONFIGENTRY->intValue != -INT64_MAX) {
|
||||||
try {
|
try {
|
||||||
if (VALUE.find("0x") == 0) {
|
if (VALUE.find("0x") == 0) {
|
||||||
// Values with 0x are hex
|
// Values with 0x are hex
|
||||||
@@ -304,7 +311,7 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
|||||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||||
}
|
}
|
||||||
} else if (CONFIGENTRY->floatValue != -1) {
|
} else if (CONFIGENTRY->floatValue != -__FLT_MAX__) {
|
||||||
try {
|
try {
|
||||||
CONFIGENTRY->floatValue = stof(VALUE);
|
CONFIGENTRY->floatValue = stof(VALUE);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -318,6 +325,23 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
|||||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||||
}
|
}
|
||||||
|
} else if (CONFIGENTRY->vecValue != Vector2D(-__FLT_MAX__, -__FLT_MAX__)) {
|
||||||
|
try {
|
||||||
|
if (const auto SPACEPOS = VALUE.find(' '); SPACEPOS != std::string::npos) {
|
||||||
|
const auto X = VALUE.substr(0, SPACEPOS);
|
||||||
|
const auto Y = VALUE.substr(SPACEPOS + 1);
|
||||||
|
|
||||||
|
if (isNumber(X, true) && isNumber(Y, true)) {
|
||||||
|
CONFIGENTRY->vecValue = Vector2D(std::stof(X), std::stof(Y));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||||
|
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||||
|
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,35 +405,15 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
|||||||
// get the monitor config
|
// get the monitor config
|
||||||
SMonitorRule newrule;
|
SMonitorRule newrule;
|
||||||
|
|
||||||
std::string curitem = "";
|
const auto ARGS = CVarList(args);
|
||||||
|
|
||||||
std::string argZ = args;
|
newrule.name = ARGS[0];
|
||||||
|
|
||||||
auto nextItem = [&]() {
|
if (ARGS[1] == "disable" || ARGS[1] == "disabled" || ARGS[1] == "addreserved" || ARGS[1] == "transform") {
|
||||||
auto idx = argZ.find_first_of(',');
|
if (ARGS[1] == "disable" || ARGS[1] == "disabled")
|
||||||
|
|
||||||
if (idx != std::string::npos) {
|
|
||||||
curitem = argZ.substr(0, idx);
|
|
||||||
argZ = argZ.substr(idx + 1);
|
|
||||||
} else {
|
|
||||||
curitem = argZ;
|
|
||||||
argZ = "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
nextItem();
|
|
||||||
|
|
||||||
newrule.name = curitem;
|
|
||||||
|
|
||||||
nextItem();
|
|
||||||
|
|
||||||
if (curitem == "disable" || curitem == "disabled" || curitem == "addreserved" || curitem == "transform") {
|
|
||||||
if (curitem == "disable" || curitem == "disabled")
|
|
||||||
newrule.disabled = true;
|
newrule.disabled = true;
|
||||||
else if (curitem == "transform") {
|
else if (ARGS[1] == "transform") {
|
||||||
nextItem();
|
wl_output_transform transform = (wl_output_transform)std::stoi(ARGS[2]);
|
||||||
|
|
||||||
wl_output_transform transform = (wl_output_transform)std::stoi(curitem);
|
|
||||||
|
|
||||||
// overwrite if exists
|
// overwrite if exists
|
||||||
for (auto& r : m_dMonitorRules) {
|
for (auto& r : m_dMonitorRules) {
|
||||||
@@ -420,22 +424,14 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else if (curitem == "addreserved") {
|
} else if (ARGS[1] == "addreserved") {
|
||||||
nextItem();
|
int top = std::stoi(ARGS[2]);
|
||||||
|
|
||||||
int top = std::stoi(curitem);
|
int bottom = std::stoi(ARGS[3]);
|
||||||
|
|
||||||
nextItem();
|
int left = std::stoi(ARGS[4]);
|
||||||
|
|
||||||
int bottom = std::stoi(curitem);
|
int right = std::stoi(ARGS[5]);
|
||||||
|
|
||||||
nextItem();
|
|
||||||
|
|
||||||
int left = std::stoi(curitem);
|
|
||||||
|
|
||||||
nextItem();
|
|
||||||
|
|
||||||
int right = std::stoi(curitem);
|
|
||||||
|
|
||||||
m_mAdditionalReservedAreas[newrule.name] = {top, bottom, left, right};
|
m_mAdditionalReservedAreas[newrule.name] = {top, bottom, left, right};
|
||||||
|
|
||||||
@@ -453,23 +449,25 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curitem.find("pref") == 0) {
|
if (ARGS[1].find("pref") == 0) {
|
||||||
newrule.resolution = Vector2D();
|
newrule.resolution = Vector2D();
|
||||||
|
} else if (ARGS[1].find("highrr") == 0) {
|
||||||
|
newrule.resolution = Vector2D(-1,-1);
|
||||||
|
} else if (ARGS[1].find("highres") == 0) {
|
||||||
|
newrule.resolution = Vector2D(-1,-2);
|
||||||
} else {
|
} else {
|
||||||
newrule.resolution.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
|
newrule.resolution.x = stoi(ARGS[1].substr(0, ARGS[1].find_first_of('x')));
|
||||||
newrule.resolution.y = stoi(curitem.substr(curitem.find_first_of('x') + 1, curitem.find_first_of('@')));
|
newrule.resolution.y = stoi(ARGS[1].substr(ARGS[1].find_first_of('x') + 1, ARGS[1].find_first_of('@')));
|
||||||
|
|
||||||
if (curitem.contains("@"))
|
if (ARGS[1].contains("@"))
|
||||||
newrule.refreshRate = stof(curitem.substr(curitem.find_first_of('@') + 1));
|
newrule.refreshRate = stof(ARGS[1].substr(ARGS[1].find_first_of('@') + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
nextItem();
|
if (ARGS[2].find("auto") == 0) {
|
||||||
|
|
||||||
if (curitem.find("auto") == 0) {
|
|
||||||
newrule.offset = Vector2D(-1, -1);
|
newrule.offset = Vector2D(-1, -1);
|
||||||
} else {
|
} else {
|
||||||
newrule.offset.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
|
newrule.offset.x = stoi(ARGS[2].substr(0, ARGS[2].find_first_of('x')));
|
||||||
newrule.offset.y = stoi(curitem.substr(curitem.find_first_of('x') + 1));
|
newrule.offset.y = stoi(ARGS[2].substr(ARGS[2].find_first_of('x') + 1));
|
||||||
|
|
||||||
if (newrule.offset.x < 0 || newrule.offset.y < 0) {
|
if (newrule.offset.x < 0 || newrule.offset.y < 0) {
|
||||||
parseError = "invalid offset. Offset cannot be negative.";
|
parseError = "invalid offset. Offset cannot be negative.";
|
||||||
@@ -477,24 +475,28 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nextItem();
|
newrule.scale = stof(ARGS[3]);
|
||||||
|
|
||||||
newrule.scale = stof(curitem);
|
|
||||||
|
|
||||||
if (newrule.scale < 0.25f) {
|
if (newrule.scale < 0.25f) {
|
||||||
parseError = "not a valid scale.";
|
parseError = "not a valid scale.";
|
||||||
newrule.scale = 1;
|
newrule.scale = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextItem();
|
int argno = 4;
|
||||||
|
|
||||||
if (curitem != "") {
|
while (ARGS[argno] != "") {
|
||||||
// warning for old cfg
|
if (ARGS[argno] == "mirror") {
|
||||||
Debug::log(ERR, "Error in parsing rule for %s, possibly old config!", newrule.name.c_str());
|
newrule.mirrorOf = ARGS[argno + 1];
|
||||||
parseError = "Error in setting monitor rule. Are you using the old syntax? Confront the wiki.";
|
argno++;
|
||||||
|
} else {
|
||||||
|
Debug::log(ERR, "Config error: invalid monitor syntax");
|
||||||
|
parseError = "invalid syntax at \"" + ARGS[argno] + "\"";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argno++;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::find_if(m_dMonitorRules.begin(), m_dMonitorRules.end(), [&](const auto& other) { return other.name == newrule.name; }) != m_dMonitorRules.end())
|
if (std::find_if(m_dMonitorRules.begin(), m_dMonitorRules.end(), [&](const auto& other) { return other.name == newrule.name; }) != m_dMonitorRules.end())
|
||||||
m_dMonitorRules.erase(std::remove_if(m_dMonitorRules.begin(), m_dMonitorRules.end(), [&](const auto& other) { return other.name == newrule.name; }));
|
m_dMonitorRules.erase(std::remove_if(m_dMonitorRules.begin(), m_dMonitorRules.end(), [&](const auto& other) { return other.name == newrule.name; }));
|
||||||
|
|
||||||
@@ -502,44 +504,27 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::handleBezier(const std::string& command, const std::string& args) {
|
void CConfigManager::handleBezier(const std::string& command, const std::string& args) {
|
||||||
std::string curitem = "";
|
const auto ARGS = CVarList(args);
|
||||||
|
|
||||||
std::string argZ = args;
|
std::string bezierName = ARGS[0];
|
||||||
|
|
||||||
auto nextItem = [&]() {
|
if (ARGS[1] == "")
|
||||||
auto idx = argZ.find_first_of(',');
|
|
||||||
|
|
||||||
if (idx != std::string::npos) {
|
|
||||||
curitem = argZ.substr(0, idx);
|
|
||||||
argZ = argZ.substr(idx + 1);
|
|
||||||
} else {
|
|
||||||
curitem = argZ;
|
|
||||||
argZ = "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
nextItem();
|
|
||||||
|
|
||||||
std::string bezierName = curitem;
|
|
||||||
|
|
||||||
nextItem();
|
|
||||||
if (curitem == "")
|
|
||||||
parseError = "too few arguments";
|
parseError = "too few arguments";
|
||||||
float p1x = std::stof(curitem);
|
float p1x = std::stof(ARGS[1]);
|
||||||
nextItem();
|
|
||||||
if (curitem == "")
|
if (ARGS[2] == "")
|
||||||
parseError = "too few arguments";
|
parseError = "too few arguments";
|
||||||
float p1y = std::stof(curitem);
|
float p1y = std::stof(ARGS[2]);
|
||||||
nextItem();
|
|
||||||
if (curitem == "")
|
if (ARGS[3] == "")
|
||||||
parseError = "too few arguments";
|
parseError = "too few arguments";
|
||||||
float p2x = std::stof(curitem);
|
float p2x = std::stof(ARGS[3]);
|
||||||
nextItem();
|
|
||||||
if (curitem == "")
|
if (ARGS[4] == "")
|
||||||
parseError = "too few arguments";
|
parseError = "too few arguments";
|
||||||
float p2y = std::stof(curitem);
|
float p2y = std::stof(ARGS[4]);
|
||||||
nextItem();
|
|
||||||
if (curitem != "")
|
if (ARGS[5] != "")
|
||||||
parseError = "too many arguments";
|
parseError = "too many arguments";
|
||||||
|
|
||||||
g_pAnimationManager->addBezierWithName(bezierName, Vector2D(p1x, p1y), Vector2D(p2x, p2y));
|
g_pAnimationManager->addBezierWithName(bezierName, Vector2D(p1x, p1y), Vector2D(p2x, p2y));
|
||||||
@@ -557,28 +542,12 @@ void CConfigManager::setAnimForChildren(SAnimationPropertyConfig *const ANIM) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void CConfigManager::handleAnimation(const std::string& command, const std::string& args) {
|
void CConfigManager::handleAnimation(const std::string& command, const std::string& args) {
|
||||||
std::string curitem = "";
|
const auto ARGS = CVarList(args);
|
||||||
|
|
||||||
std::string argZ = args;
|
|
||||||
|
|
||||||
auto nextItem = [&]() {
|
|
||||||
auto idx = argZ.find_first_of(',');
|
|
||||||
|
|
||||||
if (idx != std::string::npos) {
|
|
||||||
curitem = argZ.substr(0, idx);
|
|
||||||
argZ = argZ.substr(idx + 1);
|
|
||||||
} else {
|
|
||||||
curitem = argZ;
|
|
||||||
argZ = "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
nextItem();
|
|
||||||
|
|
||||||
// Master on/off
|
// Master on/off
|
||||||
|
|
||||||
// anim name
|
// anim name
|
||||||
const auto ANIMNAME = curitem;
|
const auto ANIMNAME = ARGS[0];
|
||||||
|
|
||||||
const auto PANIM = animationConfig.find(ANIMNAME);
|
const auto PANIM = animationConfig.find(ANIMNAME);
|
||||||
|
|
||||||
@@ -590,20 +559,16 @@ void CConfigManager::handleAnimation(const std::string& command, const std::stri
|
|||||||
PANIM->second.overriden = true;
|
PANIM->second.overriden = true;
|
||||||
PANIM->second.pValues = &PANIM->second;
|
PANIM->second.pValues = &PANIM->second;
|
||||||
|
|
||||||
nextItem();
|
|
||||||
|
|
||||||
// on/off
|
// on/off
|
||||||
PANIM->second.internalEnabled = curitem == "1";
|
PANIM->second.internalEnabled = ARGS[1] == "1";
|
||||||
|
|
||||||
if (curitem != "0" && curitem != "1") {
|
if (ARGS[1] != "0" && ARGS[1] != "1") {
|
||||||
parseError = "invalid animation on/off state";
|
parseError = "invalid animation on/off state";
|
||||||
}
|
}
|
||||||
|
|
||||||
nextItem();
|
|
||||||
|
|
||||||
// speed
|
// speed
|
||||||
if (isNumber(curitem, true)) {
|
if (isNumber(ARGS[2], true)) {
|
||||||
PANIM->second.internalSpeed = std::stof(curitem);
|
PANIM->second.internalSpeed = std::stof(ARGS[2]);
|
||||||
|
|
||||||
if (PANIM->second.internalSpeed <= 0) {
|
if (PANIM->second.internalSpeed <= 0) {
|
||||||
parseError = "invalid speed";
|
parseError = "invalid speed";
|
||||||
@@ -614,23 +579,19 @@ void CConfigManager::handleAnimation(const std::string& command, const std::stri
|
|||||||
parseError = "invalid speed";
|
parseError = "invalid speed";
|
||||||
}
|
}
|
||||||
|
|
||||||
nextItem();
|
|
||||||
|
|
||||||
// curve
|
// curve
|
||||||
PANIM->second.internalBezier = curitem;
|
PANIM->second.internalBezier = ARGS[3];
|
||||||
|
|
||||||
if (!g_pAnimationManager->bezierExists(curitem)) {
|
if (!g_pAnimationManager->bezierExists(ARGS[3])) {
|
||||||
parseError = "no such bezier";
|
parseError = "no such bezier";
|
||||||
PANIM->second.internalBezier = "default";
|
PANIM->second.internalBezier = "default";
|
||||||
}
|
}
|
||||||
|
|
||||||
nextItem();
|
|
||||||
|
|
||||||
// style
|
// style
|
||||||
PANIM->second.internalStyle = curitem;
|
PANIM->second.internalStyle = ARGS[4];
|
||||||
|
|
||||||
if (curitem != "") {
|
if (ARGS[4] != "") {
|
||||||
const auto ERR = g_pAnimationManager->styleValidInConfigVar(ANIMNAME, curitem);
|
const auto ERR = g_pAnimationManager->styleValidInConfigVar(ANIMNAME, ARGS[4]);
|
||||||
|
|
||||||
if (ERR != "")
|
if (ERR != "")
|
||||||
parseError = ERR;
|
parseError = ERR;
|
||||||
@@ -648,15 +609,18 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
|||||||
bool locked = false;
|
bool locked = false;
|
||||||
bool release = false;
|
bool release = false;
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
const auto ARGS = command.substr(4);
|
bool mouse = false;
|
||||||
|
const auto BINDARGS = command.substr(4);
|
||||||
|
|
||||||
for (auto& arg : ARGS) {
|
for (auto& arg : BINDARGS) {
|
||||||
if (arg == 'l') {
|
if (arg == 'l') {
|
||||||
locked = true;
|
locked = true;
|
||||||
} else if (arg == 'r') {
|
} else if (arg == 'r') {
|
||||||
release = true;
|
release = true;
|
||||||
} else if (arg == 'e') {
|
} else if (arg == 'e') {
|
||||||
repeat = true;
|
repeat = true;
|
||||||
|
} else if (arg == 'm') {
|
||||||
|
mouse = true;
|
||||||
} else {
|
} else {
|
||||||
parseError = "bind: invalid flag";
|
parseError = "bind: invalid flag";
|
||||||
return;
|
return;
|
||||||
@@ -668,19 +632,35 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto valueCopy = value;
|
if (mouse && (repeat || release || locked)) {
|
||||||
|
parseError = "flag m is exclusive";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto MOD = g_pKeybindManager->stringToModMask(valueCopy.substr(0, valueCopy.find_first_of(",")));
|
const auto ARGS = CVarList(value, 4);
|
||||||
const auto MODSTR = valueCopy.substr(0, valueCopy.find_first_of(","));
|
|
||||||
valueCopy = valueCopy.substr(valueCopy.find_first_of(",") + 1);
|
|
||||||
|
|
||||||
const auto KEY = valueCopy.substr(0, valueCopy.find_first_of(","));
|
if ((ARGS.size() < 3 && !mouse) || (ARGS.size() < 3 && mouse)) {
|
||||||
valueCopy = valueCopy.substr(valueCopy.find_first_of(",") + 1);
|
parseError = "bind: too few args";
|
||||||
|
return;
|
||||||
|
} else if ((ARGS.size() > 4 && !mouse) || (ARGS.size() > 3 && mouse)) {
|
||||||
|
parseError = "bind: too many args";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto HANDLER = valueCopy.substr(0, valueCopy.find_first_of(","));
|
const auto MOD = g_pKeybindManager->stringToModMask(ARGS[0]);
|
||||||
valueCopy = valueCopy.substr(valueCopy.find_first_of(",") + 1);
|
const auto MODSTR = ARGS[0];
|
||||||
|
|
||||||
const auto COMMAND = valueCopy;
|
const auto KEY = ARGS[1];
|
||||||
|
|
||||||
|
auto HANDLER = ARGS[2];
|
||||||
|
|
||||||
|
const auto COMMAND = mouse ? HANDLER : ARGS[3];
|
||||||
|
|
||||||
|
if (mouse)
|
||||||
|
HANDLER = "mouse";
|
||||||
|
|
||||||
|
// to lower
|
||||||
|
std::transform(HANDLER.begin(), HANDLER.end(), HANDLER.begin(), ::tolower);
|
||||||
|
|
||||||
const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find(HANDLER);
|
const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find(HANDLER);
|
||||||
|
|
||||||
@@ -703,35 +683,24 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
|||||||
|
|
||||||
if (KEY != "") {
|
if (KEY != "") {
|
||||||
if (isNumber(KEY) && std::stoi(KEY) > 9)
|
if (isNumber(KEY) && std::stoi(KEY) > 9)
|
||||||
g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat});
|
g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse});
|
||||||
else
|
else
|
||||||
g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat});
|
g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::handleUnbind(const std::string& command, const std::string& value) {
|
void CConfigManager::handleUnbind(const std::string& command, const std::string& value) {
|
||||||
auto valueCopy = value;
|
const auto ARGS = CVarList(value);
|
||||||
|
|
||||||
const auto MOD = g_pKeybindManager->stringToModMask(valueCopy.substr(0, valueCopy.find_first_of(",")));
|
const auto MOD = g_pKeybindManager->stringToModMask(ARGS[0]);
|
||||||
valueCopy = valueCopy.substr(valueCopy.find_first_of(",") + 1);
|
|
||||||
|
|
||||||
const auto KEY = valueCopy;
|
const auto KEY = ARGS[1];
|
||||||
|
|
||||||
g_pKeybindManager->removeKeybind(MOD, KEY);
|
g_pKeybindManager->removeKeybind(MOD, KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::handleWindowRule(const std::string& command, const std::string& value) {
|
bool windowRuleValid(const std::string& RULE) {
|
||||||
const auto RULE = value.substr(0, value.find_first_of(","));
|
return !(RULE != "float"
|
||||||
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"
|
|
||||||
&& RULE != "tile"
|
&& RULE != "tile"
|
||||||
&& RULE.find("opacity") != 0
|
&& RULE.find("opacity") != 0
|
||||||
&& RULE.find("move") != 0
|
&& RULE.find("move") != 0
|
||||||
@@ -744,21 +713,100 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str
|
|||||||
&& RULE != "opaque"
|
&& RULE != "opaque"
|
||||||
&& RULE != "forceinput"
|
&& RULE != "forceinput"
|
||||||
&& RULE != "fullscreen"
|
&& RULE != "fullscreen"
|
||||||
|
&& RULE != "pin"
|
||||||
&& RULE.find("animation") != 0
|
&& RULE.find("animation") != 0
|
||||||
&& RULE.find("rounding") != 0
|
&& RULE.find("rounding") != 0
|
||||||
&& RULE.find("workspace") != 0) {
|
&& RULE.find("workspace") != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CConfigManager::handleWindowRule(const std::string& command, const std::string& value) {
|
||||||
|
const auto RULE = removeBeginEndSpacesTabs(value.substr(0, value.find_first_of(",")));
|
||||||
|
const auto VALUE = removeBeginEndSpacesTabs(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());
|
Debug::log(ERR, "Invalid rule found: %s", RULE.c_str());
|
||||||
parseError = "Invalid rule found: " + RULE;
|
parseError = "Invalid rule found: " + RULE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dWindowRules.push_back({RULE, VALUE});
|
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);
|
||||||
|
|
||||||
|
result = removeBeginEndSpacesTabs(result);
|
||||||
|
|
||||||
|
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) {
|
void CConfigManager::handleBlurLS(const std::string& command, const std::string& value) {
|
||||||
if (value.find("remove,") == 0) {
|
if (value.find("remove,") == 0) {
|
||||||
const auto TOREMOVE = value.substr(7);
|
const auto TOREMOVE = removeBeginEndSpacesTabs(value.substr(7));
|
||||||
m_dBlurLSNamespaces.erase(std::remove(m_dBlurLSNamespaces.begin(), m_dBlurLSNamespaces.end(), TOREMOVE));
|
m_dBlurLSNamespaces.erase(std::remove(m_dBlurLSNamespaces.begin(), m_dBlurLSNamespaces.end(), TOREMOVE));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -767,13 +815,11 @@ void CConfigManager::handleBlurLS(const std::string& command, const std::string&
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::handleDefaultWorkspace(const std::string& command, const std::string& value) {
|
void CConfigManager::handleDefaultWorkspace(const std::string& command, const std::string& value) {
|
||||||
|
const auto ARGS = CVarList(value);
|
||||||
const auto DISPLAY = value.substr(0, value.find_first_of(','));
|
|
||||||
const auto WORKSPACE = value.substr(value.find_first_of(',') + 1);
|
|
||||||
|
|
||||||
for (auto& mr : m_dMonitorRules) {
|
for (auto& mr : m_dMonitorRules) {
|
||||||
if (mr.name == DISPLAY) {
|
if (mr.name == ARGS[0]) {
|
||||||
mr.defaultWorkspace = WORKSPACE;
|
mr.defaultWorkspace = ARGS[1];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -840,6 +886,19 @@ void CConfigManager::handleSource(const std::string& command, const std::string&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CConfigManager::handleBindWS(const std::string& command, const std::string& value) {
|
||||||
|
const auto ARGS = CVarList(value);
|
||||||
|
|
||||||
|
const auto FOUND = std::find_if(boundWorkspaces.begin(), boundWorkspaces.end(), [&](const auto& other) { return other.first == ARGS[0]; });
|
||||||
|
|
||||||
|
if (FOUND != boundWorkspaces.end()) {
|
||||||
|
FOUND->second = ARGS[1];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boundWorkspaces.push_back({ARGS[0], ARGS[1]});
|
||||||
|
}
|
||||||
|
|
||||||
std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::string& VALUE, bool dynamic) {
|
std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::string& VALUE, bool dynamic) {
|
||||||
if (dynamic) {
|
if (dynamic) {
|
||||||
parseError = "";
|
parseError = "";
|
||||||
@@ -862,11 +921,13 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
|||||||
else if (COMMAND == "unbind") handleUnbind(COMMAND, VALUE);
|
else if (COMMAND == "unbind") handleUnbind(COMMAND, VALUE);
|
||||||
else if (COMMAND == "workspace") handleDefaultWorkspace(COMMAND, VALUE);
|
else if (COMMAND == "workspace") handleDefaultWorkspace(COMMAND, VALUE);
|
||||||
else if (COMMAND == "windowrule") handleWindowRule(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 == "bezier") handleBezier(COMMAND, VALUE);
|
||||||
else if (COMMAND == "animation") handleAnimation(COMMAND, VALUE);
|
else if (COMMAND == "animation") handleAnimation(COMMAND, VALUE);
|
||||||
else if (COMMAND == "source") handleSource(COMMAND, VALUE);
|
else if (COMMAND == "source") handleSource(COMMAND, VALUE);
|
||||||
else if (COMMAND == "submap") handleSubmap(COMMAND, VALUE);
|
else if (COMMAND == "submap") handleSubmap(COMMAND, VALUE);
|
||||||
else if (COMMAND == "blurls") handleBlurLS(COMMAND, VALUE);
|
else if (COMMAND == "blurls") handleBlurLS(COMMAND, VALUE);
|
||||||
|
else if (COMMAND == "wsbind") handleBindWS(COMMAND, VALUE);
|
||||||
else
|
else
|
||||||
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
||||||
|
|
||||||
@@ -978,6 +1039,7 @@ void CConfigManager::loadConfigLoadVars() {
|
|||||||
configDynamicVars.clear();
|
configDynamicVars.clear();
|
||||||
deviceConfigs.clear();
|
deviceConfigs.clear();
|
||||||
m_dBlurLSNamespaces.clear();
|
m_dBlurLSNamespaces.clear();
|
||||||
|
boundWorkspaces.clear();
|
||||||
setDefaultAnimationVars(); // reset anims
|
setDefaultAnimationVars(); // reset anims
|
||||||
|
|
||||||
// paths
|
// paths
|
||||||
@@ -1100,13 +1162,13 @@ void CConfigManager::loadConfigLoadVars() {
|
|||||||
// update layout
|
// update layout
|
||||||
g_pLayoutManager->switchToLayout(configValues["general:layout"].strValue);
|
g_pLayoutManager->switchToLayout(configValues["general:layout"].strValue);
|
||||||
|
|
||||||
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
// mark blur dirty
|
// mark blur dirty
|
||||||
for (auto& m : g_pCompositor->m_vMonitors)
|
|
||||||
g_pHyprOpenGL->markBlurDirtyForMonitor(m.get());
|
g_pHyprOpenGL->markBlurDirtyForMonitor(m.get());
|
||||||
|
|
||||||
// Force the compositor to fully re-render all monitors
|
// Force the compositor to fully re-render all monitors
|
||||||
for (auto& m : g_pCompositor->m_vMonitors)
|
|
||||||
m->forceFullFrames = 2;
|
m->forceFullFrames = 2;
|
||||||
|
}
|
||||||
|
|
||||||
// Reset no monitor reload
|
// Reset no monitor reload
|
||||||
m_bNoMonitorReload = false;
|
m_bNoMonitorReload = false;
|
||||||
@@ -1275,6 +1337,7 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow) {
|
|||||||
|
|
||||||
for (auto& rule : m_dWindowRules) {
|
for (auto& rule : m_dWindowRules) {
|
||||||
// check if we have a matching rule
|
// check if we have a matching rule
|
||||||
|
if (!rule.v2) {
|
||||||
try {
|
try {
|
||||||
if (rule.szValue.find("title:") == 0) {
|
if (rule.szValue.find("title:") == 0) {
|
||||||
// we have a title rule.
|
// we have a title rule.
|
||||||
@@ -1292,6 +1355,36 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow) {
|
|||||||
Debug::log(ERR, "Regex error at %s", rule.szValue.c_str());
|
Debug::log(ERR, "Regex error at %s", rule.szValue.c_str());
|
||||||
continue;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// applies. Read the rule and behave accordingly
|
// applies. Read the rule and behave accordingly
|
||||||
Debug::log(LOG, "Window rule %s -> %s matched %x [%s]", rule.szRule.c_str(), rule.szValue.c_str(), pWindow, pWindow->m_szTitle.c_str());
|
Debug::log(LOG, "Window rule %s -> %s matched %x [%s]", rule.szRule.c_str(), rule.szValue.c_str(), pWindow, pWindow->m_szTitle.c_str());
|
||||||
@@ -1330,10 +1423,16 @@ void CConfigManager::performMonitorReload() {
|
|||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||||
auto rule = getMonitorRuleFor(m->szName);
|
auto rule = getMonitorRuleFor(m->szName);
|
||||||
|
|
||||||
|
// ensure mirror
|
||||||
|
m->setMirror(rule.mirrorOf);
|
||||||
|
|
||||||
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule)) {
|
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule)) {
|
||||||
overAgain = true;
|
overAgain = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_pHyprRenderer->arrangeLayersForMonitor(m->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overAgain)
|
if (overAgain)
|
||||||
@@ -1393,3 +1492,15 @@ void CConfigManager::addParseError(const std::string& err) {
|
|||||||
if (parseError == "")
|
if (parseError == "")
|
||||||
parseError = err;
|
parseError = err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMonitor* CConfigManager::getBoundMonitorForWS(std::string wsname) {
|
||||||
|
for (auto&[ws, mon] : boundWorkspaces) {
|
||||||
|
const auto WSNAME = ws.find("name:") == 0 ? ws.substr(5) : ws;
|
||||||
|
|
||||||
|
if (WSNAME == wsname) {
|
||||||
|
return g_pCompositor->getMonitorFromString(mon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
@@ -20,9 +20,10 @@
|
|||||||
#define CREATEANIMCFG(name, parent) animationConfig[name] = {false, "", "", 0.f, -1, &animationConfig["global"], &animationConfig[parent]}
|
#define CREATEANIMCFG(name, parent) animationConfig[name] = {false, "", "", 0.f, -1, &animationConfig["global"], &animationConfig[parent]}
|
||||||
|
|
||||||
struct SConfigValue {
|
struct SConfigValue {
|
||||||
int64_t intValue = -1;
|
int64_t intValue = -INT64_MAX;
|
||||||
float floatValue = -1;
|
float floatValue = -__FLT_MAX__;
|
||||||
std::string strValue = "";
|
std::string strValue = "";
|
||||||
|
Vector2D vecValue = Vector2D(-__FLT_MAX__, -__FLT_MAX__);
|
||||||
|
|
||||||
bool set = false; // used for device configs
|
bool set = false; // used for device configs
|
||||||
};
|
};
|
||||||
@@ -36,6 +37,7 @@ struct SMonitorRule {
|
|||||||
std::string defaultWorkspace = "";
|
std::string defaultWorkspace = "";
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
|
std::string mirrorOf = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SMonitorAdditionalReservedArea {
|
struct SMonitorAdditionalReservedArea {
|
||||||
@@ -48,6 +50,12 @@ struct SMonitorAdditionalReservedArea {
|
|||||||
struct SWindowRule {
|
struct SWindowRule {
|
||||||
std::string szRule;
|
std::string szRule;
|
||||||
std::string szValue;
|
std::string szValue;
|
||||||
|
|
||||||
|
bool v2 = false;
|
||||||
|
std::string szTitle;
|
||||||
|
std::string szClass;
|
||||||
|
int bX11 = -1; // -1 means "ANY"
|
||||||
|
int bFloating = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SAnimationPropertyConfig {
|
struct SAnimationPropertyConfig {
|
||||||
@@ -62,6 +70,48 @@ struct SAnimationPropertyConfig {
|
|||||||
SAnimationPropertyConfig* pParentAnimation = nullptr;
|
SAnimationPropertyConfig* pParentAnimation = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CVarList {
|
||||||
|
public:
|
||||||
|
CVarList(const std::string& in, long unsigned int lastArgNo = 0) {
|
||||||
|
std::string curitem = "";
|
||||||
|
std::string argZ = in;
|
||||||
|
|
||||||
|
auto nextItem = [&]() {
|
||||||
|
auto idx = lastArgNo != 0 && m_vArgs.size() >= lastArgNo - 1 ? std::string::npos : argZ.find_first_of(',');
|
||||||
|
|
||||||
|
if (idx != std::string::npos) {
|
||||||
|
curitem = argZ.substr(0, idx);
|
||||||
|
argZ = argZ.substr(idx + 1);
|
||||||
|
} else {
|
||||||
|
curitem = argZ;
|
||||||
|
argZ = STRVAL_EMPTY;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
nextItem();
|
||||||
|
|
||||||
|
while (curitem != STRVAL_EMPTY) {
|
||||||
|
m_vArgs.push_back(removeBeginEndSpacesTabs(curitem));
|
||||||
|
nextItem();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
~CVarList() = default;
|
||||||
|
|
||||||
|
int size() const {
|
||||||
|
return m_vArgs.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string operator[](const long unsigned int& idx) const {
|
||||||
|
if (idx >= m_vArgs.size())
|
||||||
|
return "";
|
||||||
|
return m_vArgs[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::string> m_vArgs;
|
||||||
|
};
|
||||||
|
|
||||||
class CConfigManager {
|
class CConfigManager {
|
||||||
public:
|
public:
|
||||||
CConfigManager();
|
CConfigManager();
|
||||||
@@ -87,6 +137,8 @@ public:
|
|||||||
|
|
||||||
SMonitorRule getMonitorRuleFor(std::string);
|
SMonitorRule getMonitorRuleFor(std::string);
|
||||||
|
|
||||||
|
CMonitor* getBoundMonitorForWS(std::string);
|
||||||
|
|
||||||
std::vector<SWindowRule> getMatchingRules(CWindow*);
|
std::vector<SWindowRule> getMatchingRules(CWindow*);
|
||||||
|
|
||||||
std::unordered_map<std::string, SMonitorAdditionalReservedArea> m_mAdditionalReservedAreas;
|
std::unordered_map<std::string, SMonitorAdditionalReservedArea> m_mAdditionalReservedAreas;
|
||||||
@@ -123,6 +175,8 @@ private:
|
|||||||
|
|
||||||
std::string m_szCurrentSubmap = ""; // For storing the current keybind submap
|
std::string m_szCurrentSubmap = ""; // For storing the current keybind submap
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> boundWorkspaces;
|
||||||
|
|
||||||
bool isFirstLaunch = true; // For exec-once
|
bool isFirstLaunch = true; // For exec-once
|
||||||
|
|
||||||
std::deque<SMonitorRule> m_dMonitorRules;
|
std::deque<SMonitorRule> m_dMonitorRules;
|
||||||
@@ -151,12 +205,14 @@ private:
|
|||||||
void handleBind(const std::string&, const std::string&);
|
void handleBind(const std::string&, const std::string&);
|
||||||
void handleUnbind(const std::string&, const std::string&);
|
void handleUnbind(const std::string&, const std::string&);
|
||||||
void handleWindowRule(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 handleDefaultWorkspace(const std::string&, const std::string&);
|
||||||
void handleBezier(const std::string&, const std::string&);
|
void handleBezier(const std::string&, const std::string&);
|
||||||
void handleAnimation(const std::string&, const std::string&);
|
void handleAnimation(const std::string&, const std::string&);
|
||||||
void handleSource(const std::string&, const std::string&);
|
void handleSource(const std::string&, const std::string&);
|
||||||
void handleSubmap(const std::string&, const std::string&);
|
void handleSubmap(const std::string&, const std::string&);
|
||||||
void handleBlurLS(const std::string&, const std::string&);
|
void handleBlurLS(const std::string&, const std::string&);
|
||||||
|
void handleBindWS(const std::string&, const std::string&);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
||||||
|
@@ -83,6 +83,10 @@ gestures {
|
|||||||
#windowrule=pseudo,abc
|
#windowrule=pseudo,abc
|
||||||
#windowrule=monitor 0,xyz
|
#windowrule=monitor 0,xyz
|
||||||
|
|
||||||
|
# some nice mouse binds
|
||||||
|
bindm=SUPER,mouse:272,movewindow
|
||||||
|
bindm=SUPER,mouse:273,resizewindow
|
||||||
|
|
||||||
# example binds
|
# example binds
|
||||||
bind=SUPER,Q,exec,kitty
|
bind=SUPER,Q,exec,kitty
|
||||||
bind=SUPER,RETURN,exec,alacritty
|
bind=SUPER,RETURN,exec,alacritty
|
||||||
|
@@ -85,7 +85,10 @@ R"#({
|
|||||||
"class": "%s",
|
"class": "%s",
|
||||||
"title": "%s",
|
"title": "%s",
|
||||||
"pid": %i,
|
"pid": %i,
|
||||||
"xwayland": %s
|
"xwayland": %s,
|
||||||
|
"pinned": %s,
|
||||||
|
"fullscreen": %s,
|
||||||
|
"fullscreenMode": %i
|
||||||
},)#",
|
},)#",
|
||||||
w.get(),
|
w.get(),
|
||||||
(int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y,
|
(int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y,
|
||||||
@@ -96,7 +99,10 @@ R"#({
|
|||||||
escapeJSONStrings(g_pXWaylandManager->getAppIDClass(w.get())).c_str(),
|
escapeJSONStrings(g_pXWaylandManager->getAppIDClass(w.get())).c_str(),
|
||||||
escapeJSONStrings(g_pXWaylandManager->getTitle(w.get())).c_str(),
|
escapeJSONStrings(g_pXWaylandManager->getTitle(w.get())).c_str(),
|
||||||
w->getPID(),
|
w->getPID(),
|
||||||
((int)w->m_bIsX11 == 1 ? "true" : "false")
|
((int)w->m_bIsX11 == 1 ? "true" : "false"),
|
||||||
|
(w->m_bPinned ? "true" : "false"),
|
||||||
|
(w->m_bIsFullscreen ? "true" : "false"),
|
||||||
|
(w->m_bIsFullscreen ? (g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_efFullscreenMode : 0) : 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,8 +115,8 @@ R"#({
|
|||||||
} else {
|
} else {
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
if (w->m_bIsMapped) {
|
if (w->m_bIsMapped) {
|
||||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\txwayland: %i\n\n",
|
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\txwayland: %i\n\tpinned: %i\n\tfullscreen: %i\n\tfullscreenmode: %i\n\n",
|
||||||
w.get(), w->m_szTitle.c_str(), (int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y, (int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w.get()).c_str(), g_pXWaylandManager->getTitle(w.get()).c_str(), w->getPID(), (int)w->m_bIsX11);
|
w.get(), w->m_szTitle.c_str(), (int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y, (int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w.get()).c_str(), g_pXWaylandManager->getTitle(w.get()).c_str(), w->getPID(), (int)w->m_bIsX11, (int)w->m_bPinned, (int)w->m_bIsFullscreen, (w->m_bIsFullscreen ? (g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_efFullscreenMode : 0) : 0));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,19 +130,25 @@ std::string workspacesRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
|||||||
result += "[";
|
result += "[";
|
||||||
|
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||||
|
const auto PLASTW = w->getLastFocusedWindow();
|
||||||
|
|
||||||
result += getFormat(
|
result += getFormat(
|
||||||
R"#({
|
R"#({
|
||||||
"id": %i,
|
"id": %i,
|
||||||
"name": "%s",
|
"name": "%s",
|
||||||
"monitor": "%s",
|
"monitor": "%s",
|
||||||
"windows": %i,
|
"windows": %i,
|
||||||
"hasfullscreen": %s
|
"hasfullscreen": %s,
|
||||||
|
"lastwindow": "0x%x",
|
||||||
|
"lastwindowtitle": "%s"
|
||||||
},)#",
|
},)#",
|
||||||
w->m_iID,
|
w->m_iID,
|
||||||
escapeJSONStrings(w->m_szName).c_str(),
|
escapeJSONStrings(w->m_szName).c_str(),
|
||||||
escapeJSONStrings(g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName).c_str(),
|
escapeJSONStrings(g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName).c_str(),
|
||||||
g_pCompositor->getWindowsOnWorkspace(w->m_iID),
|
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 +158,9 @@ R"#({
|
|||||||
result += "]";
|
result += "]";
|
||||||
} else {
|
} else {
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||||
result += getFormat("workspace ID %i (%s) on monitor %s:\n\twindows: %i\n\thasfullscreen: %i\n\n",
|
const auto PLASTW = w->getLastFocusedWindow();
|
||||||
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);
|
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;
|
return result;
|
||||||
@@ -287,10 +300,12 @@ std::string devicesRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
|||||||
result += getFormat(
|
result += getFormat(
|
||||||
R"#( {
|
R"#( {
|
||||||
"address": "0x%x",
|
"address": "0x%x",
|
||||||
"name": "%s"
|
"name": "%s",
|
||||||
|
"defaultSpeed": %f
|
||||||
},)#",
|
},)#",
|
||||||
&m,
|
&m,
|
||||||
escapeJSONStrings(m.mouse->name).c_str()
|
escapeJSONStrings(m.mouse->name).c_str(),
|
||||||
|
wlr_input_device_is_libinput(m.mouse) ? libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(m.mouse)) : 0.f
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,6 +385,23 @@ R"#( {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove trailing comma
|
||||||
|
result.pop_back();
|
||||||
|
result += "\n],\n";
|
||||||
|
|
||||||
|
result += "\"touch\": [\n";
|
||||||
|
|
||||||
|
for (auto& d : g_pInputManager->m_lTouchDevices) {
|
||||||
|
result += getFormat(
|
||||||
|
R"#( {
|
||||||
|
"address": "0x%x",
|
||||||
|
"name": "%s"
|
||||||
|
},)#",
|
||||||
|
&d,
|
||||||
|
d.pWlrDevice ? d.pWlrDevice->name : ""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// remove trailing comma
|
// remove trailing comma
|
||||||
if (result[result.size() - 1] == ',')
|
if (result[result.size() - 1] == ',')
|
||||||
result.pop_back();
|
result.pop_back();
|
||||||
@@ -381,7 +413,7 @@ R"#( {
|
|||||||
result += "mice:\n";
|
result += "mice:\n";
|
||||||
|
|
||||||
for (auto& m : g_pInputManager->m_lMice) {
|
for (auto& m : g_pInputManager->m_lMice) {
|
||||||
result += getFormat("\tMouse at %x:\n\t\t%s\n", &m, m.mouse->name);
|
result += getFormat("\tMouse at %x:\n\t\t%s\n\t\t\tdefault speed: %f\n", &m, m.mouse->name, (wlr_input_device_is_libinput(m.mouse) ? libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(m.mouse)) : 0.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
result += "\n\nKeyboards:\n";
|
result += "\n\nKeyboards:\n";
|
||||||
@@ -404,6 +436,12 @@ R"#( {
|
|||||||
for (auto& d : g_pInputManager->m_lTabletTools) {
|
for (auto& d : g_pInputManager->m_lTabletTools) {
|
||||||
result += getFormat("\tTablet Tool at %x (belongs to %x)\n", &d, d.wlrTabletTool ? d.wlrTabletTool->data : 0);
|
result += getFormat("\tTablet Tool at %x (belongs to %x)\n", &d, d.wlrTabletTool ? d.wlrTabletTool->data : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result += "\n\nTouch:\n";
|
||||||
|
|
||||||
|
for (auto& d : g_pInputManager->m_lTouchDevices) {
|
||||||
|
result += getFormat("\tTouch Device at %x:\n\t\t%s\n", &d, d.pWlrDevice ? d.pWlrDevice->name : "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -519,6 +557,8 @@ std::string reloadRequest(std::string request) {
|
|||||||
g_pConfigManager->m_bNoMonitorReload = true;
|
g_pConfigManager->m_bNoMonitorReload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_pConfigManager->tick();
|
||||||
|
|
||||||
return "ok";
|
return "ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,9 +752,21 @@ std::string getReply(std::string request) {
|
|||||||
return "unknown request";
|
return "unknown request";
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyprCtl::tickHyprCtl() {
|
int hyprCtlFDTick(int fd, uint32_t mask, void* data) {
|
||||||
if (!requestMade)
|
if (mask & WL_EVENT_ERROR || mask & WL_EVENT_HANGUP)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
|
sockaddr_in clientAddress;
|
||||||
|
socklen_t clientSize = sizeof(clientAddress);
|
||||||
|
|
||||||
|
const auto ACCEPTEDCONNECTION = accept(HyprCtl::iSocketFD, (sockaddr*)&clientAddress, &clientSize);
|
||||||
|
|
||||||
|
char readBuffer[1024];
|
||||||
|
|
||||||
|
auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024);
|
||||||
|
readBuffer[messageSize == 1024 ? 1023 : messageSize] = '\0';
|
||||||
|
|
||||||
|
std::string request(readBuffer);
|
||||||
|
|
||||||
std::string reply = "";
|
std::string reply = "";
|
||||||
|
|
||||||
@@ -725,44 +777,22 @@ void HyprCtl::tickHyprCtl() {
|
|||||||
reply = "Err: " + std::string(e.what());
|
reply = "Err: " + std::string(e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
request = reply;
|
write(ACCEPTEDCONNECTION, reply.c_str(), reply.length());
|
||||||
|
|
||||||
requestMade = false;
|
close(ACCEPTEDCONNECTION);
|
||||||
requestReady = true;
|
|
||||||
|
|
||||||
if (g_pConfigManager->m_bWantsMonitorReload) {
|
if (g_pConfigManager->m_bWantsMonitorReload) {
|
||||||
g_pConfigManager->ensureDPMS();
|
g_pConfigManager->ensureDPMS();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
std::string getRequestFromThread(std::string rq) {
|
return 0;
|
||||||
|
|
||||||
while (HyprCtl::request != "" || HyprCtl::requestMade || HyprCtl::requestReady) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
HyprCtl::request = rq;
|
|
||||||
HyprCtl::requestMade = true;
|
|
||||||
|
|
||||||
while (!HyprCtl::requestReady) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
HyprCtl::requestReady = false;
|
|
||||||
HyprCtl::requestMade = false;
|
|
||||||
|
|
||||||
std::string toReturn = HyprCtl::request;
|
|
||||||
|
|
||||||
HyprCtl::request = "";
|
|
||||||
|
|
||||||
return toReturn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyprCtl::startHyprCtlSocket() {
|
void HyprCtl::startHyprCtlSocket() {
|
||||||
tThread = std::thread([&]() {
|
|
||||||
const auto SOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
||||||
|
|
||||||
if (SOCKET < 0) {
|
iSocketFD = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (iSocketFD < 0) {
|
||||||
Debug::log(ERR, "Couldn't start the Hyprland Socket. (1) IPC will not work.");
|
Debug::log(ERR, "Couldn't start the Hyprland Socket. (1) IPC will not work.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -773,40 +803,12 @@ void HyprCtl::startHyprCtlSocket() {
|
|||||||
|
|
||||||
strcpy(SERVERADDRESS.sun_path, socketPath.c_str());
|
strcpy(SERVERADDRESS.sun_path, socketPath.c_str());
|
||||||
|
|
||||||
bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
|
bind(iSocketFD, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
|
||||||
|
|
||||||
// 10 max queued.
|
// 10 max queued.
|
||||||
listen(SOCKET, 10);
|
listen(iSocketFD, 10);
|
||||||
|
|
||||||
sockaddr_in clientAddress;
|
|
||||||
socklen_t clientSize = sizeof(clientAddress);
|
|
||||||
|
|
||||||
char readBuffer[1024] = {0};
|
|
||||||
|
|
||||||
Debug::log(LOG, "Hypr socket started at %s", socketPath.c_str());
|
Debug::log(LOG, "Hypr socket started at %s", socketPath.c_str());
|
||||||
|
|
||||||
while(1) {
|
wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, iSocketFD, WL_EVENT_READABLE, hyprCtlFDTick, nullptr);
|
||||||
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);
|
|
||||||
|
|
||||||
if (ACCEPTEDCONNECTION < 0) {
|
|
||||||
Debug::log(ERR, "Couldn't listen on the Hyprland Socket. (3) IPC will not work.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024);
|
|
||||||
readBuffer[messageSize == 1024 ? 1023 : messageSize] = '\0';
|
|
||||||
|
|
||||||
std::string request(readBuffer);
|
|
||||||
|
|
||||||
std::string reply = getRequestFromThread(request);
|
|
||||||
|
|
||||||
write(ACCEPTEDCONNECTION, reply.c_str(), reply.length());
|
|
||||||
|
|
||||||
close(ACCEPTEDCONNECTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(SOCKET);
|
|
||||||
});
|
|
||||||
|
|
||||||
tThread.detach();
|
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
namespace HyprCtl {
|
namespace HyprCtl {
|
||||||
void startHyprCtlSocket();
|
void startHyprCtlSocket();
|
||||||
void tickHyprCtl();
|
|
||||||
|
|
||||||
// very simple thread-safe request method
|
// very simple thread-safe request method
|
||||||
inline bool requestMade = false;
|
inline bool requestMade = false;
|
||||||
@@ -15,7 +14,9 @@ namespace HyprCtl {
|
|||||||
|
|
||||||
inline std::ifstream requestStream;
|
inline std::ifstream requestStream;
|
||||||
|
|
||||||
inline std::thread tThread;
|
inline wl_event_source* hyprCtlTickSource = nullptr;
|
||||||
|
|
||||||
|
inline int iSocketFD = -1;
|
||||||
|
|
||||||
enum eHyprCtlOutputFormat {
|
enum eHyprCtlOutputFormat {
|
||||||
FORMAT_NORMAL = 0,
|
FORMAT_NORMAL = 0,
|
||||||
|
@@ -72,7 +72,7 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
|
|||||||
break;
|
break;
|
||||||
case WLR_INPUT_DEVICE_TOUCH:
|
case WLR_INPUT_DEVICE_TOUCH:
|
||||||
Debug::log(LOG, "Attached a touch device with name %s", DEVICE->name);
|
Debug::log(LOG, "Attached a touch device with name %s", DEVICE->name);
|
||||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, DEVICE);
|
g_pInputManager->newTouchDevice(DEVICE);
|
||||||
break;
|
break;
|
||||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||||
Debug::log(LOG, "Attached a tablet tool with name %s", DEVICE->name);
|
Debug::log(LOG, "Attached a tablet tool with name %s", DEVICE->name);
|
||||||
@@ -207,3 +207,15 @@ void Events::listener_touchEnd(wl_listener* listener, void* data) {
|
|||||||
void Events::listener_touchUpdate(wl_listener* listener, void* data) {
|
void Events::listener_touchUpdate(wl_listener* listener, void* data) {
|
||||||
g_pInputManager->onTouchMove((wlr_touch_motion_event*)data);
|
g_pInputManager->onTouchMove((wlr_touch_motion_event*)data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Events::listener_touchFrame(wl_listener* listener, void* data) {
|
||||||
|
wlr_seat_touch_notify_frame(g_pCompositor->m_sSeat.seat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::listener_holdBegin(wl_listener* listener, void* data) {
|
||||||
|
g_pInputManager->onPointerHoldBegin((wlr_pointer_hold_begin_event*)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::listener_holdEnd(wl_listener* listener, void* data) {
|
||||||
|
g_pInputManager->onPointerHoldEnd((wlr_pointer_hold_end_event*)data);
|
||||||
|
}
|
@@ -152,4 +152,8 @@ namespace Events {
|
|||||||
LISTENER(touchBegin);
|
LISTENER(touchBegin);
|
||||||
LISTENER(touchEnd);
|
LISTENER(touchEnd);
|
||||||
LISTENER(touchUpdate);
|
LISTENER(touchUpdate);
|
||||||
|
LISTENER(touchFrame);
|
||||||
|
|
||||||
|
LISTENER(holdBegin);
|
||||||
|
LISTENER(holdEnd);
|
||||||
};
|
};
|
@@ -133,8 +133,9 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
|
|||||||
|
|
||||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||||
|
|
||||||
if (layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint)) { // don't focus if constrained
|
|
||||||
wlr_surface_send_enter(layersurface->layerSurface->surface, layersurface->layerSurface->output);
|
wlr_surface_send_enter(layersurface->layerSurface->surface, layersurface->layerSurface->output);
|
||||||
|
|
||||||
|
if (layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint)) { // don't focus if constrained
|
||||||
g_pCompositor->focusSurface(layersurface->layerSurface->surface);
|
g_pCompositor->focusSurface(layersurface->layerSurface->surface);
|
||||||
|
|
||||||
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y);
|
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y);
|
||||||
@@ -158,7 +159,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
|||||||
|
|
||||||
Debug::log(LOG, "LayerSurface %x unmapped", layersurface->layerSurface);
|
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.");
|
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
|
||||||
|
|
||||||
g_pCompositor->addToFadingOutSafe(layersurface);
|
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) {
|
void Events::listener_destroyDrag(void* owner, void* data) {
|
||||||
Debug::log(LOG, "Drag destroyed.");
|
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.drag = nullptr;
|
||||||
g_pInputManager->m_sDrag.dragIcon = nullptr;
|
g_pInputManager->m_sDrag.dragIcon = nullptr;
|
||||||
g_pInputManager->m_sDrag.hyprListener_destroy.removeCallback();
|
g_pInputManager->m_sDrag.hyprListener_destroy.removeCallback();
|
||||||
|
@@ -190,8 +190,8 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if we have no tracking or full tracking, invalidate the entire monitor
|
// if we have no tracking or full tracking, invalidate the entire monitor
|
||||||
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || PMONITOR->forceFullFrames > 0 || damageBlinkCleanup > 0) {
|
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || PMONITOR->forceFullFrames > 0 || damageBlinkCleanup > 0 || PMONITOR->isMirror() /* why??? */) {
|
||||||
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);
|
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
||||||
} else {
|
} else {
|
||||||
@@ -224,6 +224,12 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
// potentially can save on resources.
|
// potentially can save on resources.
|
||||||
|
|
||||||
g_pHyprOpenGL->begin(PMONITOR, &damage);
|
g_pHyprOpenGL->begin(PMONITOR, &damage);
|
||||||
|
|
||||||
|
if (PMONITOR->isMirror()) {
|
||||||
|
g_pHyprOpenGL->renderMirrored();
|
||||||
|
|
||||||
|
Debug::log(LOG, "Mirror frame");
|
||||||
|
} else {
|
||||||
g_pHyprOpenGL->clear(CColor(17, 17, 17, 255));
|
g_pHyprOpenGL->clear(CColor(17, 17, 17, 255));
|
||||||
g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper"
|
g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper"
|
||||||
|
|
||||||
@@ -241,8 +247,8 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*PDAMAGEBLINK && damageBlinkCleanup == 0) {
|
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);
|
g_pHyprOpenGL->renderRect(&monrect, CColor(255, 0, 255, 100), 0);
|
||||||
damageBlinkCleanup = 1;
|
damageBlinkCleanup = 1;
|
||||||
} else if (*PDAMAGEBLINK) {
|
} else if (*PDAMAGEBLINK) {
|
||||||
damageBlinkCleanup++;
|
damageBlinkCleanup++;
|
||||||
@@ -255,6 +261,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
wlr_output_render_software_cursors(PMONITOR->output, NULL);
|
wlr_output_render_software_cursors(PMONITOR->output, NULL);
|
||||||
|
|
||||||
wlr_renderer_end(g_pCompositor->m_sWLRRenderer);
|
wlr_renderer_end(g_pCompositor->m_sWLRRenderer);
|
||||||
|
}
|
||||||
|
|
||||||
g_pHyprOpenGL->end();
|
g_pHyprOpenGL->end();
|
||||||
|
|
||||||
@@ -272,10 +279,15 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||||||
pixman_region32_union(&frameDamage, &frameDamage, &damage);
|
pixman_region32_union(&frameDamage, &frameDamage, &damage);
|
||||||
|
|
||||||
wlr_output_set_damage(PMONITOR->output, &frameDamage);
|
wlr_output_set_damage(PMONITOR->output, &frameDamage);
|
||||||
|
|
||||||
|
if (!PMONITOR->mirrors.empty())
|
||||||
|
g_pHyprRenderer->damageMirrorsWith(PMONITOR, &frameDamage);
|
||||||
|
|
||||||
pixman_region32_fini(&frameDamage);
|
pixman_region32_fini(&frameDamage);
|
||||||
pixman_region32_fini(&damage);
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
wlr_output_commit(PMONITOR->output);
|
if (!wlr_output_commit(PMONITOR->output))
|
||||||
|
return;
|
||||||
|
|
||||||
if (*PDAMAGEBLINK || *PNOVFR)
|
if (*PDAMAGEBLINK || *PNOVFR)
|
||||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||||
|
@@ -32,6 +32,12 @@ void addPopupGlobalCoords(void* pPopup, int* x, int* y) {
|
|||||||
py -= curPopup->popup->base->current.geometry.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) {
|
if (curPopup->parentPopup) {
|
||||||
curPopup = curPopup->parentPopup;
|
curPopup = curPopup->parentPopup;
|
||||||
} else {
|
} else {
|
||||||
|
@@ -48,8 +48,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
|
|
||||||
static auto *const PINACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity")->floatValue;
|
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 PACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:active_opacity")->floatValue;
|
||||||
|
static auto *const PDIMSTRENGTH = &g_pConfigManager->getConfigValuePtr("decoration:dim_strength")->floatValue;
|
||||||
|
static auto *const PSWALLOW = &g_pConfigManager->getConfigValuePtr("misc:enable_swallow")->intValue;
|
||||||
|
static auto *const PSWALLOWREGEX = &g_pConfigManager->getConfigValuePtr("misc:swallow_regex")->strValue;
|
||||||
|
|
||||||
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);
|
const auto PWORKSPACE = PMONITOR->specialWorkspaceOpen ? g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||||
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||||
PWINDOW->m_bMappedX11 = true;
|
PWINDOW->m_bMappedX11 = true;
|
||||||
@@ -161,6 +164,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
PWINDOW->m_sAdditionalConfigData.forceOpaque = true;
|
PWINDOW->m_sAdditionalConfigData.forceOpaque = true;
|
||||||
} else if (r.szRule == "forceinput") {
|
} else if (r.szRule == "forceinput") {
|
||||||
PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true;
|
PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true;
|
||||||
|
} else if (r.szRule == "pin") {
|
||||||
|
PWINDOW->m_bPinned = true;
|
||||||
} else if (r.szRule.find("rounding") == 0) {
|
} else if (r.szRule.find("rounding") == 0) {
|
||||||
try {
|
try {
|
||||||
PWINDOW->m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
PWINDOW->m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
||||||
@@ -187,6 +192,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disallow tiled pinned
|
||||||
|
if (PWINDOW->m_bPinned && !PWINDOW->m_bIsFloating)
|
||||||
|
PWINDOW->m_bPinned = false;
|
||||||
|
|
||||||
if (requestedWorkspace != "") {
|
if (requestedWorkspace != "") {
|
||||||
// process requested workspace
|
// process requested workspace
|
||||||
if (requestedWorkspace.contains(' ')) {
|
if (requestedWorkspace.contains(' ')) {
|
||||||
@@ -226,8 +235,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(" "));
|
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||||
const auto SIZEYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
const auto SIZEYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||||
|
|
||||||
const auto SIZEX = !SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stoi(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW);
|
||||||
const auto SIZEY = !SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stoi(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
|
||||||
|
const auto SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, 20.0, PMONITOR->vecSize.x) : (!SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stoi(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.x);
|
||||||
|
const auto SIZEY = SIZEYSTR == "max" ? std::clamp(MAXSIZE.y, 20.0, PMONITOR->vecSize.y) : (!SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stoi(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y);
|
||||||
|
|
||||||
Debug::log(LOG, "Rule size, applying to window %x", PWINDOW);
|
Debug::log(LOG, "Rule size, applying to window %x", PWINDOW);
|
||||||
|
|
||||||
@@ -244,8 +255,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
const auto POSXSTR = VALUE.substr(0, VALUE.find(" "));
|
const auto POSXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||||
const auto POSYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
const auto POSYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||||
|
|
||||||
const auto POSX = !POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
const auto POSX = !POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.x;
|
||||||
const auto POSY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
const auto POSY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y;
|
||||||
|
|
||||||
Debug::log(LOG, "Rule move, applying to window %x", PWINDOW);
|
Debug::log(LOG, "Rule move, applying to window %x", PWINDOW);
|
||||||
|
|
||||||
@@ -263,6 +274,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
// set the pseudo size to the GOAL of our current size
|
// set the pseudo size to the GOAL of our current size
|
||||||
// because the windows are animated on RealSize
|
// because the windows are animated on RealSize
|
||||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv();
|
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv();
|
||||||
|
|
||||||
|
g_pCompositor->moveWindowToTop(PWINDOW);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
|
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
|
||||||
@@ -282,8 +295,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && PWINDOW->m_iX11Type != 2) {
|
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && PWINDOW->m_iX11Type != 2) {
|
||||||
g_pCompositor->focusWindow(PWINDOW);
|
g_pCompositor->focusWindow(PWINDOW);
|
||||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
|
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
|
||||||
} else
|
PWINDOW->m_fDimPercent.setValueAndWarp(*PDIMSTRENGTH);
|
||||||
|
} else {
|
||||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PINACTIVEALPHA);
|
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PINACTIVEALPHA);
|
||||||
|
PWINDOW->m_fDimPercent.setValueAndWarp(0);
|
||||||
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Window got assigned a surfaceTreeNode %x", PWINDOW->m_pSurfaceTree);
|
Debug::log(LOG, "Window got assigned a surfaceTreeNode %x", PWINDOW->m_pSurfaceTree);
|
||||||
|
|
||||||
@@ -316,6 +332,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
|
|
||||||
if (workspaceSilent) {
|
if (workspaceSilent) {
|
||||||
// move the window
|
// move the window
|
||||||
|
const auto OLDWORKSPACE = PWINDOW->m_iWorkspaceID;
|
||||||
|
|
||||||
if (g_pCompositor->m_pLastWindow == PWINDOW) {
|
if (g_pCompositor->m_pLastWindow == PWINDOW) {
|
||||||
if (requestedWorkspace != "special")
|
if (requestedWorkspace != "special")
|
||||||
g_pKeybindManager->m_mDispatchers["movetoworkspacesilent"](requestedWorkspace);
|
g_pKeybindManager->m_mDispatchers["movetoworkspacesilent"](requestedWorkspace);
|
||||||
@@ -324,14 +342,15 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
} else {
|
} else {
|
||||||
Debug::log(ERR, "Tried to set workspace silent rule to a nofocus window!");
|
Debug::log(ERR, "Tried to set workspace silent rule to a nofocus window!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_pCompositor->forceReportSizesToWindowsOnWorkspace(OLDWORKSPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestsFullscreen) {
|
if (requestsFullscreen) {
|
||||||
// fix fullscreen on requested (basically do a switcheroo)
|
// fix fullscreen on requested (basically do a switcheroo)
|
||||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||||
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PFULLWINDOW, FULLSCREEN_FULL, false);
|
g_pCompositor->setWindowFullscreen(PFULLWINDOW, false, FULLSCREEN_FULL);
|
||||||
g_pXWaylandManager->setWindowFullscreen(PFULLWINDOW, PFULLWINDOW->m_bIsFullscreen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PWINDOW->m_vRealPosition.warp();
|
PWINDOW->m_vRealPosition.warp();
|
||||||
@@ -359,6 +378,46 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
g_pCompositor->focusWindow(nullptr);
|
g_pCompositor->focusWindow(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verify swallowing
|
||||||
|
if (*PSWALLOW) {
|
||||||
|
// check parent
|
||||||
|
int ppid = getPPIDof(PWINDOW->getPID());
|
||||||
|
|
||||||
|
const auto PPPID = getPPIDof(ppid);
|
||||||
|
|
||||||
|
// why? no clue. Blame terminals.
|
||||||
|
if (PPPID > 2) {
|
||||||
|
ppid = PPPID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ppid) {
|
||||||
|
// get window by pid
|
||||||
|
CWindow* found = nullptr;
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
if (!w->m_bIsMapped || w->m_bHidden)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (w->getPID() == ppid) {
|
||||||
|
found = w.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
// check if it's the window we want
|
||||||
|
std::regex rgx(*PSWALLOWREGEX);
|
||||||
|
if (std::regex_match(g_pXWaylandManager->getAppIDClass(found), rgx)) {
|
||||||
|
// swallow
|
||||||
|
PWINDOW->m_pSwallowed = found;
|
||||||
|
|
||||||
|
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(found);
|
||||||
|
|
||||||
|
found->m_bHidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y);
|
Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y);
|
||||||
|
|
||||||
auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName;
|
auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName;
|
||||||
@@ -392,13 +451,19 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (PWINDOW->m_bIsFullscreen) {
|
if (PWINDOW->m_bIsFullscreen) {
|
||||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL, false);
|
g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL);
|
||||||
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow the renderer to catch the last frame.
|
// Allow the renderer to catch the last frame.
|
||||||
g_pHyprOpenGL->makeWindowSnapshot(PWINDOW);
|
g_pHyprOpenGL->makeWindowSnapshot(PWINDOW);
|
||||||
|
|
||||||
|
// swallowing
|
||||||
|
if (PWINDOW->m_pSwallowed && g_pCompositor->windowExists(PWINDOW->m_pSwallowed)) {
|
||||||
|
PWINDOW->m_pSwallowed->m_bHidden = false;
|
||||||
|
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW->m_pSwallowed);
|
||||||
|
PWINDOW->m_pSwallowed = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool wasLastWindow = false;
|
bool wasLastWindow = false;
|
||||||
|
|
||||||
if (PWINDOW == g_pCompositor->m_pLastWindow) {
|
if (PWINDOW == g_pCompositor->m_pLastWindow) {
|
||||||
@@ -691,7 +756,10 @@ void Events::listener_NewXDGDeco(wl_listener* listener, void* data) {
|
|||||||
void Events::listener_requestMaximize(void* owner, void* data) {
|
void Events::listener_requestMaximize(void* owner, void* data) {
|
||||||
const auto PWINDOW = (CWindow*)owner;
|
const auto PWINDOW = (CWindow*)owner;
|
||||||
|
|
||||||
// ignore
|
const auto EV = (wlr_foreign_toplevel_handle_v1_maximized_event*)data;
|
||||||
|
|
||||||
|
g_pCompositor->setWindowFullscreen(PWINDOW, EV ? EV->maximized : !PWINDOW->m_bIsFullscreen, FULLSCREEN_MAXIMIZED); // this will be rejected if there already is a fullscreen window
|
||||||
|
|
||||||
wlr_xdg_surface_schedule_configure(PWINDOW->m_uSurface.xdg);
|
wlr_xdg_surface_schedule_configure(PWINDOW->m_uSurface.xdg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -59,5 +59,5 @@ void CAnimatedVariable::unregister() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int CAnimatedVariable::getDurationLeftMs() {
|
int CAnimatedVariable::getDurationLeftMs() {
|
||||||
return std::clamp((int)(m_pConfig->pValues->internalSpeed * 100) - (int)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - animationBegin).count(), 0, INT_MAX);
|
return std::max((int)(m_pConfig->pValues->internalSpeed * 100) - (int)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - animationBegin).count(), 0);
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
#include "Color.hpp"
|
#include "Color.hpp"
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
|
|
||||||
CColor::CColor() {
|
CColor::CColor() { }
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
CColor::CColor(float r, float g, float b, float a) {
|
CColor::CColor(float r, float g, float b, float a) {
|
||||||
this->r = r;
|
this->r = r;
|
||||||
|
@@ -120,14 +120,18 @@ void scaleBox(wlr_box* box, float scale) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string removeBeginEndSpacesTabs(std::string str) {
|
std::string removeBeginEndSpacesTabs(std::string str) {
|
||||||
while (str[0] == ' ' || str[0] == '\t') {
|
int countBefore = 0;
|
||||||
str = str.substr(1);
|
while (str[countBefore] == ' ' || str[countBefore] == '\t') {
|
||||||
|
countBefore++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (str.length() != 0 && (str[str.length() - 1] == ' ' || str[str.length() - 1] == '\t')) {
|
int countAfter = 0;
|
||||||
str = str.substr(0, str.length() - 1);
|
while (str.length() != 0 && (str[str.length() - countAfter - 1] == ' ' || str[str.length() - 1 - countAfter] == '\t')) {
|
||||||
|
countAfter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
str = str.substr(countBefore, str.length() - countBefore - countAfter);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +174,28 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isNumber(const std::string& str, bool allowfloat) {
|
bool isNumber(const std::string& str, bool allowfloat) {
|
||||||
return std::ranges::all_of(str.begin(), str.end(), [&](char c) { return isdigit(c) != 0 || c == '-' || (allowfloat && c == '.'); });
|
|
||||||
|
std::string copy = str;
|
||||||
|
if (*copy.begin() == '-')
|
||||||
|
copy = copy.substr(1);
|
||||||
|
|
||||||
|
if (copy.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool point = !allowfloat;
|
||||||
|
for (auto& c : copy) {
|
||||||
|
if (c == '.') {
|
||||||
|
if (point)
|
||||||
|
return false;
|
||||||
|
point = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::isdigit(c))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDirection(const std::string& arg) {
|
bool isDirection(const std::string& arg) {
|
||||||
@@ -192,7 +217,7 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
|||||||
}
|
}
|
||||||
outName = WORKSPACENAME;
|
outName = WORKSPACENAME;
|
||||||
} else {
|
} else {
|
||||||
if (in[0] == 'm' || in[0] == 'e') {
|
if ((in[0] == 'm' || in[0] == 'e') && (in[1] == '-' || in[1] == '+') && isNumber(in.substr(2))) {
|
||||||
bool onAllMonitors = in[0] == 'e';
|
bool onAllMonitors = in[0] == 'e';
|
||||||
|
|
||||||
if (!g_pCompositor->m_pLastMonitor) {
|
if (!g_pCompositor->m_pLastMonitor) {
|
||||||
@@ -221,6 +246,9 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
|||||||
int highestID = -99999;
|
int highestID = -99999;
|
||||||
|
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||||
|
if (w->m_iID == SPECIAL_WORKSPACE_ID)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (w->m_iID < lowestID)
|
if (w->m_iID < lowestID)
|
||||||
lowestID = w->m_iID;
|
lowestID = w->m_iID;
|
||||||
|
|
||||||
@@ -250,14 +278,22 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
|||||||
outName = g_pCompositor->getWorkspaceByID(currentID)->m_szName;
|
outName = g_pCompositor->getWorkspaceByID(currentID)->m_szName;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (in[0] == '+' || in[0] == '-') {
|
||||||
if (g_pCompositor->m_pLastMonitor)
|
if (g_pCompositor->m_pLastMonitor)
|
||||||
result = std::clamp((int)getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspace), 1, INT_MAX);
|
result = std::max((int)getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspace), 1);
|
||||||
else if (isNumber(in))
|
|
||||||
result = std::clamp(std::stoi(in), 1, INT_MAX);
|
|
||||||
else {
|
else {
|
||||||
Debug::log(ERR, "Relative workspace on no mon!");
|
Debug::log(ERR, "Relative workspace on no mon!");
|
||||||
result = INT_MAX;
|
result = INT_MAX;
|
||||||
}
|
}
|
||||||
|
} else if (isNumber(in))
|
||||||
|
result = std::max(std::stoi(in), 1);
|
||||||
|
else {
|
||||||
|
// maybe name
|
||||||
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByName(in);
|
||||||
|
if (PWORKSPACE)
|
||||||
|
result = PWORKSPACE->m_iID;
|
||||||
|
}
|
||||||
|
|
||||||
outName = std::to_string(result);
|
outName = std::to_string(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,8 +302,8 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2) {
|
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2) {
|
||||||
const float DX = std::max((double)0, std::max(p1.x - vec.x, vec.x - p2.x));
|
const float DX = std::max({0.0, p1.x - vec.x, vec.x - p2.x});
|
||||||
const float DY = std::max((double)0, std::max(p1.y - vec.y, vec.y - p2.y));
|
const float DY = std::max({0.0, p1.y - vec.y, vec.y - p2.y});
|
||||||
return DX * DX + DY * DY;
|
return DX * DX + DY * DY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,3 +358,38 @@ void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) {
|
|||||||
// Identity
|
// Identity
|
||||||
mat[8] = 1.0f;
|
mat[8] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t getPPIDof(int64_t pid) {
|
||||||
|
std::string dir = "/proc/" + std::to_string(pid) + "/status";
|
||||||
|
FILE* infile;
|
||||||
|
|
||||||
|
infile = fopen(dir.c_str(), "r");
|
||||||
|
if (!infile)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
char* line = nullptr;
|
||||||
|
size_t len = 0;
|
||||||
|
ssize_t len2 = 0;
|
||||||
|
|
||||||
|
std::string pidstr;
|
||||||
|
|
||||||
|
while ((len2 = getline(&line, &len, infile)) != -1) {
|
||||||
|
if (strstr(line, "PPid:")) {
|
||||||
|
pidstr = std::string(line, len2);
|
||||||
|
const auto tabpos = pidstr.find_last_of('\t');
|
||||||
|
if (tabpos != std::string::npos)
|
||||||
|
pidstr = pidstr.substr(tabpos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(infile);
|
||||||
|
if (line)
|
||||||
|
free(line);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return std::stoll(pidstr);
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@@ -14,6 +14,7 @@ int getWorkspaceIDFromString(const std::string&, std::string&);
|
|||||||
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2);
|
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2);
|
||||||
void logSystemInfo();
|
void logSystemInfo();
|
||||||
std::string execAndGet(const char*);
|
std::string execAndGet(const char*);
|
||||||
|
int64_t getPPIDof(int64_t pid);
|
||||||
|
|
||||||
float getPlusMinusKeywordResult(std::string in, float relative);
|
float getPlusMinusKeywordResult(std::string in, float relative);
|
||||||
|
|
||||||
|
@@ -65,6 +65,8 @@ void CMonitor::onConnect(bool noRule) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!m_bRenderingInitPassed) {
|
if (!m_bRenderingInitPassed) {
|
||||||
|
output->allocator = nullptr;
|
||||||
|
output->renderer = nullptr;
|
||||||
wlr_output_init_render(output, g_pCompositor->m_sWLRAllocator, g_pCompositor->m_sWLRRenderer);
|
wlr_output_init_render(output, g_pCompositor->m_sWLRAllocator, g_pCompositor->m_sWLRRenderer);
|
||||||
m_bRenderingInitPassed = true;
|
m_bRenderingInitPassed = true;
|
||||||
}
|
}
|
||||||
@@ -90,8 +92,6 @@ void CMonitor::onConnect(bool noRule) {
|
|||||||
wlr_xcursor_manager_load(g_pCompositor->m_sWLRXCursorMgr, monitorRule.scale);
|
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_set_transform(output, WL_OUTPUT_TRANSFORM_NORMAL); // TODO: support other transforms
|
||||||
|
|
||||||
wlr_output_enable_adaptive_sync(output, 1);
|
|
||||||
|
|
||||||
// create it in the arr
|
// create it in the arr
|
||||||
vecPosition = monitorRule.offset;
|
vecPosition = monitorRule.offset;
|
||||||
vecSize = monitorRule.resolution;
|
vecSize = monitorRule.resolution;
|
||||||
@@ -118,49 +118,13 @@ void CMonitor::onConnect(bool noRule) {
|
|||||||
|
|
||||||
wlr_ext_workspace_group_handle_v1_output_enter(pWLRWorkspaceGroupHandle, output);
|
wlr_ext_workspace_group_handle_v1_output_enter(pWLRWorkspaceGroupHandle, output);
|
||||||
|
|
||||||
// Workspace
|
setupDefaultWS(monitorRule);
|
||||||
std::string newDefaultWorkspaceName = "";
|
|
||||||
auto WORKSPACEID = monitorRule.defaultWorkspace == "" ? g_pCompositor->m_vWorkspaces.size() + 1 : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName);
|
|
||||||
|
|
||||||
if (WORKSPACEID == INT_MAX || WORKSPACEID == (long unsigned int)SPECIAL_WORKSPACE_ID) {
|
|
||||||
WORKSPACEID = g_pCompositor->m_vWorkspaces.size() + 1;
|
|
||||||
newDefaultWorkspaceName = std::to_string(WORKSPACEID);
|
|
||||||
|
|
||||||
Debug::log(LOG, "Invalid workspace= directive name in monitor parsing, workspace name \"%s\" is invalid.", monitorRule.defaultWorkspace.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PNEWWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
|
||||||
|
|
||||||
Debug::log(LOG, "New monitor: WORKSPACEID %d, exists: %d", WORKSPACEID, (int)(PNEWWORKSPACE != nullptr));
|
|
||||||
|
|
||||||
if (PNEWWORKSPACE) {
|
|
||||||
// workspace exists, move it to the newly connected monitor
|
|
||||||
g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, this);
|
|
||||||
activeWorkspace = PNEWWORKSPACE->m_iID;
|
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
|
|
||||||
PNEWWORKSPACE->startAnim(true, true, true);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (newDefaultWorkspaceName == "")
|
|
||||||
newDefaultWorkspaceName = std::to_string(WORKSPACEID);
|
|
||||||
|
|
||||||
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(ID, newDefaultWorkspaceName)).get();
|
|
||||||
|
|
||||||
// We are required to set the name here immediately
|
|
||||||
wlr_ext_workspace_handle_v1_set_name(PNEWWORKSPACE->m_pWlrHandle, newDefaultWorkspaceName.c_str());
|
|
||||||
|
|
||||||
PNEWWORKSPACE->m_iID = WORKSPACEID;
|
|
||||||
}
|
|
||||||
|
|
||||||
activeWorkspace = PNEWWORKSPACE->m_iID;
|
|
||||||
scale = monitorRule.scale;
|
scale = monitorRule.scale;
|
||||||
|
|
||||||
m_pThisWrap = nullptr;
|
m_pThisWrap = nullptr;
|
||||||
|
|
||||||
forceFullFrames = 3; // force 3 full frames to make sure there is no blinking due to double-buffering.
|
forceFullFrames = 3; // force 3 full frames to make sure there is no blinking due to double-buffering.
|
||||||
|
|
||||||
g_pCompositor->deactivateAllWLRWorkspaces(PNEWWORKSPACE->m_pWlrHandle);
|
|
||||||
PNEWWORKSPACE->setActive(true);
|
|
||||||
//
|
//
|
||||||
|
|
||||||
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
|
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
|
||||||
@@ -188,6 +152,20 @@ void CMonitor::onDisconnect() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove mirror
|
||||||
|
if (pMirrorOf) {
|
||||||
|
pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; }));
|
||||||
|
pMirrorOf = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mirrors.empty()) {
|
||||||
|
for (auto& m : mirrors) {
|
||||||
|
m->setMirror("");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pConfigManager->m_bWantsMonitorReload = true;
|
||||||
|
}
|
||||||
|
|
||||||
m_bEnabled = false;
|
m_bEnabled = false;
|
||||||
m_bRenderingInitPassed = false;
|
m_bRenderingInitPassed = false;
|
||||||
|
|
||||||
@@ -248,3 +226,136 @@ void CMonitor::addDamage(pixman_region32_t* rg) {
|
|||||||
void CMonitor::addDamage(wlr_box* box) {
|
void CMonitor::addDamage(wlr_box* box) {
|
||||||
wlr_output_damage_add_box(damage, box);
|
wlr_output_damage_add_box(damage, box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CMonitor::isMirror() {
|
||||||
|
return pMirrorOf != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
|
||||||
|
// Workspace
|
||||||
|
std::string newDefaultWorkspaceName = "";
|
||||||
|
auto WORKSPACEID = monitorRule.defaultWorkspace == "" ? g_pCompositor->m_vWorkspaces.size() + 1 : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName);
|
||||||
|
|
||||||
|
if (WORKSPACEID == INT_MAX || WORKSPACEID == (long unsigned int)SPECIAL_WORKSPACE_ID) {
|
||||||
|
WORKSPACEID = g_pCompositor->m_vWorkspaces.size() + 1;
|
||||||
|
newDefaultWorkspaceName = std::to_string(WORKSPACEID);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Invalid workspace= directive name in monitor parsing, workspace name \"%s\" is invalid.", monitorRule.defaultWorkspace.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PNEWWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||||
|
|
||||||
|
Debug::log(LOG, "New monitor: WORKSPACEID %d, exists: %d", WORKSPACEID, (int)(PNEWWORKSPACE != nullptr));
|
||||||
|
|
||||||
|
if (PNEWWORKSPACE) {
|
||||||
|
// workspace exists, move it to the newly connected monitor
|
||||||
|
g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, this);
|
||||||
|
activeWorkspace = PNEWWORKSPACE->m_iID;
|
||||||
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
|
||||||
|
PNEWWORKSPACE->startAnim(true, true, true);
|
||||||
|
} else {
|
||||||
|
if (newDefaultWorkspaceName == "")
|
||||||
|
newDefaultWorkspaceName = std::to_string(WORKSPACEID);
|
||||||
|
|
||||||
|
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(ID, newDefaultWorkspaceName)).get();
|
||||||
|
|
||||||
|
// We are required to set the name here immediately
|
||||||
|
wlr_ext_workspace_handle_v1_set_name(PNEWWORKSPACE->m_pWlrHandle, newDefaultWorkspaceName.c_str());
|
||||||
|
|
||||||
|
PNEWWORKSPACE->m_iID = WORKSPACEID;
|
||||||
|
}
|
||||||
|
|
||||||
|
activeWorkspace = PNEWWORKSPACE->m_iID;
|
||||||
|
|
||||||
|
g_pCompositor->deactivateAllWLRWorkspaces(PNEWWORKSPACE->m_pWlrHandle);
|
||||||
|
PNEWWORKSPACE->setActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||||
|
const auto PMIRRORMON = g_pCompositor->getMonitorFromString(mirrorOf);
|
||||||
|
|
||||||
|
if (PMIRRORMON == pMirrorOf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (PMIRRORMON && PMIRRORMON->isMirror()) {
|
||||||
|
Debug::log(ERR, "Cannot mirror a mirror!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PMIRRORMON == this) {
|
||||||
|
Debug::log(ERR, "Cannot mirror self!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PMIRRORMON) {
|
||||||
|
// disable mirroring
|
||||||
|
|
||||||
|
if (pMirrorOf) {
|
||||||
|
pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; }));
|
||||||
|
}
|
||||||
|
|
||||||
|
pMirrorOf = nullptr;
|
||||||
|
|
||||||
|
// set rule
|
||||||
|
const auto RULE = g_pConfigManager->getMonitorRuleFor(this->szName);
|
||||||
|
|
||||||
|
vecPosition = RULE.offset;
|
||||||
|
|
||||||
|
// push to mvmonitors
|
||||||
|
if (!m_pThisWrap) {
|
||||||
|
// find the wrap
|
||||||
|
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||||
|
if (m->ID == ID) {
|
||||||
|
m_pThisWrap = &m;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::find_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& other) { return other.get() == this; }) == g_pCompositor->m_vMonitors.end()) {
|
||||||
|
g_pCompositor->m_vMonitors.push_back(*m_pThisWrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
setupDefaultWS(RULE);
|
||||||
|
|
||||||
|
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, output, (int)vecPosition.x, (int)vecPosition.y);
|
||||||
|
} else {
|
||||||
|
CMonitor* BACKUPMON = nullptr;
|
||||||
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
|
if (m.get() != this) {
|
||||||
|
BACKUPMON = m.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// move all the WS
|
||||||
|
std::deque<CWorkspace*> wspToMove;
|
||||||
|
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||||
|
if (w->m_iMonitorID == ID) {
|
||||||
|
wspToMove.push_back(w.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& w : wspToMove) {
|
||||||
|
g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON);
|
||||||
|
w->startAnim(true, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
activeWorkspace = -1;
|
||||||
|
|
||||||
|
wlr_output_layout_remove(g_pCompositor->m_sWLROutputLayout, output);
|
||||||
|
|
||||||
|
vecPosition = Vector2D(-1337420, -1337420);
|
||||||
|
|
||||||
|
pMirrorOf = PMIRRORMON;
|
||||||
|
|
||||||
|
pMirrorOf->mirrors.push_back(this);
|
||||||
|
|
||||||
|
// remove from mvmonitors
|
||||||
|
if (std::find_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& other) { return other.get() == this; }) != g_pCompositor->m_vMonitors.end()) {
|
||||||
|
g_pCompositor->m_vMonitors.erase(std::remove_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](const auto& other) { return other.get() == this; }));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pCompositor->m_pLastMonitor = g_pCompositor->m_vMonitors.front().get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -7,6 +7,8 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
struct SMonitorRule;
|
||||||
|
|
||||||
class CMonitor {
|
class CMonitor {
|
||||||
public:
|
public:
|
||||||
Vector2D vecPosition = Vector2D(0,0);
|
Vector2D vecPosition = Vector2D(0,0);
|
||||||
@@ -35,6 +37,10 @@ public:
|
|||||||
bool scheduledRecalc = false;
|
bool scheduledRecalc = false;
|
||||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
|
|
||||||
|
// mirroring
|
||||||
|
CMonitor* pMirrorOf = nullptr;
|
||||||
|
std::vector<CMonitor*> mirrors;
|
||||||
|
|
||||||
// for the special workspace
|
// for the special workspace
|
||||||
bool specialWorkspaceOpen = false;
|
bool specialWorkspaceOpen = false;
|
||||||
|
|
||||||
@@ -57,6 +63,8 @@ public:
|
|||||||
void onDisconnect();
|
void onDisconnect();
|
||||||
void addDamage(pixman_region32_t* rg);
|
void addDamage(pixman_region32_t* rg);
|
||||||
void addDamage(wlr_box* box);
|
void addDamage(wlr_box* box);
|
||||||
|
void setMirror(const std::string&);
|
||||||
|
bool isMirror();
|
||||||
|
|
||||||
std::shared_ptr<CMonitor>* m_pThisWrap = nullptr;
|
std::shared_ptr<CMonitor>* m_pThisWrap = nullptr;
|
||||||
bool m_bEnabled = false;
|
bool m_bEnabled = false;
|
||||||
@@ -67,4 +75,7 @@ public:
|
|||||||
bool operator==(const CMonitor& rhs) {
|
bool operator==(const CMonitor& rhs) {
|
||||||
return vecPosition == rhs.vecPosition && vecSize == rhs.vecSize && szName == rhs.szName;
|
return vecPosition == rhs.vecPosition && vecSize == rhs.vecSize && szName == rhs.szName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupDefaultWS(const SMonitorRule&);
|
||||||
};
|
};
|
@@ -101,6 +101,14 @@ void SubsurfaceTree::destroySurfaceTree(SSurfaceTreeNode* pNode) {
|
|||||||
g_pHyprRenderer->damageBox(&extents);
|
g_pHyprRenderer->damageBox(&extents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove references to this node
|
||||||
|
for (auto& tn : surfaceTreeNodes) {
|
||||||
|
for (auto& cs : tn.childSubsurfaces) {
|
||||||
|
if (cs.pChild == pNode)
|
||||||
|
cs.pChild = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
surfaceTreeNodes.remove(*pNode);
|
surfaceTreeNodes.remove(*pNode);
|
||||||
|
|
||||||
Debug::log(LOG, "SurfaceTree Node removed");
|
Debug::log(LOG, "SurfaceTree Node removed");
|
||||||
@@ -154,6 +162,9 @@ void Events::listener_newSubsurfaceNode(void* owner, void* data) {
|
|||||||
void Events::listener_mapSubsurface(void* owner, void* data) {
|
void Events::listener_mapSubsurface(void* owner, void* data) {
|
||||||
SSubsurface* subsurface = (SSubsurface*)owner;
|
SSubsurface* subsurface = (SSubsurface*)owner;
|
||||||
|
|
||||||
|
if (subsurface->pChild)
|
||||||
|
return;
|
||||||
|
|
||||||
Debug::log(LOG, "Subsurface %x mapped", subsurface->pSubsurface);
|
Debug::log(LOG, "Subsurface %x mapped", subsurface->pSubsurface);
|
||||||
|
|
||||||
subsurface->pChild = createSubsurfaceNode(subsurface->pParent, subsurface, subsurface->pSubsurface->surface, subsurface->pWindowOwner);
|
subsurface->pChild = createSubsurfaceNode(subsurface->pParent, subsurface, subsurface->pSubsurface->surface, subsurface->pWindowOwner);
|
||||||
@@ -170,18 +181,16 @@ void Events::listener_unmapSubsurface(void* owner, void* data) {
|
|||||||
int lx = 0, ly = 0;
|
int lx = 0, ly = 0;
|
||||||
addSurfaceGlobalOffset(PNODE, &lx, &ly);
|
addSurfaceGlobalOffset(PNODE, &lx, &ly);
|
||||||
|
|
||||||
wlr_box extents = {0};
|
wlr_box extents = {lx, ly, 0, 0};
|
||||||
if (PNODE->pSurface) {
|
if (PNODE->pSurface) {
|
||||||
wlr_surface_get_extends(PNODE->pSurface, &extents);
|
extents.width = PNODE->pSurface->current.width;
|
||||||
|
extents.height = PNODE->pSurface->current.height;
|
||||||
extents.x += lx;
|
|
||||||
extents.y += ly;
|
|
||||||
|
|
||||||
g_pHyprRenderer->damageBox(&extents);
|
g_pHyprRenderer->damageBox(&extents);
|
||||||
}
|
}
|
||||||
|
|
||||||
SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
|
//SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
|
||||||
subsurface->pChild = nullptr;
|
//subsurface->pChild = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,8 +226,9 @@ void Events::listener_commitSubsurface(void* owner, void* data) {
|
|||||||
void Events::listener_destroySubsurface(void* owner, void* data) {
|
void Events::listener_destroySubsurface(void* owner, void* data) {
|
||||||
SSubsurface* subsurface = (SSubsurface*)owner;
|
SSubsurface* subsurface = (SSubsurface*)owner;
|
||||||
|
|
||||||
if (subsurface->pChild)
|
if (subsurface->pChild) {
|
||||||
listener_destroySubsurfaceNode(subsurface->pChild, nullptr);
|
SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
|
||||||
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Subsurface %x destroyed", subsurface);
|
Debug::log(LOG, "Subsurface %x destroyed", subsurface);
|
||||||
|
|
||||||
|
@@ -322,3 +322,13 @@ struct SIMEPopup {
|
|||||||
return pSurface == other.pSurface;
|
return pSurface == other.pSurface;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct STouchDevice {
|
||||||
|
wlr_input_device* pWlrDevice = nullptr;
|
||||||
|
|
||||||
|
DYNLISTENER(destroy);
|
||||||
|
|
||||||
|
bool operator==(const STouchDevice& other) {
|
||||||
|
return pWlrDevice == other.pWlrDevice;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@@ -91,6 +91,15 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
|||||||
m_vRenderOffset.warp();
|
m_vRenderOffset.warp();
|
||||||
m_fAlpha.warp();
|
m_fAlpha.warp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check LS-es
|
||||||
|
if (in) {
|
||||||
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||||
|
for (auto& ls : PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||||
|
if (!ls->fadingOut)
|
||||||
|
ls->alpha = m_bHasFullscreenWindow && m_efFullscreenMode == FULLSCREEN_FULL ? 0.f : 255.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorkspace::setActive(bool on) {
|
void CWorkspace::setActive(bool on) {
|
||||||
@@ -120,3 +129,10 @@ void CWorkspace::moveToMonitor(const int& id) {
|
|||||||
|
|
||||||
wlr_ext_workspace_handle_v1_set_name(m_pWlrHandle, m_szName.c_str());
|
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
|
FULLSCREEN_MAXIMIZED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CWindow;
|
||||||
|
|
||||||
class CWorkspace {
|
class CWorkspace {
|
||||||
public:
|
public:
|
||||||
CWorkspace(int monitorID, std::string name, bool special = false);
|
CWorkspace(int monitorID, std::string name, bool special = false);
|
||||||
@@ -36,6 +38,9 @@ public:
|
|||||||
// "scratchpad"
|
// "scratchpad"
|
||||||
bool m_bIsSpecialWorkspace = false;
|
bool m_bIsSpecialWorkspace = false;
|
||||||
|
|
||||||
|
// last window
|
||||||
|
CWindow* m_pLastFocusedWindow = nullptr;
|
||||||
|
|
||||||
// user-set
|
// user-set
|
||||||
bool m_bDefaultFloating = false;
|
bool m_bDefaultFloating = false;
|
||||||
bool m_bDefaultPseudo = false;
|
bool m_bDefaultPseudo = false;
|
||||||
@@ -44,4 +49,6 @@ public:
|
|||||||
void setActive(bool on);
|
void setActive(bool on);
|
||||||
|
|
||||||
void moveToMonitor(const int&);
|
void moveToMonitor(const int&);
|
||||||
|
|
||||||
|
CWindow* getLastFocusedWindow();
|
||||||
};
|
};
|
@@ -90,6 +90,19 @@ void SDwindleNodeData::setGroupFocusedNode(SDwindleNodeData* pMember) {
|
|||||||
this->pWindow->m_bHidden = pMember != this;
|
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 CHyprDwindleLayout::getNodesOnWorkspace(const int& id) {
|
||||||
int no = 0;
|
int no = 0;
|
||||||
for (auto& n : m_lDwindleNodesData) {
|
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 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 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 PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||||
const auto GAPSIN = g_pConfigManager->getInt("general:gaps_in");
|
const auto PGAPSIN = &g_pConfigManager->getConfigValuePtr("general:gaps_in")->intValue;
|
||||||
const auto GAPSOUT = g_pConfigManager->getInt("general:gaps_out");
|
const auto PGAPSOUT = &g_pConfigManager->getConfigValuePtr("general:gaps_out")->intValue;
|
||||||
|
|
||||||
const auto PWINDOW = pNode->pWindow;
|
const auto PWINDOW = pNode->pWindow;
|
||||||
|
|
||||||
if (!g_pCompositor->windowExists(PWINDOW) || !PWINDOW->m_bIsMapped) {
|
if (!g_pCompositor->windowExists(PWINDOW) || !PWINDOW->m_bIsMapped) {
|
||||||
Debug::log(ERR, "Node %x holding invalid window %x!!", pNode, PWINDOW);
|
Debug::log(ERR, "Node %x holding invalid window %x!!", pNode, PWINDOW);
|
||||||
|
onWindowRemovedTiling(PWINDOW);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,29 +183,33 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
|||||||
|
|
||||||
static auto *const PNOGAPSWHENONLY = &g_pConfigManager->getConfigValuePtr("dwindle:no_gaps_when_only")->intValue;
|
static auto *const PNOGAPSWHENONLY = &g_pConfigManager->getConfigValuePtr("dwindle:no_gaps_when_only")->intValue;
|
||||||
|
|
||||||
auto calcPos = PWINDOW->m_vPosition + Vector2D(BORDERSIZE, BORDERSIZE);
|
auto calcPos = PWINDOW->m_vPosition + Vector2D(*PBORDERSIZE, *PBORDERSIZE);
|
||||||
auto calcSize = PWINDOW->m_vSize - Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE);
|
auto calcSize = PWINDOW->m_vSize - Vector2D(2 * *PBORDERSIZE, 2 * *PBORDERSIZE);
|
||||||
|
|
||||||
if (*PNOGAPSWHENONLY && PWINDOW->m_iWorkspaceID != SPECIAL_WORKSPACE_ID && getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1) {
|
const auto NODESONWORKSPACE = getNodesOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||||
PWINDOW->m_vRealPosition = calcPos - Vector2D(BORDERSIZE, BORDERSIZE);
|
|
||||||
PWINDOW->m_vRealSize = calcSize + Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE);
|
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();
|
PWINDOW->updateWindowDecos();
|
||||||
|
|
||||||
PWINDOW->m_sSpecialRenderData.rounding = false;
|
PWINDOW->m_sSpecialRenderData.rounding = false;
|
||||||
PWINDOW->m_sSpecialRenderData.border = false;
|
PWINDOW->m_sSpecialRenderData.border = false;
|
||||||
|
PWINDOW->m_sSpecialRenderData.decorate = false;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PWINDOW->m_sSpecialRenderData.rounding = true;
|
PWINDOW->m_sSpecialRenderData.rounding = true;
|
||||||
PWINDOW->m_sSpecialRenderData.border = true;
|
PWINDOW->m_sSpecialRenderData.border = true;
|
||||||
|
PWINDOW->m_sSpecialRenderData.decorate = true;
|
||||||
|
|
||||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? GAPSOUT : GAPSIN,
|
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? *PGAPSOUT : *PGAPSIN,
|
||||||
DISPLAYTOP ? GAPSOUT : GAPSIN);
|
DISPLAYTOP ? *PGAPSOUT : *PGAPSIN);
|
||||||
|
|
||||||
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? GAPSOUT : GAPSIN,
|
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? *PGAPSOUT : *PGAPSIN,
|
||||||
DISPLAYBOTTOM ? GAPSOUT : GAPSIN);
|
DISPLAYBOTTOM ? *PGAPSOUT : *PGAPSIN);
|
||||||
|
|
||||||
calcPos = calcPos + OFFSETTOPLEFT;
|
calcPos = calcPos + OFFSETTOPLEFT;
|
||||||
calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT;
|
calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT;
|
||||||
@@ -311,6 +329,13 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||||
|
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||||
|
g_pCompositor->setWindowFullscreen(PFULLWINDOW, false, FULLSCREEN_FULL);
|
||||||
|
}
|
||||||
|
|
||||||
// if it's the first, it's easy. Make it fullscreen.
|
// if it's the first, it's easy. Make it fullscreen.
|
||||||
if (!OPENINGON || OPENINGON->pWindow == pWindow) {
|
if (!OPENINGON || OPENINGON->pWindow == pWindow) {
|
||||||
PNODE->position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
PNODE->position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
||||||
@@ -340,6 +365,8 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
|||||||
|
|
||||||
applyNodeDataToWindow(PNODE);
|
applyNodeDataToWindow(PNODE);
|
||||||
|
|
||||||
|
pWindow->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,19 +382,19 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
|||||||
NEWPARENT->pParent = OPENINGON->pParent;
|
NEWPARENT->pParent = OPENINGON->pParent;
|
||||||
NEWPARENT->isNode = true; // it is a node
|
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
|
// 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;
|
NEWPARENT->splitTop = !SIDEBYSIDE;
|
||||||
|
|
||||||
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
|
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 (*PFORCESPLIT == 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))
|
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 / WIDTHMULTIPLIER, NEWPARENT->position.x + NEWPARENT->size.x, NEWPARENT->position.y + NEWPARENT->size.y / 2.f))) {
|
|| (!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.
|
// we are hovering over the first node, make PNODE first.
|
||||||
NEWPARENT->children[1] = OPENINGON;
|
NEWPARENT->children[1] = OPENINGON;
|
||||||
NEWPARENT->children[0] = PNODE;
|
NEWPARENT->children[0] = PNODE;
|
||||||
@@ -377,7 +404,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
|||||||
NEWPARENT->children[1] = PNODE;
|
NEWPARENT->children[1] = PNODE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (FORCESPLIT == 1) {
|
if (*PFORCESPLIT == 1) {
|
||||||
NEWPARENT->children[1] = OPENINGON;
|
NEWPARENT->children[1] = OPENINGON;
|
||||||
NEWPARENT->children[0] = PNODE;
|
NEWPARENT->children[0] = PNODE;
|
||||||
} else {
|
} else {
|
||||||
@@ -398,7 +425,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
|||||||
// Update the children
|
// Update the children
|
||||||
|
|
||||||
|
|
||||||
if (NEWPARENT->size.x * WIDTHMULTIPLIER > NEWPARENT->size.y) {
|
if (NEWPARENT->size.x * *PWIDTHMULTIPLIER > NEWPARENT->size.y) {
|
||||||
// split left/right
|
// split left/right
|
||||||
OPENINGON->position = NEWPARENT->position;
|
OPENINGON->position = NEWPARENT->position;
|
||||||
OPENINGON->size = Vector2D(NEWPARENT->size.x / 2.f, NEWPARENT->size.y);
|
OPENINGON->size = Vector2D(NEWPARENT->size.x / 2.f, NEWPARENT->size.y);
|
||||||
@@ -430,6 +457,9 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pWindow->m_bIsFullscreen)
|
||||||
|
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
|
||||||
|
|
||||||
// check if it was grouped
|
// check if it was grouped
|
||||||
if (PNODE->isGroupMember()) {
|
if (PNODE->isGroupMember()) {
|
||||||
// get shit
|
// get shit
|
||||||
@@ -453,21 +483,25 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
|||||||
|
|
||||||
PNEXT->position = PNODE->position;
|
PNEXT->position = PNODE->position;
|
||||||
PNEXT->size = PNODE->size;
|
PNEXT->size = PNODE->size;
|
||||||
|
|
||||||
applyNodeDataToWindow(PNEXT);
|
|
||||||
} else {
|
} else {
|
||||||
const auto PHEAD = PNODE->getGroupHead();
|
const auto PHEAD = PNODE->getGroupHead();
|
||||||
|
|
||||||
PNEXT->position = PHEAD->position;
|
PNEXT->position = PHEAD->position;
|
||||||
PNEXT->size = PHEAD->size;
|
PNEXT->size = PHEAD->size;
|
||||||
|
|
||||||
applyNodeDataToWindow(PNEXT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PNEXT->setGroupFocusedNode(PNEXT);
|
PNEXT->setGroupFocusedNode(PNEXT);
|
||||||
PNEXT->pWindow->m_bHidden = false;
|
PNEXT->pWindow->m_bHidden = false;
|
||||||
|
|
||||||
m_lDwindleNodesData.remove(*PNODE);
|
m_lDwindleNodesData.remove(*PNODE);
|
||||||
|
|
||||||
|
applyNodeDataToWindow(PNEXT);
|
||||||
|
|
||||||
|
if (!PNEXT->isGroupMember()) {
|
||||||
|
// means we dissolved the group
|
||||||
|
recalculateMonitor(PNEXT->pWindow->m_iMonitorID);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,6 +519,17 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
|||||||
PSIBLING->size = PPARENT->size;
|
PSIBLING->size = PPARENT->size;
|
||||||
PSIBLING->pParent = PPARENT->pParent;
|
PSIBLING->pParent = PPARENT->pParent;
|
||||||
|
|
||||||
|
if (PSIBLING->isGroupMember()) {
|
||||||
|
// apply to all group members
|
||||||
|
SDwindleNodeData* current = PSIBLING->pNextGroupMember;
|
||||||
|
|
||||||
|
while (current != PSIBLING) {
|
||||||
|
current->position = PPARENT->position;
|
||||||
|
current->size = PPARENT->size;
|
||||||
|
current = current->pNextGroupMember;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (PPARENT->pParent != nullptr) {
|
if (PPARENT->pParent != nullptr) {
|
||||||
if (PPARENT->pParent->children[0] == PPARENT) {
|
if (PPARENT->pParent->children[0] == PPARENT) {
|
||||||
PPARENT->pParent->children[0] = PSIBLING;
|
PPARENT->pParent->children[0] = PSIBLING;
|
||||||
@@ -576,7 +621,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
|||||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||||
|
|
||||||
if (!PNODE) {
|
if (!PNODE) {
|
||||||
PWINDOW->m_vRealSize = Vector2D(std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).x, (double)20, (double)999999), std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).y, (double)20, (double)999999));
|
PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goalv() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goalv() + pixResize).y, 20.0));
|
||||||
PWINDOW->updateWindowDecos();
|
PWINDOW->updateWindowDecos();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -613,11 +658,11 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
|||||||
if (!PPARENT2) {
|
if (!PPARENT2) {
|
||||||
if (PARENTSIDEBYSIDE) {
|
if (PARENTSIDEBYSIDE) {
|
||||||
allowedMovement.x *= 2.f / PPARENT->size.x;
|
allowedMovement.x *= 2.f / PPARENT->size.x;
|
||||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9);
|
||||||
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
||||||
} else {
|
} else {
|
||||||
allowedMovement.y *= 2.f / PPARENT->size.y;
|
allowedMovement.y *= 2.f / PPARENT->size.y;
|
||||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9);
|
||||||
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,11 +677,11 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
|||||||
if (!PPARENT2) {
|
if (!PPARENT2) {
|
||||||
if (PARENTSIDEBYSIDE) {
|
if (PARENTSIDEBYSIDE) {
|
||||||
allowedMovement.x *= 2.f / PPARENT->size.x;
|
allowedMovement.x *= 2.f / PPARENT->size.x;
|
||||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9);
|
||||||
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
||||||
} else {
|
} else {
|
||||||
allowedMovement.y *= 2.f / PPARENT->size.y;
|
allowedMovement.y *= 2.f / PPARENT->size.y;
|
||||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9);
|
||||||
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,8 +695,8 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
|||||||
allowedMovement.x *= 2.f / SIDECONTAINER->size.x;
|
allowedMovement.x *= 2.f / SIDECONTAINER->size.x;
|
||||||
allowedMovement.y *= 2.f / TOPCONTAINER->size.y;
|
allowedMovement.y *= 2.f / TOPCONTAINER->size.y;
|
||||||
|
|
||||||
SIDECONTAINER->splitRatio = std::clamp(SIDECONTAINER->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
SIDECONTAINER->splitRatio = std::clamp(SIDECONTAINER->splitRatio + allowedMovement.x, 0.1, 1.9);
|
||||||
TOPCONTAINER->splitRatio = std::clamp(TOPCONTAINER->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
TOPCONTAINER->splitRatio = std::clamp(TOPCONTAINER->splitRatio + allowedMovement.y, 0.1, 1.9);
|
||||||
SIDECONTAINER->recalcSizePosRecursive(*PANIMATE == 0);
|
SIDECONTAINER->recalcSizePosRecursive(*PANIMATE == 0);
|
||||||
TOPCONTAINER->recalcSizePosRecursive(*PANIMATE == 0);
|
TOPCONTAINER->recalcSizePosRecursive(*PANIMATE == 0);
|
||||||
}
|
}
|
||||||
@@ -660,10 +705,7 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
|
|||||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
if (on == pWindow->m_bIsFullscreen || pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||||
return;
|
|
||||||
|
|
||||||
if (on == pWindow->m_bIsFullscreen)
|
|
||||||
return; // ignore
|
return; // ignore
|
||||||
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||||
@@ -763,12 +805,13 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
|||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PNODE->workspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PNODE->workspaceID);
|
||||||
|
|
||||||
if (PWORKSPACE->m_bHasFullscreenWindow)
|
if (PWORKSPACE->m_bHasFullscreenWindow && !PNODE->isGroupMember()) {
|
||||||
fullscreenRequestForWindow(g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID), FULLSCREEN_FULL, false);
|
Debug::log(ERR, "Cannot enable group on fullscreen window");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (PNODE->isGroupMember()) {
|
if (PNODE->isGroupMember()) {
|
||||||
// dissolve group
|
// dissolve group
|
||||||
|
|
||||||
const auto PHEAD = PNODE->getGroupHead();
|
const auto PHEAD = PNODE->getGroupHead();
|
||||||
|
|
||||||
SDwindleNodeData* current = PNODE->pNextGroupMember;
|
SDwindleNodeData* current = PNODE->pNextGroupMember;
|
||||||
@@ -789,8 +832,15 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
|||||||
PWINDOW->m_bHidden = false;
|
PWINDOW->m_bHidden = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PHEAD->pPreviousGroupMember)
|
||||||
|
PHEAD->pPreviousGroupMember->pNextGroupMember = PHEAD->pNextGroupMember;
|
||||||
|
|
||||||
|
if (PHEAD->pNextGroupMember)
|
||||||
|
PHEAD->pNextGroupMember->pPreviousGroupMember = PHEAD->pPreviousGroupMember;
|
||||||
|
|
||||||
PHEAD->pPreviousGroupMember = nullptr;
|
PHEAD->pPreviousGroupMember = nullptr;
|
||||||
PHEAD->pNextGroupMember = nullptr;
|
PHEAD->pNextGroupMember = nullptr;
|
||||||
|
|
||||||
onWindowRemoved(PHEAD->pWindow);
|
onWindowRemoved(PHEAD->pWindow);
|
||||||
|
|
||||||
for (auto& pw : toAddWindows) {
|
for (auto& pw : toAddWindows) {
|
||||||
@@ -803,6 +853,7 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
|||||||
|
|
||||||
for (auto& pw : toAddWindows) {
|
for (auto& pw : toAddWindows) {
|
||||||
onWindowCreated(pw);
|
onWindowCreated(pw);
|
||||||
|
pw->removeDecorationByType(DECORATION_GROUPBAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
recalculateMonitor(PWORKSPACE->m_iMonitorID);
|
recalculateMonitor(PWORKSPACE->m_iMonitorID);
|
||||||
@@ -862,10 +913,16 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
|||||||
|
|
||||||
newGroupMembers[i]->pPreviousGroupMember = PREVMEMBER;
|
newGroupMembers[i]->pPreviousGroupMember = PREVMEMBER;
|
||||||
newGroupMembers[i]->pNextGroupMember = NEXTMEMBER;
|
newGroupMembers[i]->pNextGroupMember = NEXTMEMBER;
|
||||||
|
|
||||||
|
// add the deco
|
||||||
|
newGroupMembers[i]->pWindow->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(newGroupMembers[i]->pWindow));
|
||||||
}
|
}
|
||||||
|
|
||||||
// focus
|
// focus
|
||||||
PNODE->setGroupFocusedNode(PNODE);
|
PNODE->setGroupFocusedNode(PNODE);
|
||||||
|
|
||||||
|
// required for no_gaps_when_only to work
|
||||||
|
applyNodeDataToWindow(PNODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||||
@@ -883,14 +940,15 @@ std::deque<CWindow*> CHyprDwindleLayout::getGroupMembers(CWindow* pWindow) {
|
|||||||
// get the node
|
// get the node
|
||||||
const auto PNODE = getNodeFromWindow(pWindow);
|
const auto PNODE = getNodeFromWindow(pWindow);
|
||||||
|
|
||||||
if (!PNODE)
|
if (!PNODE || !PNODE->isGroupMember())
|
||||||
return result; // reject with empty
|
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);
|
result.push_back(current->pWindow);
|
||||||
current = current->pNextGroupMember;
|
current = current->pNextGroupMember;
|
||||||
}
|
}
|
||||||
@@ -898,7 +956,7 @@ std::deque<CWindow*> CHyprDwindleLayout::getGroupMembers(CWindow* pWindow) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward) {
|
void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward, CWindow* forceTo) {
|
||||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||||
return; // reject
|
return; // reject
|
||||||
|
|
||||||
@@ -916,10 +974,18 @@ void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward) {
|
|||||||
else
|
else
|
||||||
pNewNode = PNODE->pPreviousGroupMember;
|
pNewNode = PNODE->pPreviousGroupMember;
|
||||||
|
|
||||||
|
if (forceTo) {
|
||||||
|
const auto NODETO = getNodeFromWindow(forceTo);
|
||||||
|
|
||||||
|
if (NODETO)
|
||||||
|
pNewNode = NODETO;
|
||||||
|
}
|
||||||
|
|
||||||
PNODE->setGroupFocusedNode(pNewNode);
|
PNODE->setGroupFocusedNode(pNewNode);
|
||||||
|
|
||||||
pNewNode->position = PNODE->position;
|
pNewNode->position = PNODE->position;
|
||||||
pNewNode->size = PNODE->size;
|
pNewNode->size = PNODE->size;
|
||||||
|
pNewNode->workspaceID = PNODE->workspaceID;
|
||||||
|
|
||||||
applyNodeDataToWindow(pNewNode);
|
applyNodeDataToWindow(pNewNode);
|
||||||
|
|
||||||
@@ -939,6 +1005,9 @@ void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward) {
|
|||||||
pNewNode->pWindow->m_vRealSize.warp();
|
pNewNode->pWindow->m_vRealSize.warp();
|
||||||
pNewNode->pWindow->m_vRealPosition.warp();
|
pNewNode->pWindow->m_vRealPosition.warp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pNewNode->pWindow->updateWindowDecos();
|
||||||
|
PNODE->pWindow->updateWindowDecos();
|
||||||
}
|
}
|
||||||
|
|
||||||
SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow) {
|
SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow) {
|
||||||
@@ -946,6 +1015,9 @@ SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow
|
|||||||
|
|
||||||
SWindowRenderLayoutHints hints;
|
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);
|
const auto PNODE = getNodeFromWindow(pWindow);
|
||||||
if (!PNODE)
|
if (!PNODE)
|
||||||
return hints; // left for the future, maybe floating funkiness
|
return hints; // left for the future, maybe floating funkiness
|
||||||
@@ -954,9 +1026,9 @@ SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow
|
|||||||
hints.isBorderColor = true;
|
hints.isBorderColor = true;
|
||||||
|
|
||||||
if (pWindow == g_pCompositor->m_pLastWindow)
|
if (pWindow == g_pCompositor->m_pLastWindow)
|
||||||
hints.borderColor = CColor(g_pConfigManager->getInt("dwindle:col.group_border_active"));
|
hints.borderColor = CColor(*PGROUPCOLACTIVE);
|
||||||
else
|
else
|
||||||
hints.borderColor = CColor(g_pConfigManager->getInt("dwindle:col.group_border"));
|
hints.borderColor = CColor(*PGROUPCOLINACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hints;
|
return hints;
|
||||||
@@ -965,18 +1037,33 @@ SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow
|
|||||||
void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
|
void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
|
||||||
// windows should be valid, insallah
|
// windows should be valid, insallah
|
||||||
|
|
||||||
const auto PNODE = getNodeFromWindow(pWindow);
|
auto PNODE = getNodeFromWindow(pWindow);
|
||||||
const auto PNODE2 = getNodeFromWindow(pWindow2);
|
auto PNODE2 = getNodeFromWindow(pWindow2);
|
||||||
|
|
||||||
if (!PNODE2 || !PNODE)
|
if (!PNODE2 || !PNODE) {
|
||||||
return;
|
|
||||||
|
|
||||||
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
|
||||||
Debug::log(ERR, "Dwindle: Rejecting a swap between workspaces");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we will not delete the nodes, just fix the tree
|
SDwindleNodeData* ACTIVE1 = nullptr;
|
||||||
|
SDwindleNodeData* ACTIVE2 = nullptr;
|
||||||
|
|
||||||
|
if (PNODE2->isGroupMember() || PNODE->isGroupMember()) {
|
||||||
|
|
||||||
|
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||||
|
Debug::log(ERR, "Groups are confined to a monitor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PNODE->isGroupMember()) {
|
||||||
|
ACTIVE1 = PNODE;
|
||||||
|
PNODE = PNODE->getGroupHead();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PNODE2->isGroupMember()) {
|
||||||
|
ACTIVE2 = PNODE2;
|
||||||
|
PNODE2 = PNODE2->getGroupHead();
|
||||||
|
}
|
||||||
|
|
||||||
if (PNODE2->pParent == PNODE->pParent) {
|
if (PNODE2->pParent == PNODE->pParent) {
|
||||||
const auto PPARENT = PNODE->pParent;
|
const auto PPARENT = PNODE->pParent;
|
||||||
|
|
||||||
@@ -1013,10 +1100,38 @@ void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
|
|||||||
PNODE2->pParent = PNODE->pParent;
|
PNODE2->pParent = PNODE->pParent;
|
||||||
PNODE->pParent = PPARENTNODE2;
|
PNODE->pParent = PPARENTNODE2;
|
||||||
|
|
||||||
// these are window nodes, so no children.
|
std::swap(PNODE2->workspaceID, PNODE->workspaceID);
|
||||||
|
} else {
|
||||||
|
// swap the windows and recalc
|
||||||
|
PNODE2->pWindow = pWindow;
|
||||||
|
PNODE->pWindow = pWindow2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||||
|
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
|
||||||
|
std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID);
|
||||||
|
}
|
||||||
|
|
||||||
// recalc the workspace
|
// recalc the workspace
|
||||||
getMasterNodeOnWorkspace(PNODE->workspaceID)->recalcSizePosRecursive();
|
getMasterNodeOnWorkspace(PNODE->workspaceID)->recalcSizePosRecursive();
|
||||||
|
|
||||||
|
if (PNODE2->workspaceID != PNODE->workspaceID) {
|
||||||
|
getMasterNodeOnWorkspace(PNODE2->workspaceID)->recalcSizePosRecursive();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ACTIVE1) {
|
||||||
|
ACTIVE1->position = PNODE->position;
|
||||||
|
ACTIVE1->size = PNODE->size;
|
||||||
|
ACTIVE1->pWindow->m_vPosition = ACTIVE1->position;
|
||||||
|
ACTIVE1->pWindow->m_vSize = ACTIVE1->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ACTIVE2) {
|
||||||
|
ACTIVE2->position = PNODE2->position;
|
||||||
|
ACTIVE2->size = PNODE2->size;
|
||||||
|
ACTIVE2->pWindow->m_vPosition = ACTIVE2->position;
|
||||||
|
ACTIVE2->pWindow->m_vSize = ACTIVE2->size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDwindleLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
void CHyprDwindleLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
||||||
@@ -1024,7 +1139,7 @@ void CHyprDwindleLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
|||||||
|
|
||||||
const auto PNODE = getNodeFromWindow(pWindow);
|
const auto PNODE = getNodeFromWindow(pWindow);
|
||||||
|
|
||||||
if (!PNODE || !PNODE->pParent)
|
if (!PNODE || !PNODE->pParent || (PNODE->isGroupMember() && PNODE->getGroupMemberCount() == g_pCompositor->getWindowsOnWorkspace(PNODE->workspaceID)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PNODE->pParent->splitRatio = std::clamp(PNODE->pParent->splitRatio + ratio, 0.1f, 1.9f);
|
PNODE->pParent->splitRatio = std::clamp(PNODE->pParent->splitRatio + ratio, 0.1f, 1.9f);
|
||||||
@@ -1042,7 +1157,7 @@ std::any CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::str
|
|||||||
else if (message == "togglesplit")
|
else if (message == "togglesplit")
|
||||||
toggleSplit(header.pWindow);
|
toggleSplit(header.pWindow);
|
||||||
else if (message == "groupinfo") {
|
else if (message == "groupinfo") {
|
||||||
auto res = getGroupMembers(g_pCompositor->m_pLastWindow);
|
auto res = getGroupMembers(header.pWindow ? header.pWindow : g_pCompositor->m_pLastWindow);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,6 +41,7 @@ struct SDwindleNodeData {
|
|||||||
bool isGroupMember();
|
bool isGroupMember();
|
||||||
SDwindleNodeData* getGroupHead();
|
SDwindleNodeData* getGroupHead();
|
||||||
SDwindleNodeData* getGroupVisible();
|
SDwindleNodeData* getGroupVisible();
|
||||||
|
int getGroupMemberCount();
|
||||||
void setGroupFocusedNode(SDwindleNodeData*);
|
void setGroupFocusedNode(SDwindleNodeData*);
|
||||||
CHyprDwindleLayout* layout = nullptr;
|
CHyprDwindleLayout* layout = nullptr;
|
||||||
};
|
};
|
||||||
@@ -74,7 +75,7 @@ private:
|
|||||||
SDwindleNodeData* getMasterNodeOnWorkspace(const int&);
|
SDwindleNodeData* getMasterNodeOnWorkspace(const int&);
|
||||||
|
|
||||||
void toggleWindowGroup(CWindow*);
|
void toggleWindowGroup(CWindow*);
|
||||||
void switchGroupWindow(CWindow*, bool forward);
|
void switchGroupWindow(CWindow*, bool forward, CWindow* to = nullptr);
|
||||||
void toggleSplit(CWindow*);
|
void toggleSplit(CWindow*);
|
||||||
std::deque<CWindow*> getGroupMembers(CWindow*);
|
std::deque<CWindow*> getGroupMembers(CWindow*);
|
||||||
|
|
||||||
|
@@ -64,8 +64,24 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
|||||||
// check if it's on the correct monitor!
|
// check if it's on the correct monitor!
|
||||||
Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f;
|
Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f;
|
||||||
|
|
||||||
|
// check if it's visible on any monitor (only for XDG)
|
||||||
|
bool visible = pWindow->m_bIsX11;
|
||||||
|
|
||||||
|
if (!pWindow->m_bIsX11) {
|
||||||
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
|
if (VECINRECT(Vector2D(desiredGeometry.x, desiredGeometry.y), m->vecPosition.x, m->vecPosition.y, m->vecPosition.x + m->vecSize.x, m->vecPosition.y + m->vecPosition.y)
|
||||||
|
|| VECINRECT(Vector2D(desiredGeometry.x + desiredGeometry.width, desiredGeometry.y), m->vecPosition.x, m->vecPosition.y, m->vecPosition.x + m->vecSize.x, m->vecPosition.y + m->vecPosition.y)
|
||||||
|
|| VECINRECT(Vector2D(desiredGeometry.x, desiredGeometry.y + desiredGeometry.height), m->vecPosition.x, m->vecPosition.y, m->vecPosition.x + m->vecSize.x, m->vecPosition.y + m->vecPosition.y)
|
||||||
|
|| VECINRECT(Vector2D(desiredGeometry.x + desiredGeometry.width, desiredGeometry.y + desiredGeometry.height), m->vecPosition.x, m->vecPosition.y, m->vecPosition.x + m->vecSize.x, m->vecPosition.y + m->vecPosition.y)) {
|
||||||
|
|
||||||
|
visible = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: detect a popup in a more consistent way.
|
// TODO: detect a popup in a more consistent way.
|
||||||
if ((desiredGeometry.x == 0 && desiredGeometry.y == 0)) {
|
if ((desiredGeometry.x == 0 && desiredGeometry.y == 0) || !visible) {
|
||||||
// if it's not, fall back to the center placement
|
// if it's not, fall back to the center placement
|
||||||
pWindow->m_vRealPosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f);
|
pWindow->m_vRealPosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f);
|
||||||
} else {
|
} else {
|
||||||
@@ -121,7 +137,7 @@ void IHyprLayout::onBeginDragWindow() {
|
|||||||
DRAGGINGWINDOW->m_bDraggingTiled = false;
|
DRAGGINGWINDOW->m_bDraggingTiled = false;
|
||||||
|
|
||||||
if (!DRAGGINGWINDOW->m_bIsFloating) {
|
if (!DRAGGINGWINDOW->m_bIsFloating) {
|
||||||
if (g_pInputManager->dragButton == BTN_LEFT) {
|
if (g_pInputManager->dragMode == MBIND_MOVE) {
|
||||||
changeWindowFloatingMode(DRAGGINGWINDOW);
|
changeWindowFloatingMode(DRAGGINGWINDOW);
|
||||||
DRAGGINGWINDOW->m_bIsFloating = true;
|
DRAGGINGWINDOW->m_bIsFloating = true;
|
||||||
DRAGGINGWINDOW->m_bDraggingTiled = true;
|
DRAGGINGWINDOW->m_bDraggingTiled = true;
|
||||||
@@ -135,6 +151,21 @@ void IHyprLayout::onBeginDragWindow() {
|
|||||||
m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.goalv();
|
m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.goalv();
|
||||||
m_vLastDragXY = m_vBeginDragXY;
|
m_vLastDragXY = m_vBeginDragXY;
|
||||||
|
|
||||||
|
// get the grab corner
|
||||||
|
if (m_vBeginDragXY.x < m_vBeginDragPositionXY.x + m_vBeginDragSizeXY.x / 2.0) {
|
||||||
|
// left
|
||||||
|
if (m_vBeginDragXY.y < m_vBeginDragPositionXY.y + m_vBeginDragSizeXY.y / 2.0)
|
||||||
|
m_iGrabbedCorner = 0;
|
||||||
|
else
|
||||||
|
m_iGrabbedCorner = 4;
|
||||||
|
} else {
|
||||||
|
// right
|
||||||
|
if (m_vBeginDragXY.y < m_vBeginDragPositionXY.y + m_vBeginDragSizeXY.y / 2.0)
|
||||||
|
m_iGrabbedCorner = 1;
|
||||||
|
else
|
||||||
|
m_iGrabbedCorner = 3;
|
||||||
|
}
|
||||||
|
|
||||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||||
|
|
||||||
// shadow to ignore any bound to MAIN_MOD
|
// shadow to ignore any bound to MAIN_MOD
|
||||||
@@ -176,20 +207,41 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
|||||||
|
|
||||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||||
|
|
||||||
if (g_pInputManager->dragButton == BTN_LEFT) {
|
if (g_pInputManager->dragMode == MBIND_MOVE) {
|
||||||
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA);
|
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA);
|
||||||
|
|
||||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||||
} else {
|
} else if (g_pInputManager->dragMode == MBIND_RESIZE) {
|
||||||
if (DRAGGINGWINDOW->m_bIsFloating) {
|
if (DRAGGINGWINDOW->m_bIsFloating) {
|
||||||
|
|
||||||
const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW);
|
const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW);
|
||||||
|
|
||||||
|
// calc the new size and pos
|
||||||
|
|
||||||
|
Vector2D newSize = m_vBeginDragSizeXY;
|
||||||
|
Vector2D newPos = m_vBeginDragPositionXY;
|
||||||
|
|
||||||
|
if (m_iGrabbedCorner == 3) {
|
||||||
|
newSize = newSize + DELTA;
|
||||||
|
} else if (m_iGrabbedCorner == 0) {
|
||||||
|
newSize = newSize - DELTA;
|
||||||
|
newPos = newPos + DELTA;
|
||||||
|
} else if (m_iGrabbedCorner == 1) {
|
||||||
|
newSize = newSize + Vector2D(DELTA.x, -DELTA.y);
|
||||||
|
newPos = newPos + Vector2D(0, DELTA.y);
|
||||||
|
} else if (m_iGrabbedCorner == 4) {
|
||||||
|
newSize = newSize + Vector2D(-DELTA.x, DELTA.y);
|
||||||
|
newPos = newPos + Vector2D(DELTA.x, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
newSize = newSize.clamp(Vector2D(20,20), MAXSIZE);
|
||||||
|
|
||||||
if (*PANIMATE) {
|
if (*PANIMATE) {
|
||||||
DRAGGINGWINDOW->m_vRealSize = Vector2D(std::clamp(m_vBeginDragSizeXY.x + DELTA.x, (double)20, (double)MAXSIZE.x), std::clamp(m_vBeginDragSizeXY.y + DELTA.y, (double)20, (double)MAXSIZE.y));
|
DRAGGINGWINDOW->m_vRealSize = newSize;
|
||||||
|
DRAGGINGWINDOW->m_vRealPosition = newPos;
|
||||||
} else {
|
} else {
|
||||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(m_vBeginDragSizeXY + DELTA);
|
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(newSize);
|
||||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(Vector2D(std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().x, (double)20, (double)MAXSIZE.x), std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().y, (double)20, (double)MAXSIZE.y)));
|
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(newPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||||
@@ -226,6 +278,8 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pWindow->m_bPinned = false;
|
||||||
|
|
||||||
const auto TILED = isWindowTiled(pWindow);
|
const auto TILED = isWindowTiled(pWindow);
|
||||||
|
|
||||||
if (!TILED) {
|
if (!TILED) {
|
||||||
|
@@ -128,4 +128,5 @@ private:
|
|||||||
Vector2D m_vLastDragXY;
|
Vector2D m_vLastDragXY;
|
||||||
Vector2D m_vBeginDragPositionXY;
|
Vector2D m_vBeginDragPositionXY;
|
||||||
Vector2D m_vBeginDragSizeXY;
|
Vector2D m_vBeginDragSizeXY;
|
||||||
|
int m_iGrabbedCorner = 0;
|
||||||
};
|
};
|
@@ -84,6 +84,13 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||||
|
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||||
|
g_pCompositor->setWindowFullscreen(PFULLWINDOW, false, FULLSCREEN_FULL);
|
||||||
|
}
|
||||||
|
|
||||||
// recalc
|
// recalc
|
||||||
recalculateMonitor(pWindow->m_iMonitorID);
|
recalculateMonitor(pWindow->m_iMonitorID);
|
||||||
}
|
}
|
||||||
@@ -94,6 +101,9 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
|||||||
if (!PNODE)
|
if (!PNODE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (pWindow->m_bIsFullscreen)
|
||||||
|
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
|
||||||
|
|
||||||
if (PNODE->isMaster) {
|
if (PNODE->isMaster) {
|
||||||
// find new one
|
// find new one
|
||||||
for (auto& nd : m_lMasterNodesData) {
|
for (auto& nd : m_lMasterNodesData) {
|
||||||
@@ -215,9 +225,9 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
|||||||
const bool DISPLAYTOP = STICKS(pNode->position.y, PMONITOR->vecPosition.y + PMONITOR->vecReservedTopLeft.y);
|
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 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 PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||||
const auto GAPSIN = g_pConfigManager->getInt("general:gaps_in");
|
const auto PGAPSIN = &g_pConfigManager->getConfigValuePtr("general:gaps_in")->intValue;
|
||||||
const auto GAPSOUT = g_pConfigManager->getInt("general:gaps_out");
|
const auto PGAPSOUT = &g_pConfigManager->getConfigValuePtr("general:gaps_out")->intValue;
|
||||||
|
|
||||||
const auto PWINDOW = pNode->pWindow;
|
const auto PWINDOW = pNode->pWindow;
|
||||||
|
|
||||||
@@ -231,29 +241,31 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
|||||||
PWINDOW->m_vSize = pNode->size;
|
PWINDOW->m_vSize = pNode->size;
|
||||||
PWINDOW->m_vPosition = pNode->position;
|
PWINDOW->m_vPosition = pNode->position;
|
||||||
|
|
||||||
auto calcPos = PWINDOW->m_vPosition + Vector2D(BORDERSIZE, BORDERSIZE);
|
auto calcPos = PWINDOW->m_vPosition + Vector2D(*PBORDERSIZE, *PBORDERSIZE);
|
||||||
auto calcSize = PWINDOW->m_vSize - Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE);
|
auto calcSize = PWINDOW->m_vSize - Vector2D(2 * *PBORDERSIZE, 2 * *PBORDERSIZE);
|
||||||
|
|
||||||
if (*PNOGAPSWHENONLY && PWINDOW->m_iWorkspaceID != SPECIAL_WORKSPACE_ID && getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1) {
|
if (*PNOGAPSWHENONLY && PWINDOW->m_iWorkspaceID != SPECIAL_WORKSPACE_ID && getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1) {
|
||||||
PWINDOW->m_vRealPosition = calcPos - Vector2D(BORDERSIZE, BORDERSIZE);
|
PWINDOW->m_vRealPosition = calcPos - Vector2D(*PBORDERSIZE, *PBORDERSIZE);
|
||||||
PWINDOW->m_vRealSize = calcSize + Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE);
|
PWINDOW->m_vRealSize = calcSize + Vector2D(2 * *PBORDERSIZE, 2 * *PBORDERSIZE);
|
||||||
|
|
||||||
PWINDOW->updateWindowDecos();
|
PWINDOW->updateWindowDecos();
|
||||||
|
|
||||||
PWINDOW->m_sSpecialRenderData.rounding = false;
|
PWINDOW->m_sSpecialRenderData.rounding = false;
|
||||||
PWINDOW->m_sSpecialRenderData.border = false;
|
PWINDOW->m_sSpecialRenderData.border = false;
|
||||||
|
PWINDOW->m_sSpecialRenderData.decorate = false;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PWINDOW->m_sSpecialRenderData.rounding = true;
|
PWINDOW->m_sSpecialRenderData.rounding = true;
|
||||||
PWINDOW->m_sSpecialRenderData.border = true;
|
PWINDOW->m_sSpecialRenderData.border = true;
|
||||||
|
PWINDOW->m_sSpecialRenderData.decorate = true;
|
||||||
|
|
||||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? GAPSOUT : GAPSIN,
|
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? *PGAPSOUT : *PGAPSIN,
|
||||||
DISPLAYTOP ? GAPSOUT : GAPSIN);
|
DISPLAYTOP ? *PGAPSOUT : *PGAPSIN);
|
||||||
|
|
||||||
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? GAPSOUT : GAPSIN,
|
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? *PGAPSOUT : *PGAPSIN,
|
||||||
DISPLAYBOTTOM ? GAPSOUT : GAPSIN);
|
DISPLAYBOTTOM ? *PGAPSOUT : *PGAPSIN);
|
||||||
|
|
||||||
calcPos = calcPos + OFFSETTOPLEFT;
|
calcPos = calcPos + OFFSETTOPLEFT;
|
||||||
calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT;
|
calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT;
|
||||||
@@ -297,7 +309,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* p
|
|||||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||||
|
|
||||||
if (!PNODE) {
|
if (!PNODE) {
|
||||||
PWINDOW->m_vRealSize = Vector2D(std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).x, (double)20, (double)999999), std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).y, (double)20, (double)999999));
|
PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goalv() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goalv() + pixResize).y, 20.0));
|
||||||
PWINDOW->updateWindowDecos();
|
PWINDOW->updateWindowDecos();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -326,10 +338,7 @@ void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreen
|
|||||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
if (on == pWindow->m_bIsFullscreen || pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||||
return;
|
|
||||||
|
|
||||||
if (on == pWindow->m_bIsFullscreen)
|
|
||||||
return; // ignore
|
return; // ignore
|
||||||
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||||
@@ -425,16 +434,17 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||||
Debug::log(ERR, "Master: Rejecting a swap between workspaces");
|
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
|
||||||
return;
|
std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// massive hack: just swap window pointers, lol
|
// massive hack: just swap window pointers, lol
|
||||||
const auto PWINDOW1 = PNODE->pWindow;
|
PNODE->pWindow = pWindow2;
|
||||||
PNODE->pWindow = PNODE2->pWindow;
|
PNODE2->pWindow = pWindow;
|
||||||
PNODE2->pWindow = PWINDOW1;
|
|
||||||
|
|
||||||
recalculateMonitor(PWINDOW1->m_iMonitorID);
|
recalculateMonitor(pWindow->m_iMonitorID);
|
||||||
|
if (PNODE2->workspaceID != PNODE->workspaceID)
|
||||||
|
recalculateMonitor(pWindow2->m_iMonitorID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprMasterLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
void CHyprMasterLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
||||||
|
@@ -14,6 +14,12 @@ int main(int argc, char** argv) {
|
|||||||
if (!getenv("XDG_RUNTIME_DIR"))
|
if (!getenv("XDG_RUNTIME_DIR"))
|
||||||
throw std::runtime_error("XDG_RUNTIME_DIR is not set!");
|
throw std::runtime_error("XDG_RUNTIME_DIR is not set!");
|
||||||
|
|
||||||
|
// export HYPRLAND_CMD
|
||||||
|
std::string cmd = "";
|
||||||
|
for (auto i = 0; i < argc; ++i)
|
||||||
|
cmd += std::string(i == 0 ? "" : " ") + argv[i];
|
||||||
|
setenv("HYPRLAND_CMD", cmd.c_str(), 1);
|
||||||
|
|
||||||
// parse some args
|
// parse some args
|
||||||
std::string configPath;
|
std::string configPath;
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
@@ -36,19 +36,12 @@ void CEventManager::startThread() {
|
|||||||
// 10 max queued.
|
// 10 max queued.
|
||||||
listen(SOCKET, 10);
|
listen(SOCKET, 10);
|
||||||
|
|
||||||
char readBuf[1024] = {0};
|
|
||||||
|
|
||||||
sockaddr_in clientAddress;
|
sockaddr_in clientAddress;
|
||||||
socklen_t clientSize = sizeof(clientAddress);
|
socklen_t clientSize = sizeof(clientAddress);
|
||||||
|
|
||||||
Debug::log(LOG, "Hypr socket 2 started at %s", socketPath.c_str());
|
Debug::log(LOG, "Hypr socket 2 started at %s", socketPath.c_str());
|
||||||
|
|
||||||
// set the socket nonblock
|
|
||||||
int flags = fcntl(SOCKET, F_GETFL, 0);
|
|
||||||
fcntl(SOCKET, F_SETFL, flags | O_NONBLOCK);
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);
|
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);
|
||||||
|
|
||||||
if (ACCEPTEDCONNECTION > 0) {
|
if (ACCEPTEDCONNECTION > 0) {
|
||||||
@@ -61,6 +54,18 @@ void CEventManager::startThread() {
|
|||||||
Debug::log(LOG, "Socket 2 accepted a new client at FD %d", ACCEPTEDCONNECTION);
|
Debug::log(LOG, "Socket 2 accepted a new client at FD %d", ACCEPTEDCONNECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensureFDsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
close(SOCKET);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_tThread.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEventManager::ensureFDsValid() {
|
||||||
|
static char readBuf[1024] = {0};
|
||||||
|
|
||||||
// pong if all FDs valid
|
// pong if all FDs valid
|
||||||
for (auto it = m_dAcceptedSocketFDs.begin(); it != m_dAcceptedSocketFDs.end();) {
|
for (auto it = m_dAcceptedSocketFDs.begin(); it != m_dAcceptedSocketFDs.end();) {
|
||||||
auto sizeRead = recv(*it, &readBuf, 1024, 0);
|
auto sizeRead = recv(*it, &readBuf, 1024, 0);
|
||||||
@@ -74,18 +79,14 @@ void CEventManager::startThread() {
|
|||||||
Debug::log(LOG, "Removed invalid socket (2) FD: %d", *it);
|
Debug::log(LOG, "Removed invalid socket (2) FD: %d", *it);
|
||||||
it = m_dAcceptedSocketFDs.erase(it);
|
it = m_dAcceptedSocketFDs.erase(it);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEventManager::flushEvents() {
|
||||||
|
|
||||||
|
ensureFDsValid();
|
||||||
|
|
||||||
// valid FDs, check the queue
|
|
||||||
// don't do anything if main thread is writing to the eventqueue
|
|
||||||
eventQueueMutex.lock();
|
eventQueueMutex.lock();
|
||||||
|
|
||||||
if (m_dQueuedEvents.empty()){ // if queue empty, sleep and ignore
|
|
||||||
eventQueueMutex.unlock();
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write all queued events
|
|
||||||
for (auto& ev : m_dQueuedEvents) {
|
for (auto& ev : m_dQueuedEvents) {
|
||||||
std::string eventString = (ev.event + ">>" + ev.data).substr(0, 1022) + "\n";
|
std::string eventString = (ev.event + ">>" + ev.data).substr(0, 1022) + "\n";
|
||||||
for (auto& fd : m_dAcceptedSocketFDs) {
|
for (auto& fd : m_dAcceptedSocketFDs) {
|
||||||
@@ -96,14 +97,6 @@ void CEventManager::startThread() {
|
|||||||
m_dQueuedEvents.clear();
|
m_dQueuedEvents.clear();
|
||||||
|
|
||||||
eventQueueMutex.unlock();
|
eventQueueMutex.unlock();
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
close(SOCKET);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_tThread.detach();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEventManager::postEvent(const SHyprIPCEvent event, bool force) {
|
void CEventManager::postEvent(const SHyprIPCEvent event, bool force) {
|
||||||
@@ -117,5 +110,7 @@ void CEventManager::postEvent(const SHyprIPCEvent event, bool force) {
|
|||||||
eventQueueMutex.lock();
|
eventQueueMutex.lock();
|
||||||
m_dQueuedEvents.push_back(ev);
|
m_dQueuedEvents.push_back(ev);
|
||||||
eventQueueMutex.unlock();
|
eventQueueMutex.unlock();
|
||||||
|
|
||||||
|
flushEvents();
|
||||||
}, event).detach();
|
}, event).detach();
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void flushEvents();
|
||||||
|
void ensureFDsValid();
|
||||||
|
|
||||||
std::mutex eventQueueMutex;
|
std::mutex eventQueueMutex;
|
||||||
std::deque<SHyprIPCEvent> m_dQueuedEvents;
|
std::deque<SHyprIPCEvent> m_dQueuedEvents;
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@ CKeybindManager::CKeybindManager() {
|
|||||||
|
|
||||||
m_mDispatchers["exec"] = spawn;
|
m_mDispatchers["exec"] = spawn;
|
||||||
m_mDispatchers["killactive"] = killActive;
|
m_mDispatchers["killactive"] = killActive;
|
||||||
|
m_mDispatchers["closewindow"] = kill;
|
||||||
m_mDispatchers["togglefloating"] = toggleActiveFloating;
|
m_mDispatchers["togglefloating"] = toggleActiveFloating;
|
||||||
m_mDispatchers["workspace"] = changeworkspace;
|
m_mDispatchers["workspace"] = changeworkspace;
|
||||||
m_mDispatchers["fullscreen"] = fullscreenActive;
|
m_mDispatchers["fullscreen"] = fullscreenActive;
|
||||||
@@ -41,6 +42,8 @@ CKeybindManager::CKeybindManager() {
|
|||||||
m_mDispatchers["resizewindowpixel"] = resizeWindow;
|
m_mDispatchers["resizewindowpixel"] = resizeWindow;
|
||||||
m_mDispatchers["swapnext"] = swapnext;
|
m_mDispatchers["swapnext"] = swapnext;
|
||||||
m_mDispatchers["swapactiveworkspaces"] = swapActiveWorkspaces;
|
m_mDispatchers["swapactiveworkspaces"] = swapActiveWorkspaces;
|
||||||
|
m_mDispatchers["pin"] = pinActive;
|
||||||
|
m_mDispatchers["mouse"] = mouse;
|
||||||
|
|
||||||
m_tScrollTimer.reset();
|
m_tScrollTimer.reset();
|
||||||
}
|
}
|
||||||
@@ -120,12 +123,39 @@ void CKeybindManager::updateXKBTranslationState() {
|
|||||||
|
|
||||||
const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
|
||||||
const auto PKEYMAP = FILEPATH == "" ? xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS) : xkb_keymap_new_from_file(PCONTEXT, fopen(FILEPATH.c_str(), "r"), XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
auto PKEYMAP = FILEPATH == "" ? xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS) : xkb_keymap_new_from_file(PCONTEXT, fopen(FILEPATH.c_str(), "r"), XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
|
if (!PKEYMAP) {
|
||||||
|
g_pHyprError->queueCreate("[Runtime Error] Invalid keyboard layout passed. ( rules: " + RULES + ", model: " + MODEL + ", variant: " + VARIANT + ", options: " + OPTIONS + ", layout: " + LAYOUT + " )", CColor(255, 50, 50, 255));
|
||||||
|
|
||||||
|
Debug::log(ERR, "[XKBTranslationState] Keyboard layout %s with variant %s (rules: %s, model: %s, options: %s) couldn't have been loaded.", rules.layout, rules.variant, rules.rules, rules.model, rules.options);
|
||||||
|
memset(&rules, 0, sizeof(rules));
|
||||||
|
|
||||||
|
PKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
}
|
||||||
|
|
||||||
xkb_context_unref(PCONTEXT);
|
xkb_context_unref(PCONTEXT);
|
||||||
m_pXKBTranslationState = xkb_state_new(PKEYMAP);
|
m_pXKBTranslationState = xkb_state_new(PKEYMAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CKeybindManager::ensureMouseBindState() {
|
||||||
|
if (!m_bIsMouseBindActive)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (g_pInputManager->currentlyDraggedWindow) {
|
||||||
|
m_bIsMouseBindActive = false;
|
||||||
|
g_pLayoutManager->getCurrentLayout()->onEndDragWindow();
|
||||||
|
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||||
|
g_pInputManager->dragMode = MBIND_INVALID;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bIsMouseBindActive = false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
|
bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
|
||||||
if (!g_pCompositor->m_bSessionActive) {
|
if (!g_pCompositor->m_bSessionActive) {
|
||||||
m_dPressedKeycodes.clear();
|
m_dPressedKeycodes.clear();
|
||||||
@@ -158,6 +188,8 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
|||||||
m_uLastCode = KEYCODE;
|
m_uLastCode = KEYCODE;
|
||||||
m_uLastMouseCode = 0;
|
m_uLastMouseCode = 0;
|
||||||
|
|
||||||
|
bool mouseBindWasActive = ensureMouseBindState();
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
// clean repeat
|
// clean repeat
|
||||||
@@ -184,8 +216,8 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
|||||||
m_pActiveKeybind = nullptr;
|
m_pActiveKeybind = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dPressedKeycodes.erase(std::remove(m_dPressedKeycodes.begin(), m_dPressedKeycodes.end(), KEYCODE));
|
m_dPressedKeycodes.erase(std::remove(m_dPressedKeycodes.begin(), m_dPressedKeycodes.end(), KEYCODE), m_dPressedKeycodes.end());
|
||||||
m_dPressedKeysyms.erase(std::remove(m_dPressedKeysyms.begin(), m_dPressedKeysyms.end(), keysym));
|
m_dPressedKeysyms.erase(std::remove(m_dPressedKeysyms.begin(), m_dPressedKeysyms.end(), keysym), m_dPressedKeysyms.end());
|
||||||
|
|
||||||
found = g_pKeybindManager->handleKeybinds(MODS, "", keysym, 0, false, e->time_msec) || found;
|
found = g_pKeybindManager->handleKeybinds(MODS, "", keysym, 0, false, e->time_msec) || found;
|
||||||
|
|
||||||
@@ -194,7 +226,7 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
|||||||
shadowKeybinds();
|
shadowKeybinds();
|
||||||
}
|
}
|
||||||
|
|
||||||
return !found;
|
return !found && !mouseBindWasActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) {
|
bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) {
|
||||||
@@ -233,6 +265,8 @@ bool CKeybindManager::onMouseEvent(wlr_pointer_button_event* e) {
|
|||||||
m_uLastCode = 0;
|
m_uLastCode = 0;
|
||||||
m_uTimeLastMs = e->time_msec;
|
m_uTimeLastMs = e->time_msec;
|
||||||
|
|
||||||
|
bool mouseBindWasActive = ensureMouseBindState();
|
||||||
|
|
||||||
if (e->state == WLR_BUTTON_PRESSED) {
|
if (e->state == WLR_BUTTON_PRESSED) {
|
||||||
found = g_pKeybindManager->handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, true, 0);
|
found = g_pKeybindManager->handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, true, 0);
|
||||||
|
|
||||||
@@ -244,7 +278,7 @@ bool CKeybindManager::onMouseEvent(wlr_pointer_button_event* e) {
|
|||||||
shadowKeybinds();
|
shadowKeybinds();
|
||||||
}
|
}
|
||||||
|
|
||||||
return !found;
|
return !found && !mouseBindWasActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
int repeatKeyHandler(void* data) {
|
int repeatKeyHandler(void* data) {
|
||||||
@@ -276,7 +310,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto& k : m_lKeybinds) {
|
for (auto& k : m_lKeybinds) {
|
||||||
if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || (!pressed && !k.release && k.handler != "pass") || k.shadowed)
|
if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || (!pressed && !k.release && k.handler != "pass" && k.handler != "mouse") || k.shadowed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!key.empty()) {
|
if (!key.empty()) {
|
||||||
@@ -305,7 +339,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto DISPATCHER = m_mDispatchers.find(k.handler);
|
const auto DISPATCHER = m_mDispatchers.find(k.mouse ? "mouse" : k.handler);
|
||||||
|
|
||||||
// Should never happen, as we check in the ConfigManager, but oh well
|
// Should never happen, as we check in the ConfigManager, but oh well
|
||||||
if (DISPATCHER == m_mDispatchers.end()) {
|
if (DISPATCHER == m_mDispatchers.end()) {
|
||||||
@@ -316,6 +350,9 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
|||||||
|
|
||||||
m_iPassPressed = (int)pressed;
|
m_iPassPressed = (int)pressed;
|
||||||
|
|
||||||
|
if (k.handler == "mouse")
|
||||||
|
DISPATCHER->second((pressed ? "1" : "0") + k.arg);
|
||||||
|
else
|
||||||
DISPATCHER->second(k.arg);
|
DISPATCHER->second(k.arg);
|
||||||
|
|
||||||
m_iPassPressed = -1;
|
m_iPassPressed = -1;
|
||||||
@@ -475,6 +512,17 @@ void CKeybindManager::killActive(std::string args) {
|
|||||||
g_pCompositor->closeWindow(g_pCompositor->m_pLastWindow);
|
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() {
|
void CKeybindManager::clearKeybinds() {
|
||||||
m_lKeybinds.clear();
|
m_lKeybinds.clear();
|
||||||
}
|
}
|
||||||
@@ -495,11 +543,10 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
|
|||||||
// remove drag status
|
// remove drag status
|
||||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
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) {
|
PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating;
|
||||||
moveActiveToWorkspace(std::to_string(g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeWorkspace));
|
|
||||||
}
|
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW);
|
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW);
|
||||||
}
|
}
|
||||||
@@ -513,6 +560,7 @@ void CKeybindManager::toggleActivePseudo(std::string args) {
|
|||||||
|
|
||||||
ACTIVEWINDOW->m_bIsPseudotiled = !ACTIVEWINDOW->m_bIsPseudotiled;
|
ACTIVEWINDOW->m_bIsPseudotiled = !ACTIVEWINDOW->m_bIsPseudotiled;
|
||||||
|
|
||||||
|
if (!ACTIVEWINDOW->m_bIsFullscreen)
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(ACTIVEWINDOW);
|
g_pLayoutManager->getCurrentLayout()->recalculateWindow(ACTIVEWINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,13 +611,10 @@ void CKeybindManager::changeworkspace(std::string args) {
|
|||||||
|
|
||||||
// Workspace_back_and_forth being enabled means that an attempt to switch to
|
// Workspace_back_and_forth being enabled means that an attempt to switch to
|
||||||
// the current workspace will instead switch to the previous.
|
// the current workspace will instead switch to the previous.
|
||||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(
|
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||||
g_pCompositor->m_pLastMonitor->activeWorkspace);
|
|
||||||
static auto *const PBACKANDFORTH = &g_pConfigManager->getConfigValuePtr("binds:workspace_back_and_forth")->intValue;
|
static auto *const PBACKANDFORTH = &g_pConfigManager->getConfigValuePtr("binds:workspace_back_and_forth")->intValue;
|
||||||
if (*PBACKANDFORTH
|
|
||||||
&& PCURRENTWORKSPACE->m_iID == workspaceToChangeTo
|
if (*PBACKANDFORTH && PCURRENTWORKSPACE->m_iID == workspaceToChangeTo && PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1 && !internal) {
|
||||||
&& PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1
|
|
||||||
&& !internal) {
|
|
||||||
|
|
||||||
workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID;
|
workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID;
|
||||||
isSwitchingToPrevious = true;
|
isSwitchingToPrevious = true;
|
||||||
@@ -579,7 +624,9 @@ void CKeybindManager::changeworkspace(std::string args) {
|
|||||||
static auto *const PALLOWWORKSPACECYCLES = &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue;
|
static auto *const PALLOWWORKSPACECYCLES = &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue;
|
||||||
if (!*PALLOWWORKSPACECYCLES)
|
if (!*PALLOWWORKSPACECYCLES)
|
||||||
PCURRENTWORKSPACE->m_iPrevWorkspaceID = -1;
|
PCURRENTWORKSPACE->m_iPrevWorkspaceID = -1;
|
||||||
}
|
|
||||||
|
} else if (PCURRENTWORKSPACE->m_iID == workspaceToChangeTo && !internal)
|
||||||
|
return;
|
||||||
|
|
||||||
// remove constraints
|
// remove constraints
|
||||||
g_pInputManager->unconstrainMouse();
|
g_pInputManager->unconstrainMouse();
|
||||||
@@ -605,6 +652,13 @@ void CKeybindManager::changeworkspace(std::string args) {
|
|||||||
if (!g_pCompositor->isWorkspaceVisible(workspaceToChangeTo)) {
|
if (!g_pCompositor->isWorkspaceVisible(workspaceToChangeTo)) {
|
||||||
const auto OLDWORKSPACEID = PMONITOR->activeWorkspace;
|
const auto OLDWORKSPACEID = PMONITOR->activeWorkspace;
|
||||||
|
|
||||||
|
// fix pinned windows
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
if (w->m_iWorkspaceID == PMONITOR->activeWorkspace && w->m_bPinned) {
|
||||||
|
w->m_iWorkspaceID = workspaceToChangeTo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// change it
|
// change it
|
||||||
if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID)
|
if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID)
|
||||||
PMONITOR->activeWorkspace = workspaceToChangeTo;
|
PMONITOR->activeWorkspace = workspaceToChangeTo;
|
||||||
@@ -625,7 +679,8 @@ void CKeybindManager::changeworkspace(std::string args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the monitor is not the one our cursor's at, warp to it.
|
// 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;
|
Vector2D middle = PMONITOR->vecPosition + PMONITOR->vecSize / 2.f;
|
||||||
g_pCompositor->warpCursorTo(middle);
|
g_pCompositor->warpCursorTo(middle);
|
||||||
}
|
}
|
||||||
@@ -640,7 +695,20 @@ void CKeybindManager::changeworkspace(std::string args) {
|
|||||||
Debug::log(LOG, "Changed to workspace %i", workspaceToChangeTo);
|
Debug::log(LOG, "Changed to workspace %i", workspaceToChangeTo);
|
||||||
|
|
||||||
// focus
|
// focus
|
||||||
|
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();
|
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
|
// mark the monitor dirty
|
||||||
g_pHyprRenderer->damageMonitor(PMONITOR);
|
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||||
@@ -649,7 +717,9 @@ void CKeybindManager::changeworkspace(std::string args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Workspace doesn't exist, create and switch
|
// Workspace doesn't exist, create and switch
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
const auto BOUNDMON = g_pConfigManager->getBoundMonitorForWS(workspaceName);
|
||||||
|
|
||||||
|
const auto PMONITOR = BOUNDMON ? BOUNDMON : g_pCompositor->getMonitorFromCursor();
|
||||||
|
|
||||||
const auto OLDWORKSPACE = PMONITOR->activeWorkspace;
|
const auto OLDWORKSPACE = PMONITOR->activeWorkspace;
|
||||||
|
|
||||||
@@ -678,6 +748,13 @@ void CKeybindManager::changeworkspace(std::string args) {
|
|||||||
|
|
||||||
PMONITOR->specialWorkspaceOpen = false;
|
PMONITOR->specialWorkspaceOpen = false;
|
||||||
|
|
||||||
|
// fix pinned windows
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
if (w->m_iWorkspaceID == PMONITOR->activeWorkspace && w->m_bPinned) {
|
||||||
|
w->m_iWorkspaceID = workspaceToChangeTo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID)
|
if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID)
|
||||||
PMONITOR->activeWorkspace = workspaceToChangeTo;
|
PMONITOR->activeWorkspace = workspaceToChangeTo;
|
||||||
else
|
else
|
||||||
@@ -690,6 +767,12 @@ void CKeybindManager::changeworkspace(std::string args) {
|
|||||||
// mark the monitor dirty
|
// mark the monitor dirty
|
||||||
g_pHyprRenderer->damageMonitor(PMONITOR);
|
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||||
|
|
||||||
|
// some stuf with the cursor and focus
|
||||||
|
if (g_pCompositor->m_pLastMonitor != PMONITOR)
|
||||||
|
g_pCompositor->warpCursorTo(PMONITOR->vecPosition + PMONITOR->vecSize / 2.f);
|
||||||
|
|
||||||
|
g_pCompositor->m_pLastMonitor = PMONITOR;
|
||||||
|
|
||||||
// focus (clears the last)
|
// focus (clears the last)
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
|
|
||||||
@@ -705,6 +788,9 @@ void CKeybindManager::fullscreenActive(std::string args) {
|
|||||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||||
|
return;
|
||||||
|
|
||||||
g_pCompositor->setWindowFullscreen(PWINDOW, !PWINDOW->m_bIsFullscreen, args == "1" ? FULLSCREEN_MAXIMIZED : FULLSCREEN_FULL);
|
g_pCompositor->setWindowFullscreen(PWINDOW, !PWINDOW->m_bIsFullscreen, args == "1" ? FULLSCREEN_MAXIMIZED : FULLSCREEN_FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,8 +819,8 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PSAVEDSIZE = PWINDOW->m_vRealSize.vec();
|
auto PSAVEDSIZE = PWINDOW->m_vRealSize.goalv();
|
||||||
auto PSAVEDPOS = PWINDOW->m_vRealPosition.vec();
|
auto PSAVEDPOS = PWINDOW->m_vRealPosition.goalv();
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
|
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
|
||||||
|
|
||||||
@@ -756,17 +842,13 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
|||||||
|
|
||||||
PWINDOW->moveToWorkspace(PWORKSPACE->m_iID);
|
PWINDOW->moveToWorkspace(PWORKSPACE->m_iID);
|
||||||
PWINDOW->m_iMonitorID = PWORKSPACE->m_iMonitorID;
|
PWINDOW->m_iMonitorID = PWORKSPACE->m_iMonitorID;
|
||||||
PWINDOW->m_bIsFullscreen = false;
|
|
||||||
|
|
||||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
|
||||||
g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID)->m_bIsFullscreen = false;
|
|
||||||
PWORKSPACE->m_bHasFullscreenWindow = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PWINDOW->m_bIsFullscreen) {
|
if (PWINDOW->m_bIsFullscreen) {
|
||||||
PWINDOW->m_bIsFullscreen = false;
|
g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL);
|
||||||
PSAVEDPOS = PSAVEDPOS + Vector2D(10, 10);
|
}
|
||||||
PSAVEDSIZE = PSAVEDSIZE - Vector2D(20, 20);
|
|
||||||
|
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||||
|
g_pCompositor->setWindowFullscreen(g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID), false, FULLSCREEN_FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hack: So that the layout doesnt find our window at the cursor
|
// Hack: So that the layout doesnt find our window at the cursor
|
||||||
@@ -790,10 +872,10 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
|||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors)
|
for (auto& m : g_pCompositor->m_vMonitors)
|
||||||
m->specialWorkspaceOpen = false;
|
m->specialWorkspaceOpen = false;
|
||||||
|
} else {
|
||||||
|
g_pCompositor->focusWindow(PWINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pInputManager->refocus();
|
|
||||||
|
|
||||||
PWINDOW->updateToplevel();
|
PWINDOW->updateToplevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -832,7 +914,12 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
|||||||
// may be null until later!
|
// may be null until later!
|
||||||
auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToMoveTo);
|
auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToMoveTo);
|
||||||
|
|
||||||
const auto PMONITORNEW = PWORKSPACE ? g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID) : PMONITOR;
|
auto PMONITORNEW = PWORKSPACE ? g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID) : PMONITOR;
|
||||||
|
if (!PWORKSPACE) {
|
||||||
|
const auto BOUNDMON = g_pConfigManager->getBoundMonitorForWS(workspaceName);
|
||||||
|
if (BOUNDMON)
|
||||||
|
PMONITORNEW = BOUNDMON;
|
||||||
|
}
|
||||||
|
|
||||||
const auto OLDWORKSPACEIDONMONITOR = PMONITORNEW->activeWorkspace;
|
const auto OLDWORKSPACEIDONMONITOR = PMONITORNEW->activeWorkspace;
|
||||||
const auto OLDWORKSPACEIDRETURN = PMONITOR->activeWorkspace;
|
const auto OLDWORKSPACEIDRETURN = PMONITOR->activeWorkspace;
|
||||||
@@ -861,6 +948,9 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
|||||||
|
|
||||||
g_pEventManager->m_bIgnoreEvents = false;
|
g_pEventManager->m_bIgnoreEvents = false;
|
||||||
|
|
||||||
|
// manually post event cuz it got ignored above
|
||||||
|
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", PWINDOW, PWORKSPACE->m_szName.c_str())});
|
||||||
|
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -885,15 +975,27 @@ void CKeybindManager::moveFocusTo(std::string args) {
|
|||||||
if (PLASTWINDOW->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && PLASTWINDOW->m_bIsFullscreen) {
|
if (PLASTWINDOW->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && PLASTWINDOW->m_bIsFullscreen) {
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PLASTWINDOW->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PLASTWINDOW->m_iWorkspaceID);
|
||||||
const auto FSMODE = PWORKSPACE->m_efFullscreenMode;
|
const auto FSMODE = PWORKSPACE->m_efFullscreenMode;
|
||||||
|
|
||||||
|
if (!PWINDOWTOCHANGETO->m_bPinned)
|
||||||
g_pCompositor->setWindowFullscreen(PLASTWINDOW, false, FULLSCREEN_FULL);
|
g_pCompositor->setWindowFullscreen(PLASTWINDOW, false, FULLSCREEN_FULL);
|
||||||
|
|
||||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||||
|
|
||||||
|
if (!PWINDOWTOCHANGETO->m_bPinned)
|
||||||
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
|
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
|
||||||
} else {
|
} else {
|
||||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||||
Vector2D middle = PWINDOWTOCHANGETO->m_vRealPosition.goalv() + PWINDOWTOCHANGETO->m_vRealSize.goalv() / 2.f;
|
Vector2D middle = PWINDOWTOCHANGETO->m_vRealPosition.goalv() + PWINDOWTOCHANGETO->m_vRealSize.goalv() / 2.f;
|
||||||
g_pCompositor->warpCursorTo(middle);
|
g_pCompositor->warpCursorTo(middle);
|
||||||
|
|
||||||
|
if (PWINDOWTOCHANGETO->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID) {
|
||||||
|
// event
|
||||||
|
const auto PNEWMON = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID);
|
||||||
|
const auto PNEWWS = g_pCompositor->getWorkspaceByID(PNEWMON->activeWorkspace);
|
||||||
|
g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", PNEWMON->szName + "," + PNEWWS->m_szName});
|
||||||
|
|
||||||
|
g_pCompositor->m_pLastMonitor = PNEWMON;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -912,7 +1014,7 @@ void CKeybindManager::moveFocusTo(std::string args) {
|
|||||||
if (PWINDOWTOCHANGETO) {
|
if (PWINDOWTOCHANGETO) {
|
||||||
switchToWindow(PWINDOWTOCHANGETO);
|
switchToWindow(PWINDOWTOCHANGETO);
|
||||||
} else {
|
} else {
|
||||||
const auto PWINDOWNEXT = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW);
|
const auto PWINDOWNEXT = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true);
|
||||||
if (PWINDOWNEXT) {
|
if (PWINDOWNEXT) {
|
||||||
switchToWindow(PWINDOWNEXT);
|
switchToWindow(PWINDOWNEXT);
|
||||||
}
|
}
|
||||||
@@ -1116,18 +1218,7 @@ void CKeybindManager::exitHyprland(std::string argz) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
||||||
CMonitor* PMONITOR = nullptr;
|
CMonitor* PMONITOR = g_pCompositor->getMonitorFromString(args);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PMONITOR)
|
if (!PMONITOR)
|
||||||
return;
|
return;
|
||||||
@@ -1148,19 +1239,7 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
|||||||
std::string workspace = args.substr(0, args.find_first_of(' '));
|
std::string workspace = args.substr(0, args.find_first_of(' '));
|
||||||
std::string monitor = args.substr(args.find_first_of(' ') + 1);
|
std::string monitor = args.substr(args.find_first_of(' ') + 1);
|
||||||
|
|
||||||
CMonitor* PMONITOR = nullptr;
|
const auto PMONITOR = g_pCompositor->getMonitorFromString(monitor);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!PMONITOR){
|
if (!PMONITOR){
|
||||||
Debug::log(ERR, "Ignoring moveWorkspaceToMonitor: monitor doesnt exist");
|
Debug::log(ERR, "Ignoring moveWorkspaceToMonitor: monitor doesnt exist");
|
||||||
@@ -1215,6 +1294,11 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||||||
g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID)->startAnim(false, false);
|
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 {
|
} else {
|
||||||
auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID);
|
auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID);
|
||||||
|
|
||||||
@@ -1228,9 +1312,12 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||||||
|
|
||||||
PSPECIALWORKSPACE->startAnim(true, true);
|
PSPECIALWORKSPACE->startAnim(true, true);
|
||||||
PSPECIALWORKSPACE->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID;
|
PSPECIALWORKSPACE->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID;
|
||||||
}
|
|
||||||
|
|
||||||
|
if (const auto PWINDOW = PSPECIALWORKSPACE->getLastFocusedWindow(); PWINDOW)
|
||||||
|
g_pCompositor->focusWindow(PWINDOW);
|
||||||
|
else
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::forceRendererReload(std::string args) {
|
void CKeybindManager::forceRendererReload(std::string args) {
|
||||||
@@ -1249,7 +1336,7 @@ void CKeybindManager::forceRendererReload(std::string args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::resizeActive(std::string args) {
|
void CKeybindManager::resizeActive(std::string args) {
|
||||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealSize.goalv());
|
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealSize.goalv());
|
||||||
@@ -1261,7 +1348,7 @@ void CKeybindManager::resizeActive(std::string args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::moveActive(std::string args) {
|
void CKeybindManager::moveActive(std::string args) {
|
||||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealPosition.goalv());
|
const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealPosition.goalv());
|
||||||
@@ -1281,6 +1368,9 @@ void CKeybindManager::moveWindow(std::string args) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PWINDOW->m_bIsFullscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
const auto POS = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealPosition.goalv());
|
const auto POS = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealPosition.goalv());
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PWINDOW->m_vRealPosition.goalv(), PWINDOW);
|
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PWINDOW->m_vRealPosition.goalv(), PWINDOW);
|
||||||
@@ -1298,6 +1388,9 @@ void CKeybindManager::resizeWindow(std::string args) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PWINDOW->m_bIsFullscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealSize.goalv());
|
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealSize.goalv());
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goalv(), PWINDOW);
|
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goalv(), PWINDOW);
|
||||||
@@ -1317,10 +1410,13 @@ void CKeybindManager::circleNext(std::string arg) {
|
|||||||
if (g_pCompositor->m_pLastWindow->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsFullscreen) {
|
if (g_pCompositor->m_pLastWindow->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsFullscreen) {
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastWindow->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastWindow->m_iWorkspaceID);
|
||||||
const auto FSMODE = PWORKSPACE->m_efFullscreenMode;
|
const auto FSMODE = PWORKSPACE->m_efFullscreenMode;
|
||||||
|
|
||||||
|
if (!PWINDOWTOCHANGETO->m_bPinned)
|
||||||
g_pCompositor->setWindowFullscreen(g_pCompositor->m_pLastWindow, false, FULLSCREEN_FULL);
|
g_pCompositor->setWindowFullscreen(g_pCompositor->m_pLastWindow, false, FULLSCREEN_FULL);
|
||||||
|
|
||||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||||
|
|
||||||
|
if (!PWINDOWTOCHANGETO->m_bPinned)
|
||||||
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
|
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
|
||||||
} else {
|
} else {
|
||||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||||
@@ -1330,9 +1426,9 @@ void CKeybindManager::circleNext(std::string arg) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||||
switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow, true));
|
||||||
else
|
else
|
||||||
switchToWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
switchToWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::focusWindow(std::string regexp) {
|
void CKeybindManager::focusWindow(std::string regexp) {
|
||||||
@@ -1343,8 +1439,6 @@ void CKeybindManager::focusWindow(std::string regexp) {
|
|||||||
|
|
||||||
Debug::log(LOG, "Focusing to window name: %s", PWINDOW->m_szTitle.c_str());
|
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);
|
g_pCompositor->focusWindow(PWINDOW);
|
||||||
|
|
||||||
const auto MIDPOINT = PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f;
|
const auto MIDPOINT = PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f;
|
||||||
@@ -1356,6 +1450,7 @@ void CKeybindManager::setSubmap(std::string submap) {
|
|||||||
if (submap == "reset" || submap == "") {
|
if (submap == "reset" || submap == "") {
|
||||||
m_szCurrentSelectedSubmap = "";
|
m_szCurrentSelectedSubmap = "";
|
||||||
Debug::log(LOG, "Reset active submap to the default one.");
|
Debug::log(LOG, "Reset active submap to the default one.");
|
||||||
|
g_pEventManager->postEvent(SHyprIPCEvent{"submap", ""});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1363,6 +1458,7 @@ void CKeybindManager::setSubmap(std::string submap) {
|
|||||||
if (k.submap == submap) {
|
if (k.submap == submap) {
|
||||||
m_szCurrentSelectedSubmap = submap;
|
m_szCurrentSelectedSubmap = submap;
|
||||||
Debug::log(LOG, "Changed keybind submap to %s", submap.c_str());
|
Debug::log(LOG, "Changed keybind submap to %s", submap.c_str());
|
||||||
|
g_pEventManager->postEvent(SHyprIPCEvent{"submap", submap});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1492,16 +1588,16 @@ void CKeybindManager::swapnext(std::string arg) {
|
|||||||
const auto PLASTCYCLED = g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow->m_pLastCycledWindow) && g_pCompositor->m_pLastWindow->m_pLastCycledWindow->m_iWorkspaceID == PLASTWINDOW->m_iWorkspaceID ? g_pCompositor->m_pLastWindow->m_pLastCycledWindow : nullptr;
|
const auto PLASTCYCLED = g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow->m_pLastCycledWindow) && g_pCompositor->m_pLastWindow->m_pLastCycledWindow->m_iWorkspaceID == PLASTWINDOW->m_iWorkspaceID ? g_pCompositor->m_pLastWindow->m_pLastCycledWindow : nullptr;
|
||||||
|
|
||||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||||
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW);
|
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true);
|
||||||
else
|
else
|
||||||
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW);
|
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true);
|
||||||
|
|
||||||
// sometimes we may come back to ourselves.
|
// sometimes we may come back to ourselves.
|
||||||
if (toSwap == PLASTWINDOW) {
|
if (toSwap == PLASTWINDOW) {
|
||||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||||
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW);
|
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW), true;
|
||||||
else
|
else
|
||||||
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW);
|
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, toSwap);
|
g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, toSwap);
|
||||||
@@ -1523,3 +1619,56 @@ void CKeybindManager::swapActiveWorkspaces(std::string args) {
|
|||||||
|
|
||||||
g_pCompositor->swapActiveWorkspaces(PMON1, PMON2);
|
g_pCompositor->swapActiveWorkspaces(PMON1, PMON2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CKeybindManager::pinActive(std::string args) {
|
||||||
|
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) || !g_pCompositor->m_pLastWindow->m_bIsFloating || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_pCompositor->m_pLastWindow->m_bPinned = !g_pCompositor->m_pLastWindow->m_bPinned;
|
||||||
|
g_pCompositor->m_pLastWindow->m_iWorkspaceID = g_pCompositor->getMonitorFromID(g_pCompositor->m_pLastWindow->m_iMonitorID)->activeWorkspace;
|
||||||
|
|
||||||
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
|
PWORKSPACE->m_pLastFocusedWindow = g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKeybindManager::mouse(std::string args) {
|
||||||
|
const auto TRUEARG = args.substr(1);
|
||||||
|
const auto PRESSED = args[0] == '1';
|
||||||
|
|
||||||
|
if (TRUEARG == "movewindow") {
|
||||||
|
if (PRESSED) {
|
||||||
|
g_pKeybindManager->m_bIsMouseBindActive = true;
|
||||||
|
|
||||||
|
g_pInputManager->currentlyDraggedWindow = g_pCompositor->windowFromCursor();
|
||||||
|
g_pInputManager->dragMode = MBIND_MOVE;
|
||||||
|
|
||||||
|
g_pLayoutManager->getCurrentLayout()->onBeginDragWindow();
|
||||||
|
} else {
|
||||||
|
g_pKeybindManager->m_bIsMouseBindActive = false;
|
||||||
|
|
||||||
|
if (g_pInputManager->currentlyDraggedWindow) {
|
||||||
|
g_pLayoutManager->getCurrentLayout()->onEndDragWindow();
|
||||||
|
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||||
|
g_pInputManager->dragMode = MBIND_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (TRUEARG == "resizewindow") {
|
||||||
|
if (PRESSED) {
|
||||||
|
g_pKeybindManager->m_bIsMouseBindActive = true;
|
||||||
|
|
||||||
|
g_pInputManager->currentlyDraggedWindow = g_pCompositor->windowFromCursor();
|
||||||
|
g_pInputManager->dragMode = MBIND_RESIZE;
|
||||||
|
|
||||||
|
g_pLayoutManager->getCurrentLayout()->onBeginDragWindow();
|
||||||
|
} else {
|
||||||
|
g_pKeybindManager->m_bIsMouseBindActive = false;
|
||||||
|
|
||||||
|
if (g_pInputManager->currentlyDraggedWindow) {
|
||||||
|
g_pLayoutManager->getCurrentLayout()->onEndDragWindow();
|
||||||
|
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||||
|
g_pInputManager->dragMode = MBIND_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -18,6 +18,7 @@ struct SKeybind {
|
|||||||
std::string submap = "";
|
std::string submap = "";
|
||||||
bool release = false;
|
bool release = false;
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
|
bool mouse = false;
|
||||||
|
|
||||||
// DO NOT INITIALIZE
|
// DO NOT INITIALIZE
|
||||||
bool shadowed = false;
|
bool shadowed = false;
|
||||||
@@ -63,6 +64,8 @@ private:
|
|||||||
uint32_t m_uLastCode = 0;
|
uint32_t m_uLastCode = 0;
|
||||||
uint32_t m_uLastMouseCode = 0;
|
uint32_t m_uLastMouseCode = 0;
|
||||||
|
|
||||||
|
bool m_bIsMouseBindActive = false;
|
||||||
|
|
||||||
int m_iPassPressed = -1; // used for pass
|
int m_iPassPressed = -1; // used for pass
|
||||||
|
|
||||||
CTimer m_tScrollTimer;
|
CTimer m_tScrollTimer;
|
||||||
@@ -75,9 +78,11 @@ private:
|
|||||||
xkb_state* m_pXKBTranslationState = nullptr;
|
xkb_state* m_pXKBTranslationState = nullptr;
|
||||||
|
|
||||||
void updateXKBTranslationState();
|
void updateXKBTranslationState();
|
||||||
|
bool ensureMouseBindState();
|
||||||
|
|
||||||
// -------------- Dispatchers -------------- //
|
// -------------- Dispatchers -------------- //
|
||||||
static void killActive(std::string);
|
static void killActive(std::string);
|
||||||
|
static void kill(std::string);
|
||||||
static void spawn(std::string);
|
static void spawn(std::string);
|
||||||
static void toggleActiveFloating(std::string);
|
static void toggleActiveFloating(std::string);
|
||||||
static void toggleActivePseudo(std::string);
|
static void toggleActivePseudo(std::string);
|
||||||
@@ -112,6 +117,8 @@ private:
|
|||||||
static void dpms(std::string);
|
static void dpms(std::string);
|
||||||
static void swapnext(std::string);
|
static void swapnext(std::string);
|
||||||
static void swapActiveWorkspaces(std::string);
|
static void swapActiveWorkspaces(std::string);
|
||||||
|
static void pinActive(std::string);
|
||||||
|
static void mouse(std::string);
|
||||||
|
|
||||||
friend class CCompositor;
|
friend class CCompositor;
|
||||||
friend class CInputManager;
|
friend class CInputManager;
|
||||||
|
@@ -7,6 +7,9 @@ int slowUpdate = 0;
|
|||||||
int handleTimer(void* data) {
|
int handleTimer(void* data) {
|
||||||
const auto PTM = (CThreadManager*)data;
|
const auto PTM = (CThreadManager*)data;
|
||||||
|
|
||||||
|
static auto *const PDISABLECFGRELOAD = &g_pConfigManager->getConfigValuePtr("misc:disable_autoreload")->intValue;
|
||||||
|
|
||||||
|
if (*PDISABLECFGRELOAD != 1)
|
||||||
g_pConfigManager->tick();
|
g_pConfigManager->tick();
|
||||||
|
|
||||||
wl_event_source_timer_update(PTM->m_esConfigTimer, 1000);
|
wl_event_source_timer_update(PTM->m_esConfigTimer, 1000);
|
||||||
@@ -19,8 +22,6 @@ CThreadManager::CThreadManager() {
|
|||||||
|
|
||||||
HyprCtl::startHyprCtlSocket();
|
HyprCtl::startHyprCtlSocket();
|
||||||
|
|
||||||
g_pCompositor->startHyprCtlTick();
|
|
||||||
|
|
||||||
m_esConfigTimer = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, handleTimer, this);
|
m_esConfigTimer = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, handleTimer, this);
|
||||||
|
|
||||||
wl_event_source_timer_update(m_esConfigTimer, 1000);
|
wl_event_source_timer_update(m_esConfigTimer, 1000);
|
||||||
|
@@ -32,9 +32,12 @@ wlr_surface* CHyprXWaylandManager::getWindowSurface(CWindow* pWindow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate) {
|
void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate) {
|
||||||
|
if (!pSurface)
|
||||||
|
return;
|
||||||
|
|
||||||
if (wlr_surface_is_xdg_surface(pSurface)) {
|
if (wlr_surface_is_xdg_surface(pSurface)) {
|
||||||
const auto PSURF = wlr_xdg_surface_from_wlr_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);
|
wlr_xdg_toplevel_set_activated(PSURF->toplevel, activate);
|
||||||
}
|
}
|
||||||
} else if (wlr_surface_is_xwayland_surface(pSurface)) {
|
} else if (wlr_surface_is_xwayland_surface(pSurface)) {
|
||||||
@@ -59,6 +62,9 @@ void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
|
|||||||
|
|
||||||
g_pCompositor->m_pLastFocus = getWindowSurface(pWindow);
|
g_pCompositor->m_pLastFocus = getWindowSurface(pWindow);
|
||||||
g_pCompositor->m_pLastWindow = pWindow;
|
g_pCompositor->m_pLastWindow = pWindow;
|
||||||
|
|
||||||
|
if (!pWindow->m_bPinned)
|
||||||
|
g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_pLastFocusedWindow = pWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprXWaylandManager::getGeometryForWindow(CWindow* pWindow, wlr_box* pbox) {
|
void CHyprXWaylandManager::getGeometryForWindow(CWindow* pWindow, wlr_box* pbox) {
|
||||||
|
@@ -2,16 +2,18 @@
|
|||||||
#include "../../Compositor.hpp"
|
#include "../../Compositor.hpp"
|
||||||
|
|
||||||
void CInputManager::onMouseMoved(wlr_pointer_motion_event* e) {
|
void CInputManager::onMouseMoved(wlr_pointer_motion_event* e) {
|
||||||
float sensitivity = g_pConfigManager->getFloat("general:sensitivity");
|
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)
|
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 * sensitivity, DELTA.y * sensitivity, e->unaccel_dx * sensitivity, e->unaccel_dy * sensitivity);
|
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
|
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_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);
|
mouseMoveUnified(e->time_msec);
|
||||||
|
|
||||||
@@ -27,7 +29,6 @@ void CInputManager::onMouseWarp(wlr_pointer_motion_absolute_event* e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||||
|
|
||||||
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||||
static auto *const PMOUSEDPMS = &g_pConfigManager->getConfigValuePtr("misc:mouse_move_enables_dpms")->intValue;
|
static auto *const PMOUSEDPMS = &g_pConfigManager->getConfigValuePtr("misc:mouse_move_enables_dpms")->intValue;
|
||||||
static auto *const PFOLLOWONDND = &g_pConfigManager->getConfigValuePtr("misc:always_follow_on_dnd")->intValue;
|
static auto *const PFOLLOWONDND = &g_pConfigManager->getConfigValuePtr("misc:always_follow_on_dnd")->intValue;
|
||||||
@@ -138,17 +139,27 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||||||
if (!foundSurface)
|
if (!foundSurface)
|
||||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfaceCoords, &pFoundLayerSurface);
|
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfaceCoords, &pFoundLayerSurface);
|
||||||
|
|
||||||
|
if (!foundSurface)
|
||||||
|
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface);
|
||||||
|
|
||||||
// then, we check if the workspace doesnt have a fullscreen window
|
// then, we check if the workspace doesnt have a fullscreen window
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||||
if (PWORKSPACE->m_bHasFullscreenWindow && !foundSurface && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) {
|
if (PWORKSPACE->m_bHasFullscreenWindow && !foundSurface && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) {
|
||||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
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);
|
foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow);
|
||||||
surfacePos = pFoundWindow->m_vRealPosition.vec();
|
surfacePos = pFoundWindow->m_vRealPosition.vec();
|
||||||
|
|
||||||
// only check floating because tiled cant be over fullscreen
|
// only check floating because tiled cant be over fullscreen
|
||||||
for (auto w = g_pCompositor->m_vWindows.rbegin(); w != g_pCompositor->m_vWindows.rend(); w++) {
|
for (auto w = g_pCompositor->m_vWindows.rbegin(); w != g_pCompositor->m_vWindows.rend(); w++) {
|
||||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||||
if ((((*w)->m_bIsFloating && (*w)->m_bIsMapped && (*w)->m_bCreatedOverFullscreen) || ((*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden) {
|
if ((((*w)->m_bIsFloating && (*w)->m_bIsMapped && ((*w)->m_bCreatedOverFullscreen || (*w)->m_bPinned)) || ((*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden) {
|
||||||
pFoundWindow = (*w).get();
|
pFoundWindow = (*w).get();
|
||||||
|
|
||||||
if (!pFoundWindow->m_bIsX11) {
|
if (!pFoundWindow->m_bIsX11) {
|
||||||
@@ -164,9 +175,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundSurface)
|
|
||||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface);
|
|
||||||
|
|
||||||
// then windows
|
// then windows
|
||||||
if (!foundSurface) {
|
if (!foundSurface) {
|
||||||
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) {
|
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) {
|
||||||
@@ -267,26 +275,36 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
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) {
|
if (pFoundWindow == g_pCompositor->m_pLastWindow) {
|
||||||
// we changed the subsurface
|
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);
|
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (*PFOLLOWONDND && m_sDrag.dragIcon) {
|
if (*PFOLLOWONDND && m_sDrag.dragIcon) {
|
||||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*PFOLLOWMOUSE != 0 || pFoundWindow == g_pCompositor->m_pLastWindow)
|
||||||
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
|
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
|
return; // don't enter any new surfaces
|
||||||
} else {
|
} else {
|
||||||
if ((*PFOLLOWMOUSE != 3 && allowKeyboardRefocus) || refocus)
|
if ((*PFOLLOWMOUSE != 3 && allowKeyboardRefocus) || refocus)
|
||||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_bLastFocusOnLS = false;
|
||||||
} else {
|
} else {
|
||||||
if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive && *PFOLLOWMOUSE != 3 && allowKeyboardRefocus) {
|
if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive && *PFOLLOWMOUSE != 3 && allowKeyboardRefocus) {
|
||||||
g_pCompositor->focusSurface(foundSurface);
|
g_pCompositor->focusSurface(foundSurface);
|
||||||
g_pCompositor->m_pLastWindow = nullptr; // reset last window as we have a full focus on a LS
|
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);
|
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||||
@@ -381,22 +399,8 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
|
|||||||
if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_bIsFloating)
|
if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_bIsFloating)
|
||||||
g_pCompositor->moveWindowToTop(g_pCompositor->m_pLastWindow);
|
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")) {
|
|
||||||
currentlyDraggedWindow = g_pCompositor->windowFromCursor();
|
|
||||||
dragButton = e->button;
|
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->onBeginDragWindow();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case WLR_BUTTON_RELEASED:
|
case WLR_BUTTON_RELEASED:
|
||||||
if (currentlyDraggedWindow) {
|
|
||||||
g_pLayoutManager->getCurrentLayout()->onEndDragWindow();
|
|
||||||
currentlyDraggedWindow = nullptr;
|
|
||||||
dragButton = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -783,12 +787,17 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
|
|||||||
void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
||||||
const auto PIMEGRAB = m_sIMERelay.getIMEKeyboardGrab(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) {
|
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_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 {
|
} else {
|
||||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
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);
|
const auto PWLRKB = wlr_keyboard_from_input_device(pKeyboard->keyboard);
|
||||||
@@ -900,11 +909,7 @@ void CInputManager::unconstrainMouse() {
|
|||||||
const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
|
const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
|
||||||
|
|
||||||
if (CONSTRAINTWINDOW) {
|
if (CONSTRAINTWINDOW) {
|
||||||
if (CONSTRAINTWINDOW->m_bIsX11) {
|
g_pXWaylandManager->activateSurface(g_pXWaylandManager->getWindowSurface(CONSTRAINTWINDOW), false);
|
||||||
wlr_xwayland_surface_activate(CONSTRAINTWINDOW->m_uSurface.xwayland, false);
|
|
||||||
} else {
|
|
||||||
wlr_xdg_toplevel_set_activated(CONSTRAINTWINDOW->m_uSurface.xdg->toplevel, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_pointer_constraint_v1_send_deactivated(g_pCompositor->m_sSeat.mouse->currentConstraint);
|
wlr_pointer_constraint_v1_send_deactivated(g_pCompositor->m_sSeat.mouse->currentConstraint);
|
||||||
@@ -945,6 +950,9 @@ uint32_t CInputManager::accumulateModsFromAllKBs() {
|
|||||||
uint32_t finalMask = 0;
|
uint32_t finalMask = 0;
|
||||||
|
|
||||||
for (auto& kb : m_lKeyboards) {
|
for (auto& kb : m_lKeyboards) {
|
||||||
|
if (kb.isVirtual)
|
||||||
|
continue;
|
||||||
|
|
||||||
finalMask |= wlr_keyboard_get_modifiers(wlr_keyboard_from_input_device(kb.keyboard));
|
finalMask |= wlr_keyboard_get_modifiers(wlr_keyboard_from_input_device(kb.keyboard));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -979,3 +987,22 @@ void CInputManager::disableAllKeyboards(bool virt) {
|
|||||||
k.active = false;
|
k.active = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
|
||||||
|
const auto PNEWDEV = &m_lTouchDevices.emplace_back();
|
||||||
|
PNEWDEV->pWlrDevice = pDevice;
|
||||||
|
|
||||||
|
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, pDevice);
|
||||||
|
|
||||||
|
Debug::log(LOG, "New touch device added at %x", PNEWDEV);
|
||||||
|
|
||||||
|
PNEWDEV->hyprListener_destroy.initCallback(&pDevice->events.destroy, [&](void* owner, void* data) {
|
||||||
|
destroyTouchDevice((STouchDevice*)data);
|
||||||
|
}, PNEWDEV, "TouchDevice");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInputManager::destroyTouchDevice(STouchDevice* pDevice) {
|
||||||
|
Debug::log(LOG, "Touch device at %x removed", pDevice);
|
||||||
|
|
||||||
|
m_lTouchDevices.remove(*pDevice);
|
||||||
|
}
|
||||||
|
@@ -12,6 +12,12 @@ enum eClickBehaviorMode {
|
|||||||
CLICKMODE_KILL
|
CLICKMODE_KILL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum eMouseBindMode {
|
||||||
|
MBIND_INVALID = -1,
|
||||||
|
MBIND_MOVE = 0,
|
||||||
|
MBIND_RESIZE
|
||||||
|
};
|
||||||
|
|
||||||
struct STouchData {
|
struct STouchData {
|
||||||
CWindow* touchFocusWindow = nullptr;
|
CWindow* touchFocusWindow = nullptr;
|
||||||
Vector2D touchSurfaceOrigin;
|
Vector2D touchSurfaceOrigin;
|
||||||
@@ -30,6 +36,8 @@ public:
|
|||||||
void newKeyboard(wlr_input_device*);
|
void newKeyboard(wlr_input_device*);
|
||||||
void newVirtualKeyboard(wlr_input_device*);
|
void newVirtualKeyboard(wlr_input_device*);
|
||||||
void newMouse(wlr_input_device*, bool virt = false);
|
void newMouse(wlr_input_device*, bool virt = false);
|
||||||
|
void newTouchDevice(wlr_input_device*);
|
||||||
|
void destroyTouchDevice(STouchDevice*);
|
||||||
void destroyKeyboard(SKeyboard*);
|
void destroyKeyboard(SKeyboard*);
|
||||||
void destroyMouse(wlr_input_device*);
|
void destroyMouse(wlr_input_device*);
|
||||||
|
|
||||||
@@ -55,11 +63,14 @@ public:
|
|||||||
void onTouchUp(wlr_touch_up_event*);
|
void onTouchUp(wlr_touch_up_event*);
|
||||||
void onTouchMove(wlr_touch_motion_event*);
|
void onTouchMove(wlr_touch_motion_event*);
|
||||||
|
|
||||||
|
void onPointerHoldBegin(wlr_pointer_hold_begin_event*);
|
||||||
|
void onPointerHoldEnd(wlr_pointer_hold_end_event*);
|
||||||
|
|
||||||
STouchData m_sTouchData;
|
STouchData m_sTouchData;
|
||||||
|
|
||||||
// for dragging floating windows
|
// for dragging floating windows
|
||||||
CWindow* currentlyDraggedWindow = nullptr;
|
CWindow* currentlyDraggedWindow = nullptr;
|
||||||
int dragButton = -1;
|
eMouseBindMode dragMode = MBIND_INVALID;
|
||||||
|
|
||||||
SDrag m_sDrag;
|
SDrag m_sDrag;
|
||||||
|
|
||||||
@@ -75,6 +86,9 @@ public:
|
|||||||
// idle inhibitors
|
// idle inhibitors
|
||||||
std::list<SIdleInhibitor> m_lIdleInhibitors;
|
std::list<SIdleInhibitor> m_lIdleInhibitors;
|
||||||
|
|
||||||
|
// Touch devices
|
||||||
|
std::list<STouchDevice> m_lTouchDevices;
|
||||||
|
|
||||||
void newTabletTool(wlr_input_device*);
|
void newTabletTool(wlr_input_device*);
|
||||||
void newTabletPad(wlr_input_device*);
|
void newTabletPad(wlr_input_device*);
|
||||||
void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false);
|
void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false);
|
||||||
@@ -105,6 +119,9 @@ private:
|
|||||||
bool m_bEmptyFocusCursorSet = false;
|
bool m_bEmptyFocusCursorSet = false;
|
||||||
Vector2D m_vLastCursorPosFloored = Vector2D();
|
Vector2D m_vLastCursorPosFloored = Vector2D();
|
||||||
|
|
||||||
|
// for some bugs in follow mouse 0
|
||||||
|
bool m_bLastFocusOnLS = false;
|
||||||
|
|
||||||
void processMouseDownNormal(wlr_pointer_button_event* e);
|
void processMouseDownNormal(wlr_pointer_button_event* e);
|
||||||
void processMouseDownKill(wlr_pointer_button_event* e);
|
void processMouseDownKill(wlr_pointer_button_event* e);
|
||||||
|
|
||||||
|
@@ -2,9 +2,7 @@
|
|||||||
#include "InputManager.hpp"
|
#include "InputManager.hpp"
|
||||||
#include "../../Compositor.hpp"
|
#include "../../Compositor.hpp"
|
||||||
|
|
||||||
CInputMethodRelay::CInputMethodRelay() {
|
CInputMethodRelay::CInputMethodRelay() { }
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) {
|
void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) {
|
||||||
if (m_pWLRIME) {
|
if (m_pWLRIME) {
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
#include "../../Compositor.hpp"
|
#include "../../Compositor.hpp"
|
||||||
|
|
||||||
void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
||||||
|
|
||||||
static auto *const PSWIPE = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe")->intValue;
|
static auto *const PSWIPE = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe")->intValue;
|
||||||
static auto *const PSWIPEFINGERS = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_fingers")->intValue;
|
static auto *const PSWIPEFINGERS = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_fingers")->intValue;
|
||||||
|
|
||||||
@@ -11,7 +10,7 @@ void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
|||||||
|
|
||||||
int onMonitor = 0;
|
int onMonitor = 0;
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||||
if (w->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID) {
|
if (w->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID && w->m_iID != SPECIAL_WORKSPACE_ID) {
|
||||||
onMonitor++;
|
onMonitor++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,10 +27,15 @@ void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
|||||||
m_sActiveSwipe.pMonitor = g_pCompositor->m_pLastMonitor;
|
m_sActiveSwipe.pMonitor = g_pCompositor->m_pLastMonitor;
|
||||||
m_sActiveSwipe.avgSpeed = 0;
|
m_sActiveSwipe.avgSpeed = 0;
|
||||||
m_sActiveSwipe.speedPoints = 0;
|
m_sActiveSwipe.speedPoints = 0;
|
||||||
|
|
||||||
|
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||||
|
for (auto& ls : g_pCompositor->m_pLastMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||||
|
ls->alpha = 255.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||||
|
|
||||||
if (!m_sActiveSwipe.pWorkspaceBegin)
|
if (!m_sActiveSwipe.pWorkspaceBegin)
|
||||||
return; // no valid swipe
|
return; // no valid swipe
|
||||||
|
|
||||||
@@ -49,6 +53,8 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
|||||||
|
|
||||||
const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.vec();
|
const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.vec();
|
||||||
|
|
||||||
|
CWorkspace* pSwitchedTo = nullptr;
|
||||||
|
|
||||||
if ((abs(m_sActiveSwipe.delta) < *PSWIPEDIST * *PSWIPEPERC && (*PSWIPEFORC == 0 || (*PSWIPEFORC != 0 && m_sActiveSwipe.avgSpeed < *PSWIPEFORC))) || abs(m_sActiveSwipe.delta) < 2) {
|
if ((abs(m_sActiveSwipe.delta) < *PSWIPEDIST * *PSWIPEPERC && (*PSWIPEFORC == 0 || (*PSWIPEFORC != 0 && m_sActiveSwipe.avgSpeed < *PSWIPEFORC))) || abs(m_sActiveSwipe.delta) < 2) {
|
||||||
// revert
|
// revert
|
||||||
if (abs(m_sActiveSwipe.delta) < 2) {
|
if (abs(m_sActiveSwipe.delta) < 2) {
|
||||||
@@ -66,6 +72,8 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
|||||||
|
|
||||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D();
|
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pSwitchedTo = m_sActiveSwipe.pWorkspaceBegin;
|
||||||
} else if (m_sActiveSwipe.delta < 0) {
|
} else if (m_sActiveSwipe.delta < 0) {
|
||||||
// switch to left
|
// switch to left
|
||||||
const auto RENDEROFFSET = PWORKSPACEL->m_vRenderOffset.vec();
|
const auto RENDEROFFSET = PWORKSPACEL->m_vRenderOffset.vec();
|
||||||
@@ -82,6 +90,8 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
|||||||
g_pInputManager->unconstrainMouse();
|
g_pInputManager->unconstrainMouse();
|
||||||
|
|
||||||
Debug::log(LOG, "Ended swipe to the left");
|
Debug::log(LOG, "Ended swipe to the left");
|
||||||
|
|
||||||
|
pSwitchedTo = PWORKSPACEL;
|
||||||
} else {
|
} else {
|
||||||
// switch to right
|
// switch to right
|
||||||
const auto RENDEROFFSET = PWORKSPACER->m_vRenderOffset.vec();
|
const auto RENDEROFFSET = PWORKSPACER->m_vRenderOffset.vec();
|
||||||
@@ -98,6 +108,8 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
|||||||
g_pInputManager->unconstrainMouse();
|
g_pInputManager->unconstrainMouse();
|
||||||
|
|
||||||
Debug::log(LOG, "Ended swipe to the right");
|
Debug::log(LOG, "Ended swipe to the right");
|
||||||
|
|
||||||
|
pSwitchedTo = PWORKSPACER;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||||
@@ -109,6 +121,11 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
|||||||
m_sActiveSwipe.pWorkspaceBegin = nullptr;
|
m_sActiveSwipe.pWorkspaceBegin = nullptr;
|
||||||
|
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
|
|
||||||
|
// apply alpha
|
||||||
|
for (auto& ls : g_pCompositor->m_pLastMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||||
|
ls->alpha = pSwitchedTo->m_bHasFullscreenWindow ? 0.f : 255.f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||||
@@ -127,8 +144,10 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
|||||||
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
|
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
|
||||||
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
|
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
|
||||||
|
|
||||||
if (workspaceIDLeft == INT_MAX || workspaceIDRight == INT_MAX || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID)
|
if (workspaceIDLeft == INT_MAX || workspaceIDRight == INT_MAX || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID) {
|
||||||
|
m_sActiveSwipe.pWorkspaceBegin = nullptr; // invalidate the swipe
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = true;
|
m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = true;
|
||||||
|
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
#include "../../Compositor.hpp"
|
#include "../../Compositor.hpp"
|
||||||
|
|
||||||
void CInputManager::onTouchDown(wlr_touch_down_event* e) {
|
void CInputManager::onTouchDown(wlr_touch_down_event* e) {
|
||||||
|
|
||||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, g_pCompositor->m_pLastMonitor->vecPosition.x + e->x * g_pCompositor->m_pLastMonitor->vecSize.x, g_pCompositor->m_pLastMonitor->vecPosition.y + e->y * g_pCompositor->m_pLastMonitor->vecSize.y);
|
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, g_pCompositor->m_pLastMonitor->vecPosition.x + e->x * g_pCompositor->m_pLastMonitor->vecSize.x, g_pCompositor->m_pLastMonitor->vecPosition.y + e->y * g_pCompositor->m_pLastMonitor->vecSize.y);
|
||||||
|
|
||||||
refocus();
|
refocus();
|
||||||
@@ -26,7 +25,6 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CInputManager::onTouchUp(wlr_touch_up_event* e){
|
void CInputManager::onTouchUp(wlr_touch_up_event* e){
|
||||||
|
|
||||||
if (m_sTouchData.touchFocusWindow) {
|
if (m_sTouchData.touchFocusWindow) {
|
||||||
wlr_seat_touch_notify_up(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id);
|
wlr_seat_touch_notify_up(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id);
|
||||||
}
|
}
|
||||||
@@ -43,3 +41,11 @@ void CInputManager::onTouchMove(wlr_touch_motion_event* e){
|
|||||||
wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id, local.x, local.y);
|
wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id, local.x, local.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CInputManager::onPointerHoldBegin(wlr_pointer_hold_begin_event* e) {
|
||||||
|
wlr_pointer_gestures_v1_send_hold_begin(g_pCompositor->m_sWLRPointerGestures, g_pCompositor->m_sSeat.seat, e->time_msec, e->fingers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInputManager::onPointerHoldEnd(wlr_pointer_hold_end_event* e) {
|
||||||
|
wlr_pointer_gestures_v1_send_hold_end(g_pCompositor->m_sWLRPointerGestures, g_pCompositor->m_sSeat.seat, e->time_msec, e->cancelled);
|
||||||
|
}
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
bool CFramebuffer::alloc(int w, int h) {
|
bool CFramebuffer::alloc(int w, int h) {
|
||||||
bool firstAlloc = false;
|
bool firstAlloc = false;
|
||||||
|
RASSERT((w > 1 && h > 1), "cannot alloc a FB with negative / zero size! (attempted %ix%i)", w, h);
|
||||||
|
|
||||||
if (m_iFb == (uint32_t)-1) {
|
if (m_iFb == (uint32_t)-1) {
|
||||||
firstAlloc = true;
|
firstAlloc = true;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#include "OpenGL.hpp"
|
#include "OpenGL.hpp"
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../helpers/MiscFunctions.hpp"
|
#include "../helpers/MiscFunctions.hpp"
|
||||||
|
#include "Shaders.hpp"
|
||||||
|
|
||||||
CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||||
RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL)), "Couldn't unset current EGL!");
|
RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL)), "Couldn't unset current EGL!");
|
||||||
@@ -102,6 +103,7 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, pixman_region32_t* pDamage, bool
|
|||||||
m_RenderData.pCurrentMonData->primaryFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
m_RenderData.pCurrentMonData->primaryFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||||
m_RenderData.pCurrentMonData->mirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
m_RenderData.pCurrentMonData->mirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||||
m_RenderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
m_RenderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||||
|
m_RenderData.pCurrentMonData->monitorMirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||||
|
|
||||||
createBGTextureForMonitor(pMonitor);
|
createBGTextureForMonitor(pMonitor);
|
||||||
}
|
}
|
||||||
@@ -120,11 +122,14 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, pixman_region32_t* pDamage, bool
|
|||||||
void CHyprOpenGLImpl::end() {
|
void CHyprOpenGLImpl::end() {
|
||||||
// end the render, copy the data to the WLR framebuffer
|
// end the render, copy the data to the WLR framebuffer
|
||||||
if (!m_bFakeFrame) {
|
if (!m_bFakeFrame) {
|
||||||
|
pixman_region32_copy(m_RenderData.pDamage, &m_rOriginalDamageRegion);
|
||||||
|
|
||||||
|
if (!m_RenderData.pMonitor->mirrors.empty())
|
||||||
|
g_pHyprOpenGL->saveBufferForMirror(); // save with original damage region
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iWLROutputFb);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_iWLROutputFb);
|
||||||
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||||
|
|
||||||
pixman_region32_copy(m_RenderData.pDamage, &m_rOriginalDamageRegion);
|
|
||||||
|
|
||||||
clear(CColor(11, 11, 11, 255));
|
clear(CColor(11, 11, 11, 255));
|
||||||
|
|
||||||
m_bEndFrame = true;
|
m_bEndFrame = true;
|
||||||
@@ -165,6 +170,8 @@ void CHyprOpenGLImpl::initShaders() {
|
|||||||
m_RenderData.pCurrentMonData->m_shRGBA.fullSize = glGetUniformLocation(prog, "fullSize");
|
m_RenderData.pCurrentMonData->m_shRGBA.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||||
m_RenderData.pCurrentMonData->m_shRGBA.radius = glGetUniformLocation(prog, "radius");
|
m_RenderData.pCurrentMonData->m_shRGBA.radius = glGetUniformLocation(prog, "radius");
|
||||||
m_RenderData.pCurrentMonData->m_shRGBA.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
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);
|
prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBX);
|
||||||
m_RenderData.pCurrentMonData->m_shRGBX.program = prog;
|
m_RenderData.pCurrentMonData->m_shRGBX.program = prog;
|
||||||
@@ -179,6 +186,8 @@ void CHyprOpenGLImpl::initShaders() {
|
|||||||
m_RenderData.pCurrentMonData->m_shRGBX.fullSize = glGetUniformLocation(prog, "fullSize");
|
m_RenderData.pCurrentMonData->m_shRGBX.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||||
m_RenderData.pCurrentMonData->m_shRGBX.radius = glGetUniformLocation(prog, "radius");
|
m_RenderData.pCurrentMonData->m_shRGBX.radius = glGetUniformLocation(prog, "radius");
|
||||||
m_RenderData.pCurrentMonData->m_shRGBX.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
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);
|
prog = createProgram(TEXVERTSRC, TEXFRAGSRCEXT);
|
||||||
m_RenderData.pCurrentMonData->m_shEXT.program = prog;
|
m_RenderData.pCurrentMonData->m_shEXT.program = prog;
|
||||||
@@ -193,6 +202,8 @@ void CHyprOpenGLImpl::initShaders() {
|
|||||||
m_RenderData.pCurrentMonData->m_shEXT.fullSize = glGetUniformLocation(prog, "fullSize");
|
m_RenderData.pCurrentMonData->m_shEXT.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||||
m_RenderData.pCurrentMonData->m_shEXT.radius = glGetUniformLocation(prog, "radius");
|
m_RenderData.pCurrentMonData->m_shEXT.radius = glGetUniformLocation(prog, "radius");
|
||||||
m_RenderData.pCurrentMonData->m_shEXT.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
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);
|
prog = createProgram(TEXVERTSRC, FRAGBLUR1);
|
||||||
m_RenderData.pCurrentMonData->m_shBLUR1.program = prog;
|
m_RenderData.pCurrentMonData->m_shBLUR1.program = prog;
|
||||||
@@ -262,7 +273,7 @@ void CHyprOpenGLImpl::clear(const CColor& color) {
|
|||||||
scissor((wlr_box*)nullptr);
|
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()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to scissor without begin()!");
|
||||||
|
|
||||||
if (!pBox) {
|
if (!pBox) {
|
||||||
@@ -272,17 +283,19 @@ void CHyprOpenGLImpl::scissor(const wlr_box* pBox) {
|
|||||||
|
|
||||||
wlr_box newBox = *pBox;
|
wlr_box newBox = *pBox;
|
||||||
|
|
||||||
|
if (transform) {
|
||||||
int w, h;
|
int w, h;
|
||||||
wlr_output_transformed_resolution(m_RenderData.pMonitor->output, &w, &h);
|
wlr_output_transformed_resolution(m_RenderData.pMonitor->output, &w, &h);
|
||||||
|
|
||||||
const auto TR = wlr_output_transform_invert(m_RenderData.pMonitor->transform);
|
const auto TR = wlr_output_transform_invert(m_RenderData.pMonitor->transform);
|
||||||
wlr_box_transform(&newBox, &newBox, TR, w, h);
|
wlr_box_transform(&newBox, &newBox, TR, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
glScissor(newBox.x, newBox.y, newBox.width, newBox.height);
|
glScissor(newBox.x, newBox.y, newBox.width, newBox.height);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
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()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to scissor without begin()!");
|
||||||
|
|
||||||
if (!pBox) {
|
if (!pBox) {
|
||||||
@@ -292,12 +305,12 @@ void CHyprOpenGLImpl::scissor(const pixman_box32* pBox) {
|
|||||||
|
|
||||||
wlr_box newBox = {pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1};
|
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};
|
wlr_box box = {x,y,w,h};
|
||||||
scissor(&box);
|
scissor(&box, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
|
void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
|
||||||
@@ -367,15 +380,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) {
|
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()!");
|
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);
|
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(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||||
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||||
|
|
||||||
|
static auto *const PDIMINACTIVE = &g_pConfigManager->getConfigValuePtr("decoration:dim_inactive")->intValue;
|
||||||
|
|
||||||
// get transform
|
// get transform
|
||||||
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
@@ -433,7 +448,13 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
|||||||
glUniform1f(shader->radius, round);
|
glUniform1f(shader->radius, round);
|
||||||
glUniform1i(shader->primitiveMultisample, (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !noAA));
|
glUniform1i(shader->primitiveMultisample, (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !noAA));
|
||||||
|
|
||||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
const float verts[] = {
|
const float verts[] = {
|
||||||
m_RenderData.primarySurfaceUVBottomRight.x, m_RenderData.primarySurfaceUVTopLeft.y, // top right
|
m_RenderData.primarySurfaceUVBottomRight.x, m_RenderData.primarySurfaceUVTopLeft.y, // top right
|
||||||
@@ -442,6 +463,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
|||||||
m_RenderData.primarySurfaceUVTopLeft.x, m_RenderData.primarySurfaceUVBottomRight.y, // bottom left
|
m_RenderData.primarySurfaceUVTopLeft.x, m_RenderData.primarySurfaceUVBottomRight.y, // bottom left
|
||||||
};
|
};
|
||||||
|
|
||||||
|
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
|
|
||||||
if (allowCustomUV && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
|
if (allowCustomUV && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
|
||||||
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, verts);
|
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, verts);
|
||||||
} else {
|
} else {
|
||||||
@@ -475,9 +498,9 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
|
||||||
// get transforms for the full monitor
|
// 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];
|
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);
|
wlr_matrix_project_box(matrix, &MONITORBOX, TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
||||||
|
|
||||||
float glMatrix[9];
|
float glMatrix[9];
|
||||||
@@ -493,6 +516,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
pixman_region32_init(&damage);
|
pixman_region32_init(&damage);
|
||||||
pixman_region32_copy(&damage, originalDamage);
|
pixman_region32_copy(&damage, originalDamage);
|
||||||
|
wlr_region_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);
|
wlr_region_expand(&damage, &damage, pow(2, *PBLURPASSES) * *PBLURSIZE);
|
||||||
|
|
||||||
// helper
|
// helper
|
||||||
@@ -534,7 +558,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||||||
if (pixman_region32_not_empty(pDamage)) {
|
if (pixman_region32_not_empty(pDamage)) {
|
||||||
PIXMAN_DAMAGE_FOREACH(pDamage) {
|
PIXMAN_DAMAGE_FOREACH(pDamage) {
|
||||||
const auto RECT = RECTSARR[i];
|
const auto RECT = RECTSARR[i];
|
||||||
scissor(&RECT);
|
scissor(&RECT, false /* this region is already transformed */);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
@@ -621,7 +645,9 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() {
|
|||||||
|
|
||||||
clear(CColor(0,0,0,0));
|
clear(CColor(0,0,0,0));
|
||||||
|
|
||||||
|
m_bEndFrame = true; // fix transformed
|
||||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 255, &fakeDamage, 0, false, true, false);
|
renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 255, &fakeDamage, 0, false, true, false);
|
||||||
|
m_bEndFrame = false;
|
||||||
|
|
||||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
m_RenderData.pCurrentMonData->primaryFB.bind();
|
||||||
|
|
||||||
@@ -719,7 +745,9 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||||||
if (pixman_region32_not_empty(&damage)) {
|
if (pixman_region32_not_empty(&damage)) {
|
||||||
// render our great blurred FB
|
// render our great blurred FB
|
||||||
static auto *const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur_ignore_opacity")->intValue;
|
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);
|
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 255.f : a, &damage, 0, false, false, false);
|
||||||
|
m_bEndFrame = false;
|
||||||
|
|
||||||
// render the window, but clear stencil
|
// render the window, but clear stencil
|
||||||
glClearStencil(0);
|
glClearStencil(0);
|
||||||
@@ -727,7 +755,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||||||
|
|
||||||
// draw window
|
// draw window
|
||||||
glDisable(GL_STENCIL_TEST);
|
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);
|
glStencilMask(-1);
|
||||||
@@ -753,27 +781,29 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
|
|||||||
if (*PBORDERSIZE < 1)
|
if (*PBORDERSIZE < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
int scaledBorderSize = *PBORDERSIZE * m_RenderData.pMonitor->scale;
|
||||||
|
|
||||||
if (round < 1) {
|
if (round < 1) {
|
||||||
// zero rounding, just lines
|
// zero rounding, just lines
|
||||||
wlr_box borderbox = {box->x - *PBORDERSIZE, box->y - *PBORDERSIZE, *PBORDERSIZE, box->height + 2 * *PBORDERSIZE};
|
wlr_box borderbox = {box->x - scaledBorderSize, box->y - scaledBorderSize, scaledBorderSize, box->height + 2 * scaledBorderSize};
|
||||||
renderRect(&borderbox, col, 0); // left
|
renderRect(&borderbox, col, 0); // left
|
||||||
borderbox = {box->x, box->y - (int)*PBORDERSIZE, box->width + (int)*PBORDERSIZE, (int)*PBORDERSIZE};
|
borderbox = {box->x, box->y - (int)scaledBorderSize, box->width + (int)scaledBorderSize, (int)scaledBorderSize};
|
||||||
renderRect(&borderbox, col, 0); // top
|
renderRect(&borderbox, col, 0); // top
|
||||||
borderbox = {box->x + box->width, box->y, (int)*PBORDERSIZE, box->height + (int)*PBORDERSIZE};
|
borderbox = {box->x + box->width, box->y, (int)scaledBorderSize, box->height + (int)scaledBorderSize};
|
||||||
renderRect(&borderbox, col, 0); // right
|
renderRect(&borderbox, col, 0); // right
|
||||||
borderbox = {box->x, box->y + box->height, box->width, (int)*PBORDERSIZE};
|
borderbox = {box->x, box->y + box->height, box->width, (int)scaledBorderSize};
|
||||||
renderRect(&borderbox, col, 0); // bottom
|
renderRect(&borderbox, col, 0); // bottom
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust box
|
// adjust box
|
||||||
box->x -= *PBORDERSIZE;
|
box->x -= scaledBorderSize;
|
||||||
box->y -= *PBORDERSIZE;
|
box->y -= scaledBorderSize;
|
||||||
box->width += 2 * *PBORDERSIZE;
|
box->width += 2 * scaledBorderSize;
|
||||||
box->height += 2 * *PBORDERSIZE;
|
box->height += 2 * scaledBorderSize;
|
||||||
|
|
||||||
round += *PBORDERSIZE;
|
round += scaledBorderSize;
|
||||||
|
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_matrix_project_box(matrix, box, wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
wlr_matrix_project_box(matrix, box, wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
||||||
@@ -800,7 +830,7 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
|
|||||||
glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||||
glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radius, round);
|
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radius, round);
|
||||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.thick, *PBORDERSIZE);
|
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.thick, scaledBorderSize);
|
||||||
glUniform1i(m_RenderData.pCurrentMonData->m_shBORDER1.primitiveMultisample, *PMULTISAMPLE);
|
glUniform1i(m_RenderData.pCurrentMonData->m_shBORDER1.primitiveMultisample, *PMULTISAMPLE);
|
||||||
|
|
||||||
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
@@ -850,28 +880,22 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
|||||||
const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
|
const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
|
||||||
g_pConfigManager->setInt("decoration:blur", 0);
|
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
|
// 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];
|
const auto PFRAMEBUFFER = &m_mWindowFramebuffers[pWindow];
|
||||||
|
|
||||||
glViewport(0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y);
|
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->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||||
|
|
||||||
PFRAMEBUFFER->bind();
|
PFRAMEBUFFER->bind();
|
||||||
|
|
||||||
clear(CColor(0, 0, 0, 0)); // JIC
|
clear(CColor(0, 0, 0, 0)); // JIC
|
||||||
|
|
||||||
wlr_box fullMonBox = {0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
|
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL);
|
||||||
|
|
||||||
renderTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex, &fullMonBox, 255.f, 0);
|
g_pConfigManager->setInt("decoration:blur", BLURVAL);
|
||||||
m_bEndFrame = false;
|
|
||||||
|
|
||||||
// restore original fb
|
// restore original fb
|
||||||
#ifndef GLES2
|
#ifndef GLES2
|
||||||
@@ -954,8 +978,6 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
|
|||||||
// the originalClosedPos is relative to the monitor's pos
|
// 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)));
|
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.width = PMONITOR->vecTransformedSize.x * scaleXY.x;
|
||||||
windowBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y;
|
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);
|
windowBox.x = ((PWINDOW->m_vRealPosition.vec().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x);
|
||||||
@@ -964,8 +986,12 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
|
|||||||
pixman_region32_t fakeDamage;
|
pixman_region32_t fakeDamage;
|
||||||
pixman_region32_init_rect(&fakeDamage, 0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y);
|
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);
|
renderTextureInternalWithDamage(it->second.m_cTex, &windowBox, PWINDOW->m_fAlpha.fl(), &fakeDamage, 0);
|
||||||
|
|
||||||
|
m_bEndFrame = false;
|
||||||
|
|
||||||
pixman_region32_fini(&fakeDamage);
|
pixman_region32_fini(&fakeDamage);
|
||||||
|
|
||||||
static auto *const PDAMAGEMON = &g_pConfigManager->getConfigValuePtr("misc:damage_entire_on_snapshot")->intValue;
|
static auto *const PDAMAGEMON = &g_pConfigManager->getConfigValuePtr("misc:damage_entire_on_snapshot")->intValue;
|
||||||
@@ -1069,18 +1095,40 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
|
|||||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const CAIROSURFACE) {
|
void CHyprOpenGLImpl::saveBufferForMirror() {
|
||||||
|
m_RenderData.pCurrentMonData->monitorMirrorFB.bind();
|
||||||
|
|
||||||
|
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
||||||
|
|
||||||
|
renderTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex, &monbox, 255.f, 0, false, false);
|
||||||
|
|
||||||
|
m_RenderData.pCurrentMonData->primaryFB.bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprOpenGLImpl::renderMirrored() {
|
||||||
|
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
||||||
|
|
||||||
|
const auto PFB = &m_mMonitorRenderResources[m_RenderData.pMonitor->pMirrorOf].monitorMirrorFB;
|
||||||
|
|
||||||
|
if (PFB->m_cTex.m_iTexID <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
renderTexture(PFB->m_cTex, &monbox, 255.f, 0, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const CAIROSURFACE, double offsetY) {
|
||||||
cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
||||||
|
|
||||||
const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76);
|
const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76);
|
||||||
cairo_set_font_size(CAIRO, FONTSIZE);
|
cairo_set_font_size(CAIRO, FONTSIZE);
|
||||||
|
|
||||||
cairo_set_source_rgba(CAIRO, 1.f, 1.f, 1.f, 0.32f);
|
cairo_set_source_rgba(CAIRO, 1.0, 1.0, 1.0, 0.32);
|
||||||
|
|
||||||
cairo_text_extents_t textExtents;
|
cairo_text_extents_t textExtents;
|
||||||
cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &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 - textExtents.width) / 2.0, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height + offsetY);
|
||||||
|
|
||||||
cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str());
|
cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str());
|
||||||
|
|
||||||
cairo_surface_flush(CAIROSURFACE);
|
cairo_surface_flush(CAIROSURFACE);
|
||||||
@@ -1122,13 +1170,37 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
|
|||||||
|
|
||||||
PTEX->m_vSize = textureSize;
|
PTEX->m_vSize = textureSize;
|
||||||
|
|
||||||
|
// calc the target box
|
||||||
|
const double MONRATIO = m_RenderData.pMonitor->vecTransformedSize.x / m_RenderData.pMonitor->vecTransformedSize.y;
|
||||||
|
const double WPRATIO = 1.77;
|
||||||
|
|
||||||
|
Vector2D origin;
|
||||||
|
double scale;
|
||||||
|
|
||||||
|
if (MONRATIO > WPRATIO) {
|
||||||
|
scale = m_RenderData.pMonitor->vecTransformedSize.x / PTEX->m_vSize.x;
|
||||||
|
|
||||||
|
origin.y = (m_RenderData.pMonitor->vecTransformedSize.y - PTEX->m_vSize.y * scale) / 2.0;
|
||||||
|
} else {
|
||||||
|
scale = m_RenderData.pMonitor->vecTransformedSize.y / PTEX->m_vSize.y;
|
||||||
|
|
||||||
|
origin.x = (m_RenderData.pMonitor->vecTransformedSize.x - PTEX->m_vSize.x * scale) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_box box = {origin.x, origin.y, PTEX->m_vSize.x * scale, PTEX->m_vSize.y * scale};
|
||||||
|
|
||||||
|
m_mMonitorRenderResources[pMonitor].backgroundTexBox = box;
|
||||||
|
|
||||||
// create a new one with cairo
|
// create a new one with cairo
|
||||||
const auto CAIROSURFACE = cairo_image_surface_create_from_png(texPath.c_str());
|
const auto CAIROSURFACE = cairo_image_surface_create_from_png(texPath.c_str());
|
||||||
|
|
||||||
const auto CAIRO = cairo_create(CAIROSURFACE);
|
const auto CAIRO = cairo_create(CAIROSURFACE);
|
||||||
|
|
||||||
|
// scale it to fit the current monitor
|
||||||
|
cairo_scale(CAIRO, textureSize.x / pMonitor->vecTransformedSize.x, textureSize.y / pMonitor->vecTransformedSize.y);
|
||||||
|
|
||||||
|
// render splash on wallpaper
|
||||||
if (!*PNOSPLASH)
|
if (!*PNOSPLASH)
|
||||||
renderSplash(CAIRO, CAIROSURFACE);
|
renderSplash(CAIRO, CAIROSURFACE, origin.y * WPRATIO / MONRATIO);
|
||||||
|
|
||||||
// copy the data to an OpenGL texture we have
|
// copy the data to an OpenGL texture we have
|
||||||
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
||||||
@@ -1144,28 +1216,6 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
|
|||||||
cairo_surface_destroy(CAIROSURFACE);
|
cairo_surface_destroy(CAIROSURFACE);
|
||||||
cairo_destroy(CAIRO);
|
cairo_destroy(CAIRO);
|
||||||
|
|
||||||
// calc the target box
|
|
||||||
|
|
||||||
const float MONRATIO = m_RenderData.pMonitor->vecTransformedSize.x / m_RenderData.pMonitor->vecTransformedSize.y;
|
|
||||||
const float WPRATIO = 1.77f;
|
|
||||||
|
|
||||||
Vector2D origin;
|
|
||||||
float scale;
|
|
||||||
|
|
||||||
if (MONRATIO > WPRATIO) {
|
|
||||||
scale = m_RenderData.pMonitor->vecTransformedSize.x / PTEX->m_vSize.x;
|
|
||||||
|
|
||||||
origin.y = -(PTEX->m_vSize.y * scale - m_RenderData.pMonitor->vecTransformedSize.y) / 2.f / scale;
|
|
||||||
} else {
|
|
||||||
scale = m_RenderData.pMonitor->vecTransformedSize.y / PTEX->m_vSize.y;
|
|
||||||
|
|
||||||
origin.x = -(PTEX->m_vSize.x * scale - m_RenderData.pMonitor->vecTransformedSize.x) / 2.f / scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_box box = {origin.x * scale, origin.y * scale, PTEX->m_vSize.x * scale, PTEX->m_vSize.y * scale};
|
|
||||||
|
|
||||||
m_mMonitorRenderResources[pMonitor].backgroundTexBox = box;
|
|
||||||
|
|
||||||
Debug::log(LOG, "Background created for monitor %s", pMonitor->szName.c_str());
|
Debug::log(LOG, "Background created for monitor %s", pMonitor->szName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include <cairo/cairo.h>
|
#include <cairo/cairo.h>
|
||||||
|
|
||||||
#include "Shaders.hpp"
|
|
||||||
#include "Shader.hpp"
|
#include "Shader.hpp"
|
||||||
#include "Texture.hpp"
|
#include "Texture.hpp"
|
||||||
#include "Framebuffer.hpp"
|
#include "Framebuffer.hpp"
|
||||||
@@ -33,8 +32,10 @@ inline const float fanVertsFull[] = {
|
|||||||
|
|
||||||
struct SMonitorRenderData {
|
struct SMonitorRenderData {
|
||||||
CFramebuffer primaryFB;
|
CFramebuffer primaryFB;
|
||||||
CFramebuffer mirrorFB;
|
CFramebuffer mirrorFB; // these are used for some effects,
|
||||||
CFramebuffer mirrorSwapFB;
|
CFramebuffer mirrorSwapFB; // etc
|
||||||
|
|
||||||
|
CFramebuffer monitorMirrorFB; // used for mirroring outputs
|
||||||
|
|
||||||
CTexture stencilTex;
|
CTexture stencilTex;
|
||||||
|
|
||||||
@@ -91,9 +92,9 @@ public:
|
|||||||
|
|
||||||
void clear(const CColor&);
|
void clear(const CColor&);
|
||||||
void clearWithTex();
|
void clearWithTex();
|
||||||
void scissor(const wlr_box*);
|
void scissor(const wlr_box*, bool transform = true);
|
||||||
void scissor(const pixman_box32*);
|
void scissor(const pixman_box32*, bool transform = true);
|
||||||
void scissor(const int x, const int y, const int w, const int h);
|
void scissor(const int x, const int y, const int w, const int h, bool transform = true);
|
||||||
|
|
||||||
void destroyMonitorResources(CMonitor*);
|
void destroyMonitorResources(CMonitor*);
|
||||||
|
|
||||||
@@ -102,6 +103,9 @@ public:
|
|||||||
void preWindowPass();
|
void preWindowPass();
|
||||||
void preRender(CMonitor*);
|
void preRender(CMonitor*);
|
||||||
|
|
||||||
|
void saveBufferForMirror();
|
||||||
|
void renderMirrored();
|
||||||
|
|
||||||
SCurrentRenderData m_RenderData;
|
SCurrentRenderData m_RenderData;
|
||||||
|
|
||||||
GLint m_iCurrentOutputFb = 0;
|
GLint m_iCurrentOutputFb = 0;
|
||||||
@@ -134,9 +138,8 @@ private:
|
|||||||
// returns the out FB, can be either Mirror or MirrorSwap
|
// returns the out FB, can be either Mirror or MirrorSwap
|
||||||
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
||||||
|
|
||||||
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool 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, double);
|
||||||
void renderSplash(cairo_t *const, cairo_surface_t *const);
|
|
||||||
|
|
||||||
void preBlurForCurrentMonitor();
|
void preBlurForCurrentMonitor();
|
||||||
};
|
};
|
||||||
|
@@ -15,7 +15,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
|||||||
if (RDATA->surface && surface == RDATA->surface)
|
if (RDATA->surface && surface == RDATA->surface)
|
||||||
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h};
|
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h};
|
||||||
else // here we clamp to 2, these might be some tiny specks
|
else // here we clamp to 2, these might be some tiny specks
|
||||||
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::clamp(surface->current.width, 2, 1337420), std::clamp(surface->current.height, 2, 1337420)};
|
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::max(surface->current.width, 2), std::max(surface->current.height, 2)};
|
||||||
|
|
||||||
if (RDATA->squishOversized) {
|
if (RDATA->squishOversized) {
|
||||||
if (x + windowBox.width > RDATA->w)
|
if (x + windowBox.width > RDATA->w)
|
||||||
@@ -65,11 +65,14 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) {
|
|||||||
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, &geometry))
|
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, &geometry))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (pWindow->m_bPinned)
|
||||||
|
return true;
|
||||||
|
|
||||||
// now check if it has the same workspace
|
// now check if it has the same workspace
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
if (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID) {
|
if (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID) {
|
||||||
if (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated()) {
|
if (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated() || PWORKSPACE->m_bForceRendering) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (!(!PWORKSPACE->m_bHasFullscreenWindow || pWindow->m_bIsFullscreen || (pWindow->m_bIsFloating && pWindow->m_bCreatedOverFullscreen)))
|
if (!(!PWORKSPACE->m_bHasFullscreenWindow || pWindow->m_bIsFullscreen || (pWindow->m_bIsFloating && pWindow->m_bCreatedOverFullscreen)))
|
||||||
@@ -99,6 +102,9 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) {
|
|||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (pWindow->m_bPinned || PWORKSPACE->m_bForceRendering)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -116,11 +122,39 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) {
|
|||||||
void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time) {
|
void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time) {
|
||||||
CWindow* pWorkspaceWindow = nullptr;
|
CWindow* pWorkspaceWindow = nullptr;
|
||||||
|
|
||||||
|
// loop over the tiled windows that are fading out
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
if (w->m_iWorkspaceID != pMonitor->activeWorkspace)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (w->m_fAlpha.fl() == 0.f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (w->m_bIsFullscreen || w->m_bIsFloating)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// and floating ones too
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
if (w->m_iWorkspaceID != pMonitor->activeWorkspace)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (w->m_fAlpha.fl() == 0.f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (w->m_bIsFullscreen || !w->m_bIsFloating)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID);
|
||||||
|
|
||||||
if (w->m_iWorkspaceID != pWorkspace->m_iID || !w->m_bIsFullscreen){
|
if (w->m_iWorkspaceID != pWorkspace->m_iID || !w->m_bIsFullscreen){
|
||||||
if (!(PWORKSPACE && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
if (!(PWORKSPACE && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated() || PWORKSPACE->m_bForceRendering)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (w->m_iMonitorID != pMonitor->ID)
|
if (w->m_iMonitorID != pMonitor->ID)
|
||||||
@@ -135,9 +169,9 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWor
|
|||||||
pWorkspaceWindow = w.get();
|
pWorkspaceWindow = w.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// then render windows over fullscreen
|
// then render windows over fullscreen.
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || !w->m_bCreatedOverFullscreen || !w->m_bIsMapped)
|
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || !w->m_bIsMapped)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
||||||
@@ -159,12 +193,11 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// and the overlay layers
|
// and the overlay layers
|
||||||
if (pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL) {
|
|
||||||
// on non-full we draw the bar and shit
|
|
||||||
for (auto& ls : pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
for (auto& ls : pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||||
|
if (ls->alpha.fl() != 0.f)
|
||||||
renderLayer(ls.get(), pMonitor, time);
|
renderLayer(ls.get(), pMonitor, time);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& ls : pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) {
|
for (auto& ls : pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) {
|
||||||
renderLayer(ls.get(), pMonitor, time);
|
renderLayer(ls.get(), pMonitor, time);
|
||||||
@@ -188,15 +221,15 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
const auto REALPOS = pWindow->m_vRealPosition.vec() + PWORKSPACE->m_vRenderOffset.vec();
|
const auto REALPOS = pWindow->m_vRealPosition.vec() + (pWindow->m_bPinned ? Vector2D{} : PWORKSPACE->m_vRenderOffset.vec());
|
||||||
static const auto PNOFLOATINGBORDERS = &g_pConfigManager->getConfigValuePtr("general:no_border_on_floating")->intValue;
|
static const auto PNOFLOATINGBORDERS = &g_pConfigManager->getConfigValuePtr("general:no_border_on_floating")->intValue;
|
||||||
|
|
||||||
SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y};
|
SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y};
|
||||||
renderdata.surface = g_pXWaylandManager->getWindowSurface(pWindow);
|
renderdata.surface = g_pXWaylandManager->getWindowSurface(pWindow);
|
||||||
renderdata.w = std::clamp(pWindow->m_vRealSize.vec().x, (double)5, (double)1337420); // clamp the size to min 5,
|
renderdata.w = std::max(pWindow->m_vRealSize.vec().x, 5.0); // clamp the size to min 5,
|
||||||
renderdata.h = std::clamp(pWindow->m_vRealSize.vec().y, (double)5, (double)1337420); // otherwise we'll have issues later with invalid boxes
|
renderdata.h = std::max(pWindow->m_vRealSize.vec().y, 5.0); // otherwise we'll have issues later with invalid boxes
|
||||||
renderdata.dontRound = (pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) || (!pWindow->m_sSpecialRenderData.rounding);
|
renderdata.dontRound = (pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) || (!pWindow->m_sSpecialRenderData.rounding);
|
||||||
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f);
|
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (pWindow->m_bPinned ? 1.f : (PWORKSPACE->m_fAlpha.fl() / 255.f));
|
||||||
renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl();
|
renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl();
|
||||||
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
|
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||||
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
|
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
|
||||||
@@ -459,8 +492,8 @@ void CHyprRenderer::calculateUVForWindowSurface(CWindow* pWindow, wlr_surface* p
|
|||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(0, 0);
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(0, 0);
|
||||||
|
|
||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(
|
||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x * ((double)pWindow->m_vRealSize.vec().x / ((double)geom.width / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x)),
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x * (pWindow->m_vRealSize.vec().x / ((double)geom.width / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x)),
|
||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y * ((double)pWindow->m_vRealSize.vec().y / ((double)geom.height / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y)));
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y * (pWindow->m_vRealSize.vec().y / ((double)geom.height / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||||
@@ -703,6 +736,8 @@ void CHyprRenderer::arrangeLayersForMonitor(const int& monitor) {
|
|||||||
if (PMONITOR->damage)
|
if (PMONITOR->damage)
|
||||||
damageMonitor(PMONITOR);
|
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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -770,7 +805,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CHyprRenderer::damageMonitor(CMonitor* pMonitor) {
|
void CHyprRenderer::damageMonitor(CMonitor* pMonitor) {
|
||||||
if (g_pCompositor->m_bUnsafeState)
|
if (g_pCompositor->m_bUnsafeState || pMonitor->isMirror())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wlr_box damageBox = {0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y};
|
wlr_box damageBox = {0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y};
|
||||||
@@ -787,6 +822,9 @@ void CHyprRenderer::damageBox(wlr_box* pBox) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
|
if (m->isMirror())
|
||||||
|
continue; // don't damage mirrors traditionally
|
||||||
|
|
||||||
wlr_box damageBox = {pBox->x - m->vecPosition.x, pBox->y - m->vecPosition.y, pBox->width, pBox->height};
|
wlr_box damageBox = {pBox->x - m->vecPosition.x, pBox->y - m->vecPosition.y, pBox->width, pBox->height};
|
||||||
scaleBox(&damageBox, m->scale);
|
scaleBox(&damageBox, m->scale);
|
||||||
m->addDamage(&damageBox);
|
m->addDamage(&damageBox);
|
||||||
@@ -810,6 +848,19 @@ void CHyprRenderer::damageRegion(pixman_region32_t* rg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHyprRenderer::damageMirrorsWith(CMonitor* pMonitor, pixman_region32_t* pRegion) {
|
||||||
|
for (auto& mirror : pMonitor->mirrors) {
|
||||||
|
Vector2D scale = {mirror->vecSize.x / pMonitor->vecSize.x, mirror->vecSize.y / pMonitor->vecSize.y};
|
||||||
|
|
||||||
|
pixman_region32_t rg;
|
||||||
|
pixman_region32_init(&rg);
|
||||||
|
pixman_region32_copy(&rg, pRegion);
|
||||||
|
wlr_region_scale_xy(&rg, &rg, scale.x, scale.y);
|
||||||
|
pMonitor->addDamage(&rg);
|
||||||
|
pixman_region32_fini(&rg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CHyprRenderer::renderDragIcon(CMonitor* pMonitor, timespec* time) {
|
void CHyprRenderer::renderDragIcon(CMonitor* pMonitor, timespec* time) {
|
||||||
if (!(g_pInputManager->m_sDrag.dragIcon && g_pInputManager->m_sDrag.iconMapped && g_pInputManager->m_sDrag.dragIcon->surface))
|
if (!(g_pInputManager->m_sDrag.dragIcon && g_pInputManager->m_sDrag.iconMapped && g_pInputManager->m_sDrag.dragIcon->surface))
|
||||||
return;
|
return;
|
||||||
@@ -873,7 +924,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
|||||||
pMonitor->vecPosition = pMonitorRule->offset;
|
pMonitor->vecPosition = pMonitorRule->offset;
|
||||||
|
|
||||||
// loop over modes and choose an appropriate one.
|
// loop over modes and choose an appropriate one.
|
||||||
if (pMonitorRule->resolution != Vector2D()) {
|
if (pMonitorRule->resolution != Vector2D() && pMonitorRule->resolution != Vector2D(-1,-1) && pMonitorRule->resolution != Vector2D(-1,-2)) {
|
||||||
if (!wl_list_empty(&pMonitor->output->modes)) {
|
if (!wl_list_empty(&pMonitor->output->modes)) {
|
||||||
wlr_output_mode* mode;
|
wlr_output_mode* mode;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@@ -906,6 +957,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
||||||
pMonitor->vecSize = pMonitorRule->resolution;
|
pMonitor->vecSize = pMonitorRule->resolution;
|
||||||
|
pMonitor->refreshRate = pMonitorRule->refreshRate;
|
||||||
|
|
||||||
if (!wlr_output_test(pMonitor->output)) {
|
if (!wlr_output_test(pMonitor->output)) {
|
||||||
Debug::log(ERR, "Custom resolution FAILED, falling back to preferred");
|
Debug::log(ERR, "Custom resolution FAILED, falling back to preferred");
|
||||||
@@ -934,8 +986,95 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
|||||||
} else {
|
} else {
|
||||||
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
||||||
pMonitor->vecSize = pMonitorRule->resolution;
|
pMonitor->vecSize = pMonitorRule->resolution;
|
||||||
|
pMonitor->refreshRate = pMonitorRule->refreshRate;
|
||||||
|
|
||||||
Debug::log(LOG, "Setting custom mode for %s", pMonitor->output->name);
|
if (!wlr_output_test(pMonitor->output)) {
|
||||||
|
Debug::log(ERR, "Custom resolution FAILED, falling back to preferred");
|
||||||
|
|
||||||
|
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
|
||||||
|
|
||||||
|
if (!PREFERREDMODE) {
|
||||||
|
Debug::log(ERR, "Monitor %s has NO PREFERRED MODE, and an INVALID one was requested: %ix%i@%2f", (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preferred is valid
|
||||||
|
wlr_output_set_mode(pMonitor->output, PREFERREDMODE);
|
||||||
|
|
||||||
|
Debug::log(ERR, "Monitor %s got an invalid requested mode: %ix%i@%2f, using the preferred one instead: %ix%i@%2f", pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f);
|
||||||
|
|
||||||
|
pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f;
|
||||||
|
pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height);
|
||||||
|
} else {
|
||||||
|
Debug::log(LOG, "Set a custom mode %ix%i@%2f (mode not found in monitor modes)", (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pMonitorRule->resolution != Vector2D()) {
|
||||||
|
if (!wl_list_empty(&pMonitor->output->modes)) {
|
||||||
|
wlr_output_mode* mode;
|
||||||
|
float currentWidth = 0;
|
||||||
|
float currentHeight = 0;
|
||||||
|
float currentRefresh = 0;
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
//(-1,-1) indicates a preference to refreshrate over resolution, (-1,-2) preference to resolution
|
||||||
|
if(pMonitorRule->resolution == Vector2D(-1,-1)) {
|
||||||
|
wl_list_for_each(mode, &pMonitor->output->modes, link) {
|
||||||
|
if( ( mode->width >= currentWidth && mode->height >= currentHeight && mode->refresh >= ( currentRefresh - 1000.f ) ) || mode->refresh > ( currentRefresh + 3000.f ) ) {
|
||||||
|
wlr_output_set_mode(pMonitor->output, mode);
|
||||||
|
if (wlr_output_test(pMonitor->output)) {
|
||||||
|
currentWidth = mode->width;
|
||||||
|
currentHeight = mode->height;
|
||||||
|
currentRefresh = mode->refresh;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wl_list_for_each(mode, &pMonitor->output->modes, link) {
|
||||||
|
if( ( mode->width >= currentWidth && mode->height >= currentHeight && mode->refresh >= ( currentRefresh - 1000.f ) ) || ( mode->width > currentWidth && mode->height > currentHeight ) ) {
|
||||||
|
wlr_output_set_mode(pMonitor->output, mode);
|
||||||
|
if (wlr_output_test(pMonitor->output)) {
|
||||||
|
currentWidth = mode->width;
|
||||||
|
currentHeight = mode->height;
|
||||||
|
currentRefresh = mode->refresh;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
Debug::log(LOG, "Monitor %s: REJECTED mode: %ix%i@%2f! Falling back to preferred.",
|
||||||
|
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||||
|
mode->width, mode->height, mode->refresh / 1000.f);
|
||||||
|
|
||||||
|
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
|
||||||
|
|
||||||
|
if (!PREFERREDMODE) {
|
||||||
|
Debug::log(ERR, "Monitor %s has NO PREFERRED MODE, and an INVALID one was requested: %ix%i@%2f",
|
||||||
|
(int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preferred is valid
|
||||||
|
wlr_output_set_mode(pMonitor->output, PREFERREDMODE);
|
||||||
|
|
||||||
|
Debug::log(ERR, "Monitor %s got an invalid requested mode: %ix%i@%2f, using the preferred one instead: %ix%i@%2f",
|
||||||
|
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||||
|
PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f);
|
||||||
|
|
||||||
|
pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f;
|
||||||
|
pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Debug::log(LOG, "Monitor %s: Applying highest mode %ix%i@%2f.",
|
||||||
|
pMonitor->output->name, (int)currentWidth, (int)currentHeight, (int)currentRefresh / 1000.f,
|
||||||
|
mode->width, mode->height, mode->refresh / 1000.f);
|
||||||
|
|
||||||
|
pMonitor->refreshRate = currentRefresh / 1000.f;
|
||||||
|
pMonitor->vecSize = Vector2D(currentWidth, currentHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
|
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
|
||||||
@@ -984,6 +1123,14 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
|||||||
|
|
||||||
pMonitor->vecPixelSize = pMonitor->vecSize;
|
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
|
// update renderer
|
||||||
g_pHyprOpenGL->destroyMonitorResources(pMonitor);
|
g_pHyprOpenGL->destroyMonitorResources(pMonitor);
|
||||||
|
|
||||||
@@ -1013,6 +1160,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
|||||||
pMonitor->vecPosition = finalPos;
|
pMonitor->vecPosition = finalPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pMonitor->isMirror())
|
||||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitor->vecPosition.x, (int)pMonitor->vecPosition.y);
|
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitor->vecPosition.x, (int)pMonitor->vecPosition.y);
|
||||||
|
|
||||||
wlr_output_enable(pMonitor->output, true);
|
wlr_output_enable(pMonitor->output, true);
|
||||||
@@ -1026,6 +1174,9 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
|||||||
// frame skip
|
// frame skip
|
||||||
pMonitor->framesToSkip = 1;
|
pMonitor->framesToSkip = 1;
|
||||||
|
|
||||||
|
// reload to fix mirrors
|
||||||
|
g_pConfigManager->m_bWantsMonitorReload = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,6 +35,7 @@ public:
|
|||||||
void damageBox(const int& x, const int& y, const int& w, const int& h);
|
void damageBox(const int& x, const int& y, const int& w, const int& h);
|
||||||
void damageRegion(pixman_region32_t*);
|
void damageRegion(pixman_region32_t*);
|
||||||
void damageMonitor(CMonitor*);
|
void damageMonitor(CMonitor*);
|
||||||
|
void damageMirrorsWith(CMonitor*, pixman_region32_t*);
|
||||||
bool applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false);
|
bool applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false);
|
||||||
bool shouldRenderWindow(CWindow*, CMonitor*);
|
bool shouldRenderWindow(CWindow*, CMonitor*);
|
||||||
bool shouldRenderWindow(CWindow*);
|
bool shouldRenderWindow(CWindow*);
|
||||||
|
@@ -29,6 +29,9 @@ public:
|
|||||||
GLint range;
|
GLint range;
|
||||||
GLint shadowPower;
|
GLint shadowPower;
|
||||||
|
|
||||||
|
GLint applyTint;
|
||||||
|
GLint tint;
|
||||||
|
|
||||||
GLint getUniformLocation(const std::string&);
|
GLint getUniformLocation(const std::string&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -38,7 +38,7 @@ void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
|||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
const auto WORKSPACEOFFSET = PWORKSPACE ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
const auto WORKSPACEOFFSET = PWORKSPACE && !pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
||||||
|
|
||||||
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
||||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
|
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
|
||||||
@@ -56,34 +56,22 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) {
|
|||||||
if (m_pWindow->m_cRealShadowColor.col() == CColor(0, 0, 0, 0))
|
if (m_pWindow->m_cRealShadowColor.col() == CColor(0, 0, 0, 0))
|
||||||
return; // don't draw invisible shadows
|
return; // don't draw invisible shadows
|
||||||
|
|
||||||
|
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
||||||
|
return;
|
||||||
|
|
||||||
static auto *const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
static auto *const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||||
static auto *const PSHADOWSIZE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_range")->intValue;
|
static auto *const PSHADOWSIZE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_range")->intValue;
|
||||||
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||||
static auto *const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
|
static auto *const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
|
||||||
static auto *const PSHADOWOFFSET = &g_pConfigManager->getConfigValuePtr("decoration:shadow_offset")->strValue;
|
static auto *const PSHADOWOFFSET = &g_pConfigManager->getConfigValuePtr("decoration:shadow_offset")->vecValue;
|
||||||
|
|
||||||
if (*PSHADOWS != 1)
|
if (*PSHADOWS != 1)
|
||||||
return; // disabled
|
return; // disabled
|
||||||
|
|
||||||
// get the real offset
|
|
||||||
Vector2D offset;
|
|
||||||
try {
|
|
||||||
if (const auto SPACEPOS = PSHADOWOFFSET->find(' '); SPACEPOS != std::string::npos) {
|
|
||||||
const auto X = PSHADOWOFFSET->substr(0, SPACEPOS);
|
|
||||||
const auto Y = PSHADOWOFFSET->substr(SPACEPOS + 1);
|
|
||||||
|
|
||||||
if (isNumber(X, true) && isNumber(Y, true)) {
|
|
||||||
offset = Vector2D(std::stof(X), std::stof(Y));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (std::exception& e) {
|
|
||||||
return; // cannot parse
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ? 0 : (m_pWindow->m_sAdditionalConfigData.rounding == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding);
|
const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ? 0 : (m_pWindow->m_sAdditionalConfigData.rounding == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding);
|
||||||
|
|
||||||
// update the extents
|
// update the extents
|
||||||
m_seExtents = {{*PSHADOWSIZE + 2 - offset.x, *PSHADOWSIZE + 2 - offset.y}, {*PSHADOWSIZE + 2 + offset.x, *PSHADOWSIZE + 2 + offset.y}};
|
m_seExtents = {{*PSHADOWSIZE + 2 - PSHADOWOFFSET->x, *PSHADOWSIZE + 2 - PSHADOWOFFSET->y}, {*PSHADOWSIZE + 2 + PSHADOWOFFSET->x, *PSHADOWSIZE + 2 + PSHADOWOFFSET->y}};
|
||||||
|
|
||||||
// draw the shadow
|
// draw the shadow
|
||||||
wlr_box fullBox = {m_vLastWindowPos.x - m_seExtents.topLeft.x + 2, m_vLastWindowPos.y - m_seExtents.topLeft.y + 2, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x - 4, m_vLastWindowSize.y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y - 4};
|
wlr_box fullBox = {m_vLastWindowPos.x - m_seExtents.topLeft.x + 2, m_vLastWindowPos.y - m_seExtents.topLeft.y + 2, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x - 4, m_vLastWindowSize.y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y - 4};
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
CHyprGroupBarDecoration::CHyprGroupBarDecoration(CWindow* pWindow) {
|
CHyprGroupBarDecoration::CHyprGroupBarDecoration(CWindow* pWindow) {
|
||||||
m_pWindow = pWindow;
|
m_pWindow = pWindow;
|
||||||
updateWindow(pWindow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CHyprGroupBarDecoration::~CHyprGroupBarDecoration() {
|
CHyprGroupBarDecoration::~CHyprGroupBarDecoration() {
|
||||||
@@ -23,13 +22,13 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
|||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
const auto WORKSPACEOFFSET = PWORKSPACE ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
const auto WORKSPACEOFFSET = PWORKSPACE && !pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
||||||
|
|
||||||
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
||||||
// we draw 3px above the window's border with 3px
|
// 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_seExtents.bottomRight = Vector2D();
|
||||||
|
|
||||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
|
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
|
||||||
@@ -46,7 +45,7 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
|||||||
|
|
||||||
// get the group info
|
// get the group info
|
||||||
SLayoutMessageHeader header;
|
SLayoutMessageHeader header;
|
||||||
header.pWindow = g_pCompositor->m_pLastWindow;
|
header.pWindow = m_pWindow;
|
||||||
|
|
||||||
m_dwGroupMembers = std::any_cast<std::deque<CWindow*>>(g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "groupinfo"));
|
m_dwGroupMembers = std::any_cast<std::deque<CWindow*>>(g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "groupinfo"));
|
||||||
|
|
||||||
@@ -71,6 +70,9 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
|||||||
if (barsToDraw < 1 || m_pWindow->m_bHidden || !g_pCompositor->windowValidMapped(m_pWindow))
|
if (barsToDraw < 1 || m_pWindow->m_bHidden || !g_pCompositor->windowValidMapped(m_pWindow))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
||||||
|
return;
|
||||||
|
|
||||||
const int PAD = 2; //2px
|
const int PAD = 2; //2px
|
||||||
|
|
||||||
const int BARW = (m_vLastWindowSize.x - PAD * (barsToDraw - 1)) / barsToDraw;
|
const int BARW = (m_vLastWindowSize.x - PAD * (barsToDraw - 1)) / barsToDraw;
|
||||||
@@ -83,7 +85,12 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
|||||||
if (rect.width <= 0 || rect.height <= 0)
|
if (rect.width <= 0 || rect.height <= 0)
|
||||||
break;
|
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"));
|
scaleBox(&rect, pMonitor->scale);
|
||||||
|
|
||||||
|
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;
|
color.a *= a;
|
||||||
g_pHyprOpenGL->renderRect(&rect, color);
|
g_pHyprOpenGL->renderRect(&rect, color);
|
||||||
|
|
||||||
|
@@ -205,6 +205,9 @@ uniform float radius;
|
|||||||
|
|
||||||
uniform int discardOpaque;
|
uniform int discardOpaque;
|
||||||
|
|
||||||
|
uniform int applyTint;
|
||||||
|
uniform vec3 tint;
|
||||||
|
|
||||||
uniform int primitiveMultisample;
|
uniform int primitiveMultisample;
|
||||||
uniform int ignoreCorners;
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
@@ -217,6 +220,12 @@ void main() {
|
|||||||
return;
|
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;
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||||
@@ -238,6 +247,9 @@ uniform float radius;
|
|||||||
|
|
||||||
uniform int discardOpaque;
|
uniform int discardOpaque;
|
||||||
|
|
||||||
|
uniform int applyTint;
|
||||||
|
uniform vec3 tint;
|
||||||
|
|
||||||
uniform int primitiveMultisample;
|
uniform int primitiveMultisample;
|
||||||
uniform int ignoreCorners;
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
@@ -250,9 +262,16 @@ void main() {
|
|||||||
|
|
||||||
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
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;
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||||
|
R"#(
|
||||||
|
|
||||||
gl_FragColor = pixColor * alpha;
|
gl_FragColor = pixColor * alpha;
|
||||||
})#";
|
})#";
|
||||||
@@ -319,6 +338,9 @@ uniform float radius;
|
|||||||
|
|
||||||
uniform int discardOpaque;
|
uniform int discardOpaque;
|
||||||
|
|
||||||
|
uniform int applyTint;
|
||||||
|
uniform vec3 tint;
|
||||||
|
|
||||||
uniform int primitiveMultisample;
|
uniform int primitiveMultisample;
|
||||||
uniform int ignoreCorners;
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
@@ -331,9 +353,16 @@ void main() {
|
|||||||
return;
|
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;
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||||
|
R"#(
|
||||||
|
|
||||||
gl_FragColor = pixColor * alpha;
|
gl_FragColor = pixColor * alpha;
|
||||||
})#";
|
})#";
|
||||||
|
Submodule subprojects/wlroots updated: 7c575922c0...50cc1ef4d3
Reference in New Issue
Block a user