mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-07-30 03:31:53 -07:00
Compare commits
101 Commits
v0.8.1beta
...
v0.9.1beta
Author | SHA1 | Date | |
---|---|---|---|
|
02fbb3a417 | ||
|
9c8d32d1c2 | ||
|
a71f4114b0 | ||
|
a6cd552980 | ||
|
100d29d34d | ||
|
00747fc6df | ||
|
523023aec7 | ||
|
024752bbe3 | ||
|
e794de1f4d | ||
|
1edd66618f | ||
|
338865e433 | ||
|
cb36456f40 | ||
|
b90159c089 | ||
|
0ba17d4da3 | ||
|
d6e227ae0d | ||
|
6427bb41d8 | ||
|
60c16f77a6 | ||
|
f892387b70 | ||
|
6378990bc3 | ||
|
070d7699a7 | ||
|
8a4e04d789 | ||
|
46e18e08d1 | ||
|
9ac00fe52b | ||
|
d44adb1bea | ||
|
40c652f23e | ||
|
575c3e071a | ||
|
dba4596c7e | ||
|
e95aa8ef26 | ||
|
a1d1ec4c46 | ||
|
d9687c93ee | ||
|
9be239dac6 | ||
|
76f7c2510e | ||
|
2230f0ccaa | ||
|
04f8029fcc | ||
|
20cba2d707 | ||
|
e2bc07d276 | ||
|
edac94bed1 | ||
|
4610b3d864 | ||
|
0573d5987f | ||
|
e5cef8fc96 | ||
|
382f851b30 | ||
|
2e3d42a9a9 | ||
|
217ff1f401 | ||
|
c2db3ad8ce | ||
|
2e0dd4bea2 | ||
|
d6a649c1b3 | ||
|
f96b611651 | ||
|
4211b37e22 | ||
|
45747fb8e6 | ||
|
adeab98831 | ||
|
036be18bf5 | ||
|
59879e0bd1 | ||
|
132b5ba5b6 | ||
|
3c544e1c31 | ||
|
191c02a4f4 | ||
|
7c7690eb08 | ||
|
66680a1149 | ||
|
fd74208453 | ||
|
e56699826f | ||
|
ef2417fbcb | ||
|
fd999100f0 | ||
|
0eebf3ab16 | ||
|
ac8e5fef10 | ||
|
429a9bc6c3 | ||
|
233bad5011 | ||
|
0f19bd99f8 | ||
|
f0cd784f79 | ||
|
7a2f296c93 | ||
|
0b0cd85085 | ||
|
3f62a386bf | ||
|
4076a3b6d7 | ||
|
13d9c85e4e | ||
|
9afa3953e9 | ||
|
398662c75a | ||
|
5bc9534642 | ||
|
0e2038fedf | ||
|
6d35d642ea | ||
|
b0ab8afc58 | ||
|
578787b36d | ||
|
f6c7a79988 | ||
|
9d5b76b757 | ||
|
920fdd6bff | ||
|
9dd17a4be6 | ||
|
3904351678 | ||
|
b6f2a4bc36 | ||
|
e102f9ec8c | ||
|
ee15ad1215 | ||
|
1d3e1472f2 | ||
|
b2627c05c4 | ||
|
427bc35b6b | ||
|
c9c4b14ef2 | ||
|
cb1a36faf0 | ||
|
31a079b347 | ||
|
50b991674b | ||
|
28046e9da0 | ||
|
cc146f0344 | ||
|
970bcc467c | ||
|
a312f8e0ac | ||
|
88506d4284 | ||
|
9fc74a708e | ||
|
310a839700 |
8
.github/workflows/nix-build.yaml
vendored
8
.github/workflows/nix-build.yaml
vendored
@@ -13,9 +13,13 @@ jobs:
|
||||
- name: Install nix
|
||||
uses: cachix/install-nix-action@v17
|
||||
with:
|
||||
install_url: https://releases.nixos.org/nix/nix-2.8.0/install
|
||||
install_url: https://releases.nixos.org/nix/nix-2.10.3/install
|
||||
extra_nix_config: |
|
||||
auto-optimise-store = true
|
||||
experimental-features = nix-command flakes
|
||||
- name: Build HyprLand with default settings
|
||||
- uses: cachix/cachix-action@v10
|
||||
with:
|
||||
name: hyprland
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
- name: Build Hyprland with default settings
|
||||
run: nix build --print-build-logs
|
||||
|
40
Makefile
40
Makefile
@@ -9,6 +9,8 @@ PKGS = wlroots wayland-server xcb xkbcommon libinput
|
||||
CFLAGS += $(foreach p,$(PKGS),$(shell pkg-config --cflags $(p)))
|
||||
LDLIBS += $(foreach p,$(PKGS),$(shell pkg-config --libs $(p)))
|
||||
|
||||
DATE=$(shell date "+%d %b %Y")
|
||||
|
||||
xdg-shell-protocol.h:
|
||||
$(WAYLAND_SCANNER) server-header \
|
||||
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
|
||||
@@ -79,21 +81,31 @@ idle-protocol.c:
|
||||
|
||||
idle-protocol.o: idle-protocol.h
|
||||
|
||||
wlr-output-power-management-unstable-v1-protocol.h:
|
||||
$(WAYLAND_SCANNER) server-header \
|
||||
protocols/wlr-output-power-management-unstable-v1.xml $@
|
||||
|
||||
wlr-output-power-management-unstable-v1-protocol.c:
|
||||
$(WAYLAND_SCANNER) private-code \
|
||||
protocols/wlr-output-power-management-unstable-v1.xml $@
|
||||
|
||||
wlr-output-power-management-unstable-v1-protocol.o: wlr-output-power-management-unstable-v1-protocol.h
|
||||
|
||||
legacyrenderer:
|
||||
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DLEGACY_RENDERER:STRING=true -H./ -B./build -G Ninja
|
||||
cmake --build ./build --config Release --target all -j 10
|
||||
cmake --build ./build --config Release --target all -j $(nproc)
|
||||
|
||||
legacyrendererdebug:
|
||||
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DLEGACY_RENDERER:STRING=true -H./ -B./build -G Ninja
|
||||
cmake --build ./build --config Release --target all -j 10
|
||||
cmake --build ./build --config Release --target all -j $(nproc)
|
||||
|
||||
release:
|
||||
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -H./ -B./build -G Ninja
|
||||
cmake --build ./build --config Release --target all -j 10
|
||||
cmake --build ./build --config Release --target all -j $(nproc)
|
||||
|
||||
debug:
|
||||
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -H./ -B./build -G Ninja
|
||||
cmake --build ./build --config Debug --target all -j 10
|
||||
cmake --build ./build --config Debug --target all -j $(nproc)
|
||||
|
||||
clear:
|
||||
rm -rf build
|
||||
@@ -124,7 +136,6 @@ install:
|
||||
cp ./assets/wall_4K.png ${PREFIX}/share/hyprland
|
||||
cp ./assets/wall_8K.png ${PREFIX}/share/hyprland
|
||||
|
||||
|
||||
uninstall:
|
||||
rm -f ${PREFIX}/share/wayland-sessions/hyprland.desktop
|
||||
rm -f ${PREFIX}/bin/Hyprland
|
||||
@@ -132,7 +143,7 @@ uninstall:
|
||||
rm -f /usr/lib/libwlroots.so.11032
|
||||
rm -rf ${PREFIX}/share/hyprland
|
||||
|
||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o
|
||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o wlr-output-power-management-unstable-v1-protocol.o
|
||||
|
||||
fixwlr:
|
||||
sed -i -E 's/(soversion = 11)([^032]|$$)/soversion = 11032/g' subprojects/wlroots/meson.build
|
||||
@@ -148,3 +159,20 @@ config:
|
||||
cd subprojects/wlroots && ninja -C build/
|
||||
|
||||
cd subprojects/wlroots && ninja -C build/ install
|
||||
|
||||
man:
|
||||
pandoc ./docs/Hyprland.1.rst \
|
||||
--standalone \
|
||||
--variable=header:"Hyprland User Manual" \
|
||||
--variable=date:"${DATE}" \
|
||||
--variable=section:1 \
|
||||
--from rst \
|
||||
--to man | gzip -c > /usr/share/man/man1/Hyprland.1.gz
|
||||
|
||||
pandoc ./docs/hyprctl.1.rst \
|
||||
--standalone \
|
||||
--variable=header:"hyprctl User Manual" \
|
||||
--variable=date:"${DATE}" \
|
||||
--variable=section:1 \
|
||||
--from rst \
|
||||
--to man | gzip -c > /usr/share/man/man1/hyprctl.1.gz
|
||||
|
58
docs/Hyprland.1.rst
Normal file
58
docs/Hyprland.1.rst
Normal file
@@ -0,0 +1,58 @@
|
||||
:title: Hyprland
|
||||
:author: Vaxerski <*https://github.com/vaxerski*>
|
||||
|
||||
NAME
|
||||
====
|
||||
|
||||
Hyprland - Dynamic tiling Wayland compositor
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
**Hyprland** [*arg [...]*].
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
**Hyprland** is a dynamic tiling Wayland compositor based on
|
||||
wlroots that doesn't sacrifice on its looks.
|
||||
|
||||
You can launch Hyprland by either going into a TTY and
|
||||
executing **Hyprland**, or with a login manager.
|
||||
|
||||
NOTICE
|
||||
======
|
||||
|
||||
Hyprland is still in pretty early development compared to some other Wayland compositors.
|
||||
|
||||
Although Hyprland is pretty stable, it may have some bugs.
|
||||
|
||||
CONFIGURATION
|
||||
=============
|
||||
|
||||
For configuration information please see <*https://github.com/hyprwm/Hyprland/wiki*>.
|
||||
|
||||
OPTIONS
|
||||
=======
|
||||
|
||||
**-h**, **--help**
|
||||
Show command usage.
|
||||
|
||||
**-c**, **--config**
|
||||
Specify config file to use.
|
||||
|
||||
BUGS
|
||||
====
|
||||
|
||||
Submit bug reports and request features online at:
|
||||
<*https://github.com/hyprwm/Hyprland/issues*>
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
Sources at: <*https://github.com/hyprwm/Hyprland*>
|
||||
|
||||
COPYRIGHT
|
||||
=========
|
||||
|
||||
Copyright (c) 2022, vaxerski
|
121
docs/hyprctl.1.rst
Normal file
121
docs/hyprctl.1.rst
Normal file
@@ -0,0 +1,121 @@
|
||||
:title: hyprctl(1)
|
||||
:author: Vaxerski <*https://github.com/vaxerski*>
|
||||
|
||||
NAME
|
||||
====
|
||||
|
||||
hyprctl - Utility for controlling parts of Hyprland from a CLI or a script
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
**hyprctl** [*(opt)flags*] [**command**] [*(opt)args*]
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
**hyprctl** is a utility for controlling some parts of the compositor from a CLI or a script.
|
||||
|
||||
CONTROL COMMANDS
|
||||
================
|
||||
|
||||
**dispatch**
|
||||
|
||||
Call a dispatcher with an argument.
|
||||
|
||||
An argument must be present.
|
||||
For dispatchers without parameters it can be anything.
|
||||
|
||||
Returns: *ok* on success, and an error message on failure.
|
||||
|
||||
Examples:
|
||||
**hyprctl** *dispatch exec kitty*
|
||||
|
||||
**hyprctl** *dispatch pseudo x*
|
||||
|
||||
**keyword**
|
||||
|
||||
Set a config keyword dynamically.
|
||||
|
||||
Returns: *ok* on success, and an error message on failure.
|
||||
|
||||
Examples:
|
||||
**hyprctl** *keyword bind SUPER,0,pseudo*
|
||||
|
||||
**hyprctl** *keyword general:border_size 10*
|
||||
|
||||
**reload**
|
||||
|
||||
Force a reload of the config file.
|
||||
|
||||
**kill**
|
||||
|
||||
Enter kill mode, where you can kill an app by clicking on it.
|
||||
You can exit by pressing ESCAPE.
|
||||
|
||||
INFO COMMANDS
|
||||
=============
|
||||
|
||||
**version**
|
||||
|
||||
Prints the Hyprland version, flags, commit and branch of build.
|
||||
|
||||
**monitors**
|
||||
|
||||
Lists all the outputs with their properties.
|
||||
|
||||
**workspaces**
|
||||
|
||||
Lists all workspaces with their properties.
|
||||
|
||||
**clients**
|
||||
|
||||
Lists all windows with their properties.
|
||||
|
||||
**devices**
|
||||
|
||||
Lists all connected input devices.
|
||||
|
||||
**activewindow**
|
||||
|
||||
Returns the active window name.
|
||||
|
||||
**layers**
|
||||
|
||||
Lists all the layers.
|
||||
|
||||
**splash**
|
||||
|
||||
Returns the current random splash.
|
||||
|
||||
OPTIONS
|
||||
=======
|
||||
|
||||
**--batch**
|
||||
|
||||
Specify a batch of commands to execute.
|
||||
|
||||
Example:
|
||||
**hyprctl** *--batch "keyword general:border_size 2 ; keyword general:gaps_out 20"*
|
||||
|
||||
*;* separates the commands.
|
||||
|
||||
**-j**
|
||||
|
||||
Outputs information in JSON.
|
||||
|
||||
BUGS
|
||||
====
|
||||
|
||||
Submit bug reports and request features online at:
|
||||
<*https://github.com/hyprwm/Hyprland/issues*>
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
Sources at: <*https://github.com/hyprwm/Hyprland*>
|
||||
|
||||
COPYRIGHT
|
||||
=========
|
||||
|
||||
Copyright (c) 2022, vaxerski
|
@@ -8,7 +8,7 @@
|
||||
# For a full list, see the wiki (basic and advanced configuring)
|
||||
#
|
||||
|
||||
monitor=,1280x720@60,0x0,1
|
||||
monitor=,preferred,0x0,1
|
||||
workspace=DP-1,1
|
||||
|
||||
input {
|
||||
@@ -53,8 +53,8 @@ decoration {
|
||||
animations {
|
||||
enabled=1
|
||||
animation=windows,1,7,default
|
||||
animation=borders,1,10,default
|
||||
animation=fadein,1,10,default
|
||||
animation=border,1,10,default
|
||||
animation=fade,1,10,default
|
||||
animation=workspaces,1,6,default
|
||||
}
|
||||
|
||||
@@ -62,6 +62,10 @@ dwindle {
|
||||
pseudotile=0 # enable pseudotiling on dwindle
|
||||
}
|
||||
|
||||
gestures {
|
||||
workspace_swipe=no
|
||||
}
|
||||
|
||||
# example window rules
|
||||
# for windows named/classed as abc and xyz
|
||||
#windowrule=move 69 420,abc
|
||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1657447684,
|
||||
"narHash": "sha256-FCP9AuU1q6PE3vOeM5SFf58f/UKPBAsoSGDUGamNBbo=",
|
||||
"lastModified": 1659219666,
|
||||
"narHash": "sha256-pzYr5fokQPHv7CmUXioOhhzDy/XyWOIXP4LZvv/T7Mk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "5f43d8b088d3771274bcfb69d3c7435b1121ac88",
|
||||
"rev": "7b9be38c7250b22d829ab6effdee90d5e40c6e5c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -26,11 +26,11 @@
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"host": "gitlab.freedesktop.org",
|
||||
"lastModified": 1656865312,
|
||||
"narHash": "sha256-xtQ0zwJZwN8sciruveM10CzKz6TWxBY8SyXa8E4jly4=",
|
||||
"lastModified": 1658770113,
|
||||
"narHash": "sha256-VBq9vw0hvQPKGKLNKLJS8xsUHvrX0o2LUDBVolixenE=",
|
||||
"owner": "wlroots",
|
||||
"repo": "wlroots",
|
||||
"rev": "5dc1d4671dd2ca3c1f0f09587c463fdbb542f0a4",
|
||||
"rev": "7b5e890e61a27375725068a7d1884b26851b3102",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
@@ -33,7 +33,7 @@
|
||||
});
|
||||
hyprland = prev.callPackage ./nix/default.nix {
|
||||
stdenv = prev.gcc12Stdenv;
|
||||
version = "0.7.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
|
||||
version = "0.9.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
|
||||
wlroots = wlroots-hyprland;
|
||||
};
|
||||
hyprland-debug = hyprland.override {debug = true;};
|
||||
@@ -61,6 +61,7 @@
|
||||
formatter = genSystems (system: pkgsFor.${system}.alejandra);
|
||||
|
||||
nixosModules.default = import ./nix/module.nix self;
|
||||
homeManagerModules.default = import ./nix/hm-module.nix self;
|
||||
|
||||
overlay = throw "Hyprland: .overlay output is deprecated, please use the .overlays.default output";
|
||||
};
|
||||
|
@@ -36,7 +36,8 @@ commands:
|
||||
reload
|
||||
|
||||
flags:
|
||||
j -> output in JSON
|
||||
-j -> output in JSON
|
||||
--batch -> execute a batch of commands, separated by ';'
|
||||
)#";
|
||||
|
||||
void request(std::string arg) {
|
||||
|
12
meson.build
12
meson.build
@@ -1,15 +1,25 @@
|
||||
project('Hyprland', 'cpp', 'c',
|
||||
version : '0.7.0beta',
|
||||
version : '0.8.1beta',
|
||||
default_options : ['warning_level=2', 'default_library=static', 'optimization=3'])
|
||||
|
||||
add_global_arguments('-std=c++23', language: 'cpp')
|
||||
|
||||
GIT_BRANCH = run_command('git', 'rev-parse', '--abbrev-ref', 'HEAD', check: false).stdout().strip()
|
||||
GIT_COMMIT_HASH = run_command('git', 'rev-parse', 'HEAD', check: false).stdout().strip()
|
||||
GIT_COMMIT_MESSAGE = run_command('bash', '-c', 'git show | head -n 5 | tail -n 1', check: false).stdout().strip()
|
||||
GIT_DIRTY = run_command('bash', '-c', 'git diff-index --quiet HEAD -- || echo "dirty"', check: false).stdout().strip()
|
||||
|
||||
add_project_arguments(
|
||||
[
|
||||
'-Wno-unused-parameter',
|
||||
'-Wno-unused-value',
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wno-narrowing',
|
||||
|
||||
f'-DGIT_BRANCH="@GIT_BRANCH@"',
|
||||
f'-DGIT_COMMIT_HASH="@GIT_COMMIT_HASH@"',
|
||||
f'-DGIT_COMMIT_MESSAGE="@GIT_COMMIT_MESSAGE@"',
|
||||
f'-DGIT_DIRTY="@GIT_DIRTY@"',
|
||||
],
|
||||
language: 'cpp')
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
pkg-config,
|
||||
meson,
|
||||
ninja,
|
||||
git,
|
||||
libdrm,
|
||||
libinput,
|
||||
libxcb,
|
||||
@@ -18,9 +19,10 @@
|
||||
wlroots,
|
||||
xcbutilwm,
|
||||
xwayland,
|
||||
enableXWayland ? true,
|
||||
version ? "git",
|
||||
debug ? false,
|
||||
enableXWayland ? true,
|
||||
legacyRenderer ? false,
|
||||
version ? "git",
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "hyprland" + lib.optionalString debug "-debug";
|
||||
@@ -35,6 +37,7 @@ stdenv.mkDerivation {
|
||||
|
||||
buildInputs =
|
||||
[
|
||||
git
|
||||
libdrm
|
||||
libinput
|
||||
libxcb
|
||||
@@ -54,7 +57,10 @@ stdenv.mkDerivation {
|
||||
then "debug"
|
||||
else "release";
|
||||
|
||||
mesonFlags = lib.optional (!enableXWayland) "-DNO_XWAYLAND=true";
|
||||
mesonFlags = builtins.concatLists [
|
||||
(lib.optional (!enableXWayland) "-DNO_XWAYLAND=true")
|
||||
(lib.optional (legacyRenderer) "-DLEGACY_RENDERER:STRING=true")
|
||||
];
|
||||
|
||||
patches = [
|
||||
# make meson use the provided wlroots instead of the git submodule
|
||||
|
98
nix/hm-module.nix
Normal file
98
nix/hm-module.nix
Normal file
@@ -0,0 +1,98 @@
|
||||
self: {
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
cfg = config.wayland.windowManager.hyprland;
|
||||
defaultHyprlandPackage = self.packages.${pkgs.system}.default.override {
|
||||
enableXWayland = cfg.xwayland;
|
||||
};
|
||||
in {
|
||||
options.wayland.windowManager.hyprland = {
|
||||
enable = lib.mkEnableOption "hyprland wayland compositor";
|
||||
package = lib.mkOption {
|
||||
type = with lib.types; nullOr package;
|
||||
default = defaultHyprlandPackage;
|
||||
description = ''
|
||||
Hyprland package to use. Will override the 'xwayland' option.
|
||||
|
||||
Defaults to the one provided by the flake. Set it to
|
||||
<literal>pkgs.hyprland</literal> to use the one provided by nixpkgs or
|
||||
if you have an overlay.
|
||||
|
||||
Set to null to not add any Hyprland package to your path. This should
|
||||
be done if you want to use the NixOS module to install Hyprland.
|
||||
'';
|
||||
};
|
||||
systemdIntegration = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = pkgs.stdenv.isLinux;
|
||||
description = ''
|
||||
Whether to enable <filename>hyprland-session.target</filename> on
|
||||
hyprland startup. This links to <filename>graphical-session.target</filename>.
|
||||
Some important environment variables will be imported to systemd
|
||||
and dbus user environment before reaching the target, including
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>DISPLAY</literal></para></listitem>
|
||||
<listitem><para><literal>WAYLAND_DISPLAY</literal></para></listitem>
|
||||
<listitem><para><literal>HYPRLAND_INSTANCE_SIGNATURE</literal></para></listitem>
|
||||
<listitem><para><literal>XDG_CURRENT_DESKTOP</literal></para></listitem>
|
||||
</itemizedlist>
|
||||
'';
|
||||
};
|
||||
xwayland = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable xwayland.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration lines to add to ~/.config/hypr/hyprland.conf.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages =
|
||||
lib.optional (cfg.package != null) cfg.package
|
||||
++ lib.optional cfg.xwayland pkgs.xwayland;
|
||||
|
||||
xdg.configFile."hypr/hyprland.conf" = {
|
||||
text =
|
||||
(lib.optionalString cfg.systemdIntegration "
|
||||
exec-once=${pkgs.dbus}/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP; systemctl --user start hyprland-session.target
|
||||
")
|
||||
+ cfg.extraConfig;
|
||||
|
||||
onChange = let
|
||||
hyprlandPackage =
|
||||
if cfg.package == null
|
||||
then defaultHyprlandPackage
|
||||
else cfg.package;
|
||||
in "${hyprlandPackage}/bin/hyprctl reload";
|
||||
};
|
||||
|
||||
systemd.user.targets.hyprland-session = lib.mkIf cfg.systemdIntegration {
|
||||
Unit = {
|
||||
Description = "hyprland compositor session";
|
||||
Documentation = ["man:systemd.special(7)"];
|
||||
BindsTo = ["graphical-session.target"];
|
||||
Wants = ["graphical-session-pre.target"];
|
||||
After = ["graphical-session-pre.target"];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.targets.tray = {
|
||||
Unit = {
|
||||
Description = "Home Manager System Tray";
|
||||
Requires = ["graphical-session-pre.target"];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@@ -18,7 +18,7 @@ in {
|
||||
'';
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
type = types.nullOr types.package;
|
||||
default = self.packages.${pkgs.system}.default;
|
||||
defaultText = literalExpression "<Hyprland flake>.packages.<system>.default";
|
||||
example = literalExpression "<Hyprland flake>.packages.<system>.default.override { }";
|
||||
@@ -27,34 +27,18 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = with pkgs; [
|
||||
kitty
|
||||
wofi
|
||||
swaybg
|
||||
];
|
||||
defaultText = literalExpression ''
|
||||
with pkgs; [ kitty wofi swaybg ];
|
||||
'';
|
||||
example = literalExpression ''
|
||||
with pkgs; [
|
||||
alacritty wofi
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
Extra packages to be installed system wide.
|
||||
'';
|
||||
};
|
||||
imports = [
|
||||
(mkRemovedOptionModule ["programs" "hyprland" "extraPackages"] "extraPackages has been removed. Use environment.systemPackages instead.")
|
||||
];
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [cfg.package] ++ cfg.extraPackages;
|
||||
environment.systemPackages = lib.optional (cfg.package != null) cfg.package;
|
||||
security.polkit.enable = true;
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
programs.dconf.enable = mkDefault true;
|
||||
services.xserver.displayManager.sessionPackages = [cfg.package];
|
||||
services.xserver.displayManager.sessionPackages = lib.optional (cfg.package != null) cfg.package;
|
||||
programs.xwayland.enable = mkDefault true;
|
||||
xdg.portal.enable = mkDefault true;
|
||||
xdg.portal.extraPortals = [pkgs.xdg-desktop-portal-wlr];
|
||||
|
@@ -14,6 +14,7 @@ wayland_scanner = find_program(
|
||||
protocols = [
|
||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||
['wlr-layer-shell-unstable-v1.xml'],
|
||||
['wlr-output-power-management-unstable-v1.xml'],
|
||||
['ext-workspace-unstable-v1.xml'],
|
||||
['pointer-constraints-unstable-v1.xml'],
|
||||
['tablet-unstable-v2.xml'],
|
||||
|
128
protocols/wlr-output-power-management-unstable-v1.xml
Normal file
128
protocols/wlr-output-power-management-unstable-v1.xml
Normal file
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wlr_output_power_management_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2019 Purism SPC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="Control power management modes of outputs">
|
||||
This protocol allows clients to control power management modes
|
||||
of outputs that are currently part of the compositor space. The
|
||||
intent is to allow special clients like desktop shells to power
|
||||
down outputs when the system is idle.
|
||||
|
||||
To modify outputs not currently part of the compositor space see
|
||||
wlr-output-management.
|
||||
|
||||
Warning! The protocol described in this file is experimental and
|
||||
backward incompatible changes may be made. Backward compatible changes
|
||||
may be added together with the corresponding interface version bump.
|
||||
Backward incompatible changes are done by bumping the version number in
|
||||
the protocol and interface names and resetting the interface version.
|
||||
Once the protocol is to be declared stable, the 'z' prefix and the
|
||||
version number in the protocol and interface names are removed and the
|
||||
interface version number is reset.
|
||||
</description>
|
||||
|
||||
<interface name="zwlr_output_power_manager_v1" version="1">
|
||||
<description summary="manager to create per-output power management">
|
||||
This interface is a manager that allows creating per-output power
|
||||
management mode controls.
|
||||
</description>
|
||||
|
||||
<request name="get_output_power">
|
||||
<description summary="get a power management for an output">
|
||||
Create a output power management mode control that can be used to
|
||||
adjust the power management mode for a given output.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwlr_output_power_v1"/>
|
||||
<arg name="output" type="object" interface="wl_output"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the manager">
|
||||
All objects created by the manager will still remain valid, until their
|
||||
appropriate destroy request has been called.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_output_power_v1" version="1">
|
||||
<description summary="adjust power management mode for an output">
|
||||
This object offers requests to set the power management mode of
|
||||
an output.
|
||||
</description>
|
||||
|
||||
<enum name="mode">
|
||||
<entry name="off" value="0"
|
||||
summary="Output is turned off."/>
|
||||
<entry name="on" value="1"
|
||||
summary="Output is turned on, no power saving"/>
|
||||
</enum>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_mode" value="1" summary="inexistent power save mode"/>
|
||||
</enum>
|
||||
|
||||
<request name="set_mode">
|
||||
<description summary="Set an outputs power save mode">
|
||||
Set an output's power save mode to the given mode. The mode change
|
||||
is effective immediately. If the output does not support the given
|
||||
mode a failed event is sent.
|
||||
</description>
|
||||
<arg name="mode" type="uint" enum="mode" summary="the power save mode to set"/>
|
||||
</request>
|
||||
|
||||
<event name="mode">
|
||||
<description summary="Report a power management mode change">
|
||||
Report the power management mode change of an output.
|
||||
|
||||
The mode event is sent after an output changed its power
|
||||
management mode. The reason can be a client using set_mode or the
|
||||
compositor deciding to change an output's mode.
|
||||
This event is also sent immediately when the object is created
|
||||
so the client is informed about the current power management mode.
|
||||
</description>
|
||||
<arg name="mode" type="uint" enum="mode"
|
||||
summary="the output's new power management mode"/>
|
||||
</event>
|
||||
|
||||
<event name="failed">
|
||||
<description summary="object no longer valid">
|
||||
This event indicates that the output power management mode control
|
||||
is no longer valid. This can happen for a number of reasons,
|
||||
including:
|
||||
- The output doesn't support power management
|
||||
- Another client already has exclusive power management mode control
|
||||
for this output
|
||||
- The output disappeared
|
||||
|
||||
Upon receiving this event, the client should destroy this object.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy this power management">
|
||||
Destroys the output power management mode control object.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
@@ -1,6 +1,7 @@
|
||||
#include "Compositor.hpp"
|
||||
#include "helpers/Splashes.hpp"
|
||||
#include <random>
|
||||
#include "debug/HyprCtl.hpp"
|
||||
|
||||
int handleCritSignal(int signo, void* data) {
|
||||
Debug::log(LOG, "Hyprland received signal %d", signo);
|
||||
@@ -13,6 +14,8 @@ int handleCritSignal(int signo, void* data) {
|
||||
}
|
||||
|
||||
CCompositor::CCompositor() {
|
||||
wlr_log_init(WLR_INFO, NULL);
|
||||
|
||||
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
|
||||
|
||||
setenv("HYPRLAND_INSTANCE_SIGNATURE", m_szInstanceSignature.c_str(), true);
|
||||
@@ -86,20 +89,21 @@ CCompositor::CCompositor() {
|
||||
m_sWLRSubCompositor = wlr_subcompositor_create(m_sWLDisplay);
|
||||
m_sWLRDataDevMgr = wlr_data_device_manager_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRDmabuf = wlr_linux_dmabuf_v1_create(m_sWLDisplay, m_sWLRRenderer);
|
||||
wlr_export_dmabuf_manager_v1_create(m_sWLDisplay);
|
||||
wlr_screencopy_manager_v1_create(m_sWLDisplay);
|
||||
wlr_data_control_manager_v1_create(m_sWLDisplay);
|
||||
wlr_gamma_control_manager_v1_create(m_sWLDisplay);
|
||||
wlr_primary_selection_v1_device_manager_create(m_sWLDisplay);
|
||||
wlr_viewporter_create(m_sWLDisplay);
|
||||
// wlr_viewporter_create(m_sWLDisplay); // TODO: support wl_viewporter
|
||||
|
||||
m_sWLROutputLayout = wlr_output_layout_create();
|
||||
|
||||
m_sWLROutputPowerMgr = wlr_output_power_manager_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRScene = wlr_scene_create();
|
||||
wlr_scene_attach_output_layout(m_sWLRScene, m_sWLROutputLayout);
|
||||
|
||||
m_sWLRXDGShell = wlr_xdg_shell_create(m_sWLDisplay, 3);
|
||||
m_sWLRXDGShell = wlr_xdg_shell_create(m_sWLDisplay, 4);
|
||||
|
||||
m_sWLRCursor = wlr_cursor_create();
|
||||
wlr_cursor_attach_output_layout(m_sWLRCursor, m_sWLROutputLayout);
|
||||
@@ -195,6 +199,7 @@ void CCompositor::initAllSignals() {
|
||||
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
|
||||
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
||||
addWLSignal(&m_sWLRIdleInhibitMgr->events.new_inhibitor, &Events::listen_newIdleInhibitor, m_sWLRIdleInhibitMgr, "WLRIdleInhibitMgr");
|
||||
addWLSignal(&m_sWLROutputPowerMgr->events.set_mode, &Events::listen_powerMgrSetMode, m_sWLROutputPowerMgr, "PowerMgr");
|
||||
if (m_sWLRSession)
|
||||
addWLSignal(&m_sWLRSession->events.active, &Events::listen_sessionActive, m_sWLRSession, "Session");
|
||||
}
|
||||
@@ -265,10 +270,9 @@ void CCompositor::startCompositor() {
|
||||
// firefox wont detect wl
|
||||
setenv("MOZ_ENABLE_WAYLAND", "1", 1);
|
||||
|
||||
initAllSignals();
|
||||
setenv("XDG_CURRENT_DESKTOP", "Hyprland", 1);
|
||||
|
||||
// Set XDG_CURRENT_DESKTOP to our compositor's name
|
||||
setenv("XDG_CURRENT_DESKTOP", "hyprland", true);
|
||||
initAllSignals();
|
||||
|
||||
m_szWLDisplaySocket = wl_display_add_socket_auto(m_sWLDisplay);
|
||||
|
||||
@@ -298,7 +302,7 @@ void CCompositor::startCompositor() {
|
||||
wl_display_run(m_sWLDisplay);
|
||||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorFromID(const int& id) {
|
||||
CMonitor* CCompositor::getMonitorFromID(const int& id) {
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (m->ID == (uint64_t)id) {
|
||||
return m.get();
|
||||
@@ -308,7 +312,7 @@ SMonitor* CCompositor::getMonitorFromID(const int& id) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorFromName(const std::string& name) {
|
||||
CMonitor* CCompositor::getMonitorFromName(const std::string& name) {
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (m->szName == name) {
|
||||
return m.get();
|
||||
@@ -318,18 +322,18 @@ SMonitor* CCompositor::getMonitorFromName(const std::string& name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorFromCursor() {
|
||||
CMonitor* CCompositor::getMonitorFromCursor() {
|
||||
const auto COORDS = Vector2D(m_sWLRCursor->x, m_sWLRCursor->y);
|
||||
|
||||
return getMonitorFromVector(COORDS);
|
||||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
|
||||
CMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
|
||||
const auto OUTPUT = wlr_output_layout_output_at(m_sWLROutputLayout, point.x, point.y);
|
||||
|
||||
if (!OUTPUT) {
|
||||
float bestDistance = 0.f;
|
||||
SMonitor* pBestMon = nullptr;
|
||||
CMonitor* pBestMon = nullptr;
|
||||
|
||||
for (auto& m : m_vMonitors) {
|
||||
float dist = vecToRectDistanceSquared(point, m->vecPosition, m->vecPosition + m->vecSize);
|
||||
@@ -582,7 +586,7 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
|
||||
return PSURFACE->surface;
|
||||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) {
|
||||
CMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) {
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (m->output == out) {
|
||||
return m.get();
|
||||
@@ -808,7 +812,7 @@ int CCompositor::getWindowsOnWorkspace(const int& id) {
|
||||
|
||||
CWindow* CCompositor::getFirstWindowOnWorkspace(const int& id) {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == id)
|
||||
if (w->m_iWorkspaceID == id && w->m_bIsMapped && !w->m_bHidden)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
@@ -924,6 +928,10 @@ void CCompositor::cleanupFadingOut(const int& monid) {
|
||||
if (ls->monitorID != monid)
|
||||
continue;
|
||||
|
||||
// mark blur for recalc
|
||||
if (ls->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || ls->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(getMonitorFromID(monid));
|
||||
|
||||
if (ls->fadingOut && ls->readyToDelete && !ls->alpha.isBeingAnimated()) {
|
||||
g_pHyprOpenGL->m_mLayerFramebuffers[ls].release();
|
||||
g_pHyprOpenGL->m_mLayerFramebuffers.erase(ls);
|
||||
@@ -1145,12 +1153,12 @@ CWindow* CCompositor::getConstraintWindow(SMouse* pMouse) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
||||
CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
||||
const auto POSA = m_pLastMonitor->vecPosition;
|
||||
const auto SIZEA = m_pLastMonitor->vecSize;
|
||||
|
||||
auto longestIntersect = -1;
|
||||
SMonitor* longestIntersectMonitor = nullptr;
|
||||
CMonitor* longestIntersectMonitor = nullptr;
|
||||
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (m.get() == m_pLastMonitor)
|
||||
@@ -1281,7 +1289,7 @@ int CCompositor::getNextAvailableMonitorID() {
|
||||
return topID + 1;
|
||||
}
|
||||
|
||||
void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, SMonitor* pMonitor) {
|
||||
void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMonitor) {
|
||||
|
||||
// We trust the workspace and monitor to be correct.
|
||||
|
||||
@@ -1416,7 +1424,7 @@ void CCompositor::updateWorkspaceWindowDecos(const int& id) {
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::scheduleFrameForMonitor(SMonitor* pMonitor) {
|
||||
void CCompositor::scheduleFrameForMonitor(CMonitor* pMonitor) {
|
||||
if ((m_sWLRSession && !m_sWLRSession->active) || !m_bSessionActive)
|
||||
return;
|
||||
|
||||
@@ -1476,4 +1484,37 @@ CWindow* CCompositor::getWindowByRegex(const std::string& regexp) {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
// warpCursorTo should only be used for warps that
|
||||
// should be disabled with no_cursor_warps
|
||||
|
||||
static auto *const PNOWARPS = &g_pConfigManager->getConfigValuePtr("general:no_cursor_warps")->intValue;
|
||||
|
||||
if (*PNOWARPS)
|
||||
return;
|
||||
|
||||
wlr_cursor_warp(m_sWLRCursor, m_sSeat.mouse->mouse, pos.x, pos.y);
|
||||
}
|
||||
|
||||
|
@@ -65,6 +65,7 @@ public:
|
||||
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
||||
wlr_idle_inhibit_manager_v1* m_sWLRIdleInhibitMgr;
|
||||
wlr_pointer_gestures_v1* m_sWLRPointerGestures;
|
||||
wlr_output_power_manager_v1* m_sWLROutputPowerMgr;
|
||||
// ------------------------------------------------- //
|
||||
|
||||
|
||||
@@ -72,7 +73,8 @@ public:
|
||||
std::string m_szInstanceSignature = "";
|
||||
std::string m_szCurrentSplash = "error";
|
||||
|
||||
std::vector<std::unique_ptr<SMonitor>> m_vMonitors;
|
||||
std::vector<std::shared_ptr<CMonitor>> m_vMonitors;
|
||||
std::vector<std::shared_ptr<CMonitor>> m_vRealMonitors; // for all monitors, even those turned off
|
||||
std::vector<std::unique_ptr<CWindow>> m_vWindows;
|
||||
std::deque<std::unique_ptr<CWindow>> m_dUnmanagedX11Windows;
|
||||
std::vector<std::unique_ptr<SXDGPopup>> m_vXDGPopups;
|
||||
@@ -86,19 +88,20 @@ public:
|
||||
|
||||
wlr_surface* m_pLastFocus = nullptr;
|
||||
CWindow* m_pLastWindow = nullptr;
|
||||
SMonitor* m_pLastMonitor = nullptr;
|
||||
CMonitor* m_pLastMonitor = nullptr;
|
||||
|
||||
SSeat m_sSeat;
|
||||
|
||||
bool m_bReadyToProcess = false;
|
||||
bool m_bSessionActive = true;
|
||||
bool m_bDPMSStateON = true;
|
||||
|
||||
// ------------------------------------------------- //
|
||||
|
||||
SMonitor* getMonitorFromID(const int&);
|
||||
SMonitor* getMonitorFromName(const std::string&);
|
||||
SMonitor* getMonitorFromCursor();
|
||||
SMonitor* getMonitorFromVector(const Vector2D&);
|
||||
CMonitor* getMonitorFromID(const int&);
|
||||
CMonitor* getMonitorFromName(const std::string&);
|
||||
CMonitor* getMonitorFromCursor();
|
||||
CMonitor* getMonitorFromVector(const Vector2D&);
|
||||
void removeWindowFromVectorSafe(CWindow*);
|
||||
void focusWindow(CWindow*, wlr_surface* pSurface = nullptr);
|
||||
void focusSurface(wlr_surface*, CWindow* pWindowOwner = nullptr);
|
||||
@@ -111,7 +114,7 @@ public:
|
||||
wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl);
|
||||
CWindow* windowFromCursor();
|
||||
CWindow* windowFloatingFromCursor();
|
||||
SMonitor* getMonitorFromOutput(wlr_output*);
|
||||
CMonitor* getMonitorFromOutput(wlr_output*);
|
||||
CWindow* getWindowForPopup(wlr_xdg_popup*);
|
||||
CWindow* getWindowFromSurface(wlr_surface*);
|
||||
bool isWorkspaceVisible(const int&);
|
||||
@@ -135,26 +138,29 @@ public:
|
||||
int getNextAvailableNamedWorkspace();
|
||||
bool isPointOnAnyMonitor(const Vector2D&);
|
||||
CWindow* getConstraintWindow(SMouse*);
|
||||
SMonitor* getMonitorInDirection(const char&);
|
||||
CMonitor* getMonitorInDirection(const char&);
|
||||
void updateAllWindowsAnimatedDecorationValues();
|
||||
void updateWindowAnimatedDecorationValues(CWindow*);
|
||||
void moveWindowToWorkspace(CWindow*, const std::string&);
|
||||
int getNextAvailableMonitorID();
|
||||
void moveWorkspaceToMonitor(CWorkspace*, SMonitor*);
|
||||
void moveWorkspaceToMonitor(CWorkspace*, CMonitor*);
|
||||
bool workspaceIDOutOfBounds(const int&);
|
||||
void setWindowFullscreen(CWindow*, bool, eFullscreenMode);
|
||||
void moveUnmanagedX11ToWindows(CWindow*);
|
||||
CWindow* getX11Parent(CWindow*);
|
||||
void scheduleFrameForMonitor(SMonitor*);
|
||||
void scheduleFrameForMonitor(CMonitor*);
|
||||
void addToFadingOutSafe(SLayerSurface*);
|
||||
void addToFadingOutSafe(CWindow*);
|
||||
CWindow* getWindowByRegex(const std::string&);
|
||||
void warpCursorTo(const Vector2D&);
|
||||
|
||||
std::string explicitConfigPath;
|
||||
|
||||
void startHyprCtlTick();
|
||||
|
||||
private:
|
||||
void initAllSignals();
|
||||
void setRandomSplash();
|
||||
void setRandomSplash();
|
||||
};
|
||||
|
||||
|
||||
|
@@ -3,12 +3,12 @@
|
||||
#include "render/decorations/CHyprDropShadowDecoration.hpp"
|
||||
|
||||
CWindow::CWindow() {
|
||||
m_vRealPosition.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*) this, AVARDAMAGE_ENTIRE);
|
||||
m_vRealSize.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_cRealBorderColor.create(AVARTYPE_COLOR, &g_pConfigManager->getConfigValuePtr("animations:borders_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:borders")->intValue, &g_pConfigManager->getConfigValuePtr("animations:borders_curve")->strValue, (void*)this, AVARDAMAGE_BORDER);
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_fActiveInactiveAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_cRealShadowColor.create(AVARTYPE_COLOR, &g_pConfigManager->getConfigValuePtr("animations:borders_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:borders")->intValue, &g_pConfigManager->getConfigValuePtr("animations:borders_curve")->strValue, (void*)this, AVARDAMAGE_SHADOW);
|
||||
m_vRealPosition.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*) this, AVARDAMAGE_ENTIRE);
|
||||
m_vRealSize.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_cRealBorderColor.create(AVARTYPE_COLOR, g_pConfigManager->getAnimationPropertyConfig("border"), (void*)this, AVARDAMAGE_BORDER);
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_fActiveInactiveAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_cRealShadowColor.create(AVARTYPE_COLOR, g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), (void*)this, AVARDAMAGE_SHADOW);
|
||||
|
||||
m_dWindowDecorations.emplace_back(std::make_unique<CHyprDropShadowDecoration>(this)); // put the shadow so it's the first deco (has to be rendered first)
|
||||
}
|
||||
|
@@ -10,12 +10,16 @@
|
||||
struct SWindowSpecialRenderData {
|
||||
float alpha = 1.f;
|
||||
float alphaInactive = -1.f; // -1 means unset
|
||||
|
||||
// set by the layout
|
||||
bool rounding = true;
|
||||
};
|
||||
|
||||
struct SWindowAdditionalConfigData {
|
||||
std::string animationStyle = "";
|
||||
int rounding = -1; // -1 means no
|
||||
bool forceNoBlur = false;
|
||||
bool forceOpaque = false;
|
||||
};
|
||||
|
||||
class CWindow {
|
||||
@@ -50,6 +54,10 @@ public:
|
||||
CAnimatedVariable m_vRealPosition;
|
||||
CAnimatedVariable m_vRealSize;
|
||||
|
||||
// for not spamming the protocols
|
||||
Vector2D m_vReportedPosition;
|
||||
Vector2D m_vReportedSize;
|
||||
|
||||
// this is used for pseudotiling
|
||||
bool m_bIsPseudotiled = false;
|
||||
Vector2D m_vPseudoSize = Vector2D(0,0);
|
||||
|
@@ -12,6 +12,7 @@
|
||||
|
||||
CConfigManager::CConfigManager() {
|
||||
setDefaultVars();
|
||||
setDefaultAnimationVars();
|
||||
|
||||
std::string CONFIGPATH;
|
||||
if (g_pCompositor->explicitConfigPath == "") {
|
||||
@@ -44,12 +45,15 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["general:col.active_border"].intValue = 0xffffffff;
|
||||
configValues["general:col.inactive_border"].intValue = 0xff444444;
|
||||
configValues["general:cursor_inactive_timeout"].intValue = 0;
|
||||
configValues["general:no_cursor_warps"].intValue = 0;
|
||||
|
||||
configValues["general:layout"].strValue = "dwindle";
|
||||
|
||||
configValues["misc:disable_hyprland_logo"].intValue = 0;
|
||||
configValues["misc:disable_splash_rendering"].intValue = 0;
|
||||
configValues["misc:no_vfr"].intValue = 1;
|
||||
configValues["misc:damage_entire_on_snapshot"].intValue = 0;
|
||||
configValues["misc:mouse_move_enables_dpms"].intValue = 0;
|
||||
|
||||
configValues["debug:int"].intValue = 0;
|
||||
configValues["debug:log_damage"].intValue = 0;
|
||||
@@ -63,6 +67,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["decoration:blur_size"].intValue = 8;
|
||||
configValues["decoration:blur_passes"].intValue = 1;
|
||||
configValues["decoration:blur_ignore_opacity"].intValue = 0;
|
||||
configValues["decoration:blur_new_optimizations"].intValue = 0;
|
||||
configValues["decoration:active_opacity"].floatValue = 1;
|
||||
configValues["decoration:inactive_opacity"].floatValue = 1;
|
||||
configValues["decoration:fullscreen_opacity"].floatValue = 1;
|
||||
@@ -83,10 +88,12 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["dwindle:preserve_split"].intValue = 0;
|
||||
configValues["dwindle:special_scale_factor"].floatValue = 0.8f;
|
||||
configValues["dwindle:split_width_multiplier"].floatValue = 1.0f;
|
||||
configValues["dwindle:no_gaps_when_only"].intValue = 0;
|
||||
|
||||
configValues["master:special_scale_factor"].floatValue = 0.8f;
|
||||
configValues["master:new_is_master"].intValue = 1;
|
||||
configValues["master:new_on_top"].intValue = 0;
|
||||
configValues["master:no_gaps_when_only"].intValue = 0;
|
||||
|
||||
configValues["animations:enabled"].intValue = 1;
|
||||
configValues["animations:speed"].floatValue = 7.f;
|
||||
@@ -127,6 +134,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["input:touchpad:drag_lock"].intValue = 0;
|
||||
|
||||
configValues["binds:pass_mouse_when_bound"].intValue = 1;
|
||||
configValues["binds:scroll_event_delay"].intValue = 300;
|
||||
|
||||
configValues["gestures:workspace_swipe"].intValue = 0;
|
||||
configValues["gestures:workspace_swipe_fingers"].intValue = 3;
|
||||
@@ -160,6 +168,56 @@ void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
|
||||
cfgValues["drag_lock"].intValue = 0;
|
||||
}
|
||||
|
||||
void CConfigManager::setDefaultAnimationVars() {
|
||||
if (isFirstLaunch) {
|
||||
INITANIMCFG("global");
|
||||
INITANIMCFG("windows");
|
||||
INITANIMCFG("fade");
|
||||
INITANIMCFG("border");
|
||||
INITANIMCFG("workspaces");
|
||||
|
||||
// windows
|
||||
INITANIMCFG("windowsIn");
|
||||
INITANIMCFG("windowsOut");
|
||||
INITANIMCFG("windowsMove");
|
||||
|
||||
// fade
|
||||
INITANIMCFG("fadeIn");
|
||||
INITANIMCFG("fadeOut");
|
||||
INITANIMCFG("fadeSwitch");
|
||||
INITANIMCFG("fadeShadow");
|
||||
|
||||
// border
|
||||
|
||||
// workspaces
|
||||
}
|
||||
|
||||
// init the values
|
||||
animationConfig["global"] = {
|
||||
false,
|
||||
"default",
|
||||
"",
|
||||
8.f,
|
||||
1,
|
||||
&animationConfig["general"],
|
||||
nullptr
|
||||
};
|
||||
|
||||
CREATEANIMCFG("windows", "global");
|
||||
CREATEANIMCFG("fade", "global");
|
||||
CREATEANIMCFG("border", "global");
|
||||
CREATEANIMCFG("workspaces", "global");
|
||||
|
||||
CREATEANIMCFG("windowsIn", "windows");
|
||||
CREATEANIMCFG("windowsOut", "windows");
|
||||
CREATEANIMCFG("windowsMove", "windows");
|
||||
|
||||
CREATEANIMCFG("fadeIn", "fade");
|
||||
CREATEANIMCFG("fadeOut", "fade");
|
||||
CREATEANIMCFG("fadeSwitch", "fade");
|
||||
CREATEANIMCFG("fadeShadow", "fade");
|
||||
}
|
||||
|
||||
void CConfigManager::init() {
|
||||
|
||||
loadConfigLoadVars();
|
||||
@@ -388,11 +446,15 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
return;
|
||||
}
|
||||
|
||||
newrule.resolution.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
|
||||
newrule.resolution.y = stoi(curitem.substr(curitem.find_first_of('x') + 1, curitem.find_first_of('@')));
|
||||
if (curitem.find("pref") == 0) {
|
||||
newrule.resolution = Vector2D();
|
||||
} else {
|
||||
newrule.resolution.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
|
||||
newrule.resolution.y = stoi(curitem.substr(curitem.find_first_of('x') + 1, curitem.find_first_of('@')));
|
||||
|
||||
if (curitem.contains("@"))
|
||||
newrule.refreshRate = stof(curitem.substr(curitem.find_first_of('@') + 1));
|
||||
if (curitem.contains("@"))
|
||||
newrule.refreshRate = stof(curitem.substr(curitem.find_first_of('@') + 1));
|
||||
}
|
||||
|
||||
nextItem();
|
||||
|
||||
@@ -456,6 +518,17 @@ void CConfigManager::handleBezier(const std::string& command, const std::string&
|
||||
g_pAnimationManager->addBezierWithName(bezierName, Vector2D(p1x, p1y), Vector2D(p2x, p2y));
|
||||
}
|
||||
|
||||
void CConfigManager::setAnimForChildren(SAnimationPropertyConfig *const ANIM) {
|
||||
for (auto& [name, anim] : animationConfig) {
|
||||
if (anim.pParentAnimation == ANIM && !anim.overriden) {
|
||||
// if a child isnt overriden, set the values of the parent
|
||||
anim.pValues = ANIM->pValues;
|
||||
|
||||
setAnimForChildren(&anim);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void CConfigManager::handleAnimation(const std::string& command, const std::string& args) {
|
||||
std::string curitem = "";
|
||||
|
||||
@@ -479,33 +552,44 @@ void CConfigManager::handleAnimation(const std::string& command, const std::stri
|
||||
|
||||
// anim name
|
||||
const auto ANIMNAME = curitem;
|
||||
const auto ANIMMASTERSETTING = configValues.find("animations:" + ANIMNAME);
|
||||
|
||||
const auto PANIM = animationConfig.find(ANIMNAME);
|
||||
|
||||
if (ANIMMASTERSETTING == configValues.end()) {
|
||||
Debug::log(ERR, "Anim %s doesnt exist", ANIMNAME.c_str());
|
||||
parseError = "Animation " + ANIMNAME + " does not exist";
|
||||
if (PANIM == animationConfig.end()) {
|
||||
parseError = "no such animation";
|
||||
return;
|
||||
}
|
||||
|
||||
PANIM->second.overriden = true;
|
||||
PANIM->second.pValues = &PANIM->second;
|
||||
|
||||
nextItem();
|
||||
|
||||
// on/off
|
||||
configSetValueSafe("animations:" + ANIMNAME, curitem);
|
||||
PANIM->second.internalEnabled = curitem == "1";
|
||||
|
||||
nextItem();
|
||||
|
||||
// Speed
|
||||
configSetValueSafe("animations:" + ANIMNAME + "_speed", curitem);
|
||||
// speed
|
||||
if (isNumber(curitem, true)) {
|
||||
PANIM->second.internalSpeed = std::stof(curitem);
|
||||
} else {
|
||||
PANIM->second.internalSpeed = 10.f;
|
||||
parseError = "Invalid speed";
|
||||
}
|
||||
|
||||
nextItem();
|
||||
|
||||
// curve
|
||||
configSetValueSafe("animations:" + ANIMNAME + "_curve", curitem);
|
||||
PANIM->second.internalBezier = curitem;
|
||||
|
||||
nextItem();
|
||||
|
||||
// style
|
||||
configSetValueSafe("animations:" + ANIMNAME + "_style", curitem);
|
||||
PANIM->second.internalStyle = curitem;
|
||||
|
||||
// now, check for children, recursively
|
||||
setAnimForChildren(&PANIM->second);
|
||||
}
|
||||
|
||||
void CConfigManager::handleBind(const std::string& command, const std::string& value) {
|
||||
@@ -604,6 +688,7 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str
|
||||
&& RULE != "nofocus"
|
||||
&& RULE != "noblur"
|
||||
&& RULE != "center"
|
||||
&& RULE != "opaque"
|
||||
&& RULE != "fullscreen"
|
||||
&& RULE.find("animation") != 0
|
||||
&& RULE.find("rounding") != 0
|
||||
@@ -848,6 +933,7 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
configDynamicVars.clear();
|
||||
deviceConfigs.clear();
|
||||
m_dBlurLSNamespaces.clear();
|
||||
setDefaultAnimationVars(); // reset anims
|
||||
|
||||
// paths
|
||||
configPaths.clear();
|
||||
@@ -957,6 +1043,9 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
// and they'll be taken care of in the newMonitor event
|
||||
if (!isFirstLaunch) {
|
||||
m_bWantsMonitorReload = true;
|
||||
|
||||
// check
|
||||
ensureDPMS();
|
||||
}
|
||||
|
||||
// Update window border colors
|
||||
@@ -965,6 +1054,10 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
// update layout
|
||||
g_pLayoutManager->switchToLayout(configValues["general:layout"].strValue);
|
||||
|
||||
// mark blur dirty
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(m.get());
|
||||
|
||||
// Force the compositor to fully re-render all monitors
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
m->forceFullFrames = 2;
|
||||
@@ -1027,7 +1120,11 @@ SConfigValue CConfigManager::getConfigValueSafeDevice(const std::string& dev, co
|
||||
// fallback if not set explicitly
|
||||
if (!copy.set) {
|
||||
for (auto& cv : configValues) {
|
||||
if (cv.first.find(val) == cv.first.length() - val.length()) {
|
||||
auto foundIt = cv.first.find(val);
|
||||
if (foundIt == std::string::npos)
|
||||
continue;
|
||||
|
||||
if (foundIt == cv.first.length() - val.length()) {
|
||||
copy = cv.second;
|
||||
}
|
||||
}
|
||||
@@ -1211,3 +1308,18 @@ bool CConfigManager::shouldBlurLS(const std::string& ns) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CConfigManager::ensureDPMS() {
|
||||
for (auto& rm : g_pCompositor->m_vRealMonitors) {
|
||||
auto rule = getMonitorRuleFor(rm->szName);
|
||||
|
||||
if (rule.disabled == rm->m_bEnabled) {
|
||||
rm->m_pThisWrap = &rm;
|
||||
g_pHyprRenderer->applyMonitorRule(rm.get(), &rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAnimationPropertyConfig* CConfigManager::getAnimationPropertyConfig(const std::string& name) {
|
||||
return &animationConfig[name];
|
||||
}
|
||||
|
@@ -16,6 +16,9 @@
|
||||
|
||||
#define STRVAL_EMPTY "[[EMPTY]]"
|
||||
|
||||
#define INITANIMCFG(name) animationConfig[name] = {}
|
||||
#define CREATEANIMCFG(name, parent) animationConfig[name] = {false, "", "", 0.f, -1, &animationConfig["global"], &animationConfig[parent]}
|
||||
|
||||
struct SConfigValue {
|
||||
int64_t intValue = -1;
|
||||
float floatValue = -1;
|
||||
@@ -47,6 +50,18 @@ struct SWindowRule {
|
||||
std::string szValue;
|
||||
};
|
||||
|
||||
struct SAnimationPropertyConfig {
|
||||
bool overriden = true;
|
||||
|
||||
std::string internalBezier = "";
|
||||
std::string internalStyle = "";
|
||||
float internalSpeed = 0.f;
|
||||
int internalEnabled = -1;
|
||||
|
||||
SAnimationPropertyConfig* pValues = nullptr;
|
||||
SAnimationPropertyConfig* pParentAnimation = nullptr;
|
||||
};
|
||||
|
||||
class CConfigManager {
|
||||
public:
|
||||
CConfigManager();
|
||||
@@ -84,6 +99,8 @@ public:
|
||||
|
||||
std::string parseKeyword(const std::string&, const std::string&, bool dynamic = false);
|
||||
|
||||
SAnimationPropertyConfig* getAnimationPropertyConfig(const std::string&);
|
||||
|
||||
private:
|
||||
std::deque<std::string> configPaths; // stores all the config paths
|
||||
std::unordered_map<std::string, time_t> configModifyTimes; // stores modify times
|
||||
@@ -91,6 +108,8 @@ private:
|
||||
std::unordered_map<std::string, SConfigValue> configValues;
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, SConfigValue>> deviceConfigs; // stores device configs
|
||||
|
||||
std::unordered_map<std::string, SAnimationPropertyConfig> animationConfig; // stores all the animations with their set values
|
||||
|
||||
std::string configCurrentPath;
|
||||
|
||||
std::string currentCategory = ""; // For storing the category of the current item
|
||||
@@ -110,7 +129,11 @@ private:
|
||||
|
||||
// internal methods
|
||||
void setDefaultVars();
|
||||
void setDefaultAnimationVars();
|
||||
void setDeviceDefaultVars(const std::string&);
|
||||
void ensureDPMS();
|
||||
|
||||
void setAnimForChildren(SAnimationPropertyConfig *const);
|
||||
|
||||
void applyUserDefinedVars(std::string&, const size_t);
|
||||
void loadConfigLoadVars();
|
||||
|
@@ -17,7 +17,7 @@ OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
|
||||
|
||||
autogenerated=1 # remove this line to get rid of the warning on top.
|
||||
|
||||
monitor=,1920x1080@60,0x0,1
|
||||
monitor=,preferred,0x0,1
|
||||
|
||||
input {
|
||||
kb_layout=
|
||||
@@ -61,8 +61,8 @@ decoration {
|
||||
animations {
|
||||
enabled=1
|
||||
animation=windows,1,7,default
|
||||
animation=borders,1,10,default
|
||||
animation=fadein,1,10,default
|
||||
animation=border,1,10,default
|
||||
animation=fade,1,10,default
|
||||
animation=workspaces,1,6,default
|
||||
}
|
||||
|
||||
@@ -70,6 +70,10 @@ dwindle {
|
||||
pseudotile=0 # enable pseudotiling on dwindle
|
||||
}
|
||||
|
||||
gestures {
|
||||
workspace_swipe=no
|
||||
}
|
||||
|
||||
# example window rules
|
||||
# for windows named/classed as abc and xyz
|
||||
#windowrule=move 69 420,abc
|
||||
|
@@ -592,16 +592,7 @@ void HyprCtl::tickHyprCtl() {
|
||||
}
|
||||
|
||||
std::string getRequestFromThread(std::string rq) {
|
||||
// we need to do something to wake hyprland up if VFR is enabled
|
||||
|
||||
static auto *const PNOVFR = &g_pConfigManager->getConfigValuePtr("misc:no_vfr")->intValue;
|
||||
|
||||
// TODO: is this safe...?
|
||||
// this might be a race condition
|
||||
// tested with 2 instances of `watch -n 0.1 hyprctl splash` and seems to not crash so I'll take that as a yes
|
||||
if (!*PNOVFR)
|
||||
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_vMonitors.front().get());
|
||||
|
||||
|
||||
while (HyprCtl::request != "" || HyprCtl::requestMade || HyprCtl::requestReady) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include "HyprDebugOverlay.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
void CHyprMonitorDebugOverlay::renderData(SMonitor* pMonitor, float µs) {
|
||||
void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float µs) {
|
||||
m_dLastRenderTimes.push_back(µs / 1000.f);
|
||||
|
||||
if (m_dLastRenderTimes.size() > (long unsigned int)pMonitor->refreshRate)
|
||||
@@ -11,7 +11,7 @@ void CHyprMonitorDebugOverlay::renderData(SMonitor* pMonitor, float µs) {
|
||||
m_pMonitor = pMonitor;
|
||||
}
|
||||
|
||||
void CHyprMonitorDebugOverlay::renderDataNoOverlay(SMonitor* pMonitor, float µs) {
|
||||
void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float µs) {
|
||||
m_dLastRenderTimesNoOverlay.push_back(µs / 1000.f);
|
||||
|
||||
if (m_dLastRenderTimesNoOverlay.size() > (long unsigned int)pMonitor->refreshRate)
|
||||
@@ -21,7 +21,7 @@ void CHyprMonitorDebugOverlay::renderDataNoOverlay(SMonitor* pMonitor, float µs
|
||||
m_pMonitor = pMonitor;
|
||||
}
|
||||
|
||||
void CHyprMonitorDebugOverlay::frameData(SMonitor* pMonitor) {
|
||||
void CHyprMonitorDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||
m_dLastFrametimes.push_back(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - m_tpLastFrame).count() / 1000.f);
|
||||
|
||||
if (m_dLastFrametimes.size() > (long unsigned int)pMonitor->refreshRate)
|
||||
@@ -126,15 +126,15 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||
return yOffset - offset;
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::renderData(SMonitor* pMonitor, float µs) {
|
||||
void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float µs) {
|
||||
m_mMonitorOverlays[pMonitor].renderData(pMonitor, µs);
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::renderDataNoOverlay(SMonitor* pMonitor, float µs) {
|
||||
void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float µs) {
|
||||
m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, µs);
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::frameData(SMonitor* pMonitor) {
|
||||
void CHyprDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||
m_mMonitorOverlays[pMonitor].frameData(pMonitor);
|
||||
}
|
||||
|
||||
|
@@ -11,16 +11,16 @@ class CHyprMonitorDebugOverlay {
|
||||
public:
|
||||
int draw(int offset);
|
||||
|
||||
void renderData(SMonitor* pMonitor, float µs);
|
||||
void renderDataNoOverlay(SMonitor* pMonitor, float µs);
|
||||
void frameData(SMonitor* pMonitor);
|
||||
void renderData(CMonitor* pMonitor, float µs);
|
||||
void renderDataNoOverlay(CMonitor* pMonitor, float µs);
|
||||
void frameData(CMonitor* pMonitor);
|
||||
|
||||
private:
|
||||
std::deque<float> m_dLastFrametimes;
|
||||
std::deque<float> m_dLastRenderTimes;
|
||||
std::deque<float> m_dLastRenderTimesNoOverlay;
|
||||
std::chrono::high_resolution_clock::time_point m_tpLastFrame;
|
||||
SMonitor* m_pMonitor = nullptr;
|
||||
CMonitor* m_pMonitor = nullptr;
|
||||
wlr_box m_wbLastDrawnBox;
|
||||
};
|
||||
|
||||
@@ -28,13 +28,13 @@ class CHyprDebugOverlay {
|
||||
public:
|
||||
|
||||
void draw();
|
||||
void renderData(SMonitor*, float µs);
|
||||
void renderDataNoOverlay(SMonitor*, float µs);
|
||||
void frameData(SMonitor*);
|
||||
void renderData(CMonitor*, float µs);
|
||||
void renderDataNoOverlay(CMonitor*, float µs);
|
||||
void frameData(CMonitor*);
|
||||
|
||||
private:
|
||||
|
||||
std::unordered_map<SMonitor*, CHyprMonitorDebugOverlay> m_mMonitorOverlays;
|
||||
std::unordered_map<CMonitor*, CHyprMonitorDebugOverlay> m_mMonitorOverlays;
|
||||
|
||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||
cairo_t* m_pCairo = nullptr;
|
||||
|
@@ -130,4 +130,7 @@ namespace Events {
|
||||
LISTENER(pinchBegin);
|
||||
LISTENER(pinchUpdate);
|
||||
LISTENER(pinchEnd);
|
||||
|
||||
// Power
|
||||
LISTENER(powerMgrSetMode);
|
||||
};
|
@@ -31,7 +31,7 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
|
||||
WLRLAYERSURFACE->output = PMONITOR->output;
|
||||
}
|
||||
|
||||
const auto PMONITOR = (SMonitor*)g_pCompositor->getMonitorFromOutput(WLRLAYERSURFACE->output);
|
||||
const auto PMONITOR = (CMonitor*)g_pCompositor->getMonitorFromOutput(WLRLAYERSURFACE->output);
|
||||
SLayerSurface* layerSurface = PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].emplace_back(std::make_unique<SLayerSurface>()).get();
|
||||
|
||||
layerSurface->szNamespace = WLRLAYERSURFACE->_namespace;
|
||||
@@ -108,6 +108,9 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
|
||||
layersurface->layerSurface->mapped = true;
|
||||
layersurface->mapped = true;
|
||||
|
||||
// anim
|
||||
layersurface->alpha.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn"));
|
||||
|
||||
// fix if it changed its mon
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output);
|
||||
|
||||
@@ -168,6 +171,9 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
||||
return;
|
||||
}
|
||||
|
||||
// anim
|
||||
layersurface->alpha.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut"));
|
||||
|
||||
// make a snapshot and start fade
|
||||
g_pHyprOpenGL->makeLayerSnapshot(layersurface);
|
||||
layersurface->alpha = 0.f;
|
||||
@@ -213,6 +219,9 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
|
||||
if (layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd
|
||||
|
||||
wlr_box geomFixed = {layersurface->geometry.x, layersurface->geometry.y, layersurface->geometry.width, layersurface->geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
|
||||
@@ -245,6 +254,9 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
|
||||
}
|
||||
|
||||
layersurface->layer = layersurface->layerSurface->current.layer;
|
||||
|
||||
if (layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd
|
||||
}
|
||||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||
|
@@ -163,4 +163,15 @@ void Events::listener_sessionActive(wl_listener* listener, void* data) {
|
||||
Debug::log(LOG, "Session got activated!");
|
||||
|
||||
g_pCompositor->m_bSessionActive = true;
|
||||
}
|
||||
|
||||
void Events::listener_powerMgrSetMode(wl_listener* listener, void* data) {
|
||||
Debug::log(LOG, "PowerMgr set mode!");
|
||||
|
||||
const auto EVENT = (wlr_output_power_v1_set_mode_event*)data;
|
||||
|
||||
wlr_output_enable(EVENT->output, EVENT->mode == 1);
|
||||
|
||||
if (!wlr_output_commit(EVENT->output))
|
||||
Debug::log(ERR, "Couldn't set power mode");
|
||||
}
|
@@ -15,7 +15,7 @@
|
||||
// //
|
||||
// --------------------------------------------------------- //
|
||||
|
||||
SMonitor* pMostHzMonitor = nullptr;
|
||||
CMonitor* pMostHzMonitor = nullptr;
|
||||
|
||||
void Events::listener_change(wl_listener* listener, void* data) {
|
||||
// layout got changed, let's update monitors.
|
||||
@@ -58,117 +58,34 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get monitor rule that matches
|
||||
SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(OUTPUT->name);
|
||||
|
||||
// if it's disabled, disable and ignore
|
||||
if (monitorRule.disabled) {
|
||||
wlr_output_enable(OUTPUT, 0);
|
||||
wlr_output_commit(OUTPUT);
|
||||
|
||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromName(std::string(OUTPUT->name)); PMONITOR) {
|
||||
listener_monitorDestroy(nullptr, PMONITOR->output);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PNEWMONITOR = g_pCompositor->m_vMonitors.emplace_back(std::make_unique<SMonitor>()).get();
|
||||
|
||||
PNEWMONITOR->output = OUTPUT;
|
||||
PNEWMONITOR->ID = g_pCompositor->getNextAvailableMonitorID();
|
||||
PNEWMONITOR->szName = OUTPUT->name;
|
||||
// add it to real
|
||||
const auto PNEWMONITORWRAP = &g_pCompositor->m_vRealMonitors.emplace_back(std::make_shared<CMonitor>());
|
||||
const auto PNEWMONITOR = PNEWMONITORWRAP->get();
|
||||
|
||||
wlr_output_init_render(OUTPUT, g_pCompositor->m_sWLRAllocator, g_pCompositor->m_sWLRRenderer);
|
||||
|
||||
wlr_output_set_scale(OUTPUT, 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
|
||||
PNEWMONITOR->output = OUTPUT;
|
||||
PNEWMONITOR->m_pThisWrap = PNEWMONITORWRAP;
|
||||
|
||||
wlr_output_enable_adaptive_sync(OUTPUT, 1);
|
||||
PNEWMONITOR->onConnect(false);
|
||||
|
||||
// create it in the arr
|
||||
PNEWMONITOR->vecPosition = monitorRule.offset;
|
||||
PNEWMONITOR->vecSize = monitorRule.resolution;
|
||||
PNEWMONITOR->refreshRate = monitorRule.refreshRate;
|
||||
|
||||
PNEWMONITOR->hyprListener_monitorFrame.initCallback(&OUTPUT->events.frame, &Events::listener_monitorFrame, PNEWMONITOR);
|
||||
PNEWMONITOR->hyprListener_monitorDestroy.initCallback(&OUTPUT->events.destroy, &Events::listener_monitorDestroy, PNEWMONITOR);
|
||||
|
||||
wlr_output_enable(OUTPUT, 1);
|
||||
|
||||
// TODO: this doesn't seem to set the X and Y correctly,
|
||||
// wlr_output_layout_output_coords returns invalid values, I think...
|
||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, OUTPUT, monitorRule.offset.x, monitorRule.offset.y);
|
||||
|
||||
// set mode, also applies
|
||||
g_pHyprRenderer->applyMonitorRule(PNEWMONITOR, &monitorRule, true);
|
||||
|
||||
Debug::log(LOG, "Added new monitor with name %s at %i,%i with size %ix%i, pointer %x", OUTPUT->name, (int)monitorRule.offset.x, (int)monitorRule.offset.y, (int)monitorRule.resolution.x, (int)monitorRule.resolution.y, OUTPUT);
|
||||
|
||||
PNEWMONITOR->damage = wlr_output_damage_create(PNEWMONITOR->output);
|
||||
|
||||
// add a WLR workspace group
|
||||
PNEWMONITOR->pWLRWorkspaceGroupHandle = wlr_ext_workspace_group_handle_v1_create(g_pCompositor->m_sWLREXTWorkspaceMgr);
|
||||
wlr_ext_workspace_group_handle_v1_output_enter(PNEWMONITOR->pWLRWorkspaceGroupHandle, PNEWMONITOR->output);
|
||||
|
||||
// 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, PNEWMONITOR);
|
||||
PNEWMONITOR->activeWorkspace = PNEWWORKSPACE->m_iID;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PNEWMONITOR->ID);
|
||||
PNEWWORKSPACE->startAnim(true,true,true);
|
||||
} else {
|
||||
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(PNEWMONITOR->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;
|
||||
}
|
||||
|
||||
PNEWMONITOR->activeWorkspace = PNEWWORKSPACE->m_iID;
|
||||
PNEWMONITOR->scale = monitorRule.scale;
|
||||
|
||||
PNEWMONITOR->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 (!pMostHzMonitor || monitorRule.refreshRate > pMostHzMonitor->refreshRate)
|
||||
if (!pMostHzMonitor || PNEWMONITOR->refreshRate > pMostHzMonitor->refreshRate)
|
||||
pMostHzMonitor = PNEWMONITOR;
|
||||
|
||||
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
|
||||
g_pCompositor->m_pLastMonitor = PNEWMONITOR;
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", PNEWMONITOR->szName});
|
||||
|
||||
// ready to process cuz we have a monitor
|
||||
g_pCompositor->m_bReadyToProcess = true;
|
||||
}
|
||||
|
||||
void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
SMonitor* const PMONITOR = (SMonitor*)owner;
|
||||
CMonitor* const PMONITOR = (CMonitor*)owner;
|
||||
|
||||
if ((g_pCompositor->m_sWLRSession && !g_pCompositor->m_sWLRSession->active) || !g_pCompositor->m_bSessionActive) {
|
||||
Debug::log(WARN, "Attempted to render frame on inactive session!");
|
||||
return; // cannot draw on session inactive (different tty)
|
||||
}
|
||||
|
||||
if (!PMONITOR->m_bEnabled)
|
||||
return;
|
||||
|
||||
static std::chrono::high_resolution_clock::time_point startRender = std::chrono::high_resolution_clock::now();
|
||||
static std::chrono::high_resolution_clock::time_point startRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
@@ -181,6 +98,9 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
|
||||
static int damageBlinkCleanup = 0; // because double-buffered
|
||||
|
||||
if (!*PDAMAGEBLINK)
|
||||
damageBlinkCleanup = 0;
|
||||
|
||||
if (*PDEBUGOVERLAY == 1) {
|
||||
startRender = std::chrono::high_resolution_clock::now();
|
||||
g_pDebugOverlay->frameData(PMONITOR);
|
||||
@@ -195,6 +115,9 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
Debug::log(LOG, "NoFrameSchedule hit for %s.", PMONITOR->szName.c_str());
|
||||
}
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
||||
|
||||
if (PMONITOR->framesToSkip > 10)
|
||||
PMONITOR->framesToSkip = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,8 +126,6 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
g_pCompositor->sanityCheckWorkspaces();
|
||||
g_pAnimationManager->tick();
|
||||
|
||||
HyprCtl::tickHyprCtl(); // so that we dont get that race condition multithread bullshit
|
||||
|
||||
g_pConfigManager->dispatchExecOnce(); // We exec-once when at least one monitor starts refreshing, meaning stuff has init'd
|
||||
|
||||
if (g_pConfigManager->m_bWantsMonitorReload)
|
||||
@@ -232,6 +153,8 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->preRender(PMONITOR);
|
||||
|
||||
if (!wlr_output_damage_attach_render(PMONITOR->damage, &hasChanged, &damage)){
|
||||
Debug::log(ERR, "Couldn't attach render to display %s ???", PMONITOR->szName.c_str());
|
||||
return;
|
||||
@@ -274,8 +197,12 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
}
|
||||
}
|
||||
|
||||
if (PMONITOR->forceFullFrames > 0)
|
||||
if (PMONITOR->forceFullFrames > 0) {
|
||||
PMONITOR->forceFullFrames -= 1;
|
||||
if (PMONITOR->forceFullFrames > 10)
|
||||
PMONITOR->forceFullFrames = 0;
|
||||
}
|
||||
|
||||
|
||||
// TODO: this is getting called with extents being 0,0,0,0 should it be?
|
||||
// potentially can save on resources.
|
||||
@@ -352,7 +279,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
void Events::listener_monitorDestroy(void* owner, void* data) {
|
||||
const auto OUTPUT = (wlr_output*)data;
|
||||
|
||||
SMonitor* pMonitor = nullptr;
|
||||
CMonitor* pMonitor = nullptr;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->szName == OUTPUT->name) {
|
||||
@@ -364,46 +291,14 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
||||
if (!pMonitor)
|
||||
return;
|
||||
|
||||
// Cleanup everything. Move windows back, snap cursor, shit.
|
||||
const auto BACKUPMON = g_pCompositor->m_vMonitors.front().get();
|
||||
pMonitor->onDisconnect();
|
||||
|
||||
if (!BACKUPMON) {
|
||||
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
|
||||
g_pCompositor->cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto BACKUPWORKSPACE = BACKUPMON->activeWorkspace > 0 ? std::to_string(BACKUPMON->activeWorkspace) : "name:" + g_pCompositor->getWorkspaceByID(BACKUPMON->activeWorkspace)->m_szName;
|
||||
|
||||
// snap cursor
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f, BACKUPMON->vecPosition.y + BACKUPMON->vecTransformedSize.y / 2.f);
|
||||
|
||||
// move workspaces
|
||||
std::deque<CWorkspace*> wspToMove;
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
if (w->m_iMonitorID == pMonitor->ID) {
|
||||
wspToMove.push_back(w.get());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& w : wspToMove) {
|
||||
g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON);
|
||||
w->startAnim(true, true, true);
|
||||
}
|
||||
|
||||
pMonitor->activeWorkspace = -1;
|
||||
|
||||
g_pCompositor->m_vWorkspaces.erase(std::remove_if(g_pCompositor->m_vWorkspaces.begin(), g_pCompositor->m_vWorkspaces.end(), [&](std::unique_ptr<CWorkspace>& el) { return el->m_iMonitorID == pMonitor->ID; }));
|
||||
|
||||
Debug::log(LOG, "Removed monitor %s!", pMonitor->szName.c_str());
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitorremoved", pMonitor->szName});
|
||||
|
||||
g_pCompositor->m_vMonitors.erase(std::remove_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](std::unique_ptr<SMonitor>& el) { return el.get() == pMonitor; }));
|
||||
// cleanup
|
||||
g_pCompositor->m_vRealMonitors.erase(std::remove_if(g_pCompositor->m_vRealMonitors.begin(), g_pCompositor->m_vRealMonitors.end(), [&](std::shared_ptr<CMonitor>& el) { return el.get() == pMonitor; }));
|
||||
|
||||
if (pMostHzMonitor == pMonitor) {
|
||||
int mostHz = 0;
|
||||
SMonitor* pMonitorMostHz = nullptr;
|
||||
CMonitor* pMonitorMostHz = nullptr;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->refreshRate > mostHz) {
|
||||
|
@@ -55,10 +55,11 @@ void createNewPopup(wlr_xdg_popup* popup, SXDGPopup* pHyprPopup) {
|
||||
pHyprPopup->hyprListener_mapPopupXDG.initCallback(&popup->base->events.map, &Events::listener_mapPopupXDG, pHyprPopup, "HyprPopup");
|
||||
pHyprPopup->hyprListener_unmapPopupXDG.initCallback(&popup->base->events.unmap, &Events::listener_unmapPopupXDG, pHyprPopup, "HyprPopup");
|
||||
pHyprPopup->hyprListener_newPopupFromPopupXDG.initCallback(&popup->base->events.new_popup, &Events::listener_newPopupFromPopupXDG, pHyprPopup, "HyprPopup");
|
||||
pHyprPopup->hyprListener_commitPopupXDG.initCallback(&popup->base->surface->events.commit, &Events::listener_commitPopupXDG, pHyprPopup, "HyprPopup");
|
||||
|
||||
const auto PMONITOR = g_pCompositor->m_pLastMonitor;
|
||||
|
||||
wlr_box box = {.x = PMONITOR->vecPosition.x - pHyprPopup->lx, .y = PMONITOR->vecPosition.y - pHyprPopup->ly, .width = PMONITOR->vecSize.x, .height = PMONITOR->vecSize.y};
|
||||
wlr_box box = {.x = PMONITOR->vecPosition.x - pHyprPopup->lx, .y = PMONITOR->vecPosition.y - pHyprPopup->ly, .width = PMONITOR->vecTransformedSize.x, .height = PMONITOR->vecTransformedSize.y};
|
||||
|
||||
wlr_xdg_popup_unconstrain_from_box(popup, &box);
|
||||
|
||||
@@ -103,9 +104,12 @@ void Events::listener_newPopupXDG(void* owner, void* data) {
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(PWINDOW->m_uSurface.xdg, &geom);
|
||||
|
||||
PNEWPOPUP->popup = WLRPOPUP;
|
||||
PNEWPOPUP->lx = PWINDOW->m_vRealPosition.goalv().x;
|
||||
PNEWPOPUP->ly = PWINDOW->m_vRealPosition.goalv().y;
|
||||
PNEWPOPUP->lx = PWINDOW->m_vRealPosition.goalv().x - geom.x;
|
||||
PNEWPOPUP->ly = PWINDOW->m_vRealPosition.goalv().y - geom.y;
|
||||
PNEWPOPUP->parentWindow = PWINDOW;
|
||||
PNEWPOPUP->monitor = PMONITOR;
|
||||
createNewPopup(WLRPOPUP, PNEWPOPUP);
|
||||
@@ -144,6 +148,11 @@ void Events::listener_mapPopupXDG(void* owner, void* data) {
|
||||
|
||||
PPOPUP->pSurfaceTree = SubsurfaceTree::createTreeRoot(PPOPUP->popup->base->surface, addPopupGlobalCoords, PPOPUP, PPOPUP->parentWindow);
|
||||
|
||||
int lx = 0, ly = 0;
|
||||
addPopupGlobalCoords(PPOPUP, &lx, &ly);
|
||||
|
||||
g_pHyprRenderer->damageBox(lx, ly, PPOPUP->popup->current.geometry.width, PPOPUP->popup->current.geometry.width);
|
||||
|
||||
Debug::log(LOG, "XDG Popup got assigned a surfaceTreeNode %x", PPOPUP->pSurfaceTree);
|
||||
}
|
||||
|
||||
@@ -155,9 +164,23 @@ void Events::listener_unmapPopupXDG(void* owner, void* data) {
|
||||
|
||||
SubsurfaceTree::destroySurfaceTree(PPOPUP->pSurfaceTree);
|
||||
|
||||
int lx = 0, ly = 0;
|
||||
addPopupGlobalCoords(PPOPUP, &lx, &ly);
|
||||
|
||||
g_pHyprRenderer->damageBox(lx, ly, PPOPUP->popup->current.geometry.width, PPOPUP->popup->current.geometry.width);
|
||||
|
||||
PPOPUP->pSurfaceTree = nullptr;
|
||||
}
|
||||
|
||||
void Events::listener_commitPopupXDG(void* owner, void* data) {
|
||||
SXDGPopup* PPOPUP = (SXDGPopup*)owner;
|
||||
|
||||
int lx = 0, ly = 0;
|
||||
addPopupGlobalCoords(PPOPUP, &lx, &ly);
|
||||
|
||||
g_pHyprRenderer->damageSurface(PPOPUP->popup->base->surface, lx, ly);
|
||||
}
|
||||
|
||||
void Events::listener_destroyPopupXDG(void* owner, void* data) {
|
||||
SXDGPopup* PPOPUP = (SXDGPopup*)owner;
|
||||
|
||||
|
@@ -29,6 +29,20 @@ void addViewCoords(void* pWindow, int* x, int* y) {
|
||||
}
|
||||
}
|
||||
|
||||
int setAnimToMove(void* data) {
|
||||
const auto PWINDOW = (CWindow*)data;
|
||||
|
||||
auto *const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove");
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return 0;
|
||||
|
||||
PWINDOW->m_vRealPosition.setConfig(PANIMCFG);
|
||||
PWINDOW->m_vRealSize.setConfig(PANIMCFG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Events::listener_mapWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
@@ -44,7 +58,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_bReadyToDelete = false;
|
||||
PWINDOW->m_bFadingOut = false;
|
||||
PWINDOW->m_szTitle = g_pXWaylandManager->getTitle(PWINDOW);
|
||||
PWINDOW->m_fAlpha = 255.f;
|
||||
|
||||
if (PWINDOW->m_iX11Type == 2)
|
||||
g_pCompositor->moveUnmanagedX11ToWindows(PWINDOW);
|
||||
@@ -140,6 +153,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_sAdditionalConfigData.forceNoBlur = true;
|
||||
} else if (r.szRule == "fullscreen") {
|
||||
requestsFullscreen = true;
|
||||
} else if (r.szRule == "opaque") {
|
||||
PWINDOW->m_sAdditionalConfigData.forceOpaque = true;
|
||||
} else if (r.szRule.find("rounding") == 0) {
|
||||
try {
|
||||
PWINDOW->m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
||||
@@ -208,6 +223,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY);
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
||||
|
||||
PWINDOW->m_bHidden = false;
|
||||
} catch (...) {
|
||||
Debug::log(LOG, "Rule size failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str());
|
||||
}
|
||||
@@ -223,6 +240,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
Debug::log(LOG, "Rule move, applying to window %x", PWINDOW);
|
||||
|
||||
PWINDOW->m_vRealPosition = Vector2D(POSX, POSY) + PMONITOR->vecPosition;
|
||||
|
||||
PWINDOW->m_bHidden = false;
|
||||
} catch (...) {
|
||||
Debug::log(LOG, "Rule move failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str());
|
||||
}
|
||||
@@ -271,6 +290,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
// do the animation thing
|
||||
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, false);
|
||||
PWINDOW->m_fAlpha.setValueAndWarp(0.f);
|
||||
PWINDOW->m_fAlpha = 255.f;
|
||||
|
||||
const auto TIMER = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, setAnimToMove, PWINDOW);
|
||||
wl_event_source_timer_update(TIMER, PWINDOW->m_vRealPosition.getDurationLeftMs() + 5);
|
||||
|
||||
if (workspaceSilent) {
|
||||
// move the window
|
||||
@@ -343,8 +367,6 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
}
|
||||
|
||||
PWINDOW->m_fAlpha = 0.f;
|
||||
|
||||
PWINDOW->m_bMappedX11 = false;
|
||||
|
||||
// remove the fullscreen window status from workspace if we closed it
|
||||
@@ -380,7 +402,10 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
|
||||
if (!PWINDOW->m_bX11DoesntWantBorders) // don't animate out if they weren't animated in.
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.vec() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it
|
||||
|
||||
// anims
|
||||
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, true);
|
||||
PWINDOW->m_fAlpha = 0.f;
|
||||
|
||||
// Destroy Foreign Toplevel
|
||||
wlr_foreign_toplevel_handle_v1_destroy(PWINDOW->m_phForeignToplevel);
|
||||
@@ -498,6 +523,11 @@ void Events::listener_configureX11(void* owner, void* data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (E->width > 1 && E->height > 1)
|
||||
PWINDOW->m_bHidden = false;
|
||||
else
|
||||
PWINDOW->m_bHidden = true;
|
||||
|
||||
PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(E->x, E->y));
|
||||
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(E->width, E->height));
|
||||
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec();
|
||||
@@ -514,6 +544,8 @@ void Events::listener_configureX11(void* owner, void* data) {
|
||||
g_pInputManager->refocus();
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
}
|
||||
|
||||
void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
@@ -525,6 +557,11 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
const auto POS = PWINDOW->m_vRealPosition.goalv();
|
||||
const auto SIZ = PWINDOW->m_vRealSize.goalv();
|
||||
|
||||
if (PWINDOW->m_uSurface.xwayland->width > 1 && PWINDOW->m_uSurface.xwayland->height > 1)
|
||||
PWINDOW->m_bHidden = false;
|
||||
else
|
||||
PWINDOW->m_bHidden = true;
|
||||
|
||||
if (abs(std::floor(POS.x) - PWINDOW->m_uSurface.xwayland->x) > 2 || abs(std::floor(POS.y) - PWINDOW->m_uSurface.xwayland->y) > 2 || abs(std::floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2) {
|
||||
Debug::log(LOG, "Unmanaged window %x requests geometry update to %i %i %i %i", PWINDOW, (int)PWINDOW->m_uSurface.xwayland->x, (int)PWINDOW->m_uSurface.xwayland->y, (int)PWINDOW->m_uSurface.xwayland->width, (int)PWINDOW->m_uSurface.xwayland->height);
|
||||
|
||||
@@ -566,10 +603,10 @@ void Events::listener_newXDGSurface(wl_listener* listener, void* data) {
|
||||
// A window got opened
|
||||
const auto XDGSURFACE = (wlr_xdg_surface*)data;
|
||||
|
||||
Debug::log(LOG, "New XDG Surface created. (class: %s)", XDGSURFACE->toplevel->app_id);
|
||||
|
||||
if (XDGSURFACE->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
||||
return; // TODO: handle?
|
||||
return;
|
||||
|
||||
Debug::log(LOG, "New XDG Surface created. (class: %s)", XDGSURFACE->toplevel->app_id);
|
||||
|
||||
const auto PNEWWINDOW = g_pCompositor->m_vWindows.emplace_back(std::make_unique<CWindow>()).get();
|
||||
PNEWWINDOW->m_uSurface.xdg = XDGSURFACE;
|
||||
|
@@ -1,25 +1,24 @@
|
||||
#include "AnimatedVariable.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
|
||||
CAnimatedVariable::CAnimatedVariable() {
|
||||
; // dummy var
|
||||
}
|
||||
|
||||
void CAnimatedVariable::create(ANIMATEDVARTYPE type, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow, AVARDAMAGEPOLICY policy) {
|
||||
void CAnimatedVariable::create(ANIMATEDVARTYPE type, SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy) {
|
||||
m_eVarType = type;
|
||||
m_eDamagePolicy = policy;
|
||||
m_pSpeed = speed;
|
||||
m_pEnabled = enabled;
|
||||
m_pConfig = pAnimConfig;
|
||||
m_pWindow = pWindow;
|
||||
m_pBezier = pBezier;
|
||||
|
||||
g_pAnimationManager->m_lAnimatedVariables.push_back(this);
|
||||
|
||||
m_bDummy = false;
|
||||
}
|
||||
|
||||
void CAnimatedVariable::create(ANIMATEDVARTYPE type, std::any val, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow, AVARDAMAGEPOLICY policy) {
|
||||
create(type, speed, enabled, pBezier, pWindow, policy);
|
||||
void CAnimatedVariable::create(ANIMATEDVARTYPE type, std::any val, SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy) {
|
||||
create(type, pAnimConfig, pWindow, policy);
|
||||
|
||||
try {
|
||||
switch (type) {
|
||||
@@ -57,4 +56,8 @@ CAnimatedVariable::~CAnimatedVariable() {
|
||||
|
||||
void CAnimatedVariable::unregister() {
|
||||
g_pAnimationManager->m_lAnimatedVariables.remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@@ -20,13 +20,14 @@ enum AVARDAMAGEPOLICY {
|
||||
class CAnimationManager;
|
||||
class CWorkspace;
|
||||
struct SLayerSurface;
|
||||
struct SAnimationPropertyConfig;
|
||||
|
||||
class CAnimatedVariable {
|
||||
public:
|
||||
CAnimatedVariable(); // dummy var
|
||||
|
||||
void create(ANIMATEDVARTYPE, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow, AVARDAMAGEPOLICY);
|
||||
void create(ANIMATEDVARTYPE, std::any val, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow, AVARDAMAGEPOLICY);
|
||||
void create(ANIMATEDVARTYPE, SAnimationPropertyConfig*, void* pWindow, AVARDAMAGEPOLICY);
|
||||
void create(ANIMATEDVARTYPE, std::any val, SAnimationPropertyConfig*, void* pWindow, AVARDAMAGEPOLICY);
|
||||
|
||||
~CAnimatedVariable();
|
||||
|
||||
@@ -156,6 +157,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void setConfig(SAnimationPropertyConfig* pConfig) {
|
||||
m_pConfig = pConfig;
|
||||
}
|
||||
|
||||
SAnimationPropertyConfig* getConfig() {
|
||||
return m_pConfig;
|
||||
}
|
||||
|
||||
int getDurationLeftMs();
|
||||
|
||||
private:
|
||||
|
||||
Vector2D m_vValue = Vector2D(0,0);
|
||||
@@ -170,15 +181,12 @@ private:
|
||||
float m_fBegun = 0;
|
||||
CColor m_cBegun;
|
||||
|
||||
float* m_pSpeed = nullptr;
|
||||
int64_t* m_pEnabled = nullptr;
|
||||
|
||||
// owners
|
||||
void* m_pWindow = nullptr;
|
||||
void* m_pWorkspace = nullptr;
|
||||
void* m_pLayer = nullptr;
|
||||
|
||||
std::string* m_pBezier = nullptr;
|
||||
SAnimationPropertyConfig* m_pConfig = nullptr;
|
||||
|
||||
bool m_bDummy = true;
|
||||
|
||||
|
166
src/helpers/Monitor.cpp
Normal file
166
src/helpers/Monitor.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
#include "Monitor.hpp"
|
||||
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
void CMonitor::onConnect(bool noRule) {
|
||||
// get monitor rule that matches
|
||||
SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(output->name);
|
||||
|
||||
hyprListener_monitorFrame.initCallback(&output->events.frame, &Events::listener_monitorFrame, this);
|
||||
hyprListener_monitorDestroy.initCallback(&output->events.destroy, &Events::listener_monitorDestroy, this);
|
||||
|
||||
// if it's disabled, disable and ignore
|
||||
if (monitorRule.disabled) {
|
||||
wlr_output_enable(output, 0);
|
||||
wlr_output_commit(output);
|
||||
|
||||
hyprListener_monitorFrame.removeCallback();
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
m_bEnabled = true;
|
||||
|
||||
ID = g_pCompositor->getNextAvailableMonitorID();
|
||||
szName = output->name;
|
||||
|
||||
wlr_output_set_scale(output, 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_enable_adaptive_sync(output, 1);
|
||||
|
||||
// create it in the arr
|
||||
vecPosition = monitorRule.offset;
|
||||
vecSize = monitorRule.resolution;
|
||||
refreshRate = monitorRule.refreshRate;
|
||||
|
||||
wlr_output_enable(output, 1);
|
||||
|
||||
// TODO: this doesn't seem to set the X and Y correctly,
|
||||
// wlr_output_layout_output_coords returns invalid values, I think...
|
||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, output, monitorRule.offset.x, monitorRule.offset.y);
|
||||
|
||||
// set mode, also applies
|
||||
if (!noRule)
|
||||
g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true);
|
||||
|
||||
Debug::log(LOG, "Added new monitor with name %s at %i,%i with size %ix%i, pointer %x", output->name, (int)monitorRule.offset.x, (int)monitorRule.offset.y, (int)monitorRule.resolution.x, (int)monitorRule.resolution.y, output);
|
||||
|
||||
damage = wlr_output_damage_create(output);
|
||||
|
||||
// add a WLR workspace group
|
||||
if (!pWLRWorkspaceGroupHandle) {
|
||||
pWLRWorkspaceGroupHandle = wlr_ext_workspace_group_handle_v1_create(g_pCompositor->m_sWLREXTWorkspaceMgr);
|
||||
}
|
||||
|
||||
wlr_ext_workspace_group_handle_v1_output_enter(pWLRWorkspaceGroupHandle, output);
|
||||
|
||||
// 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;
|
||||
scale = monitorRule.scale;
|
||||
|
||||
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
|
||||
g_pCompositor->m_pLastMonitor = this;
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", szName});
|
||||
}
|
||||
|
||||
void CMonitor::onDisconnect() {
|
||||
// Cleanup everything. Move windows back, snap cursor, shit.
|
||||
CMonitor* BACKUPMON = nullptr;
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m.get() != this) {
|
||||
BACKUPMON = m.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!BACKUPMON) {
|
||||
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
|
||||
g_pCompositor->cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
m_bEnabled = false;
|
||||
|
||||
hyprListener_monitorFrame.removeCallback();
|
||||
|
||||
const auto BACKUPWORKSPACE = BACKUPMON->activeWorkspace > 0 ? std::to_string(BACKUPMON->activeWorkspace) : "name:" + g_pCompositor->getWorkspaceByID(BACKUPMON->activeWorkspace)->m_szName;
|
||||
|
||||
// snap cursor
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f, BACKUPMON->vecPosition.y + BACKUPMON->vecTransformedSize.y / 2.f);
|
||||
|
||||
// move workspaces
|
||||
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_damage_destroy(damage);
|
||||
|
||||
wlr_output_layout_remove(g_pCompositor->m_sWLROutputLayout, output);
|
||||
|
||||
wlr_output_enable(output, false);
|
||||
|
||||
wlr_output_commit(output);
|
||||
|
||||
g_pCompositor->m_vWorkspaces.erase(std::remove_if(g_pCompositor->m_vWorkspaces.begin(), g_pCompositor->m_vWorkspaces.end(), [&](std::unique_ptr<CWorkspace>& el) { return el->m_iMonitorID == ID; }));
|
||||
|
||||
Debug::log(LOG, "Removed monitor %s!", szName.c_str());
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitorremoved", szName});
|
||||
|
||||
g_pCompositor->m_vMonitors.erase(std::remove_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](std::shared_ptr<CMonitor>& el) { return el.get() == this; }));
|
||||
}
|
@@ -7,7 +7,8 @@
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
struct SMonitor {
|
||||
class CMonitor {
|
||||
public:
|
||||
Vector2D vecPosition = Vector2D(0,0);
|
||||
Vector2D vecSize = Vector2D(0,0);
|
||||
Vector2D vecPixelSize = Vector2D(0,0);
|
||||
@@ -51,9 +52,16 @@ struct SMonitor {
|
||||
wlr_ext_workspace_group_handle_v1* pWLRWorkspaceGroupHandle = nullptr;
|
||||
|
||||
|
||||
// methods
|
||||
void onConnect(bool noRule);
|
||||
void onDisconnect();
|
||||
|
||||
std::shared_ptr<CMonitor>* m_pThisWrap = nullptr;
|
||||
bool m_bEnabled = false;
|
||||
|
||||
// For the list lookup
|
||||
|
||||
bool operator==(const SMonitor& rhs) {
|
||||
bool operator==(const CMonitor& rhs) {
|
||||
return vecPosition == rhs.vecPosition && vecSize == rhs.vecSize && szName == rhs.szName;
|
||||
}
|
||||
};
|
@@ -2,6 +2,6 @@
|
||||
#include "../config/ConfigManager.hpp"
|
||||
|
||||
SLayerSurface::SLayerSurface() {
|
||||
alpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, nullptr, AVARDAMAGE_ENTIRE);
|
||||
alpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), nullptr, AVARDAMAGE_ENTIRE);
|
||||
alpha.m_pLayer = this;
|
||||
}
|
@@ -143,18 +143,19 @@ struct SConstraint {
|
||||
}
|
||||
};
|
||||
|
||||
struct SMonitor;
|
||||
class CMonitor;
|
||||
|
||||
struct SXDGPopup {
|
||||
CWindow* parentWindow = nullptr;
|
||||
SXDGPopup* parentPopup = nullptr;
|
||||
wlr_xdg_popup* popup = nullptr;
|
||||
SMonitor* monitor = nullptr;
|
||||
CMonitor* monitor = nullptr;
|
||||
|
||||
DYNLISTENER(newPopupFromPopupXDG);
|
||||
DYNLISTENER(destroyPopupXDG);
|
||||
DYNLISTENER(mapPopupXDG);
|
||||
DYNLISTENER(unmapPopupXDG);
|
||||
DYNLISTENER(commitPopupXDG);
|
||||
|
||||
double lx;
|
||||
double ly;
|
||||
@@ -270,5 +271,5 @@ struct SSwipeGesture {
|
||||
float avgSpeed = 0;
|
||||
int speedPoints = 0;
|
||||
|
||||
SMonitor* pMonitor = nullptr;
|
||||
CMonitor* pMonitor = nullptr;
|
||||
};
|
@@ -26,9 +26,9 @@ CWorkspace::CWorkspace(int monitorID, std::string name, bool special) {
|
||||
}
|
||||
|
||||
m_vRenderOffset.m_pWorkspace = this;
|
||||
m_vRenderOffset.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:workspaces_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces")->intValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces_curve")->strValue, nullptr, AVARDAMAGE_ENTIRE);
|
||||
m_vRenderOffset.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("workspaces"), nullptr, AVARDAMAGE_ENTIRE);
|
||||
m_fAlpha.m_pWorkspace = this;
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:workspaces_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces")->intValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces_curve")->strValue, nullptr, AVARDAMAGE_ENTIRE);
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("workspaces"), nullptr, AVARDAMAGE_ENTIRE);
|
||||
m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
g_pEventManager->postEvent({"createworkspace", m_szName}, true);
|
||||
@@ -49,7 +49,7 @@ CWorkspace::~CWorkspace() {
|
||||
}
|
||||
|
||||
void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
const auto ANIMSTYLE = g_pConfigManager->getString("animations:workspaces_style");
|
||||
const auto ANIMSTYLE = m_fAlpha.m_pConfig->pValues->internalStyle;
|
||||
|
||||
if (ANIMSTYLE == "fade") {
|
||||
m_vRenderOffset.setValueAndWarp(Vector2D(0, 0)); // fix a bug, if switching from slide -> fade.
|
||||
|
@@ -93,6 +93,7 @@ extern "C" {
|
||||
#include <wlr/types/wlr_xdg_foreign_v1.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_v2.h>
|
||||
#include <wlr/types/wlr_pointer_gestures_v1.h>
|
||||
#include <wlr/types/wlr_output_power_management_v1.h>
|
||||
}
|
||||
|
||||
#undef class
|
||||
|
@@ -63,7 +63,7 @@ void SDwindleNodeData::getAllChildrenRecursive(std::deque<SDwindleNodeData*>* pD
|
||||
int CHyprDwindleLayout::getNodesOnWorkspace(const int& id) {
|
||||
int no = 0;
|
||||
for (auto& n : m_lDwindleNodesData) {
|
||||
if (n.workspaceID == id)
|
||||
if (n.workspaceID == id && n.valid)
|
||||
++no;
|
||||
}
|
||||
return no;
|
||||
@@ -99,7 +99,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) {
|
||||
if (pNode->isNode)
|
||||
return;
|
||||
|
||||
SMonitor* PMONITOR = nullptr;
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
|
||||
if (pNode->workspaceID == SPECIAL_WORKSPACE_ID) {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
@@ -137,9 +137,24 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) {
|
||||
PWINDOW->m_vSize = pNode->size;
|
||||
PWINDOW->m_vPosition = pNode->position;
|
||||
|
||||
static auto *const PNOGAPSWHENONLY = &g_pConfigManager->getConfigValuePtr("dwindle:no_gaps_when_only")->intValue;
|
||||
|
||||
auto calcPos = PWINDOW->m_vPosition + Vector2D(BORDERSIZE, BORDERSIZE);
|
||||
auto calcSize = PWINDOW->m_vSize - Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE);
|
||||
|
||||
if (*PNOGAPSWHENONLY && PWINDOW->m_iWorkspaceID != SPECIAL_WORKSPACE_ID && getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1) {
|
||||
PWINDOW->m_vRealPosition = calcPos;
|
||||
PWINDOW->m_vRealSize = calcSize;
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
|
||||
PWINDOW->m_sSpecialRenderData.rounding = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PWINDOW->m_sSpecialRenderData.rounding = true;
|
||||
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? GAPSOUT : GAPSIN,
|
||||
DISPLAYTOP ? GAPSOUT : GAPSIN);
|
||||
|
||||
@@ -378,6 +393,9 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
PPARENT->valid = false;
|
||||
PNODE->valid = false;
|
||||
|
||||
if (PSIBLING->pParent)
|
||||
PSIBLING->pParent->recalcSizePosRecursive();
|
||||
else
|
||||
|
@@ -30,6 +30,8 @@ struct SDwindleNodeData {
|
||||
|
||||
float splitRatio = 1.f;
|
||||
|
||||
bool valid = true;
|
||||
|
||||
// For list lookup
|
||||
bool operator==(const SDwindleNodeData& rhs) {
|
||||
return pWindow == rhs.pWindow && workspaceID == rhs.workspaceID && position == rhs.position && size == rhs.size && pParent == rhs.pParent && children[0] == rhs.children[0] && children[1] == rhs.children[1];
|
||||
|
@@ -35,6 +35,11 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) {
|
||||
const auto PWINDOWSURFACE = g_pXWaylandManager->getWindowSurface(pWindow);
|
||||
pWindow->m_vRealSize = Vector2D(PWINDOWSURFACE->current.width, PWINDOWSURFACE->current.height);
|
||||
|
||||
if ((desiredGeometry.width <= 1 || desiredGeometry.height <= 1) && pWindow->m_bIsX11) { // XDG windows should be fine. TODO: check for weird atoms?
|
||||
pWindow->m_bHidden = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// reject any windows with size <= 5x5
|
||||
if (pWindow->m_vRealSize.goalv().x <= 5 || pWindow->m_vRealSize.goalv().y <= 5) {
|
||||
@@ -101,6 +106,9 @@ void IHyprLayout::onBeginDragWindow() {
|
||||
return;
|
||||
}
|
||||
|
||||
DRAGGINGWINDOW->m_vRealPosition.setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove"));
|
||||
DRAGGINGWINDOW->m_vRealSize.setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove"));
|
||||
|
||||
DRAGGINGWINDOW->m_bDraggingTiled = false;
|
||||
|
||||
if (!DRAGGINGWINDOW->m_bIsFloating) {
|
||||
|
@@ -171,7 +171,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
|
||||
}
|
||||
|
||||
void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
SMonitor* PMONITOR = nullptr;
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
|
||||
if (pNode->workspaceID == SPECIAL_WORKSPACE_ID) {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
@@ -206,14 +206,27 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
static auto *const PNOGAPSWHENONLY = &g_pConfigManager->getConfigValuePtr("master:no_gaps_when_only")->intValue;
|
||||
|
||||
PWINDOW->m_vSize = pNode->size;
|
||||
PWINDOW->m_vPosition = pNode->position;
|
||||
|
||||
// TODO: special
|
||||
|
||||
auto calcPos = PWINDOW->m_vPosition + Vector2D(BORDERSIZE, BORDERSIZE);
|
||||
auto calcSize = PWINDOW->m_vSize - Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE);
|
||||
|
||||
if (*PNOGAPSWHENONLY && PWINDOW->m_iWorkspaceID != SPECIAL_WORKSPACE_ID && getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1) {
|
||||
PWINDOW->m_vRealPosition = calcPos;
|
||||
PWINDOW->m_vRealSize = calcSize;
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
|
||||
PWINDOW->m_sSpecialRenderData.rounding = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PWINDOW->m_sSpecialRenderData.rounding = true;
|
||||
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? GAPSOUT : GAPSIN,
|
||||
DISPLAYTOP ? GAPSOUT : GAPSIN);
|
||||
|
||||
@@ -406,7 +419,110 @@ void CHyprMasterLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
||||
}
|
||||
|
||||
std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
|
||||
return "";
|
||||
auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) {
|
||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||
Vector2D middle = PWINDOWTOCHANGETO->m_vRealPosition.goalv() + PWINDOWTOCHANGETO->m_vRealSize.goalv() / 2.f;
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, middle.x, middle.y);
|
||||
};
|
||||
|
||||
if (message == "swapwithmaster") {
|
||||
|
||||
const auto PWINDOW = header.pWindow;
|
||||
|
||||
if (!isWindowTiled(PWINDOW))
|
||||
return 0;
|
||||
|
||||
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
|
||||
if (!PMASTER || PMASTER->pWindow == PWINDOW)
|
||||
return 0;
|
||||
|
||||
switchWindows(PWINDOW, PMASTER->pWindow);
|
||||
|
||||
switchToWindow(PWINDOW);
|
||||
|
||||
return 0;
|
||||
} else if (message == "cyclenext") {
|
||||
const auto PWINDOW = header.pWindow;
|
||||
|
||||
if (!isWindowTiled(PWINDOW))
|
||||
return 0;
|
||||
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
|
||||
if (PNODE->isMaster) {
|
||||
// focus the first non master
|
||||
for (auto n : m_lMasterNodesData) {
|
||||
if (n.pWindow != PWINDOW && n.workspaceID == PWINDOW->m_iWorkspaceID) {
|
||||
switchToWindow(n.pWindow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// focus next
|
||||
bool reached = false;
|
||||
bool found = false;
|
||||
for (auto n : m_lMasterNodesData) {
|
||||
if (n.pWindow == PWINDOW) {
|
||||
reached = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n.workspaceID == PWINDOW->m_iWorkspaceID && reached) {
|
||||
switchToWindow(n.pWindow);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
|
||||
if (PMASTER)
|
||||
switchToWindow(PMASTER->pWindow);
|
||||
}
|
||||
}
|
||||
} else if (message == "cycleprev") {
|
||||
const auto PWINDOW = header.pWindow;
|
||||
|
||||
if (!isWindowTiled(PWINDOW))
|
||||
return 0;
|
||||
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
|
||||
if (PNODE->isMaster) {
|
||||
// focus the first non master
|
||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||
if (it->pWindow != PWINDOW && it->workspaceID == PWINDOW->m_iWorkspaceID) {
|
||||
switchToWindow(it->pWindow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// focus next
|
||||
bool reached = false;
|
||||
bool found = false;
|
||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||
if (it->pWindow == PWINDOW) {
|
||||
reached = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (it->workspaceID == PWINDOW->m_iWorkspaceID && reached) {
|
||||
switchToWindow(it->pWindow);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
|
||||
if (PMASTER)
|
||||
switchToWindow(PMASTER->pWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CHyprMasterLayout::onEnable() {
|
||||
|
@@ -28,14 +28,10 @@ void CAnimationManager::tick() {
|
||||
if (!*PANIMENABLED)
|
||||
animationsDisabled = true;
|
||||
|
||||
static auto *const PANIMSPEED = &g_pConfigManager->getConfigValuePtr("animations:speed")->floatValue;
|
||||
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
static auto *const BEZIERSTR = &g_pConfigManager->getConfigValuePtr("animations:curve")->strValue;
|
||||
static auto *const PSHADOWSENABLED = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||
|
||||
auto DEFAULTBEZIER = m_mBezierCurves.find(*BEZIERSTR);
|
||||
if (DEFAULTBEZIER == m_mBezierCurves.end())
|
||||
DEFAULTBEZIER = m_mBezierCurves.find("default");
|
||||
const auto DEFAULTBEZIER = m_mBezierCurves.find("default");
|
||||
|
||||
for (auto& av : m_lAnimatedVariables) {
|
||||
|
||||
@@ -49,7 +45,7 @@ void CAnimationManager::tick() {
|
||||
}
|
||||
|
||||
// get speed
|
||||
const auto SPEED = *av->m_pSpeed == 0 ? *PANIMSPEED : *av->m_pSpeed;
|
||||
const auto SPEED = av->m_pConfig->pValues->internalSpeed;
|
||||
|
||||
// get the spent % (0 - 1)
|
||||
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - av->animationBegin).count();
|
||||
@@ -59,7 +55,7 @@ void CAnimationManager::tick() {
|
||||
const auto PWINDOW = (CWindow*)av->m_pWindow;
|
||||
const auto PWORKSPACE = (CWorkspace*)av->m_pWorkspace;
|
||||
const auto PLAYER = (SLayerSurface*)av->m_pLayer;
|
||||
SMonitor* PMONITOR = nullptr;
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
|
||||
wlr_box WLRBOXPREV = {0,0,0,0};
|
||||
if (PWINDOW) {
|
||||
@@ -79,7 +75,7 @@ void CAnimationManager::tick() {
|
||||
switch (av->m_eVarType) {
|
||||
case AVARTYPE_FLOAT: {
|
||||
// for disabled anims just warp
|
||||
if (*av->m_pEnabled == 0 || animationsDisabled) {
|
||||
if (av->m_pConfig->pValues->internalEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
@@ -90,7 +86,7 @@ void CAnimationManager::tick() {
|
||||
}
|
||||
|
||||
const auto DELTA = av->m_fGoal - av->m_fBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
const auto BEZIER = m_mBezierCurves.find(av->m_pConfig->pValues->internalBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_fValue = av->m_fBegun + BEZIER->second.getYForPoint(SPENT) * DELTA;
|
||||
@@ -100,7 +96,7 @@ void CAnimationManager::tick() {
|
||||
}
|
||||
case AVARTYPE_VECTOR: {
|
||||
// for disabled anims just warp
|
||||
if (*av->m_pEnabled == 0 || animationsDisabled) {
|
||||
if (av->m_pConfig->pValues->internalEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
@@ -111,7 +107,7 @@ void CAnimationManager::tick() {
|
||||
}
|
||||
|
||||
const auto DELTA = av->m_vGoal - av->m_vBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
const auto BEZIER = m_mBezierCurves.find(av->m_pConfig->pValues->internalBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_vValue = av->m_vBegun + DELTA * BEZIER->second.getYForPoint(SPENT);
|
||||
@@ -121,7 +117,7 @@ void CAnimationManager::tick() {
|
||||
}
|
||||
case AVARTYPE_COLOR: {
|
||||
// for disabled anims just warp
|
||||
if (*av->m_pEnabled == 0 || animationsDisabled) {
|
||||
if (av->m_pConfig->pValues->internalEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
@@ -132,7 +128,7 @@ void CAnimationManager::tick() {
|
||||
}
|
||||
|
||||
const auto DELTA = av->m_cGoal - av->m_cBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
const auto BEZIER = m_mBezierCurves.find(av->m_pConfig->pValues->internalBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_cValue = av->m_cBegun + DELTA * BEZIER->second.getYForPoint(SPENT);
|
||||
@@ -163,6 +159,9 @@ void CAnimationManager::tick() {
|
||||
|
||||
w->updateWindowDecos();
|
||||
}
|
||||
} else if (PLAYER) {
|
||||
if (PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -334,7 +333,17 @@ void CAnimationManager::animationSlide(CWindow* pWindow, std::string force, bool
|
||||
}
|
||||
|
||||
void CAnimationManager::onWindowPostCreateClose(CWindow* pWindow, bool close) {
|
||||
auto ANIMSTYLE = g_pConfigManager->getString("animations:windows_style");
|
||||
if (!close) {
|
||||
pWindow->m_vRealPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsIn");
|
||||
pWindow->m_vRealSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsIn");
|
||||
pWindow->m_fAlpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeIn");
|
||||
} else {
|
||||
pWindow->m_vRealPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsOut");
|
||||
pWindow->m_vRealSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsOut");
|
||||
pWindow->m_fAlpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeOut");
|
||||
}
|
||||
|
||||
auto ANIMSTYLE = pWindow->m_vRealPosition.m_pConfig->pValues->internalStyle;
|
||||
transform(ANIMSTYLE.begin(), ANIMSTYLE.end(), ANIMSTYLE.begin(), ::tolower);
|
||||
|
||||
// if the window is not being animated, that means the layout set a fixed size for it, don't animate.
|
||||
|
@@ -34,6 +34,11 @@ CKeybindManager::CKeybindManager() {
|
||||
m_mDispatchers["focuswindow"] = focusWindow;
|
||||
m_mDispatchers["submap"] = setSubmap;
|
||||
m_mDispatchers["pass"] = pass;
|
||||
m_mDispatchers["layoutmsg"] = layoutmsg;
|
||||
m_mDispatchers["toggleopaque"] = toggleOpaque;
|
||||
m_mDispatchers["dpms"] = dpms;
|
||||
|
||||
m_tScrollTimer.reset();
|
||||
}
|
||||
|
||||
void CKeybindManager::addKeybind(SKeybind kb) {
|
||||
@@ -139,6 +144,15 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||
bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) {
|
||||
const auto MODS = g_pInputManager->accumulateModsFromAllKBs();
|
||||
|
||||
static auto *const PDELAY = &g_pConfigManager->getConfigValuePtr("binds:scroll_event_delay")->intValue;
|
||||
|
||||
if (m_tScrollTimer.getMillis() < *PDELAY) {
|
||||
m_tScrollTimer.reset();
|
||||
return true; // timer hasn't passed yet!
|
||||
}
|
||||
|
||||
m_tScrollTimer.reset();
|
||||
|
||||
bool found = false;
|
||||
if (e->source == WLR_AXIS_SOURCE_WHEEL && e->orientation == WLR_AXIS_ORIENTATION_VERTICAL) {
|
||||
if (e->delta < 0) {
|
||||
@@ -241,7 +255,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
||||
Debug::log(ERR, "Inavlid handler in a keybind! (handler %s does not exist)", k.handler.c_str());
|
||||
} else {
|
||||
// call the dispatcher
|
||||
Debug::log(LOG, "Keybind triggered, calling dispatcher (%d, %s, %d)", modmask, key, keysym);
|
||||
Debug::log(LOG, "Keybind triggered, calling dispatcher (%d, %s, %d)", modmask, key.c_str(), keysym);
|
||||
DISPATCHER->second(k.arg);
|
||||
}
|
||||
|
||||
@@ -496,7 +510,7 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
// If the monitor is not the one our cursor's at, warp to it.
|
||||
if (PMONITOR != g_pCompositor->getMonitorFromCursor()) {
|
||||
Vector2D middle = PMONITOR->vecPosition + PMONITOR->vecSize / 2.f;
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, middle.x, middle.y);
|
||||
g_pCompositor->warpCursorTo(middle);
|
||||
}
|
||||
|
||||
// set active and deactivate all other in wlr
|
||||
@@ -730,7 +744,7 @@ void CKeybindManager::moveFocusTo(std::string args) {
|
||||
auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) {
|
||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||
Vector2D middle = PWINDOWTOCHANGETO->m_vRealPosition.goalv() + PWINDOWTOCHANGETO->m_vRealSize.goalv() / 2.f;
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, middle.x, middle.y);
|
||||
g_pCompositor->warpCursorTo(middle);
|
||||
};
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PLASTWINDOW)) {
|
||||
@@ -985,7 +999,7 @@ void CKeybindManager::exitHyprland(std::string argz) {
|
||||
}
|
||||
|
||||
void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
||||
SMonitor* PMONITOR = nullptr;
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
|
||||
try {
|
||||
if (!isNumber(args) && !isDirection(args)) {
|
||||
@@ -998,6 +1012,9 @@ void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
|
||||
// get the current workspace
|
||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
|
||||
@@ -1014,7 +1031,7 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
||||
std::string workspace = args.substr(0, args.find_first_of(' '));
|
||||
std::string monitor = args.substr(args.find_first_of(' ') + 1);
|
||||
|
||||
SMonitor* PMONITOR = nullptr;
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
|
||||
try {
|
||||
if (!isNumber(monitor) && !isDirection(monitor)) {
|
||||
@@ -1228,7 +1245,7 @@ void CKeybindManager::circleNext(std::string arg) {
|
||||
|
||||
const auto MIDPOINT = g_pCompositor->m_pLastWindow->m_vRealPosition.goalv() + g_pCompositor->m_pLastWindow->m_vRealSize.goalv() / 2.f;
|
||||
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, MIDPOINT.x, MIDPOINT.y);
|
||||
g_pCompositor->warpCursorTo(MIDPOINT);
|
||||
}
|
||||
|
||||
void CKeybindManager::focusWindow(std::string regexp) {
|
||||
@@ -1245,7 +1262,7 @@ void CKeybindManager::focusWindow(std::string regexp) {
|
||||
|
||||
const auto MIDPOINT = PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f;
|
||||
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, MIDPOINT.x, MIDPOINT.y);
|
||||
g_pCompositor->warpCursorTo(MIDPOINT);
|
||||
}
|
||||
|
||||
void CKeybindManager::setSubmap(std::string submap) {
|
||||
@@ -1292,4 +1309,37 @@ void CKeybindManager::pass(std::string regexp) {
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_RELEASED);
|
||||
|
||||
wlr_seat_keyboard_notify_enter(g_pCompositor->m_sSeat.seat, PLASTSRF, KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
void CKeybindManager::layoutmsg(std::string msg) {
|
||||
SLayoutMessageHeader hd = {g_pCompositor->m_pLastWindow};
|
||||
g_pLayoutManager->getCurrentLayout()->layoutMessage(hd, msg);
|
||||
}
|
||||
|
||||
void CKeybindManager::toggleOpaque(std::string unused) {
|
||||
const auto PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return;
|
||||
|
||||
PWINDOW->m_sAdditionalConfigData.forceOpaque = !PWINDOW->m_sAdditionalConfigData.forceOpaque;
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
|
||||
void CKeybindManager::dpms(std::string arg) {
|
||||
bool enable = arg == "on";
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
wlr_output_enable(m->output, enable);
|
||||
|
||||
if (!wlr_output_commit(m->output)) {
|
||||
Debug::log(ERR, "Couldn't commit output %s", m->szName.c_str());
|
||||
}
|
||||
|
||||
if (enable)
|
||||
g_pHyprRenderer->damageMonitor(m.get());
|
||||
}
|
||||
|
||||
g_pCompositor->m_bDPMSStateON = enable;
|
||||
}
|
||||
|
@@ -6,6 +6,8 @@
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
class CInputManager;
|
||||
|
||||
struct SKeybind {
|
||||
std::string key = "";
|
||||
int keycode = -1;
|
||||
@@ -60,6 +62,8 @@ private:
|
||||
uint32_t m_uTimeLastMs = 0;
|
||||
uint32_t m_uLastCode = 0;
|
||||
|
||||
CTimer m_tScrollTimer;
|
||||
|
||||
bool handleKeybinds(const uint32_t&, const std::string&, const xkb_keysym_t&, const int&, bool, uint32_t);
|
||||
|
||||
bool handleInternalKeybinds(xkb_keysym_t);
|
||||
@@ -94,8 +98,12 @@ private:
|
||||
static void focusWindow(std::string);
|
||||
static void setSubmap(std::string);
|
||||
static void pass(std::string);
|
||||
static void layoutmsg(std::string);
|
||||
static void toggleOpaque(std::string);
|
||||
static void dpms(std::string);
|
||||
|
||||
friend class CCompositor;
|
||||
friend class CInputManager;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CKeybindManager> g_pKeybindManager;
|
||||
|
@@ -19,6 +19,8 @@ CThreadManager::CThreadManager() {
|
||||
|
||||
HyprCtl::startHyprCtlSocket();
|
||||
|
||||
g_pCompositor->startHyprCtlTick();
|
||||
|
||||
m_esConfigTimer = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, handleTimer, this);
|
||||
|
||||
wl_event_source_timer_update(m_esConfigTimer, 1000);
|
||||
|
@@ -121,6 +121,13 @@ void CHyprXWaylandManager::sendCloseWindow(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, const Vector2D& size) {
|
||||
|
||||
if ((pWindow->m_vReportedSize == size && pWindow->m_vRealPosition.vec() == pWindow->m_vReportedPosition) || (pWindow->m_vReportedSize == size && !pWindow->m_bIsX11))
|
||||
return;
|
||||
|
||||
pWindow->m_vReportedPosition = pWindow->m_vRealPosition.vec();
|
||||
pWindow->m_vReportedSize = size;
|
||||
|
||||
if (pWindow->m_bIsX11)
|
||||
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, size.x, size.y);
|
||||
else
|
||||
|
@@ -29,6 +29,7 @@ void CInputManager::onMouseWarp(wlr_pointer_motion_absolute_event* e) {
|
||||
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||
static auto* const PMOUSEDPMS = &g_pConfigManager->getConfigValuePtr("misc:mouse_move_enables_dpms")->intValue;
|
||||
|
||||
if (!g_pCompositor->m_bReadyToProcess)
|
||||
return;
|
||||
@@ -41,6 +42,11 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
if (g_pCompositor->m_sSeat.mouse->virt)
|
||||
return; // don't refocus on virt
|
||||
|
||||
if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS) {
|
||||
// enable dpms
|
||||
g_pKeybindManager->dpms("on");
|
||||
}
|
||||
|
||||
Vector2D mouseCoords = getMouseCoordsInternal();
|
||||
const auto MOUSECOORDSFLOORED = mouseCoords.floor();
|
||||
|
||||
@@ -177,6 +183,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
} else
|
||||
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
|
||||
|
||||
if (!pFoundWindow && refocus)
|
||||
pFoundWindow = g_pCompositor->getFirstWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
|
||||
if (pFoundWindow) {
|
||||
if (!pFoundWindow->m_bIsX11) {
|
||||
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
|
||||
@@ -228,7 +237,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
if (*PFOLLOWMOUSE != 1 && !refocus) {
|
||||
if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && (g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating)) {
|
||||
// enter if change floating style
|
||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||
if (*PFOLLOWMOUSE != 3)
|
||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
} else if (*PFOLLOWMOUSE == 2) {
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
@@ -242,9 +252,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
|
||||
return; // don't enter any new surfaces
|
||||
} else {
|
||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||
if (*PFOLLOWMOUSE != 3)
|
||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||
}
|
||||
} else if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive)
|
||||
} else if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive && *PFOLLOWMOUSE != 3)
|
||||
g_pCompositor->focusSurface(foundSurface);
|
||||
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
@@ -434,23 +445,28 @@ void CInputManager::setKeyboardLayout() {
|
||||
}
|
||||
|
||||
void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(pKeyboard->name);
|
||||
auto devname = pKeyboard->name;
|
||||
transform(devname.begin(), devname.end(), devname.begin(), ::tolower);
|
||||
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
|
||||
|
||||
Debug::log(LOG, "ApplyConfigToKeyboard for \"%s\", hasconfig: %i", pKeyboard->name.c_str(), (int)HASCONFIG);
|
||||
|
||||
ASSERT(pKeyboard);
|
||||
|
||||
if (!wlr_keyboard_from_input_device(pKeyboard->keyboard))
|
||||
return;
|
||||
|
||||
const auto REPEATRATE = HASCONFIG ? g_pConfigManager->getDeviceInt(pKeyboard->name, "repeat_rate") : g_pConfigManager->getInt("input:repeat_rate");
|
||||
const auto REPEATDELAY = HASCONFIG ? g_pConfigManager->getDeviceInt(pKeyboard->name, "repeat_delay") : g_pConfigManager->getInt("input:repeat_delay");
|
||||
const auto REPEATRATE = HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "repeat_rate") : g_pConfigManager->getInt("input:repeat_rate");
|
||||
const auto REPEATDELAY = HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "repeat_delay") : g_pConfigManager->getInt("input:repeat_delay");
|
||||
|
||||
const auto NUMLOCKON = HASCONFIG ? g_pConfigManager->getDeviceInt(pKeyboard->name, "numlock_by_default") : g_pConfigManager->getInt("input:numlock_by_default");
|
||||
const auto NUMLOCKON = HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "numlock_by_default") : g_pConfigManager->getInt("input:numlock_by_default");
|
||||
|
||||
const auto RULES = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_rules") : g_pConfigManager->getString("input:kb_rules");
|
||||
const auto MODEL = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_model") : g_pConfigManager->getString("input:kb_model");
|
||||
const auto LAYOUT = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_layout") : g_pConfigManager->getString("input:kb_layout");
|
||||
const auto VARIANT = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_variant") : g_pConfigManager->getString("input:kb_variant");
|
||||
const auto OPTIONS = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_options") : g_pConfigManager->getString("input:kb_options");
|
||||
const auto RULES = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "kb_rules") : g_pConfigManager->getString("input:kb_rules");
|
||||
const auto MODEL = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "kb_model") : g_pConfigManager->getString("input:kb_model");
|
||||
const auto LAYOUT = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "kb_layout") : g_pConfigManager->getString("input:kb_layout");
|
||||
const auto VARIANT = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "kb_variant") : g_pConfigManager->getString("input:kb_variant");
|
||||
const auto OPTIONS = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "kb_options") : g_pConfigManager->getString("input:kb_options");
|
||||
|
||||
try {
|
||||
if (NUMLOCKON == pKeyboard->numlockOn && REPEATDELAY == pKeyboard->repeatDelay && REPEATRATE == pKeyboard->repeatRate && RULES != "" && RULES == pKeyboard->currentRules.rules && MODEL == pKeyboard->currentRules.model && LAYOUT == pKeyboard->currentRules.layout && VARIANT == pKeyboard->currentRules.variant && OPTIONS == pKeyboard->currentRules.options) {
|
||||
@@ -562,47 +578,50 @@ void CInputManager::setMouseConfigs() {
|
||||
for (auto& m : m_lMice) {
|
||||
const auto PMOUSE = &m;
|
||||
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(PMOUSE->name);
|
||||
auto devname = PMOUSE->name;
|
||||
transform(devname.begin(), devname.end(), devname.begin(), ::tolower);
|
||||
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
|
||||
|
||||
if (wlr_input_device_is_libinput(m.mouse)) {
|
||||
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(m.mouse);
|
||||
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "clickfinger_behavior") : g_pConfigManager->getInt("input:touchpad:clickfinger_behavior")) == 0) // toggle software buttons or clickfinger
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "clickfinger_behavior") : g_pConfigManager->getInt("input:touchpad:clickfinger_behavior")) == 0) // toggle software buttons or clickfinger
|
||||
libinput_device_config_click_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
|
||||
else
|
||||
libinput_device_config_click_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
|
||||
|
||||
if (libinput_device_config_middle_emulation_is_available(LIBINPUTDEV)) { // middleclick on r+l mouse button pressed
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "middle_button_emulation") : g_pConfigManager->getInt("input:touchpad:middle_button_emulation")) == 1)
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "middle_button_emulation") : g_pConfigManager->getInt("input:touchpad:middle_button_emulation")) == 1)
|
||||
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
|
||||
else
|
||||
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
|
||||
}
|
||||
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "drag_lock") : g_pConfigManager->getInt("input:touchpad:drag_lock")) == 0)
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "drag_lock") : g_pConfigManager->getInt("input:touchpad:drag_lock")) == 0)
|
||||
libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
|
||||
else
|
||||
libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_ENABLED);
|
||||
|
||||
if (libinput_device_config_tap_get_finger_count(LIBINPUTDEV)) // this is for tapping (like on a laptop)
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "tap-to-click") : g_pConfigManager->getInt("input:touchpad:tap-to-click")) == 1)
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "tap-to-click") : g_pConfigManager->getInt("input:touchpad:tap-to-click")) == 1)
|
||||
libinput_device_config_tap_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_TAP_ENABLED);
|
||||
|
||||
if (libinput_device_config_scroll_has_natural_scroll(LIBINPUTDEV)) {
|
||||
double w = 0, h = 0;
|
||||
|
||||
if (libinput_device_has_capability(LIBINPUTDEV, LIBINPUT_DEVICE_CAP_POINTER) && libinput_device_get_size(LIBINPUTDEV, &w, &h) == 0) // pointer with size is a touchpad
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, (HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "natural_scroll") : g_pConfigManager->getInt("input:touchpad:natural_scroll")));
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, (HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "natural_scroll") : g_pConfigManager->getInt("input:touchpad:natural_scroll")));
|
||||
else
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, (HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "natural_scroll") : g_pConfigManager->getInt("input:natural_scroll")));
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, (HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "natural_scroll") : g_pConfigManager->getInt("input:natural_scroll")));
|
||||
}
|
||||
|
||||
if (libinput_device_config_dwt_is_available(LIBINPUTDEV)) {
|
||||
const auto DWT = static_cast<enum libinput_config_dwt_state>((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "disable_while_typing") : g_pConfigManager->getInt("input:touchpad:disable_while_typing")) != 0);
|
||||
const auto DWT = static_cast<enum libinput_config_dwt_state>((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "disable_while_typing") : g_pConfigManager->getInt("input:touchpad:disable_while_typing")) != 0);
|
||||
libinput_device_config_dwt_set_enabled(LIBINPUTDEV, DWT);
|
||||
}
|
||||
|
||||
const auto LIBINPUTSENS = std::clamp((HASCONFIG ? g_pConfigManager->getDeviceFloat(PMOUSE->name, "sensitivity") : g_pConfigManager->getFloat("input:sensitivity")), -1.f, 1.f);
|
||||
const auto LIBINPUTSENS = std::clamp((HASCONFIG ? g_pConfigManager->getDeviceFloat(devname, "sensitivity") : g_pConfigManager->getFloat("input:sensitivity")), -1.f, 1.f);
|
||||
|
||||
libinput_device_config_accel_set_profile(LIBINPUTDEV, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
|
||||
libinput_device_config_accel_set_speed(LIBINPUTDEV, LIBINPUTSENS);
|
||||
|
@@ -31,6 +31,11 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||
m_shQUAD.color = glGetUniformLocation(prog, "color");
|
||||
m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_shQUAD.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_shQUAD.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_shQUAD.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_shQUAD.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_shQUAD.radius = glGetUniformLocation(prog, "radius");
|
||||
m_shQUAD.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBA);
|
||||
m_shRGBA.program = prog;
|
||||
@@ -40,6 +45,11 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||
m_shRGBA.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_shRGBA.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_shRGBA.discardOpaque = glGetUniformLocation(prog, "discardOpaque");
|
||||
m_shRGBA.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_shRGBA.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_shRGBA.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_shRGBA.radius = glGetUniformLocation(prog, "radius");
|
||||
m_shRGBA.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBX);
|
||||
m_shRGBX.program = prog;
|
||||
@@ -49,6 +59,11 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||
m_shRGBX.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_shRGBX.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_shRGBX.discardOpaque = glGetUniformLocation(prog, "discardOpaque");
|
||||
m_shRGBX.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_shRGBX.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_shRGBX.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_shRGBX.radius = glGetUniformLocation(prog, "radius");
|
||||
m_shRGBX.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, TEXFRAGSRCEXT);
|
||||
m_shEXT.program = prog;
|
||||
@@ -58,6 +73,11 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||
m_shEXT.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_shEXT.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_shEXT.discardOpaque = glGetUniformLocation(prog, "discardOpaque");
|
||||
m_shEXT.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_shEXT.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_shEXT.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_shEXT.radius = glGetUniformLocation(prog, "radius");
|
||||
m_shEXT.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, FRAGBLUR1);
|
||||
m_shBLUR1.program = prog;
|
||||
@@ -66,6 +86,8 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||
m_shBLUR1.proj = glGetUniformLocation(prog, "proj");
|
||||
m_shBLUR1.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_shBLUR1.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_shBLUR1.radius = glGetUniformLocation(prog, "radius");
|
||||
m_shBLUR1.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, FRAGBLUR2);
|
||||
m_shBLUR2.program = prog;
|
||||
@@ -74,18 +96,34 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||
m_shBLUR2.proj = glGetUniformLocation(prog, "proj");
|
||||
m_shBLUR2.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_shBLUR2.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_shBLUR2.radius = glGetUniformLocation(prog, "radius");
|
||||
m_shBLUR2.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||
|
||||
prog = createProgram(QUADVERTSRC, FRAGSHADOW);
|
||||
m_shSHADOW.program = prog;
|
||||
m_shSHADOW.proj = glGetUniformLocation(prog, "proj");
|
||||
m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_shSHADOW.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_shSHADOW.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_shSHADOW.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_shSHADOW.radius = glGetUniformLocation(prog, "radius");
|
||||
m_shSHADOW.range = glGetUniformLocation(prog, "range");
|
||||
m_shSHADOW.shadowPower = glGetUniformLocation(prog, "shadowPower");
|
||||
m_shSHADOW.color = glGetUniformLocation(prog, "color");
|
||||
|
||||
prog = createProgram(QUADVERTSRC, FRAGBORDER1);
|
||||
m_shBORDER1.program = prog;
|
||||
m_shBORDER1.proj = glGetUniformLocation(prog, "proj");
|
||||
m_shBORDER1.thick = glGetUniformLocation(prog, "thick");
|
||||
m_shBORDER1.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_shBORDER1.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_shBORDER1.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_shBORDER1.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_shBORDER1.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_shBORDER1.radius = glGetUniformLocation(prog, "radius");
|
||||
m_shBORDER1.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
m_shBORDER1.color = glGetUniformLocation(prog, "color");
|
||||
|
||||
Debug::log(LOG, "Shaders initialized successfully.");
|
||||
|
||||
@@ -139,7 +177,7 @@ GLuint CHyprOpenGLImpl::compileShader(const GLuint& type, std::string src) {
|
||||
return shader;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::begin(SMonitor* pMonitor, pixman_region32_t* pDamage, bool fake) {
|
||||
void CHyprOpenGLImpl::begin(CMonitor* pMonitor, pixman_region32_t* pDamage, bool fake) {
|
||||
m_RenderData.pMonitor = pMonitor;
|
||||
|
||||
glViewport(0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
@@ -285,11 +323,11 @@ void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixm
|
||||
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(m_shQUAD.getUniformLocation("topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_shQUAD.getUniformLocation("bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_shQUAD.getUniformLocation("fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_shQUAD.getUniformLocation("radius"), round);
|
||||
glUniform1i(m_shQUAD.getUniformLocation("primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 1 && round != 0));
|
||||
glUniform2f(m_shQUAD.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_shQUAD.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_shQUAD.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_shQUAD.radius, round);
|
||||
glUniform1i(m_shQUAD.primitiveMultisample, (int)(*PMULTISAMPLEEDGES == 1 && round != 0));
|
||||
|
||||
glVertexAttribPointer(m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(m_shQUAD.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
@@ -380,11 +418,11 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(shader->getUniformLocation("topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(shader->getUniformLocation("bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(shader->getUniformLocation("fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(shader->getUniformLocation("radius"), round);
|
||||
glUniform1i(shader->getUniformLocation("primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !noAA));
|
||||
glUniform2f(shader->topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(shader->bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(shader->fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(shader->radius, round);
|
||||
glUniform1i(shader->primitiveMultisample, (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !noAA));
|
||||
|
||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
@@ -471,11 +509,11 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||
|
||||
// prep two shaders
|
||||
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
|
||||
glUniform1f(pShader->getUniformLocation("radius"), *PBLURSIZE * (a / 255.f)); // this makes the blursize change with a
|
||||
glUniform1f(pShader->radius, *PBLURSIZE * (a / 255.f)); // this makes the blursize change with a
|
||||
if (pShader == &m_shBLUR1)
|
||||
glUniform2f(m_shBLUR1.getUniformLocation("halfpixel"), 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
|
||||
glUniform2f(m_shBLUR1.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
|
||||
else
|
||||
glUniform2f(m_shBLUR2.getUniformLocation("halfpixel"), 0.5f / (m_RenderData.pMonitor->vecPixelSize.x * 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y * 2.f));
|
||||
glUniform2f(m_shBLUR2.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x * 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y * 2.f));
|
||||
glUniform1i(pShader->tex, 0);
|
||||
|
||||
glVertexAttribPointer(pShader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
@@ -537,11 +575,77 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||
return currentRenderToFB;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::markBlurDirtyForMonitor(CMonitor* pMonitor) {
|
||||
m_mMonitorRenderResources[pMonitor].blurFBDirty = true;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) {
|
||||
static auto *const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
|
||||
|
||||
if (!*PBLURNEWOPTIMIZE || !m_mMonitorRenderResources[pMonitor].blurFBDirty)
|
||||
return;
|
||||
|
||||
bool has = false;
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == pMonitor->activeWorkspace && w->m_bIsMapped && !w->m_bHidden && !w->m_bIsFloating) {
|
||||
has = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (has)
|
||||
g_pHyprRenderer->damageMonitor(pMonitor);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::preBlurForCurrentMonitor() {
|
||||
|
||||
// make the fake dmg
|
||||
pixman_region32_t fakeDamage;
|
||||
pixman_region32_init_rect(&fakeDamage, 0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
wlr_box wholeMonitor = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
const auto POUTFB = blurMainFramebufferWithDamage(255, &wholeMonitor, &fakeDamage);
|
||||
|
||||
// render onto blurFB
|
||||
m_RenderData.pCurrentMonData->blurFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y);
|
||||
m_RenderData.pCurrentMonData->blurFB.bind();
|
||||
|
||||
clear(CColor(0,0,0,0));
|
||||
|
||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 255, &fakeDamage, 0, false, true, false);
|
||||
|
||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
||||
|
||||
m_RenderData.pCurrentMonData->blurFBDirty = false;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::preWindowPass() {
|
||||
static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
|
||||
|
||||
if (!m_RenderData.pCurrentMonData->blurFBDirty || !*PBLURNEWOPTIMIZE)
|
||||
return;
|
||||
|
||||
bool hasWindows = false;
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == m_RenderData.pMonitor->activeWorkspace && !w->m_bHidden && w->m_bIsMapped && !w->m_bIsFloating) {
|
||||
hasWindows = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasWindows)
|
||||
return;
|
||||
|
||||
// blur the main FB, it will be rendered onto the mirror
|
||||
preBlurForCurrentMonitor();
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, wlr_surface* pSurface, int round) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
|
||||
|
||||
static auto *const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
|
||||
static auto* const PNOBLUROVERSIZED = &g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized")->intValue;
|
||||
static auto *const PNOBLUROVERSIZED = &g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized")->intValue;
|
||||
static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
|
||||
|
||||
if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) || (m_pCurrentWindow && m_pCurrentWindow->m_sAdditionalConfigData.forceNoBlur)) {
|
||||
renderTexture(tex, pBox, a, round, false, true);
|
||||
@@ -571,8 +675,10 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
return;
|
||||
}
|
||||
|
||||
// blur the main FB, it will be rendered onto the mirror
|
||||
const auto POUTFB = blurMainFramebufferWithDamage(a, pBox, &inverseOpaque);
|
||||
// vvv TODO: layered blur fbs?
|
||||
const bool USENEWOPTIMIZE = (*PBLURNEWOPTIMIZE && m_pCurrentWindow && !m_pCurrentWindow->m_bIsFloating && m_RenderData.pCurrentMonData->blurFB.m_cTex.m_iTexID);
|
||||
|
||||
const auto POUTFB = USENEWOPTIMIZE ? &m_RenderData.pCurrentMonData->blurFB : blurMainFramebufferWithDamage(a, pBox, &inverseOpaque);
|
||||
|
||||
pixman_region32_fini(&inverseOpaque);
|
||||
|
||||
@@ -590,7 +696,10 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
renderTexture(tex, pBox, a, round, true, true); // discard opaque
|
||||
if (USENEWOPTIMIZE)
|
||||
renderRect(pBox, CColor(0,0,0,0), round);
|
||||
else
|
||||
renderTexture(tex, pBox, a, round, true, true); // discard opaque
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
glStencilFunc(GL_EQUAL, 1, -1);
|
||||
@@ -655,18 +764,18 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
|
||||
glUseProgram(m_shBORDER1.program);
|
||||
|
||||
glUniformMatrix3fv(m_shBORDER1.proj, 1, GL_FALSE, glMatrix);
|
||||
glUniform4f(m_shBORDER1.getUniformLocation("color"), col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f);
|
||||
glUniform4f(m_shBORDER1.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f);
|
||||
|
||||
const auto TOPLEFT = Vector2D(round, round);
|
||||
const auto BOTTOMRIGHT = Vector2D(box->width - round, box->height - round);
|
||||
const auto FULLSIZE = Vector2D(box->width, box->height);
|
||||
|
||||
glUniform2f(m_shBORDER1.getUniformLocation("topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_shBORDER1.getUniformLocation("bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_shBORDER1.getUniformLocation("fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_shBORDER1.getUniformLocation("radius"), round);
|
||||
glUniform1f(m_shBORDER1.getUniformLocation("thick"), *PBORDERSIZE);
|
||||
glUniform1i(m_shBORDER1.getUniformLocation("primitiveMultisample"), *PMULTISAMPLE);
|
||||
glUniform2f(m_shBORDER1.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_shBORDER1.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_shBORDER1.radius, round);
|
||||
glUniform1f(m_shBORDER1.thick, *PBORDERSIZE);
|
||||
glUniform1i(m_shBORDER1.primitiveMultisample, *PMULTISAMPLE);
|
||||
|
||||
glVertexAttribPointer(m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(m_shBORDER1.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
@@ -698,7 +807,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
// this is temporary, doesnt mess with the actual wlr damage
|
||||
pixman_region32_t fakeDamage;
|
||||
pixman_region32_init(&fakeDamage);
|
||||
pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y);
|
||||
pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||
|
||||
begin(PMONITOR, &fakeDamage, true);
|
||||
|
||||
@@ -715,10 +824,10 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
|
||||
g_pConfigManager->setInt("decoration:blur", 0);
|
||||
|
||||
m_bEndFrame = true;
|
||||
|
||||
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
|
||||
@@ -761,7 +870,7 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
|
||||
// this is temporary, doesnt mess with the actual wlr damage
|
||||
pixman_region32_t fakeDamage;
|
||||
pixman_region32_init(&fakeDamage);
|
||||
pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y);
|
||||
pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecPixelSize.x, (int)PMONITOR->vecPixelSize.y);
|
||||
|
||||
begin(PMONITOR, &fakeDamage, true);
|
||||
|
||||
@@ -778,8 +887,6 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
m_bEndFrame = true;
|
||||
|
||||
// draw the layer
|
||||
g_pHyprRenderer->renderLayer(pLayer, PMONITOR, &now);
|
||||
|
||||
@@ -836,6 +943,11 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
|
||||
renderTextureInternalWithDamage(it->second.m_cTex, &windowBox, PWINDOW->m_fAlpha.fl(), &fakeDamage, 0);
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
|
||||
static auto *const PDAMAGEMON = &g_pConfigManager->getConfigValuePtr("misc:damage_entire_on_snapshot")->intValue;
|
||||
|
||||
if (*PDAMAGEMON)
|
||||
PMONITOR->forceFullFrames += 1;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
|
||||
@@ -862,6 +974,11 @@ void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
|
||||
renderTextureInternalWithDamage(it->second.m_cTex, &windowBox, PLAYER->alpha.fl(), &fakeDamage, 0);
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
|
||||
static auto *const PDAMAGEMON = &g_pConfigManager->getConfigValuePtr("misc:damage_entire_on_snapshot")->intValue;
|
||||
|
||||
if (*PDAMAGEMON)
|
||||
PMONITOR->forceFullFrames += 1;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, float a) {
|
||||
@@ -890,19 +1007,19 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
|
||||
glUseProgram(m_shSHADOW.program);
|
||||
|
||||
glUniformMatrix3fv(m_shSHADOW.proj, 1, GL_FALSE, glMatrix);
|
||||
glUniform4f(m_shSHADOW.getUniformLocation("color"), col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f * a);
|
||||
glUniform4f(m_shSHADOW.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f * a);
|
||||
|
||||
const auto TOPLEFT = Vector2D(range + round, range + round);
|
||||
const auto BOTTOMRIGHT = Vector2D(box->width - (range + round), box->height - (range + round));
|
||||
const auto FULLSIZE = Vector2D(box->width, box->height);
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(m_shSHADOW.getUniformLocation("topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_shSHADOW.getUniformLocation("bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_shSHADOW.getUniformLocation("fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_shSHADOW.getUniformLocation("radius"), range + round);
|
||||
glUniform1f(m_shSHADOW.getUniformLocation("range"), range);
|
||||
glUniform1f(m_shSHADOW.getUniformLocation("shadowPower"), SHADOWPOWER);
|
||||
glUniform2f(m_shSHADOW.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_shSHADOW.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_shSHADOW.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_shSHADOW.radius, range + round);
|
||||
glUniform1f(m_shSHADOW.range, range);
|
||||
glUniform1f(m_shSHADOW.shadowPower, SHADOWPOWER);
|
||||
|
||||
glVertexAttribPointer(m_shSHADOW.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(m_shSHADOW.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
@@ -935,13 +1052,13 @@ void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const
|
||||
cairo_text_extents_t textExtents;
|
||||
cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &textExtents);
|
||||
|
||||
cairo_move_to(CAIRO, m_RenderData.pMonitor->vecPixelSize.x / 2.f - textExtents.width / 2.f, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height - 1);
|
||||
cairo_move_to(CAIRO, m_RenderData.pMonitor->vecTransformedSize.x / 2.f - textExtents.width / 2.f, m_RenderData.pMonitor->vecTransformedSize.y - textExtents.height - 1);
|
||||
cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str());
|
||||
|
||||
cairo_surface_flush(CAIROSURFACE);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!");
|
||||
|
||||
static auto *const PNOSPLASH = &g_pConfigManager->getConfigValuePtr("misc:disable_splash_rendering")->intValue;
|
||||
@@ -975,6 +1092,8 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
texPath += "2K.png";
|
||||
}
|
||||
|
||||
PTEX->m_vSize = textureSize;
|
||||
|
||||
// create a new one with cairo
|
||||
const auto CAIROSURFACE = cairo_image_surface_create_from_png(texPath.c_str());
|
||||
|
||||
@@ -997,6 +1116,28 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
cairo_surface_destroy(CAIROSURFACE);
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -1006,12 +1147,11 @@ void CHyprOpenGLImpl::clearWithTex() {
|
||||
static auto *const PRENDERTEX = &g_pConfigManager->getConfigValuePtr("misc:disable_hyprland_logo")->intValue;
|
||||
|
||||
if (!*PRENDERTEX) {
|
||||
wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
|
||||
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &m_mMonitorRenderResources[m_RenderData.pMonitor].backgroundTexBox, 255, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::destroyMonitorResources(SMonitor* pMonitor) {
|
||||
void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) {
|
||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].mirrorFB.release();
|
||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].primaryFB.release();
|
||||
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].stencilTex.destroyTexture();
|
||||
|
@@ -37,10 +37,15 @@ struct SMonitorRenderData {
|
||||
CFramebuffer mirrorSwapFB;
|
||||
|
||||
CTexture stencilTex;
|
||||
|
||||
CFramebuffer blurFB;
|
||||
bool blurFBDirty = true;
|
||||
|
||||
wlr_box backgroundTexBox;
|
||||
};
|
||||
|
||||
struct SCurrentRenderData {
|
||||
SMonitor* pMonitor = nullptr;
|
||||
CMonitor* pMonitor = nullptr;
|
||||
float projection[9];
|
||||
|
||||
SMonitorRenderData* pCurrentMonData = nullptr;
|
||||
@@ -56,7 +61,7 @@ public:
|
||||
|
||||
CHyprOpenGLImpl();
|
||||
|
||||
void begin(SMonitor*, pixman_region32_t*, bool fake = false);
|
||||
void begin(CMonitor*, pixman_region32_t*, bool fake = false);
|
||||
void end();
|
||||
|
||||
void renderRect(wlr_box*, const CColor&, int round = 0);
|
||||
@@ -78,7 +83,12 @@ public:
|
||||
void scissor(const pixman_box32*);
|
||||
void scissor(const int x, const int y, const int w, const int h);
|
||||
|
||||
void destroyMonitorResources(SMonitor*);
|
||||
void destroyMonitorResources(CMonitor*);
|
||||
|
||||
void markBlurDirtyForMonitor(CMonitor*);
|
||||
|
||||
void preWindowPass();
|
||||
void preRender(CMonitor*);
|
||||
|
||||
SCurrentRenderData m_RenderData;
|
||||
|
||||
@@ -91,8 +101,8 @@ public:
|
||||
|
||||
std::unordered_map<CWindow*, CFramebuffer> m_mWindowFramebuffers;
|
||||
std::unordered_map<SLayerSurface*, CFramebuffer> m_mLayerFramebuffers;
|
||||
std::unordered_map<SMonitor*, SMonitorRenderData> m_mMonitorRenderResources;
|
||||
std::unordered_map<SMonitor*, CTexture> m_mMonitorBGTextures;
|
||||
std::unordered_map<CMonitor*, SMonitorRenderData> m_mMonitorRenderResources;
|
||||
std::unordered_map<CMonitor*, CTexture> m_mMonitorBGTextures;
|
||||
|
||||
private:
|
||||
std::list<GLuint> m_lBuffers;
|
||||
@@ -117,7 +127,7 @@ private:
|
||||
|
||||
GLuint createProgram(const std::string&, const std::string&);
|
||||
GLuint compileShader(const GLuint&, std::string);
|
||||
void createBGTextureForMonitor(SMonitor*);
|
||||
void createBGTextureForMonitor(CMonitor*);
|
||||
|
||||
// returns the out FB, can be either Mirror or MirrorSwap
|
||||
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
||||
@@ -125,6 +135,8 @@ private:
|
||||
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 renderSplash(cairo_t *const, cairo_surface_t *const);
|
||||
|
||||
void preBlurForCurrentMonitor();
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;
|
@@ -32,14 +32,20 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
scaleBox(&windowBox, RDATA->output->scale);
|
||||
|
||||
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
static auto *const PBORDERTHICK = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
|
||||
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
|
||||
rounding += *PBORDERTHICK;
|
||||
|
||||
if (RDATA->surface && surface == RDATA->surface) {
|
||||
if (RDATA->blur)
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
|
||||
else
|
||||
if (wlr_surface_is_xwayland_surface(surface) && !wlr_xwayland_surface_from_wlr_surface(surface)->has_alpha && RDATA->fadeAlpha * RDATA->alpha == 255.f) {
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
|
||||
} else {
|
||||
if (RDATA->blur)
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
|
||||
else
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (RDATA->surface && wlr_surface_is_xdg_surface(RDATA->surface)) {
|
||||
@@ -58,24 +64,29 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false);
|
||||
}
|
||||
|
||||
|
||||
wlr_surface_send_frame_done(surface, RDATA->when);
|
||||
|
||||
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output);
|
||||
}
|
||||
|
||||
bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) {
|
||||
bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) {
|
||||
wlr_box geometry = pWindow->getFullWindowBoundingBox();
|
||||
|
||||
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, &geometry))
|
||||
return false;
|
||||
|
||||
// now check if it has the same workspace
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID) {
|
||||
if (!(!PWORKSPACE->m_bHasFullscreenWindow || pWindow->m_bIsFullscreen || (pWindow->m_bIsFloating && pWindow->m_bCreatedOverFullscreen)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pWindow->m_iWorkspaceID == pMonitor->activeWorkspace)
|
||||
return true;
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
// if not, check if it maybe is active on a different monitor. vvv might be animation in progress
|
||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_bForceRendering) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
||||
return true;
|
||||
@@ -107,14 +118,20 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time) {
|
||||
void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time) {
|
||||
CWindow* pWorkspaceWindow = nullptr;
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID != pWorkspace->m_iID || !w->m_bIsFullscreen)
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID);
|
||||
|
||||
if (w->m_iWorkspaceID != pWorkspace->m_iID || !w->m_bIsFullscreen){
|
||||
if (!(PWORKSPACE && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (w->m_iWorkspaceID == pMonitor->activeWorkspace && !w->m_bIsFullscreen)
|
||||
continue;
|
||||
|
||||
// found it!
|
||||
renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL);
|
||||
|
||||
pWorkspaceWindow = w.get();
|
||||
@@ -162,7 +179,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
g_pHyprError->draw();
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode) {
|
||||
void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode) {
|
||||
if (pWindow->m_bHidden)
|
||||
return;
|
||||
|
||||
@@ -180,7 +197,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||
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.h = std::clamp(pWindow->m_vRealSize.vec().y, (double)5, (double)1337420); // otherwise we'll have issues later with invalid boxes
|
||||
renderdata.dontRound = pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL;
|
||||
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.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);
|
||||
@@ -193,6 +210,10 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||
else
|
||||
renderdata.alpha *= pWindow == g_pCompositor->m_pLastWindow ? pWindow->m_sSpecialRenderData.alpha : pWindow->m_sSpecialRenderData.alphaInactive;
|
||||
|
||||
// apply opaque
|
||||
if (pWindow->m_sAdditionalConfigData.forceOpaque)
|
||||
renderdata.alpha = 1.f;
|
||||
|
||||
g_pHyprOpenGL->m_pCurrentWindow = pWindow;
|
||||
|
||||
// render window decorations first, if not fullscreen full
|
||||
@@ -266,7 +287,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||
g_pHyprOpenGL->m_pCurrentWindow = nullptr;
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderLayer(SLayerSurface* pLayer, SMonitor* pMonitor, timespec* time) {
|
||||
void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, timespec* time) {
|
||||
if (pLayer->fadingOut) {
|
||||
g_pHyprOpenGL->renderSnapshot(&pLayer);
|
||||
return;
|
||||
@@ -280,6 +301,9 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, SMonitor* pMonitor, times
|
||||
renderdata.w = pLayer->layerSurface->surface->current.width;
|
||||
renderdata.h = pLayer->layerSurface->surface->current.height;
|
||||
wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata);
|
||||
|
||||
renderdata.squishOversized = false; // don't squish popups
|
||||
wlr_layer_surface_v1_for_each_popup_surface(pLayer->layerSurface, renderSurface, &renderdata);
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
@@ -296,6 +320,9 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
renderLayer(ls.get(), PMONITOR, time);
|
||||
}
|
||||
|
||||
// pre window pass
|
||||
g_pHyprOpenGL->preWindowPass();
|
||||
|
||||
// if there is a fullscreen window, render it and then do not render anymore.
|
||||
// fullscreen window will hide other windows and top layers
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
@@ -504,7 +531,7 @@ void apply_exclusive(struct wlr_box* usable_area, uint32_t anchor, int32_t exclu
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprRenderer::arrangeLayerArray(SMonitor* pMonitor, const std::vector<std::unique_ptr<SLayerSurface>>& layerSurfaces, bool exclusiveZone, wlr_box* usableArea) {
|
||||
void CHyprRenderer::arrangeLayerArray(CMonitor* pMonitor, const std::vector<std::unique_ptr<SLayerSurface>>& layerSurfaces, bool exclusiveZone, wlr_box* usableArea) {
|
||||
wlr_box full_area = {pMonitor->vecPosition.x, pMonitor->vecPosition.y, pMonitor->vecSize.x, pMonitor->vecSize.y};
|
||||
|
||||
for (auto& ls : layerSurfaces) {
|
||||
@@ -641,17 +668,23 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) {
|
||||
return;
|
||||
}
|
||||
|
||||
pixman_region32_translate(&damageBox, x, y);
|
||||
pixman_region32_t damageBoxForEach;
|
||||
pixman_region32_init(&damageBoxForEach);
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
double lx = 0, ly = 0;
|
||||
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, m->output, &lx, &ly);
|
||||
pixman_region32_translate(&damageBox, lx, ly);
|
||||
wlr_region_scale(&damageBox, &damageBox, m->scale);
|
||||
wlr_output_damage_add(m->damage, &damageBox);
|
||||
pixman_region32_translate(&damageBox, -lx, -ly);
|
||||
|
||||
pixman_region32_copy(&damageBoxForEach, &damageBox);
|
||||
pixman_region32_translate(&damageBoxForEach, x - m->vecPosition.x, y - m->vecPosition.y);
|
||||
wlr_region_scale(&damageBoxForEach, &damageBoxForEach, m->scale);
|
||||
pixman_region32_translate(&damageBoxForEach, lx + m->vecPosition.x, ly + m->vecPosition.y);
|
||||
|
||||
wlr_output_damage_add(m->damage, &damageBoxForEach);
|
||||
}
|
||||
|
||||
pixman_region32_fini(&damageBoxForEach);
|
||||
|
||||
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
|
||||
if (*PLOGDAMAGE)
|
||||
@@ -674,7 +707,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
||||
Debug::log(LOG, "Damage: Window (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
||||
}
|
||||
|
||||
void CHyprRenderer::damageMonitor(SMonitor* pMonitor) {
|
||||
void CHyprRenderer::damageMonitor(CMonitor* pMonitor) {
|
||||
wlr_box damageBox = {0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y};
|
||||
wlr_output_damage_add_box(pMonitor->damage, &damageBox);
|
||||
|
||||
@@ -709,7 +742,7 @@ void CHyprRenderer::damageRegion(pixman_region32_t* rg) {
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderDragIcon(SMonitor* 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))
|
||||
return;
|
||||
|
||||
@@ -735,19 +768,24 @@ DAMAGETRACKINGMODES CHyprRenderer::damageTrackingModeFromStr(const std::string&
|
||||
return DAMAGE_TRACKING_INVALID;
|
||||
}
|
||||
|
||||
bool CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorRule, bool force) {
|
||||
bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorRule, bool force) {
|
||||
|
||||
Debug::log(LOG, "Applying monitor rule for %s", pMonitor->szName.c_str());
|
||||
|
||||
// if it's disabled, disable and ignore
|
||||
if (pMonitorRule->disabled) {
|
||||
wlr_output_enable(pMonitor->output, 0);
|
||||
wlr_output_commit(pMonitor->output);
|
||||
|
||||
Events::listener_monitorDestroy(nullptr, pMonitor->output);
|
||||
if (pMonitor->m_bEnabled)
|
||||
pMonitor->onDisconnect();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pMonitor->m_bEnabled) {
|
||||
pMonitor->onConnect(true); // enable it.
|
||||
force = true;
|
||||
}
|
||||
|
||||
// Check if the rule isn't already applied
|
||||
if (!force && DELTALESSTHAN(pMonitor->vecPixelSize.x, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(pMonitor->vecPixelSize.y, pMonitorRule->resolution.y, 1) && DELTALESSTHAN(pMonitor->refreshRate, pMonitorRule->refreshRate, 1) && pMonitor->scale == pMonitorRule->scale && DELTALESSTHAN(pMonitor->vecPosition.x, pMonitorRule->offset.x, 1) && DELTALESSTHAN(pMonitor->vecPosition.y, pMonitorRule->offset.y, 1) && pMonitor->transform == pMonitorRule->transform) {
|
||||
Debug::log(LOG, "Not applying a new rule to %s because it's already applied!", pMonitor->szName.c_str());
|
||||
@@ -760,67 +798,107 @@ bool CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
pMonitor->vecPosition = pMonitorRule->offset;
|
||||
|
||||
// loop over modes and choose an appropriate one.
|
||||
if (!wl_list_empty(&pMonitor->output->modes)) {
|
||||
wlr_output_mode* mode;
|
||||
bool found = false;
|
||||
if (pMonitorRule->resolution != Vector2D()) {
|
||||
if (!wl_list_empty(&pMonitor->output->modes)) {
|
||||
wlr_output_mode* mode;
|
||||
bool found = false;
|
||||
|
||||
wl_list_for_each(mode, &pMonitor->output->modes, link) {
|
||||
// if delta of refresh rate, w and h chosen and mode is < 1 we accept it
|
||||
if (DELTALESSTHAN(mode->width, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(mode->height, pMonitorRule->resolution.y, 1) && DELTALESSTHAN(mode->refresh / 1000.f, pMonitorRule->refreshRate, 1)) {
|
||||
wlr_output_set_mode(pMonitor->output, mode);
|
||||
wl_list_for_each(mode, &pMonitor->output->modes, link) {
|
||||
// if delta of refresh rate, w and h chosen and mode is < 1 we accept it
|
||||
if (DELTALESSTHAN(mode->width, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(mode->height, pMonitorRule->resolution.y, 1) && DELTALESSTHAN(mode->refresh / 1000.f, pMonitorRule->refreshRate, 1)) {
|
||||
wlr_output_set_mode(pMonitor->output, mode);
|
||||
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
Debug::log(LOG, "Monitor %s: REJECTED available mode: %ix%i@%2f!",
|
||||
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||
mode->width, mode->height, mode->refresh / 1000.f);
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Monitor %s: requested %ix%i@%2f, found available mode: %ix%i@%imHz, applying.",
|
||||
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||
mode->width, mode->height, mode->refresh);
|
||||
|
||||
found = true;
|
||||
|
||||
pMonitor->refreshRate = mode->refresh / 1000.f;
|
||||
pMonitor->vecSize = Vector2D(mode->width, mode->height);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
||||
pMonitor->vecSize = pMonitorRule->resolution;
|
||||
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
Debug::log(LOG, "Monitor %s: REJECTED available mode: %ix%i@%2f!",
|
||||
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,
|
||||
mode->width, mode->height, mode->refresh / 1000.f);
|
||||
continue;
|
||||
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);
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Monitor %s: requested %ix%i@%2f, found available mode: %ix%i@%imHz, applying.",
|
||||
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||
mode->width, mode->height, mode->refresh);
|
||||
|
||||
found = true;
|
||||
|
||||
pMonitor->refreshRate = mode->refresh / 1000.f;
|
||||
pMonitor->vecSize = Vector2D(mode->width, mode->height);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
} else {
|
||||
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
||||
pMonitor->vecSize = pMonitorRule->resolution;
|
||||
|
||||
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 {
|
||||
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
||||
pMonitor->vecSize = pMonitorRule->resolution;
|
||||
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
|
||||
|
||||
if (!PREFERREDMODE) {
|
||||
Debug::log(ERR, "Monitor %s has NO PREFERRED MODE",
|
||||
(int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate);
|
||||
|
||||
if (!wl_list_empty(&pMonitor->output->modes)) {
|
||||
wlr_output_mode* mode;
|
||||
|
||||
wl_list_for_each(mode, &pMonitor->output->modes, link) {
|
||||
wlr_output_set_mode(pMonitor->output, mode);
|
||||
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
Debug::log(LOG, "Monitor %s: REJECTED available mode: %ix%i@%2f!",
|
||||
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||
mode->width, mode->height, mode->refresh / 1000.f);
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Monitor %s: requested %ix%i@%2f, found available mode: %ix%i@%imHz, applying.",
|
||||
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||
mode->width, mode->height, mode->refresh);
|
||||
|
||||
pMonitor->refreshRate = mode->refresh / 1000.f;
|
||||
pMonitor->vecSize = Vector2D(mode->width, mode->height);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Preferred is valid
|
||||
wlr_output_set_mode(pMonitor->output, PREFERREDMODE);
|
||||
|
||||
pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height);
|
||||
pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wlr_output_set_transform(pMonitor->output, pMonitorRule->transform);
|
||||
pMonitor->transform = pMonitorRule->transform;
|
||||
|
@@ -34,9 +34,9 @@ public:
|
||||
void damageBox(wlr_box*);
|
||||
void damageBox(const int& x, const int& y, const int& w, const int& h);
|
||||
void damageRegion(pixman_region32_t*);
|
||||
void damageMonitor(SMonitor*);
|
||||
bool applyMonitorRule(SMonitor*, SMonitorRule*, bool force = false);
|
||||
bool shouldRenderWindow(CWindow*, SMonitor*);
|
||||
void damageMonitor(CMonitor*);
|
||||
bool applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false);
|
||||
bool shouldRenderWindow(CWindow*, CMonitor*);
|
||||
bool shouldRenderWindow(CWindow*);
|
||||
void ensureCursorRenderingMode();
|
||||
bool shouldRenderCursor();
|
||||
@@ -46,11 +46,11 @@ public:
|
||||
DAMAGETRACKINGMODES damageTrackingModeFromStr(const std::string&);
|
||||
|
||||
private:
|
||||
void arrangeLayerArray(SMonitor*, const std::vector<std::unique_ptr<SLayerSurface>>&, bool, wlr_box*);
|
||||
void renderWorkspaceWithFullscreenWindow(SMonitor*, CWorkspace*, timespec*);
|
||||
void renderWindow(CWindow*, SMonitor*, timespec*, bool, eRenderPassMode);
|
||||
void renderLayer(SLayerSurface*, SMonitor*, timespec*);
|
||||
void renderDragIcon(SMonitor*, timespec*);
|
||||
void arrangeLayerArray(CMonitor*, const std::vector<std::unique_ptr<SLayerSurface>>&, bool, wlr_box*);
|
||||
void renderWorkspaceWithFullscreenWindow(CMonitor*, CWorkspace*, timespec*);
|
||||
void renderWindow(CWindow*, CMonitor*, timespec*, bool, eRenderPassMode);
|
||||
void renderLayer(SLayerSurface*, CMonitor*, timespec*);
|
||||
void renderDragIcon(CMonitor*, timespec*);
|
||||
|
||||
bool m_bHasARenderedCursor = true;
|
||||
|
||||
|
@@ -14,6 +14,19 @@ public:
|
||||
GLint texAttrib;
|
||||
GLint discardOpaque;
|
||||
|
||||
GLint topLeft;
|
||||
GLint bottomRight;
|
||||
GLint fullSize;
|
||||
GLint radius;
|
||||
GLint primitiveMultisample;
|
||||
|
||||
GLint thick;
|
||||
|
||||
GLint halfpixel;
|
||||
|
||||
GLint range;
|
||||
GLint shadowPower;
|
||||
|
||||
GLint getUniformLocation(const std::string&);
|
||||
|
||||
private:
|
||||
|
@@ -48,7 +48,7 @@ void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprDropShadowDecoration::draw(SMonitor* pMonitor, float a) {
|
||||
void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(m_pWindow))
|
||||
return;
|
||||
|
@@ -9,7 +9,7 @@ public:
|
||||
|
||||
virtual SWindowDecorationExtents getWindowDecorationExtents();
|
||||
|
||||
virtual void draw(SMonitor*, float a);
|
||||
virtual void draw(CMonitor*, float a);
|
||||
|
||||
virtual eDecorationType getDecorationType();
|
||||
|
||||
|
@@ -64,7 +64,7 @@ void CHyprGroupBarDecoration::damageEntire() {
|
||||
g_pHyprRenderer->damageBox(&dm);
|
||||
}
|
||||
|
||||
void CHyprGroupBarDecoration::draw(SMonitor* pMonitor, float a) {
|
||||
void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
// get how many bars we will draw
|
||||
int barsToDraw = m_dwGroupMembers.size();
|
||||
|
||||
|
@@ -10,7 +10,7 @@ public:
|
||||
|
||||
virtual SWindowDecorationExtents getWindowDecorationExtents();
|
||||
|
||||
virtual void draw(SMonitor*, float a);
|
||||
virtual void draw(CMonitor*, float a);
|
||||
|
||||
virtual eDecorationType getDecorationType();
|
||||
|
||||
|
@@ -14,7 +14,7 @@ struct SWindowDecorationExtents {
|
||||
};
|
||||
|
||||
class CWindow;
|
||||
struct SMonitor;
|
||||
class CMonitor;
|
||||
|
||||
interface IHyprWindowDecoration {
|
||||
public:
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
|
||||
virtual SWindowDecorationExtents getWindowDecorationExtents() = 0;
|
||||
|
||||
virtual void draw(SMonitor*, float a) = 0;
|
||||
virtual void draw(CMonitor*, float a) = 0;
|
||||
|
||||
virtual eDecorationType getDecorationType() = 0;
|
||||
|
||||
|
Submodule subprojects/wlroots updated: 5dc1d4671d...7b5e890e61
Reference in New Issue
Block a user