mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-15 03:55:46 -07:00
Compare commits
40 Commits
v0.19.0bet
...
v0.19.2bet
Author | SHA1 | Date | |
---|---|---|---|
|
111d209bff | ||
|
b45a213413 | ||
|
1a9ee959dd | ||
|
46891b12cf | ||
|
0c1bec023f | ||
|
80f58bc93f | ||
|
06e6c6021e | ||
|
e8b99ae13a | ||
|
bb99f151da | ||
|
f97289a3c0 | ||
|
6381b6474f | ||
|
c3f1dc3f52 | ||
|
62f4503f07 | ||
|
bf78dcecf0 | ||
|
d5352a5d12 | ||
|
fd43d2bea7 | ||
|
b9812f8bc0 | ||
|
fba03540d5 | ||
|
11a1a6c271 | ||
|
ff12a41c40 | ||
|
629cca4816 | ||
|
9fc143cf3d | ||
|
726732244a | ||
|
be6e1a33b1 | ||
|
6e3bd440ba | ||
|
cba10ba5b7 | ||
|
050693be2e | ||
|
0803febac5 | ||
|
6259202c01 | ||
|
e1d7a13333 | ||
|
bf5844d607 | ||
|
5b7fec481b | ||
|
73b3bbe49b | ||
|
d8dcf670da | ||
|
87b9313034 | ||
|
993c382e74 | ||
|
3c9a7811b8 | ||
|
6c8d993477 | ||
|
dfa9277867 | ||
|
50e37419e9 |
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create tarball with submodules
|
- name: Create tarball with submodules
|
||||||
id: tar
|
id: tar
|
||||||
run: mkdir hyprland-source; mv ./* ./hyprland-source; tar -czv --owner=0 --group=0 --no-same-owner --no-same-permissions -f source.tar.gz *
|
run: mkdir hyprland-source; mv ./* ./hyprland-source || tar -czv --owner=0 --group=0 --no-same-owner --no-same-permissions -f source.tar.gz *
|
||||||
|
|
||||||
- id: whatrelease
|
- id: whatrelease
|
||||||
name: Get latest release
|
name: Get latest release
|
||||||
|
@@ -22,7 +22,7 @@ execute_process(
|
|||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND sh -c "git show ${GIT_COMMIT_HASH} | head -n 5 | tail -n 1 | sed -s 's/#|\"//g'"
|
COMMAND sh -c "git show ${GIT_COMMIT_HASH} | head -n 5 | tail -n 1 | sed -e 's/#//g' -e 's/\"//g'"
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_COMMIT_MESSAGE
|
OUTPUT_VARIABLE GIT_COMMIT_MESSAGE
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
@@ -89,6 +89,16 @@ message(STATUS "Setting link libraries")
|
|||||||
|
|
||||||
target_link_libraries(Hyprland PkgConfig::deps)
|
target_link_libraries(Hyprland PkgConfig::deps)
|
||||||
|
|
||||||
|
IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||||
|
message(STATUS "Setting debug flags")
|
||||||
|
|
||||||
|
target_link_libraries(Hyprland asan)
|
||||||
|
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg -no-pie -fno-builtin -fsanitize=address")
|
||||||
|
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg -no-pie -fno-builtin")
|
||||||
|
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg -no-pie -fno-builtin")
|
||||||
|
ENDIF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||||
|
|
||||||
target_link_libraries(Hyprland
|
target_link_libraries(Hyprland
|
||||||
${CMAKE_SOURCE_DIR}/subprojects/wlroots/build/libwlroots.so.12032 # wlroots is provided by us
|
${CMAKE_SOURCE_DIR}/subprojects/wlroots/build/libwlroots.so.12032 # wlroots is provided by us
|
||||||
pixman-1
|
pixman-1
|
||||||
@@ -97,13 +107,6 @@ target_link_libraries(Hyprland
|
|||||||
pthread
|
pthread
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
${CMAKE_SOURCE_DIR}/ext-workspace-unstable-v1-protocol.o
|
${CMAKE_SOURCE_DIR}/ext-workspace-unstable-v1-protocol.o
|
||||||
|
${CMAKE_SOURCE_DIR}/wlr-foreign-toplevel-management-unstable-v1-protocol.o
|
||||||
${CMAKE_SOURCE_DIR}/hyprland-toplevel-export-v1-protocol.o
|
${CMAKE_SOURCE_DIR}/hyprland-toplevel-export-v1-protocol.o
|
||||||
)
|
)
|
||||||
|
|
||||||
IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
|
||||||
message(STATUS "Setting debug flags")
|
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg -no-pie -fno-builtin")
|
|
||||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg -no-pie -fno-builtin")
|
|
||||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg -no-pie -fno-builtin")
|
|
||||||
ENDIF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
|
||||||
|
12
Makefile
12
Makefile
@@ -111,6 +111,16 @@ linux-dmabuf-unstable-v1-protocol.c:
|
|||||||
|
|
||||||
linux-dmabuf-unstable-v1-protocol.o: linux-dmabuf-unstable-v1-protocol.h
|
linux-dmabuf-unstable-v1-protocol.o: linux-dmabuf-unstable-v1-protocol.h
|
||||||
|
|
||||||
|
wlr-foreign-toplevel-management-unstable-v1-protocol.h:
|
||||||
|
$(WAYLAND_SCANNER) server-header \
|
||||||
|
protocols/wlr-foreign-toplevel-management-unstable-v1.xml $@
|
||||||
|
|
||||||
|
wlr-foreign-toplevel-management-unstable-v1-protocol.c:
|
||||||
|
$(WAYLAND_SCANNER) private-code \
|
||||||
|
protocols/wlr-foreign-toplevel-management-unstable-v1.xml $@
|
||||||
|
|
||||||
|
wlr-foreign-toplevel-management-unstable-v1-protocol.o: wlr-foreign-toplevel-management-unstable-v1-protocol.h
|
||||||
|
|
||||||
legacyrenderer:
|
legacyrenderer:
|
||||||
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DLEGACY_RENDERER:STRING=true -H./ -B./build -G Ninja
|
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$(shell nproc)
|
cmake --build ./build --config Release --target all -j$(shell nproc)
|
||||||
@@ -189,7 +199,7 @@ uninstall:
|
|||||||
rm -f ${PREFIX}/share/man/man1/Hyprland.1
|
rm -f ${PREFIX}/share/man/man1/Hyprland.1
|
||||||
rm -f ${PREFIX}/share/man/man1/hyprctl.1
|
rm -f ${PREFIX}/share/man/man1/hyprctl.1
|
||||||
|
|
||||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o wlr-output-power-management-unstable-v1-protocol.o linux-dmabuf-unstable-v1-protocol.o hyprland-toplevel-export-v1-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 linux-dmabuf-unstable-v1-protocol.o hyprland-toplevel-export-v1-protocol.o wlr-foreign-toplevel-management-unstable-v1-protocol.o
|
||||||
|
|
||||||
fixwlr:
|
fixwlr:
|
||||||
sed -i -E 's/(soversion = 12)([^032]|$$)/soversion = 12032/g' subprojects/wlroots/meson.build
|
sed -i -E 's/(soversion = 12)([^032]|$$)/soversion = 12032/g' subprojects/wlroots/meson.build
|
||||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -3,11 +3,11 @@
|
|||||||
"hyprland-protocols": {
|
"hyprland-protocols": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1670258048,
|
"lastModified": 1670703428,
|
||||||
"narHash": "sha256-Lm2sXnDVZNE+taHqsqVibvPmSdu65VHvXI507KVX4lg=",
|
"narHash": "sha256-4KUW5SKR0Y9uaYGcYwy53YJ3B/sgiprCL4fRGO+mpOA=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprland-protocols",
|
"repo": "hyprland-protocols",
|
||||||
"rev": "0dcff94fc10df2bbb66d3e1b5a1d6cfd3ada5515",
|
"rev": "d0d6db8cb5bef6d93ca3ad8fb2124964173396da",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -82,11 +82,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1670202338,
|
"lastModified": 1670797151,
|
||||||
"narHash": "sha256-StTfshdAoSxO+t0wRbq1I3YESLFIQWFjGJse5ICV8rk=",
|
"narHash": "sha256-ZFzJHqSXhGCjSeMgqTyJG1KJ2Nlwa+NEN9K4oGhWcjg=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "xdg-desktop-portal-hyprland",
|
"repo": "xdg-desktop-portal-hyprland",
|
||||||
"rev": "af840a9e0947a79a37a95a9f62062653721e43fa",
|
"rev": "36ffb6892e14b9c5be6e321b3c47fe286ac256e6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@@ -77,6 +77,10 @@
|
|||||||
waybar-hyprland = prev.waybar.overrideAttrs (oldAttrs: {
|
waybar-hyprland = prev.waybar.overrideAttrs (oldAttrs: {
|
||||||
mesonFlags = oldAttrs.mesonFlags ++ ["-Dexperimental=true"];
|
mesonFlags = oldAttrs.mesonFlags ++ ["-Dexperimental=true"];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
xdg-desktop-portal-hyprland = inputs.xdph.packages.${prev.system}.default.override {
|
||||||
|
hyprland-share-picker = inputs.xdph.packages.${prev.system}.hyprland-share-picker.override {inherit hyprland;};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
packages = genSystems (system:
|
packages = genSystems (system:
|
||||||
|
@@ -7,6 +7,11 @@ inputs: {
|
|||||||
}:
|
}:
|
||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.programs.hyprland;
|
cfg = config.programs.hyprland;
|
||||||
|
|
||||||
|
defaultHyprlandPackage = inputs.self.packages.${pkgs.system}.default.override {
|
||||||
|
enableXWayland = cfg.xwayland.enable;
|
||||||
|
hidpiXWayland = cfg.xwayland.hidpi;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
(mkRemovedOptionModule ["programs" "hyprland" "extraPackages"] "extraPackages has been removed. Use environment.systemPackages instead.")
|
(mkRemovedOptionModule ["programs" "hyprland" "extraPackages"] "extraPackages has been removed. Use environment.systemPackages instead.")
|
||||||
@@ -23,7 +28,7 @@ in {
|
|||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.nullOr types.package;
|
type = types.nullOr types.package;
|
||||||
default = inputs.self.packages.${pkgs.system}.default;
|
default = defaultHyprlandPackage;
|
||||||
defaultText = literalExpression "<Hyprland flake>.packages.<system>.default";
|
defaultText = literalExpression "<Hyprland flake>.packages.<system>.default";
|
||||||
example = literalExpression "<Hyprland flake>.packages.<system>.default.override { }";
|
example = literalExpression "<Hyprland flake>.packages.<system>.default.override { }";
|
||||||
description = ''
|
description = ''
|
||||||
@@ -31,6 +36,23 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
xwayland = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Enable XWayland.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
hidpi = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Enable HiDPI XWayland.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
recommendedEnvironment = mkOption {
|
recommendedEnvironment = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@@ -44,7 +66,7 @@ in {
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
environment = {
|
environment = {
|
||||||
systemPackages = lib.optional (cfg.package != null) cfg.package;
|
systemPackages = lib.optional (cfg.package != null) defaultHyprlandPackage;
|
||||||
|
|
||||||
sessionVariables = mkIf cfg.recommendedEnvironment {
|
sessionVariables = mkIf cfg.recommendedEnvironment {
|
||||||
NIXOS_OZONE_WL = "1";
|
NIXOS_OZONE_WL = "1";
|
||||||
@@ -57,11 +79,17 @@ in {
|
|||||||
xwayland.enable = mkDefault true;
|
xwayland.enable = mkDefault true;
|
||||||
};
|
};
|
||||||
security.polkit.enable = true;
|
security.polkit.enable = true;
|
||||||
services.xserver.displayManager.sessionPackages = lib.optional (cfg.package != null) cfg.package;
|
services.xserver.displayManager.sessionPackages = lib.optional (cfg.package != null) defaultHyprlandPackage;
|
||||||
xdg.portal = {
|
xdg.portal = {
|
||||||
enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
# xdg-desktop-portal-hyprland
|
# xdg-desktop-portal-hyprland
|
||||||
extraPortals = [inputs.xdph.packages.${pkgs.system}.default];
|
extraPortals = lib.mkIf (cfg.package != null) [
|
||||||
|
(inputs.xdph.packages.${pkgs.system}.xdg-desktop-portal-hyprland.override {
|
||||||
|
hyprland-share-picker = inputs.xdph.packages.${pkgs.system}.hyprland-share-picker.override {
|
||||||
|
hyprland = defaultHyprlandPackage;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ wayland_scanner = find_program(
|
|||||||
protocols = [
|
protocols = [
|
||||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||||
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
||||||
|
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
||||||
['wlr-layer-shell-unstable-v1.xml'],
|
['wlr-layer-shell-unstable-v1.xml'],
|
||||||
['wlr-output-power-management-unstable-v1.xml'],
|
['wlr-output-power-management-unstable-v1.xml'],
|
||||||
['ext-workspace-unstable-v1.xml'],
|
['ext-workspace-unstable-v1.xml'],
|
||||||
|
270
protocols/wlr-foreign-toplevel-management-unstable-v1.xml
Normal file
270
protocols/wlr-foreign-toplevel-management-unstable-v1.xml
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="wlr_foreign_toplevel_management_unstable_v1">
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2018 Ilia Bozhinov
|
||||||
|
|
||||||
|
Permission to use, copy, modify, distribute, and sell this
|
||||||
|
software and its documentation for any purpose is hereby granted
|
||||||
|
without fee, provided that the above copyright notice appear in
|
||||||
|
all copies and that both that copyright notice and this permission
|
||||||
|
notice appear in supporting documentation, and that the name of
|
||||||
|
the copyright holders not be used in advertising or publicity
|
||||||
|
pertaining to distribution of the software without specific,
|
||||||
|
written prior permission. The copyright holders make no
|
||||||
|
representations about the suitability of this software for any
|
||||||
|
purpose. It is provided "as is" without express or implied
|
||||||
|
warranty.
|
||||||
|
|
||||||
|
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||||
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<interface name="zwlr_foreign_toplevel_manager_v1" version="3">
|
||||||
|
<description summary="list and control opened apps">
|
||||||
|
The purpose of this protocol is to enable the creation of taskbars
|
||||||
|
and docks by providing them with a list of opened applications and
|
||||||
|
letting them request certain actions on them, like maximizing, etc.
|
||||||
|
|
||||||
|
After a client binds the zwlr_foreign_toplevel_manager_v1, each opened
|
||||||
|
toplevel window will be sent via the toplevel event
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<event name="toplevel">
|
||||||
|
<description summary="a toplevel has been created">
|
||||||
|
This event is emitted whenever a new toplevel window is created. It
|
||||||
|
is emitted for all toplevels, regardless of the app that has created
|
||||||
|
them.
|
||||||
|
|
||||||
|
All initial details of the toplevel(title, app_id, states, etc.) will
|
||||||
|
be sent immediately after this event via the corresponding events in
|
||||||
|
zwlr_foreign_toplevel_handle_v1.
|
||||||
|
</description>
|
||||||
|
<arg name="toplevel" type="new_id" interface="zwlr_foreign_toplevel_handle_v1"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="stop">
|
||||||
|
<description summary="stop sending events">
|
||||||
|
Indicates the client no longer wishes to receive events for new toplevels.
|
||||||
|
However the compositor may emit further toplevel_created events, until
|
||||||
|
the finished event is emitted.
|
||||||
|
|
||||||
|
The client must not send any more requests after this one.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="finished" type="destructor">
|
||||||
|
<description summary="the compositor has finished with the toplevel manager">
|
||||||
|
This event indicates that the compositor is done sending events to the
|
||||||
|
zwlr_foreign_toplevel_manager_v1. The server will destroy the object
|
||||||
|
immediately after sending this request, so it will become invalid and
|
||||||
|
the client should free any resources associated with it.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="zwlr_foreign_toplevel_handle_v1" version="3">
|
||||||
|
<description summary="an opened toplevel">
|
||||||
|
A zwlr_foreign_toplevel_handle_v1 object represents an opened toplevel
|
||||||
|
window. Each app may have multiple opened toplevels.
|
||||||
|
|
||||||
|
Each toplevel has a list of outputs it is visible on, conveyed to the
|
||||||
|
client with the output_enter and output_leave events.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<event name="title">
|
||||||
|
<description summary="title change">
|
||||||
|
This event is emitted whenever the title of the toplevel changes.
|
||||||
|
</description>
|
||||||
|
<arg name="title" type="string"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="app_id">
|
||||||
|
<description summary="app-id change">
|
||||||
|
This event is emitted whenever the app-id of the toplevel changes.
|
||||||
|
</description>
|
||||||
|
<arg name="app_id" type="string"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="output_enter">
|
||||||
|
<description summary="toplevel entered an output">
|
||||||
|
This event is emitted whenever the toplevel becomes visible on
|
||||||
|
the given output. A toplevel may be visible on multiple outputs.
|
||||||
|
</description>
|
||||||
|
<arg name="output" type="object" interface="wl_output"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="output_leave">
|
||||||
|
<description summary="toplevel left an output">
|
||||||
|
This event is emitted whenever the toplevel stops being visible on
|
||||||
|
the given output. It is guaranteed that an entered-output event
|
||||||
|
with the same output has been emitted before this event.
|
||||||
|
</description>
|
||||||
|
<arg name="output" type="object" interface="wl_output"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="set_maximized">
|
||||||
|
<description summary="requests that the toplevel be maximized">
|
||||||
|
Requests that the toplevel be maximized. If the maximized state actually
|
||||||
|
changes, this will be indicated by the state event.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="unset_maximized">
|
||||||
|
<description summary="requests that the toplevel be unmaximized">
|
||||||
|
Requests that the toplevel be unmaximized. If the maximized state actually
|
||||||
|
changes, this will be indicated by the state event.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_minimized">
|
||||||
|
<description summary="requests that the toplevel be minimized">
|
||||||
|
Requests that the toplevel be minimized. If the minimized state actually
|
||||||
|
changes, this will be indicated by the state event.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="unset_minimized">
|
||||||
|
<description summary="requests that the toplevel be unminimized">
|
||||||
|
Requests that the toplevel be unminimized. If the minimized state actually
|
||||||
|
changes, this will be indicated by the state event.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="activate">
|
||||||
|
<description summary="activate the toplevel">
|
||||||
|
Request that this toplevel be activated on the given seat.
|
||||||
|
There is no guarantee the toplevel will be actually activated.
|
||||||
|
</description>
|
||||||
|
<arg name="seat" type="object" interface="wl_seat"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="state">
|
||||||
|
<description summary="types of states on the toplevel">
|
||||||
|
The different states that a toplevel can have. These have the same meaning
|
||||||
|
as the states with the same names defined in xdg-toplevel
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<entry name="maximized" value="0" summary="the toplevel is maximized"/>
|
||||||
|
<entry name="minimized" value="1" summary="the toplevel is minimized"/>
|
||||||
|
<entry name="activated" value="2" summary="the toplevel is active"/>
|
||||||
|
<entry name="fullscreen" value="3" summary="the toplevel is fullscreen" since="2"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<event name="state">
|
||||||
|
<description summary="the toplevel state changed">
|
||||||
|
This event is emitted immediately after the zlw_foreign_toplevel_handle_v1
|
||||||
|
is created and each time the toplevel state changes, either because of a
|
||||||
|
compositor action or because of a request in this protocol.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="state" type="array"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="done">
|
||||||
|
<description summary="all information about the toplevel has been sent">
|
||||||
|
This event is sent after all changes in the toplevel state have been
|
||||||
|
sent.
|
||||||
|
|
||||||
|
This allows changes to the zwlr_foreign_toplevel_handle_v1 properties
|
||||||
|
to be seen as atomic, even if they happen via multiple events.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="close">
|
||||||
|
<description summary="request that the toplevel be closed">
|
||||||
|
Send a request to the toplevel to close itself. The compositor would
|
||||||
|
typically use a shell-specific method to carry out this request, for
|
||||||
|
example by sending the xdg_toplevel.close event. However, this gives
|
||||||
|
no guarantees the toplevel will actually be destroyed. If and when
|
||||||
|
this happens, the zwlr_foreign_toplevel_handle_v1.closed event will
|
||||||
|
be emitted.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_rectangle">
|
||||||
|
<description summary="the rectangle which represents the toplevel">
|
||||||
|
The rectangle of the surface specified in this request corresponds to
|
||||||
|
the place where the app using this protocol represents the given toplevel.
|
||||||
|
It can be used by the compositor as a hint for some operations, e.g
|
||||||
|
minimizing. The client is however not required to set this, in which
|
||||||
|
case the compositor is free to decide some default value.
|
||||||
|
|
||||||
|
If the client specifies more than one rectangle, only the last one is
|
||||||
|
considered.
|
||||||
|
|
||||||
|
The dimensions are given in surface-local coordinates.
|
||||||
|
Setting width=height=0 removes the already-set rectangle.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
<arg name="x" type="int"/>
|
||||||
|
<arg name="y" type="int"/>
|
||||||
|
<arg name="width" type="int"/>
|
||||||
|
<arg name="height" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="invalid_rectangle" value="0"
|
||||||
|
summary="the provided rectangle is invalid"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<event name="closed">
|
||||||
|
<description summary="this toplevel has been destroyed">
|
||||||
|
This event means the toplevel has been destroyed. It is guaranteed there
|
||||||
|
won't be any more events for this zwlr_foreign_toplevel_handle_v1. The
|
||||||
|
toplevel itself becomes inert so any requests will be ignored except the
|
||||||
|
destroy request.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the zwlr_foreign_toplevel_handle_v1 object">
|
||||||
|
Destroys the zwlr_foreign_toplevel_handle_v1 object.
|
||||||
|
|
||||||
|
This request should be called either when the client does not want to
|
||||||
|
use the toplevel anymore or after the closed event to finalize the
|
||||||
|
destruction of the object.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Version 2 additions -->
|
||||||
|
|
||||||
|
<request name="set_fullscreen" since="2">
|
||||||
|
<description summary="request that the toplevel be fullscreened">
|
||||||
|
Requests that the toplevel be fullscreened on the given output. If the
|
||||||
|
fullscreen state and/or the outputs the toplevel is visible on actually
|
||||||
|
change, this will be indicated by the state and output_enter/leave
|
||||||
|
events.
|
||||||
|
|
||||||
|
The output parameter is only a hint to the compositor. Also, if output
|
||||||
|
is NULL, the compositor should decide which output the toplevel will be
|
||||||
|
fullscreened on, if at all.
|
||||||
|
</description>
|
||||||
|
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="unset_fullscreen" since="2">
|
||||||
|
<description summary="request that the toplevel be unfullscreened">
|
||||||
|
Requests that the toplevel be unfullscreened. If the fullscreen state
|
||||||
|
actually changes, this will be indicated by the state event.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Version 3 additions -->
|
||||||
|
|
||||||
|
<event name="parent" since="3">
|
||||||
|
<description summary="parent change">
|
||||||
|
This event is emitted whenever the parent of the toplevel changes.
|
||||||
|
|
||||||
|
No event is emitted when the parent handle is destroyed by the client.
|
||||||
|
</description>
|
||||||
|
<arg name="parent" type="object" interface="zwlr_foreign_toplevel_handle_v1" allow-null="true"/>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
@@ -366,7 +366,7 @@ void CCompositor::startCompositor() {
|
|||||||
if (m_sWLRSession /* Session-less Hyprland usually means a nest, don't update the env in that case */ && fork() == 0)
|
if (m_sWLRSession /* Session-less Hyprland usually means a nest, don't update the env in that case */ && fork() == 0)
|
||||||
execl("/bin/sh", "/bin/sh", "-c", "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE", nullptr);
|
execl("/bin/sh", "/bin/sh", "-c", "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE", nullptr);
|
||||||
|
|
||||||
Debug::log(LOG, "Running on WAYLAND_DISPLAY: %s", m_szWLDisplaySocket);
|
Debug::log(LOG, "Running on WAYLAND_DISPLAY: %s", m_szWLDisplaySocket.c_str());
|
||||||
|
|
||||||
if (!wlr_backend_start(m_sWLRBackend)) {
|
if (!wlr_backend_start(m_sWLRBackend)) {
|
||||||
Debug::log(CRIT, "Backend did not start!");
|
Debug::log(CRIT, "Backend did not start!");
|
||||||
@@ -438,7 +438,7 @@ CMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
|
|||||||
void CCompositor::removeWindowFromVectorSafe(CWindow* pWindow) {
|
void CCompositor::removeWindowFromVectorSafe(CWindow* pWindow) {
|
||||||
if (windowExists(pWindow) && !pWindow->m_bFadingOut){
|
if (windowExists(pWindow) && !pWindow->m_bFadingOut){
|
||||||
if (pWindow->m_bIsX11 && pWindow->m_iX11Type == 2) {
|
if (pWindow->m_bIsX11 && pWindow->m_iX11Type == 2) {
|
||||||
m_dUnmanagedX11Windows.erase(std::remove_if(m_dUnmanagedX11Windows.begin(), m_dUnmanagedX11Windows.end(), [&](std::unique_ptr<CWindow>& el) { return el.get() == pWindow; }));
|
std::erase_if(m_dUnmanagedX11Windows, [&](std::unique_ptr<CWindow>& el) { return el.get() == pWindow; });
|
||||||
}
|
}
|
||||||
|
|
||||||
// if X11, also check its children
|
// if X11, also check its children
|
||||||
@@ -449,16 +449,16 @@ void CCompositor::removeWindowFromVectorSafe(CWindow* pWindow) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (w->m_pX11Parent == pWindow)
|
if (w->m_pX11Parent == pWindow)
|
||||||
m_vWindows.erase(std::remove_if(m_vWindows.begin(), m_vWindows.end(), [&](std::unique_ptr<CWindow>& el) { return el.get() == w.get(); }));
|
std::erase_if(m_vWindows, [&](std::unique_ptr<CWindow>& el) { return el.get() == w.get(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& w : m_dUnmanagedX11Windows) {
|
for (auto& w : m_dUnmanagedX11Windows) {
|
||||||
if (w->m_pX11Parent == pWindow)
|
if (w->m_pX11Parent == pWindow)
|
||||||
m_dUnmanagedX11Windows.erase(std::remove_if(m_dUnmanagedX11Windows.begin(), m_dUnmanagedX11Windows.end(), [&](std::unique_ptr<CWindow>& el) { return el.get() == w.get(); }));
|
std::erase_if(m_dUnmanagedX11Windows, [&](std::unique_ptr<CWindow>& el) { return el.get() == w.get(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vWindows.erase(std::remove_if(m_vWindows.begin(), m_vWindows.end(), [&](std::unique_ptr<CWindow>& el) { return el.get() == pWindow; }));
|
std::erase_if(m_vWindows, [&](std::unique_ptr<CWindow>& el) { return el.get() == pWindow; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -911,6 +911,9 @@ wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<
|
|||||||
|
|
||||||
CWindow* CCompositor::getWindowFromSurface(wlr_surface* pSurface) {
|
CWindow* CCompositor::getWindowFromSurface(wlr_surface* pSurface) {
|
||||||
for (auto& w : m_vWindows) {
|
for (auto& w : m_vWindows) {
|
||||||
|
if (!w->m_bIsMapped || w->m_bFadingOut || !w->m_bMappedX11)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (g_pXWaylandManager->getWindowSurface(w.get()) == pSurface)
|
if (g_pXWaylandManager->getWindowSurface(w.get()) == pSurface)
|
||||||
return w.get();
|
return w.get();
|
||||||
}
|
}
|
||||||
@@ -928,6 +931,23 @@ CWindow* CCompositor::getWindowFromHandle(uint32_t handle) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CWindow* CCompositor::getWindowFromZWLRHandle(wl_resource* handle) {
|
||||||
|
for (auto& w : m_vWindows) {
|
||||||
|
if (!w->m_bIsMapped || w->isHidden() || !w->m_phForeignToplevel)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wl_resource* current;
|
||||||
|
|
||||||
|
wl_list_for_each(current, &w->m_phForeignToplevel->resources, link) {
|
||||||
|
if (current == handle) {
|
||||||
|
return w.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
CWindow* CCompositor::getFullscreenWindowOnWorkspace(const int& ID) {
|
CWindow* CCompositor::getFullscreenWindowOnWorkspace(const int& ID) {
|
||||||
for (auto& w : m_vWindows) {
|
for (auto& w : m_vWindows) {
|
||||||
if (w->m_iWorkspaceID == ID && w->m_bIsFullscreen)
|
if (w->m_iWorkspaceID == ID && w->m_bIsFullscreen)
|
||||||
@@ -1068,8 +1088,9 @@ void CCompositor::cleanupFadingOut(const int& monid) {
|
|||||||
|
|
||||||
g_pHyprOpenGL->m_mWindowFramebuffers[w].release();
|
g_pHyprOpenGL->m_mWindowFramebuffers[w].release();
|
||||||
g_pHyprOpenGL->m_mWindowFramebuffers.erase(w);
|
g_pHyprOpenGL->m_mWindowFramebuffers.erase(w);
|
||||||
|
w->m_bFadingOut = false;
|
||||||
removeWindowFromVectorSafe(w);
|
removeWindowFromVectorSafe(w);
|
||||||
m_vWindowsFadingOut.erase(std::remove(m_vWindowsFadingOut.begin(), m_vWindowsFadingOut.end(), w));
|
std::erase(m_vWindowsFadingOut, w);
|
||||||
|
|
||||||
Debug::log(LOG, "Cleanup: destroyed a window");
|
Debug::log(LOG, "Cleanup: destroyed a window");
|
||||||
|
|
||||||
@@ -1454,22 +1475,14 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
|
|||||||
|
|
||||||
|
|
||||||
// opacity
|
// opacity
|
||||||
if (pWindow->m_bIsFullscreen) {
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
if (pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) {
|
||||||
if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL)
|
|
||||||
pWindow->m_fActiveInactiveAlpha = *PFULLSCREENALPHA;
|
pWindow->m_fActiveInactiveAlpha = *PFULLSCREENALPHA;
|
||||||
else {
|
|
||||||
if (pWindow == m_pLastWindow)
|
|
||||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alpha * *PACTIVEALPHA;
|
|
||||||
else
|
|
||||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? pWindow->m_sSpecialRenderData.alphaInactive * *PINACTIVEALPHA : *PINACTIVEALPHA;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (pWindow == m_pLastWindow)
|
if (pWindow == m_pLastWindow)
|
||||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alpha * *PACTIVEALPHA;
|
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaOverride ? pWindow->m_sSpecialRenderData.alpha : pWindow->m_sSpecialRenderData.alpha * *PACTIVEALPHA;
|
||||||
else
|
else
|
||||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? pWindow->m_sSpecialRenderData.alphaInactive * *PINACTIVEALPHA : *PINACTIVEALPHA;
|
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? (pWindow->m_sSpecialRenderData.alphaInactiveOverride ? pWindow->m_sSpecialRenderData.alphaInactive : pWindow->m_sSpecialRenderData.alphaInactive * *PINACTIVEALPHA) : *PINACTIVEALPHA;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dim
|
// dim
|
||||||
@@ -1580,7 +1593,8 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int offsetLeft = std::stoi(OFFSET) % m_vMonitors.size(); // no need to cycle more
|
int offsetLeft = std::stoi(OFFSET);
|
||||||
|
offsetLeft = offsetLeft < 0 ? -((-offsetLeft) % m_vMonitors.size()) : offsetLeft % m_vMonitors.size();
|
||||||
|
|
||||||
int currentPlace = 0;
|
int currentPlace = 0;
|
||||||
for (int i = 0; i < (int)m_vMonitors.size(); i++) {
|
for (int i = 0; i < (int)m_vMonitors.size(); i++) {
|
||||||
|
@@ -128,6 +128,7 @@ public:
|
|||||||
CWindow* getWindowForPopup(wlr_xdg_popup*);
|
CWindow* getWindowForPopup(wlr_xdg_popup*);
|
||||||
CWindow* getWindowFromSurface(wlr_surface*);
|
CWindow* getWindowFromSurface(wlr_surface*);
|
||||||
CWindow* getWindowFromHandle(uint32_t);
|
CWindow* getWindowFromHandle(uint32_t);
|
||||||
|
CWindow* getWindowFromZWLRHandle(wl_resource*);
|
||||||
bool isWorkspaceVisible(const int&);
|
bool isWorkspaceVisible(const int&);
|
||||||
CWorkspace* getWorkspaceByID(const int&);
|
CWorkspace* getWorkspaceByID(const int&);
|
||||||
CWorkspace* getWorkspaceByName(const std::string&);
|
CWorkspace* getWorkspaceByName(const std::string&);
|
||||||
|
@@ -328,14 +328,23 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
|
|||||||
}
|
}
|
||||||
} else if (r.szRule.find("opacity") == 0) {
|
} else if (r.szRule.find("opacity") == 0) {
|
||||||
try {
|
try {
|
||||||
std::string alphaPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
CVarList vars(r.szRule, 0, ' ');
|
||||||
|
|
||||||
if (alphaPart.contains(' ')) {
|
for (size_t i = 1 /* first item is "opacity" */; i < vars.size(); ++i) {
|
||||||
// we have a space, 2 values
|
if (i == 1) {
|
||||||
m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' ')));
|
// first arg, alpha
|
||||||
m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1));
|
m_sSpecialRenderData.alpha = std::stof(vars[i]);
|
||||||
} else {
|
} else {
|
||||||
m_sSpecialRenderData.alpha = std::stof(alphaPart);
|
if (vars[i] == "override") {
|
||||||
|
if (i == 2) {
|
||||||
|
m_sSpecialRenderData.alphaOverride = true;
|
||||||
|
} else {
|
||||||
|
m_sSpecialRenderData.alphaInactiveOverride = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_sSpecialRenderData.alphaInactive = std::stof(vars[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
Debug::log(ERR, "Opacity rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
|
Debug::log(ERR, "Opacity rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
|
||||||
|
@@ -16,7 +16,9 @@ enum eIdleInhibitMode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SWindowSpecialRenderData {
|
struct SWindowSpecialRenderData {
|
||||||
|
bool alphaOverride = false;
|
||||||
float alpha = 1.f;
|
float alpha = 1.f;
|
||||||
|
bool alphaInactiveOverride = false;
|
||||||
float alphaInactive = -1.f; // -1 means unset
|
float alphaInactive = -1.f; // -1 means unset
|
||||||
|
|
||||||
int64_t activeBorderColor = -1; // -1 means unset
|
int64_t activeBorderColor = -1; // -1 means unset
|
||||||
@@ -39,6 +41,7 @@ struct SWindowAdditionalConfigData {
|
|||||||
bool forceNoBorder = false;
|
bool forceNoBorder = false;
|
||||||
bool forceNoShadow = false;
|
bool forceNoShadow = false;
|
||||||
bool windowDanceCompat = false;
|
bool windowDanceCompat = false;
|
||||||
|
bool noMaxSize = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SWindowRule {
|
struct SWindowRule {
|
||||||
|
@@ -109,6 +109,8 @@ void CConfigManager::setDefaultVars() {
|
|||||||
configValues["master:new_is_master"].intValue = 1;
|
configValues["master:new_is_master"].intValue = 1;
|
||||||
configValues["master:new_on_top"].intValue = 0;
|
configValues["master:new_on_top"].intValue = 0;
|
||||||
configValues["master:no_gaps_when_only"].intValue = 0;
|
configValues["master:no_gaps_when_only"].intValue = 0;
|
||||||
|
configValues["master:orientation"].strValue = "left";
|
||||||
|
configValues["master:inherit_fullscreen"].intValue = 1;
|
||||||
|
|
||||||
configValues["animations:enabled"].intValue = 1;
|
configValues["animations:enabled"].intValue = 1;
|
||||||
configValues["animations:speed"].floatValue = 7.f;
|
configValues["animations:speed"].floatValue = 7.f;
|
||||||
@@ -749,6 +751,7 @@ bool windowRuleValid(const std::string& RULE) {
|
|||||||
&& RULE != "forceinput"
|
&& RULE != "forceinput"
|
||||||
&& RULE != "fullscreen"
|
&& RULE != "fullscreen"
|
||||||
&& RULE != "nofullscreenrequest"
|
&& RULE != "nofullscreenrequest"
|
||||||
|
&& RULE != "nomaxsize"
|
||||||
&& RULE != "pin"
|
&& RULE != "pin"
|
||||||
&& RULE != "noanim"
|
&& RULE != "noanim"
|
||||||
&& RULE != "windowdance"
|
&& RULE != "windowdance"
|
||||||
@@ -1687,6 +1690,18 @@ CMonitor* CConfigManager::getBoundMonitorForWS(std::string wsname) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CConfigManager::getBoundMonitorStringForWS(std::string wsname) {
|
||||||
|
for (auto& [ws, mon] : boundWorkspaces) {
|
||||||
|
const auto WSNAME = ws.find("name:") == 0 ? ws.substr(5) : ws;
|
||||||
|
|
||||||
|
if (WSNAME == wsname) {
|
||||||
|
return mon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
void CConfigManager::addExecRule(SExecRequestedRule rule) {
|
void CConfigManager::addExecRule(SExecRequestedRule rule) {
|
||||||
execRequestedRules.push_back(rule);
|
execRequestedRules.push_back(rule);
|
||||||
}
|
}
|
||||||
|
@@ -95,7 +95,7 @@ public:
|
|||||||
|
|
||||||
~CVarList() = default;
|
~CVarList() = default;
|
||||||
|
|
||||||
int size() const {
|
size_t size() const {
|
||||||
return m_vArgs.size();
|
return m_vArgs.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +141,7 @@ public:
|
|||||||
SMonitorRule getMonitorRuleFor(std::string, std::string displayName = "");
|
SMonitorRule getMonitorRuleFor(std::string, std::string displayName = "");
|
||||||
|
|
||||||
CMonitor* getBoundMonitorForWS(std::string);
|
CMonitor* getBoundMonitorForWS(std::string);
|
||||||
|
std::string getBoundMonitorStringForWS(std::string);
|
||||||
|
|
||||||
std::vector<SWindowRule> getMatchingRules(CWindow*);
|
std::vector<SWindowRule> getMatchingRules(CWindow*);
|
||||||
|
|
||||||
|
@@ -18,10 +18,10 @@
|
|||||||
#define ISDEBUG false
|
#define ISDEBUG false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LISTENER(name) void listener_##name(wl_listener*, void*); inline wl_listener listen_##name = { .notify = listener_##name };
|
#define LISTENER(name) void listener_##name(wl_listener*, void*); inline wl_listener listen_##name = { .notify = listener_##name }
|
||||||
#define DYNLISTENFUNC(name) void listener_##name(void*, void*);
|
#define DYNLISTENFUNC(name) void listener_##name(void*, void*)
|
||||||
#define DYNLISTENER(name) CHyprWLListener hyprListener_##name;
|
#define DYNLISTENER(name) CHyprWLListener hyprListener_##name
|
||||||
#define DYNMULTILISTENER(name) wl_listener listen_##name;
|
#define DYNMULTILISTENER(name) wl_listener listen_##name
|
||||||
|
|
||||||
#define VECINRECT(vec, x1, y1, x2, y2) (vec.x >= (x1) && vec.x <= (x2) && vec.y >= (y1) && vec.y <= (y2))
|
#define VECINRECT(vec, x1, y1, x2, y2) (vec.x >= (x1) && vec.x <= (x2) && vec.y >= (y1) && vec.y <= (y2))
|
||||||
|
|
||||||
|
@@ -110,6 +110,11 @@ void Events::listener_newConstraint(wl_listener* listener, void* data) {
|
|||||||
|
|
||||||
if (g_pCompositor->m_pLastFocus == PCONSTRAINT->surface) {
|
if (g_pCompositor->m_pLastFocus == PCONSTRAINT->surface) {
|
||||||
g_pInputManager->constrainMouse(CONSTRAINT->pMouse, PCONSTRAINT);
|
g_pInputManager->constrainMouse(CONSTRAINT->pMouse, PCONSTRAINT);
|
||||||
|
|
||||||
|
if (!CONSTRAINT->hintSet) {
|
||||||
|
const auto PWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
|
||||||
|
CONSTRAINT->positionHint = g_pInputManager->getMouseCoordsInternal() - PWINDOW->m_vRealPosition.goalv();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,14 +129,14 @@ void Events::listener_destroyConstraint(void* owner, void* data) {
|
|||||||
if (PWINDOW) {
|
if (PWINDOW) {
|
||||||
if (PWINDOW->m_bIsX11) {
|
if (PWINDOW->m_bIsX11) {
|
||||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr,
|
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr,
|
||||||
PCONSTRAINT->constraint->current.cursor_hint.x + PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y + PCONSTRAINT->constraint->current.cursor_hint.y);
|
PCONSTRAINT->positionHint.x + PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y + PCONSTRAINT->positionHint.y);
|
||||||
|
|
||||||
wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->constraint->current.cursor_hint.x, PCONSTRAINT->constraint->current.cursor_hint.y);
|
wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->positionHint.x, PCONSTRAINT->positionHint.y);
|
||||||
} else {
|
} else {
|
||||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr,
|
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr,
|
||||||
PCONSTRAINT->constraint->current.cursor_hint.x + PWINDOW->m_vRealPosition.vec().x, PCONSTRAINT->constraint->current.cursor_hint.y + PWINDOW->m_vRealPosition.vec().y);
|
PCONSTRAINT->positionHint.x + PWINDOW->m_vRealPosition.vec().x, PCONSTRAINT->positionHint.y + PWINDOW->m_vRealPosition.vec().y);
|
||||||
|
|
||||||
wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->constraint->current.cursor_hint.x, PCONSTRAINT->constraint->current.cursor_hint.y);
|
wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->positionHint.x, PCONSTRAINT->positionHint.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ void addViewCoords(void* pWindow, int* x, int* y) {
|
|||||||
*x += PWINDOW->m_vRealPosition.goalv().x;
|
*x += PWINDOW->m_vRealPosition.goalv().x;
|
||||||
*y += PWINDOW->m_vRealPosition.goalv().y;
|
*y += PWINDOW->m_vRealPosition.goalv().y;
|
||||||
|
|
||||||
if (!PWINDOW->m_bIsX11) {
|
if (!PWINDOW->m_bIsX11 && PWINDOW->m_bIsMapped) {
|
||||||
wlr_box geom;
|
wlr_box geom;
|
||||||
wlr_xdg_surface_get_geometry(PWINDOW->m_uSurface.xdg, &geom);
|
wlr_xdg_surface_get_geometry(PWINDOW->m_uSurface.xdg, &geom);
|
||||||
|
|
||||||
@@ -29,18 +29,12 @@ void addViewCoords(void* pWindow, int* x, int* y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int setAnimToMove(void* data) {
|
void setAnimToMove(void* data) {
|
||||||
const auto PWINDOW = (CWindow*)data;
|
|
||||||
|
|
||||||
auto *const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove");
|
auto *const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove");
|
||||||
|
|
||||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
CAnimatedVariable* animvar = (CAnimatedVariable*)data;
|
||||||
return 0;
|
|
||||||
|
|
||||||
PWINDOW->m_vRealPosition.setConfig(PANIMCFG);
|
animvar->setConfig(PANIMCFG);
|
||||||
PWINDOW->m_vRealSize.setConfig(PANIMCFG);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_mapWindow(void* owner, void* data) {
|
void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
@@ -170,6 +164,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
requestsFullscreen = true;
|
requestsFullscreen = true;
|
||||||
} else if (r.szRule == "windowdance") {
|
} else if (r.szRule == "windowdance") {
|
||||||
PWINDOW->m_sAdditionalConfigData.windowDanceCompat = true;
|
PWINDOW->m_sAdditionalConfigData.windowDanceCompat = true;
|
||||||
|
} else if (r.szRule == "nomaxsize") {
|
||||||
|
PWINDOW->m_sAdditionalConfigData.noMaxSize = true;
|
||||||
} else if (r.szRule == "forceinput") {
|
} else if (r.szRule == "forceinput") {
|
||||||
PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true;
|
PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true;
|
||||||
} else if (r.szRule == "pin") {
|
} else if (r.szRule == "pin") {
|
||||||
@@ -445,8 +441,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
PWINDOW->m_fAlpha.setValueAndWarp(0.f);
|
PWINDOW->m_fAlpha.setValueAndWarp(0.f);
|
||||||
PWINDOW->m_fAlpha = 255.f;
|
PWINDOW->m_fAlpha = 255.f;
|
||||||
|
|
||||||
const auto TIMER = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, setAnimToMove, PWINDOW);
|
PWINDOW->m_vRealPosition.setCallbackOnEnd(setAnimToMove);
|
||||||
wl_event_source_timer_update(TIMER, PWINDOW->m_vRealPosition.getDurationLeftMs() + 5);
|
PWINDOW->m_vRealSize.setCallbackOnEnd(setAnimToMove);
|
||||||
|
|
||||||
if (requestsFullscreen && !PWINDOW->m_bNoFullscreenRequest) {
|
if (requestsFullscreen && !PWINDOW->m_bNoFullscreenRequest) {
|
||||||
// fix fullscreen on requested (basically do a switcheroo)
|
// fix fullscreen on requested (basically do a switcheroo)
|
||||||
@@ -706,6 +702,11 @@ void Events::listener_destroyWindow(void* owner, void* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PWINDOW->m_bReadyToDelete = true;
|
PWINDOW->m_bReadyToDelete = true;
|
||||||
|
|
||||||
|
if (!PWINDOW->m_bFadingOut) {
|
||||||
|
g_pCompositor->removeWindowFromVectorSafe(PWINDOW); // most likely X11 unmanaged or sumn
|
||||||
|
Debug::log(LOG, "Unmapped window %x removed instantly", PWINDOW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_setTitleWindow(void* owner, void* data) {
|
void Events::listener_setTitleWindow(void* owner, void* data) {
|
||||||
|
@@ -277,51 +277,41 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
|||||||
|
|
||||||
// result now has +/- what we should move on mon
|
// result now has +/- what we should move on mon
|
||||||
int remains = (int)result;
|
int remains = (int)result;
|
||||||
int currentID = g_pCompositor->m_pLastMonitor->activeWorkspace;
|
|
||||||
int searchID = currentID;
|
|
||||||
|
|
||||||
while (remains != 0) {
|
std::vector<int> validWSes;
|
||||||
if (remains < 0)
|
for (auto& ws : g_pCompositor->m_vWorkspaces) {
|
||||||
searchID--;
|
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID && !onAllMonitors))
|
||||||
else
|
|
||||||
searchID++;
|
|
||||||
|
|
||||||
if (g_pCompositor->workspaceIDOutOfBounds(searchID)){
|
|
||||||
// means we need to wrap around
|
|
||||||
int lowestID = 99999;
|
|
||||||
int highestID = -99999;
|
|
||||||
|
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
|
||||||
if (g_pCompositor->isWorkspaceSpecial(w->m_iID))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (w->m_iID < lowestID)
|
validWSes.push_back(ws->m_iID);
|
||||||
lowestID = w->m_iID;
|
|
||||||
|
|
||||||
if (w->m_iID > highestID)
|
|
||||||
highestID = w->m_iID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remains < 0)
|
std::sort(validWSes.begin(), validWSes.end());
|
||||||
searchID = highestID;
|
|
||||||
else
|
|
||||||
searchID = lowestID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(searchID); PWORKSPACE && !PWORKSPACE->m_bIsSpecialWorkspace) {
|
// get the offset
|
||||||
if (onAllMonitors || PWORKSPACE->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID) {
|
remains = remains < 0 ? -((-remains) % validWSes.size()) : remains % validWSes.size();
|
||||||
currentID = PWORKSPACE->m_iID;
|
|
||||||
|
|
||||||
if (remains < 0)
|
// get the current item
|
||||||
remains++;
|
int currentItem = -1;
|
||||||
else
|
for (size_t i = 0; i < validWSes.size(); i++) {
|
||||||
remains--;
|
if (validWSes[i] == g_pCompositor->m_pLastMonitor->activeWorkspace) {
|
||||||
}
|
currentItem = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = currentID;
|
// apply
|
||||||
outName = g_pCompositor->getWorkspaceByID(currentID)->m_szName;
|
currentItem += remains;
|
||||||
|
|
||||||
|
// sanitize
|
||||||
|
if (currentItem >= (int)validWSes.size()) {
|
||||||
|
currentItem = currentItem % validWSes.size();
|
||||||
|
} else if (currentItem < 0) {
|
||||||
|
currentItem = validWSes.size() + currentItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = validWSes[currentItem];
|
||||||
|
outName = g_pCompositor->getWorkspaceByID(validWSes[currentItem])->m_szName;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (in[0] == '+' || in[0] == '-') {
|
if (in[0] == '+' || in[0] == '-') {
|
||||||
|
@@ -240,10 +240,24 @@ bool CMonitor::isMirror() {
|
|||||||
return pMirrorOf != nullptr;
|
return pMirrorOf != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CMonitor::findAvailableDefaultWS() {
|
||||||
|
for (size_t i = 1; i < INT32_MAX; ++i) {
|
||||||
|
if (g_pCompositor->getWorkspaceByID(i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (const auto BOUND = g_pConfigManager->getBoundMonitorStringForWS(std::to_string(i)); !BOUND.empty() && BOUND != szName)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return INT32_MAX; // shouldn't be reachable
|
||||||
|
}
|
||||||
|
|
||||||
void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
|
void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
|
||||||
// Workspace
|
// Workspace
|
||||||
std::string newDefaultWorkspaceName = "";
|
std::string newDefaultWorkspaceName = "";
|
||||||
int64_t WORKSPACEID = monitorRule.defaultWorkspace == "" ? g_pCompositor->m_vWorkspaces.size() + 1 : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName);
|
int64_t WORKSPACEID = monitorRule.defaultWorkspace == "" ? findAvailableDefaultWS() : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName);
|
||||||
|
|
||||||
if (WORKSPACEID == INT_MAX || (WORKSPACEID >= SPECIAL_WORKSPACE_START && WORKSPACEID <= -2)) {
|
if (WORKSPACEID == INT_MAX || (WORKSPACEID >= SPECIAL_WORKSPACE_START && WORKSPACEID <= -2)) {
|
||||||
WORKSPACEID = g_pCompositor->m_vWorkspaces.size() + 1;
|
WORKSPACEID = g_pCompositor->m_vWorkspaces.size() + 1;
|
||||||
|
@@ -83,4 +83,5 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void setupDefaultWS(const SMonitorRule&);
|
void setupDefaultWS(const SMonitorRule&);
|
||||||
|
int findAvailableDefaultWS();
|
||||||
};
|
};
|
||||||
|
@@ -146,6 +146,9 @@ struct SConstraint {
|
|||||||
SMouse* pMouse = nullptr;
|
SMouse* pMouse = nullptr;
|
||||||
wlr_pointer_constraint_v1* constraint = nullptr;
|
wlr_pointer_constraint_v1* constraint = nullptr;
|
||||||
|
|
||||||
|
bool hintSet = false;
|
||||||
|
Vector2D positionHint; // the position hint, but will be set to the current cursor pos if not set.
|
||||||
|
|
||||||
DYNLISTENER(setConstraintRegion);
|
DYNLISTENER(setConstraintRegion);
|
||||||
DYNLISTENER(destroyConstraint);
|
DYNLISTENER(destroyConstraint);
|
||||||
|
|
||||||
|
@@ -336,6 +336,16 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
|||||||
g_pCompositor->setWindowFullscreen(PFULLWINDOW, false, FULLSCREEN_FULL);
|
g_pCompositor->setWindowFullscreen(PFULLWINDOW, false, FULLSCREEN_FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// last fail-safe to avoid duplicate fullscreens
|
||||||
|
if ((!OPENINGON || OPENINGON->pWindow == pWindow) && getNodesOnWorkspace(PNODE->workspaceID) > 1) {
|
||||||
|
for (auto& node : m_lDwindleNodesData) {
|
||||||
|
if (node.workspaceID == PNODE->workspaceID && node.pWindow != pWindow) {
|
||||||
|
OPENINGON = &node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if it's the first, it's easy. Make it fullscreen.
|
// if it's the first, it's easy. Make it fullscreen.
|
||||||
if (!OPENINGON || OPENINGON->pWindow == pWindow) {
|
if (!OPENINGON || OPENINGON->pWindow == pWindow) {
|
||||||
PNODE->position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
PNODE->position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
||||||
|
@@ -21,6 +21,9 @@ void IHyprLayout::onWindowCreated(CWindow* pWindow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IHyprLayout::onWindowRemoved(CWindow* pWindow) {
|
void IHyprLayout::onWindowRemoved(CWindow* pWindow) {
|
||||||
|
if (pWindow->m_bIsFullscreen)
|
||||||
|
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
|
||||||
|
|
||||||
if (pWindow->m_bIsFloating) {
|
if (pWindow->m_bIsFloating) {
|
||||||
onWindowRemovedFloating(pWindow);
|
onWindowRemovedFloating(pWindow);
|
||||||
} else {
|
} else {
|
||||||
@@ -129,16 +132,13 @@ void IHyprLayout::onBeginDragWindow() {
|
|||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(DRAGGINGWINDOW->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(DRAGGINGWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
if (PWORKSPACE->m_bHasFullscreenWindow && (!DRAGGINGWINDOW->m_bCreatedOverFullscreen || !DRAGGINGWINDOW->m_bIsFloating)) {
|
||||||
Debug::log(LOG, "Rejecting drag on a fullscreen workspace.");
|
Debug::log(LOG, "Rejecting drag on a fullscreen workspace. (window under fullscreen)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pInputManager->setCursorImageUntilUnset("hand1");
|
g_pInputManager->setCursorImageUntilUnset("hand1");
|
||||||
|
|
||||||
DRAGGINGWINDOW->m_vRealPosition.setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove"));
|
|
||||||
DRAGGINGWINDOW->m_vRealSize.setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove"));
|
|
||||||
|
|
||||||
DRAGGINGWINDOW->m_bDraggingTiled = false;
|
DRAGGINGWINDOW->m_bDraggingTiled = false;
|
||||||
|
|
||||||
if (!DRAGGINGWINDOW->m_bIsFloating) {
|
if (!DRAGGINGWINDOW->m_bIsFloating) {
|
||||||
@@ -180,11 +180,11 @@ void IHyprLayout::onBeginDragWindow() {
|
|||||||
void IHyprLayout::onEndDragWindow() {
|
void IHyprLayout::onEndDragWindow() {
|
||||||
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow;
|
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow;
|
||||||
|
|
||||||
|
g_pInputManager->unsetCursorImage();
|
||||||
|
|
||||||
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW))
|
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_pInputManager->unsetCursorImage();
|
|
||||||
|
|
||||||
if (DRAGGINGWINDOW->m_bDraggingTiled) {
|
if (DRAGGINGWINDOW->m_bDraggingTiled) {
|
||||||
DRAGGINGWINDOW->m_bIsFloating = false;
|
DRAGGINGWINDOW->m_bIsFloating = false;
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
@@ -201,10 +201,13 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
|||||||
|
|
||||||
// Window invalid or drag begin size 0,0 meaning we rejected it.
|
// Window invalid or drag begin size 0,0 meaning we rejected it.
|
||||||
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW) || m_vBeginDragSizeXY == Vector2D()) {
|
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW) || m_vBeginDragSizeXY == Vector2D()) {
|
||||||
|
onEndDragWindow();
|
||||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto SPECIAL = g_pCompositor->isWorkspaceSpecial(DRAGGINGWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
const auto DELTA = Vector2D(mousePos.x - m_vBeginDragXY.x, mousePos.y - m_vBeginDragXY.y);
|
const auto DELTA = Vector2D(mousePos.x - m_vBeginDragXY.x, mousePos.y - m_vBeginDragXY.y);
|
||||||
const auto TICKDELTA = Vector2D(mousePos.x - m_vLastDragXY.x, mousePos.y - m_vLastDragXY.y);
|
const auto TICKDELTA = Vector2D(mousePos.x - m_vLastDragXY.x, mousePos.y - m_vLastDragXY.y);
|
||||||
|
|
||||||
@@ -271,7 +274,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
|||||||
// and check its monitor
|
// and check its monitor
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle);
|
const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle);
|
||||||
|
|
||||||
if (PMONITOR) {
|
if (PMONITOR && !SPECIAL) {
|
||||||
DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID;
|
DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||||
DRAGGINGWINDOW->moveToWorkspace(PMONITOR->activeWorkspace);
|
DRAGGINGWINDOW->moveToWorkspace(PMONITOR->activeWorkspace);
|
||||||
|
|
||||||
@@ -297,6 +300,9 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
|||||||
|
|
||||||
const auto TILED = isWindowTiled(pWindow);
|
const auto TILED = isWindowTiled(pWindow);
|
||||||
|
|
||||||
|
// event
|
||||||
|
g_pEventManager->postEvent(SHyprIPCEvent{ "changefloatingmode", getFormat("%x,%d", pWindow, (int)TILED) });
|
||||||
|
|
||||||
if (!TILED) {
|
if (!TILED) {
|
||||||
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.vec() + pWindow->m_vRealSize.vec() / 2.f);
|
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.vec() + pWindow->m_vRealSize.vec() / 2.f);
|
||||||
pWindow->m_iMonitorID = PNEWMON->ID;
|
pWindow->m_iMonitorID = PNEWMON->ID;
|
||||||
|
@@ -30,6 +30,28 @@ int CHyprMasterLayout::getMastersOnWorkspace(const int& ws) {
|
|||||||
return no;
|
return no;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMasterWorkspaceData* CHyprMasterLayout::getMasterWorkspaceData(const int& ws) {
|
||||||
|
for (auto& n : m_lMasterWorkspacesData) {
|
||||||
|
if (n.workspaceID == ws)
|
||||||
|
return &n;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create on the fly if it doesn't exist yet
|
||||||
|
const auto PWORKSPACEDATA = &m_lMasterWorkspacesData.emplace_back();
|
||||||
|
PWORKSPACEDATA->workspaceID = ws;
|
||||||
|
const auto orientation = &g_pConfigManager->getConfigValuePtr("master:orientation")->strValue;
|
||||||
|
if (*orientation == "top") {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_TOP;
|
||||||
|
} else if (*orientation == "right") {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_RIGHT;
|
||||||
|
} else if (*orientation == "bottom") {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM;
|
||||||
|
} else {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_LEFT;
|
||||||
|
}
|
||||||
|
return PWORKSPACEDATA;
|
||||||
|
}
|
||||||
|
|
||||||
std::string CHyprMasterLayout::getLayoutName() {
|
std::string CHyprMasterLayout::getLayoutName() {
|
||||||
return "Master";
|
return "Master";
|
||||||
}
|
}
|
||||||
@@ -130,11 +152,13 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto WORKSPACEID = PNODE->workspaceID;
|
||||||
|
|
||||||
m_lMasterNodesData.remove(*PNODE);
|
m_lMasterNodesData.remove(*PNODE);
|
||||||
|
|
||||||
if (getMastersOnWorkspace(PNODE->workspaceID) == getNodesOnWorkspace(PNODE->workspaceID) && MASTERSLEFT > 1) {
|
if (getMastersOnWorkspace(WORKSPACEID) == getNodesOnWorkspace(WORKSPACEID) && MASTERSLEFT > 1) {
|
||||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||||
if (it->workspaceID == PNODE->workspaceID) {
|
if (it->workspaceID == WORKSPACEID) {
|
||||||
it->isMaster = false;
|
it->isMaster = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -187,6 +211,8 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
|
|||||||
if (!PWORKSPACE)
|
if (!PWORKSPACE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const auto PWORKSPACEDATA = getMasterWorkspaceData(ws);
|
||||||
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||||
|
|
||||||
const auto PMASTERNODE = getMasterNodeOnWorkspace(PWORKSPACE->m_iID);
|
const auto PMASTERNODE = getMasterNodeOnWorkspace(PWORKSPACE->m_iID);
|
||||||
@@ -196,46 +222,85 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
|
|||||||
|
|
||||||
const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID);
|
const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID);
|
||||||
|
|
||||||
|
//compute placement of master window(s)
|
||||||
if (getNodesOnWorkspace(PWORKSPACE->m_iID) < 2) {
|
if (getNodesOnWorkspace(PWORKSPACE->m_iID) < 2) {
|
||||||
PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition;
|
PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition;
|
||||||
PMASTERNODE->size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x, PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y);
|
PMASTERNODE->size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x, PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y);
|
||||||
applyNodeDataToWindow(PMASTERNODE);
|
applyNodeDataToWindow(PMASTERNODE);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT || PWORKSPACEDATA->orientation == ORIENTATION_RIGHT) {
|
||||||
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
|
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
|
||||||
int nodesLeft = MASTERS;
|
int nodesLeft = MASTERS;
|
||||||
float nextY = 0;
|
float nextY = 0;
|
||||||
|
const float WIDTH = (PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) * PMASTERNODE->percMaster;
|
||||||
|
|
||||||
for (auto& n : m_lMasterNodesData) {
|
for (auto& n : m_lMasterNodesData) {
|
||||||
if (n.workspaceID == PWORKSPACE->m_iID && n.isMaster) {
|
if (n.workspaceID == PWORKSPACE->m_iID && n.isMaster) {
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_RIGHT) {
|
||||||
|
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(PMONITOR->vecSize.x - WIDTH, nextY);
|
||||||
|
} else {
|
||||||
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(0, nextY);
|
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(0, nextY);
|
||||||
|
}
|
||||||
float HEIGHT = nodesLeft > 1 ? heightLeft / nodesLeft * n.percSize : heightLeft;
|
float HEIGHT = nodesLeft > 1 ? heightLeft / nodesLeft * n.percSize : heightLeft;
|
||||||
if (HEIGHT > heightLeft * 0.9f && nodesLeft > 1)
|
if (HEIGHT > heightLeft * 0.9f && nodesLeft > 1)
|
||||||
HEIGHT = heightLeft * 0.9f;
|
HEIGHT = heightLeft * 0.9f;
|
||||||
n.size = Vector2D((PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) * PMASTERNODE->percMaster, HEIGHT);
|
n.size = Vector2D(WIDTH, HEIGHT);
|
||||||
|
|
||||||
nodesLeft--;
|
nodesLeft--;
|
||||||
heightLeft -= HEIGHT;
|
heightLeft -= HEIGHT;
|
||||||
nextY += HEIGHT;
|
nextY += HEIGHT;
|
||||||
|
|
||||||
|
applyNodeDataToWindow(&n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (PWORKSPACEDATA->orientation == ORIENTATION_TOP || PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) {
|
||||||
|
float widthLeft = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x;
|
||||||
|
int nodesLeft = MASTERS;
|
||||||
|
float nextX = 0;
|
||||||
|
const float HEIGHT = (PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y) * PMASTERNODE->percMaster;
|
||||||
|
|
||||||
|
for (auto& n : m_lMasterNodesData) {
|
||||||
|
if (n.workspaceID == PWORKSPACE->m_iID && n.isMaster) {
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) {
|
||||||
|
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(nextX,PMONITOR->vecSize.y - HEIGHT - PMONITOR->vecReservedBottomRight.y);
|
||||||
|
} else {
|
||||||
|
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(nextX, 0);
|
||||||
|
}
|
||||||
|
float WIDTH = nodesLeft > 1 ? widthLeft / nodesLeft * n.percSize : widthLeft;
|
||||||
|
if (WIDTH > widthLeft * 0.9f && nodesLeft > 1)
|
||||||
|
WIDTH = widthLeft * 0.9f;
|
||||||
|
n.size = Vector2D(WIDTH, HEIGHT);
|
||||||
|
|
||||||
|
nodesLeft--;
|
||||||
|
widthLeft -= WIDTH;
|
||||||
|
nextX += WIDTH;
|
||||||
|
|
||||||
applyNodeDataToWindow(&n);
|
applyNodeDataToWindow(&n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
|
|
||||||
|
//compute placement of slave window(s)
|
||||||
int slavesLeft = getNodesOnWorkspace(PWORKSPACE->m_iID) - MASTERS;
|
int slavesLeft = getNodesOnWorkspace(PWORKSPACE->m_iID) - MASTERS;
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT || PWORKSPACEDATA->orientation == ORIENTATION_RIGHT) {
|
||||||
|
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
|
||||||
float nextY = 0;
|
float nextY = 0;
|
||||||
|
const float WIDTH = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x - PMASTERNODE->size.x;
|
||||||
|
|
||||||
for (auto& nd : m_lMasterNodesData) {
|
for (auto& nd : m_lMasterNodesData) {
|
||||||
if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster)
|
if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(PMASTERNODE->percMaster * PMONITOR->vecSize.x, nextY);
|
if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT) {
|
||||||
|
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(PMASTERNODE->percMaster * (PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x), nextY);
|
||||||
|
} else {
|
||||||
|
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(0, nextY);
|
||||||
|
}
|
||||||
float HEIGHT = slavesLeft > 1 ? heightLeft / slavesLeft * nd.percSize : heightLeft;
|
float HEIGHT = slavesLeft > 1 ? heightLeft / slavesLeft * nd.percSize : heightLeft;
|
||||||
if (HEIGHT > heightLeft * 0.9f && slavesLeft > 1)
|
if (HEIGHT > heightLeft * 0.9f && slavesLeft > 1)
|
||||||
HEIGHT = heightLeft * 0.9f;
|
HEIGHT = heightLeft * 0.9f;
|
||||||
nd.size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x - PMASTERNODE->size.x, HEIGHT);
|
nd.size = Vector2D(WIDTH, HEIGHT);
|
||||||
|
|
||||||
slavesLeft--;
|
slavesLeft--;
|
||||||
heightLeft -= HEIGHT;
|
heightLeft -= HEIGHT;
|
||||||
@@ -243,6 +308,33 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
|
|||||||
|
|
||||||
applyNodeDataToWindow(&nd);
|
applyNodeDataToWindow(&nd);
|
||||||
}
|
}
|
||||||
|
} else if (PWORKSPACEDATA->orientation == ORIENTATION_TOP || PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) {
|
||||||
|
float widthLeft = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x;
|
||||||
|
float nextX = 0;
|
||||||
|
const float HEIGHT = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y - PMASTERNODE->size.y;
|
||||||
|
|
||||||
|
for (auto& nd : m_lMasterNodesData) {
|
||||||
|
if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster)
|
||||||
|
continue;
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_TOP) {
|
||||||
|
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(nextX, PMASTERNODE->percMaster * (PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y));
|
||||||
|
} else {
|
||||||
|
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(nextX, 0);
|
||||||
|
}
|
||||||
|
float WIDTH = slavesLeft > 1 ? widthLeft / slavesLeft * nd.percSize : widthLeft;
|
||||||
|
if (WIDTH > widthLeft * 0.9f && slavesLeft > 1)
|
||||||
|
WIDTH = widthLeft * 0.9f;
|
||||||
|
nd.size = Vector2D(WIDTH, HEIGHT);
|
||||||
|
|
||||||
|
slavesLeft--;
|
||||||
|
widthLeft -= WIDTH;
|
||||||
|
nextX += WIDTH;
|
||||||
|
|
||||||
|
applyNodeDataToWindow(&nd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||||
@@ -490,6 +582,8 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
|
|||||||
if (!PNODE2 || !PNODE)
|
if (!PNODE2 || !PNODE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const auto inheritFullscreen = prepareLoseFocus(pWindow);
|
||||||
|
|
||||||
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||||
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
|
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
|
||||||
std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID);
|
std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID);
|
||||||
@@ -505,6 +599,8 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
|
|||||||
|
|
||||||
g_pHyprRenderer->damageWindow(pWindow);
|
g_pHyprRenderer->damageWindow(pWindow);
|
||||||
g_pHyprRenderer->damageWindow(pWindow2);
|
g_pHyprRenderer->damageWindow(pWindow2);
|
||||||
|
|
||||||
|
prepareNewFocus(pWindow2, inheritFullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprMasterLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
void CHyprMasterLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
||||||
@@ -559,14 +655,14 @@ CWindow* CHyprMasterLayout::getNextWindow(CWindow* pWindow, bool next) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (PNODE->isMaster) {
|
if (PNODE->isMaster) {
|
||||||
// focus the first non master
|
// focus the last non master
|
||||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||||
if (it->pWindow != pWindow && it->workspaceID == pWindow->m_iWorkspaceID) {
|
if (it->pWindow != pWindow && it->workspaceID == pWindow->m_iWorkspaceID) {
|
||||||
return it->pWindow;
|
return it->pWindow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// focus next
|
// focus previous
|
||||||
bool reached = false;
|
bool reached = false;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||||
@@ -591,6 +687,28 @@ CWindow* CHyprMasterLayout::getNextWindow(CWindow* pWindow, bool next) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CHyprMasterLayout::prepareLoseFocus(CWindow* pWindow) {
|
||||||
|
if (!pWindow)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//if the current window is fullscreen, make it normal again if we are about to lose focus
|
||||||
|
if (pWindow->m_bIsFullscreen) {
|
||||||
|
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
|
||||||
|
static auto *const INHERIT = &g_pConfigManager->getConfigValuePtr("master:inherit_fullscreen")->intValue;
|
||||||
|
return *INHERIT == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprMasterLayout::prepareNewFocus(CWindow* pWindow, bool inheritFullscreen) {
|
||||||
|
if (!pWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (inheritFullscreen)
|
||||||
|
g_pCompositor->setWindowFullscreen(pWindow, true, FULLSCREEN_MAXIMIZED);
|
||||||
|
}
|
||||||
|
|
||||||
std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
|
std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
|
||||||
auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) {
|
auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) {
|
||||||
if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO))
|
if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO))
|
||||||
@@ -614,6 +732,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
|||||||
if (!PMASTER)
|
if (!PMASTER)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
if (PMASTER->pWindow != PWINDOW) {
|
if (PMASTER->pWindow != PWINDOW) {
|
||||||
switchWindows(PWINDOW, PMASTER->pWindow);
|
switchWindows(PWINDOW, PMASTER->pWindow);
|
||||||
switchToWindow(PWINDOW);
|
switchToWindow(PWINDOW);
|
||||||
@@ -634,17 +753,21 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
|||||||
if (!PWINDOW)
|
if (!PWINDOW)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
|
||||||
|
|
||||||
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
|
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
if (!PMASTER)
|
if (!PMASTER)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (PMASTER->pWindow != PWINDOW)
|
if (PMASTER->pWindow != PWINDOW) {
|
||||||
switchToWindow(PMASTER->pWindow);
|
switchToWindow(PMASTER->pWindow);
|
||||||
else {
|
prepareNewFocus(PMASTER->pWindow, inheritFullscreen);
|
||||||
|
} else {
|
||||||
for (auto& n : m_lMasterNodesData) {
|
for (auto& n : m_lMasterNodesData) {
|
||||||
if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) {
|
if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) {
|
||||||
switchToWindow(n.pWindow);
|
switchToWindow(n.pWindow);
|
||||||
|
prepareNewFocus(n.pWindow, inheritFullscreen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -657,14 +780,22 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
|||||||
if (!PWINDOW)
|
if (!PWINDOW)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switchToWindow(getNextWindow(PWINDOW, true));
|
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
|
||||||
|
|
||||||
|
const auto PNEXTWINDOW = getNextWindow(PWINDOW, true);
|
||||||
|
switchToWindow(PNEXTWINDOW);
|
||||||
|
prepareNewFocus(PNEXTWINDOW, inheritFullscreen);
|
||||||
} else if (message == "cycleprev") {
|
} else if (message == "cycleprev") {
|
||||||
const auto PWINDOW = header.pWindow;
|
const auto PWINDOW = header.pWindow;
|
||||||
|
|
||||||
if (!PWINDOW)
|
if (!PWINDOW)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switchToWindow(getNextWindow(PWINDOW, false));
|
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
|
||||||
|
|
||||||
|
const auto PPREVWINDOW = getNextWindow(PWINDOW, true);
|
||||||
|
switchToWindow(PPREVWINDOW);
|
||||||
|
prepareNewFocus(PPREVWINDOW, inheritFullscreen);
|
||||||
} else if (message == "swapnext") {
|
} else if (message == "swapnext") {
|
||||||
if (!g_pCompositor->windowValidMapped(header.pWindow))
|
if (!g_pCompositor->windowValidMapped(header.pWindow))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -677,6 +808,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
|||||||
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true);
|
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true);
|
||||||
|
|
||||||
if (PWINDOWTOSWAPWITH) {
|
if (PWINDOWTOSWAPWITH) {
|
||||||
|
prepareLoseFocus(header.pWindow);
|
||||||
switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
|
switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
|
||||||
g_pCompositor->focusWindow(header.pWindow);
|
g_pCompositor->focusWindow(header.pWindow);
|
||||||
}
|
}
|
||||||
@@ -692,6 +824,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
|||||||
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false);
|
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false);
|
||||||
|
|
||||||
if (PWINDOWTOSWAPWITH) {
|
if (PWINDOWTOSWAPWITH) {
|
||||||
|
prepareLoseFocus(header.pWindow);
|
||||||
switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
|
switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
|
||||||
g_pCompositor->focusWindow(header.pWindow);
|
g_pCompositor->focusWindow(header.pWindow);
|
||||||
}
|
}
|
||||||
@@ -710,6 +843,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
|||||||
if (MASTERS + 2 > WINDOWS)
|
if (MASTERS + 2 > WINDOWS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
prepareLoseFocus(header.pWindow);
|
||||||
|
|
||||||
if (!PNODE || PNODE->isMaster) {
|
if (!PNODE || PNODE->isMaster) {
|
||||||
// first non-master node
|
// first non-master node
|
||||||
for (auto& n : m_lMasterNodesData) {
|
for (auto& n : m_lMasterNodesData) {
|
||||||
@@ -740,6 +875,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
|||||||
if (WINDOWS < 2 || MASTERS < 2)
|
if (WINDOWS < 2 || MASTERS < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
prepareLoseFocus(header.pWindow);
|
||||||
|
|
||||||
if (!PNODE || !PNODE->isMaster) {
|
if (!PNODE || !PNODE->isMaster) {
|
||||||
// first non-master node
|
// first non-master node
|
||||||
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) {
|
||||||
@@ -752,6 +889,61 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
|||||||
PNODE->isMaster = false;
|
PNODE->isMaster = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||||
|
} else if (message == "orientationleft" || message == "orientationright" || message == "orientationtop" || message == "orientationbottom") {
|
||||||
|
const auto PWINDOW = header.pWindow;
|
||||||
|
|
||||||
|
if (!PWINDOW)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
prepareLoseFocus(PWINDOW);
|
||||||
|
|
||||||
|
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (message == "orientationleft")
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_LEFT;
|
||||||
|
else if (message == "orientationright")
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_RIGHT;
|
||||||
|
else if (message == "orientationtop")
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_TOP;
|
||||||
|
else if (message == "orientationbottom")
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM;
|
||||||
|
|
||||||
|
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||||
|
|
||||||
|
} else if (message == "orientationnext") {
|
||||||
|
const auto PWINDOW = header.pWindow;
|
||||||
|
|
||||||
|
if (!PWINDOW)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
prepareLoseFocus(PWINDOW);
|
||||||
|
|
||||||
|
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_LEFT;
|
||||||
|
} else {
|
||||||
|
PWORKSPACEDATA->orientation = (eOrientation) (PWORKSPACEDATA->orientation + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||||
|
} else if (message == "orientationprev") {
|
||||||
|
const auto PWINDOW = header.pWindow;
|
||||||
|
|
||||||
|
if (!PWINDOW)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
prepareLoseFocus(PWINDOW);
|
||||||
|
|
||||||
|
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT) {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM;
|
||||||
|
} else {
|
||||||
|
PWORKSPACEDATA->orientation = (eOrientation) (PWORKSPACEDATA->orientation - 1);
|
||||||
|
}
|
||||||
|
|
||||||
recalculateMonitor(header.pWindow->m_iMonitorID);
|
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,11 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IHyprLayout.hpp"
|
#include "IHyprLayout.hpp"
|
||||||
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
enum eFullscreenMode : uint8_t;
|
enum eFullscreenMode : uint8_t;
|
||||||
|
|
||||||
|
//orientation determines which side of the screen the master area resides
|
||||||
|
enum eOrientation : uint8_t {
|
||||||
|
ORIENTATION_LEFT = 0,
|
||||||
|
ORIENTATION_TOP,
|
||||||
|
ORIENTATION_RIGHT,
|
||||||
|
ORIENTATION_BOTTOM
|
||||||
|
};
|
||||||
|
|
||||||
struct SMasterNodeData {
|
struct SMasterNodeData {
|
||||||
bool isMaster = false;
|
bool isMaster = false;
|
||||||
float percMaster = 0.5f;
|
float percMaster = 0.5f;
|
||||||
@@ -24,6 +33,15 @@ struct SMasterNodeData {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SMasterWorkspaceData {
|
||||||
|
int workspaceID = -1;
|
||||||
|
eOrientation orientation = ORIENTATION_LEFT;
|
||||||
|
|
||||||
|
bool operator==(const SMasterWorkspaceData& rhs) {
|
||||||
|
return workspaceID == rhs.workspaceID;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class CHyprMasterLayout : public IHyprLayout {
|
class CHyprMasterLayout : public IHyprLayout {
|
||||||
public:
|
public:
|
||||||
virtual void onWindowCreatedTiling(CWindow*);
|
virtual void onWindowCreatedTiling(CWindow*);
|
||||||
@@ -45,6 +63,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::list<SMasterNodeData> m_lMasterNodesData;
|
std::list<SMasterNodeData> m_lMasterNodesData;
|
||||||
|
std::vector<SMasterWorkspaceData> m_lMasterWorkspacesData;
|
||||||
|
|
||||||
bool m_bForceWarps = false;
|
bool m_bForceWarps = false;
|
||||||
|
|
||||||
@@ -52,9 +71,13 @@ private:
|
|||||||
void applyNodeDataToWindow(SMasterNodeData*);
|
void applyNodeDataToWindow(SMasterNodeData*);
|
||||||
SMasterNodeData* getNodeFromWindow(CWindow*);
|
SMasterNodeData* getNodeFromWindow(CWindow*);
|
||||||
SMasterNodeData* getMasterNodeOnWorkspace(const int&);
|
SMasterNodeData* getMasterNodeOnWorkspace(const int&);
|
||||||
|
SMasterWorkspaceData* getMasterWorkspaceData(const int&);
|
||||||
void calculateWorkspace(const int&);
|
void calculateWorkspace(const int&);
|
||||||
CWindow* getNextWindow(CWindow*, bool);
|
CWindow* getNextWindow(CWindow*, bool);
|
||||||
int getMastersOnWorkspace(const int&);
|
int getMastersOnWorkspace(const int&);
|
||||||
|
bool prepareLoseFocus(CWindow*);
|
||||||
|
void prepareNewFocus(CWindow*, bool inherit_fullscreen);
|
||||||
|
|
||||||
friend struct SMasterNodeData;
|
friend struct SMasterNodeData;
|
||||||
|
friend struct SMasterWorkspaceData;
|
||||||
};
|
};
|
@@ -899,9 +899,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
|||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
|
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
|
||||||
|
|
||||||
g_pKeybindManager->changeworkspace(args);
|
auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
|
||||||
|
|
||||||
if (PWORKSPACE == OLDWORKSPACE) {
|
if (PWORKSPACE == OLDWORKSPACE) {
|
||||||
Debug::log(LOG, "Not moving to workspace because it didn't change.");
|
Debug::log(LOG, "Not moving to workspace because it didn't change.");
|
||||||
@@ -909,8 +907,8 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!PWORKSPACE) {
|
if (!PWORKSPACE) {
|
||||||
Debug::log(ERR, "Workspace null in moveActiveToWorkspace?");
|
// create
|
||||||
return;
|
PWORKSPACE = g_pCompositor->createNewWorkspace(WORKSPACEID, OLDWORKSPACE->m_iMonitorID, workspaceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
PWINDOW->moveToWorkspace(PWORKSPACE->m_iID);
|
PWINDOW->moveToWorkspace(PWORKSPACE->m_iID);
|
||||||
@@ -932,21 +930,14 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
|||||||
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec();
|
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WASFULLSCREEN) {
|
if (WASFULLSCREEN)
|
||||||
g_pCompositor->setWindowFullscreen(PWINDOW, true, OLDWORKSPACE->m_efFullscreenMode);
|
g_pCompositor->setWindowFullscreen(PWINDOW, true, OLDWORKSPACE->m_efFullscreenMode);
|
||||||
}
|
|
||||||
|
|
||||||
// undo the damage if we are moving to the special workspace
|
if (!g_pCompositor->isWorkspaceSpecial(WORKSPACEID)) {
|
||||||
if (g_pCompositor->isWorkspaceSpecial(WORKSPACEID)) {
|
g_pKeybindManager->changeworkspace(args);
|
||||||
changeworkspace("[internal]" + std::to_string(OLDWORKSPACE->m_iID));
|
|
||||||
OLDWORKSPACE->startAnim(true, true, true);
|
|
||||||
toggleSpecialWorkspace(workspaceName.length() > 7 ? workspaceName.substr(8) : workspaceName /* remove special: */);
|
|
||||||
g_pCompositor->getWorkspaceByID(WORKSPACEID)->startAnim(false, false, true);
|
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors)
|
|
||||||
m->specialWorkspaceID = 0;
|
|
||||||
} else {
|
|
||||||
g_pCompositor->focusWindow(PWINDOW);
|
g_pCompositor->focusWindow(PWINDOW);
|
||||||
|
} else {
|
||||||
|
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID));
|
||||||
}
|
}
|
||||||
|
|
||||||
PWINDOW->updateToplevel();
|
PWINDOW->updateToplevel();
|
||||||
@@ -954,6 +945,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
|||||||
|
|
||||||
void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||||
// hacky, but works lol
|
// hacky, but works lol
|
||||||
|
// TODO: this sucks
|
||||||
|
|
||||||
CWindow* PWINDOW = nullptr;
|
CWindow* PWINDOW = nullptr;
|
||||||
|
|
||||||
@@ -1024,7 +1016,11 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
|||||||
// manually post event cuz it got ignored above
|
// manually post event cuz it got ignored above
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", PWINDOW, PWORKSPACE->m_szName.c_str())});
|
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", PWINDOW, PWORKSPACE->m_szName.c_str())});
|
||||||
|
|
||||||
g_pInputManager->refocus();
|
PWINDOW->m_iWorkspaceID = OLDWORKSPACEIDRETURN;
|
||||||
|
const auto PNEXTCANDIDATE = g_pLayoutManager->getCurrentLayout()->getNextWindowCandidate(PWINDOW);
|
||||||
|
PWINDOW->m_iWorkspaceID = workspaceToMoveTo;
|
||||||
|
|
||||||
|
g_pCompositor->focusWindow(PNEXTCANDIDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::moveFocusTo(std::string args) {
|
void CKeybindManager::moveFocusTo(std::string args) {
|
||||||
@@ -1327,6 +1323,8 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
|||||||
|
|
||||||
void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
||||||
|
|
||||||
|
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||||
|
|
||||||
std::string workspaceName = "";
|
std::string workspaceName = "";
|
||||||
int workspaceID = getWorkspaceIDFromString("special:" + args, workspaceName);
|
int workspaceID = getWorkspaceIDFromString("special:" + args, workspaceName);
|
||||||
|
|
||||||
@@ -1341,7 +1339,8 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool requestedWorkspaceIsAlreadyOpen = false;
|
bool requestedWorkspaceIsAlreadyOpen = false;
|
||||||
int specialOpenOnMonitor = g_pCompositor->m_pLastMonitor->specialWorkspaceID;
|
const auto PMONITOR = *PFOLLOWMOUSE == 1 ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->m_pLastMonitor;
|
||||||
|
int specialOpenOnMonitor = PMONITOR->specialWorkspaceID;
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
if (m->specialWorkspaceID == workspaceID) {
|
if (m->specialWorkspaceID == workspaceID) {
|
||||||
@@ -1358,12 +1357,12 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||||||
if (requestedWorkspaceIsAlreadyOpen && specialOpenOnMonitor == workspaceID) {
|
if (requestedWorkspaceIsAlreadyOpen && specialOpenOnMonitor == workspaceID) {
|
||||||
// already open on this monitor
|
// already open on this monitor
|
||||||
|
|
||||||
g_pCompositor->m_pLastMonitor->specialWorkspaceID = 0;
|
PMONITOR->specialWorkspaceID = 0;
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
||||||
|
|
||||||
g_pCompositor->getWorkspaceByID(workspaceID)->startAnim(false, false);
|
g_pCompositor->getWorkspaceByID(workspaceID)->startAnim(false, false);
|
||||||
|
|
||||||
if (const auto PWINDOW = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace)->getLastFocusedWindow(); PWINDOW)
|
if (const auto PWINDOW = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace)->getLastFocusedWindow(); PWINDOW)
|
||||||
g_pCompositor->focusWindow(PWINDOW);
|
g_pCompositor->focusWindow(PWINDOW);
|
||||||
else
|
else
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
@@ -1371,9 +1370,9 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||||||
// already open on another monitor
|
// already open on another monitor
|
||||||
|
|
||||||
if (specialOpenOnMonitor) {
|
if (specialOpenOnMonitor) {
|
||||||
g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->specialWorkspaceID)->startAnim(false, false);
|
g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID)->startAnim(false, false);
|
||||||
g_pCompositor->m_pLastMonitor->specialWorkspaceID = 0;
|
PMONITOR->specialWorkspaceID = 0;
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// move to current
|
// move to current
|
||||||
@@ -1382,8 +1381,9 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||||||
|
|
||||||
POLDMON->specialWorkspaceID = 0;
|
POLDMON->specialWorkspaceID = 0;
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(POLDMON->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(POLDMON->ID);
|
||||||
g_pCompositor->m_pLastMonitor->specialWorkspaceID = workspaceID;
|
PMONITOR->specialWorkspaceID = workspaceID;
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
||||||
|
PSPECIALWORKSPACE->m_iMonitorID = PMONITOR->ID;
|
||||||
|
|
||||||
if (const auto PWINDOW = PSPECIALWORKSPACE->getLastFocusedWindow(); PWINDOW)
|
if (const auto PWINDOW = PSPECIALWORKSPACE->getLastFocusedWindow(); PWINDOW)
|
||||||
g_pCompositor->focusWindow(PWINDOW);
|
g_pCompositor->focusWindow(PWINDOW);
|
||||||
@@ -1393,23 +1393,23 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||||||
// not open anywhere
|
// not open anywhere
|
||||||
|
|
||||||
if (specialOpenOnMonitor) {
|
if (specialOpenOnMonitor) {
|
||||||
g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->specialWorkspaceID)->startAnim(false, false);
|
g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID)->startAnim(false, false);
|
||||||
g_pCompositor->m_pLastMonitor->specialWorkspaceID = 0;
|
PMONITOR->specialWorkspaceID = 0;
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceID);
|
auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceID);
|
||||||
|
|
||||||
if (!PSPECIALWORKSPACE) {
|
if (!PSPECIALWORKSPACE) {
|
||||||
// ??? happens sometimes...?
|
// ??? happens sometimes...?
|
||||||
PSPECIALWORKSPACE = g_pCompositor->createNewWorkspace(workspaceID, g_pCompositor->m_pLastMonitor->ID, workspaceName);
|
PSPECIALWORKSPACE = g_pCompositor->createNewWorkspace(workspaceID, PMONITOR->ID, workspaceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pCompositor->m_pLastMonitor->specialWorkspaceID = workspaceID;
|
PMONITOR->specialWorkspaceID = workspaceID;
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
||||||
|
|
||||||
|
PSPECIALWORKSPACE->m_iMonitorID = PMONITOR->ID;
|
||||||
PSPECIALWORKSPACE->startAnim(true, true);
|
PSPECIALWORKSPACE->startAnim(true, true);
|
||||||
PSPECIALWORKSPACE->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID;
|
|
||||||
|
|
||||||
if (const auto PWINDOW = PSPECIALWORKSPACE->getLastFocusedWindow(); PWINDOW)
|
if (const auto PWINDOW = PSPECIALWORKSPACE->getLastFocusedWindow(); PWINDOW)
|
||||||
g_pCompositor->focusWindow(PWINDOW);
|
g_pCompositor->focusWindow(PWINDOW);
|
||||||
|
@@ -263,7 +263,7 @@ Vector2D CHyprXWaylandManager::getMaxSizeForWindow(CWindow* pWindow) {
|
|||||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||||
return Vector2D(99999, 99999);
|
return Vector2D(99999, 99999);
|
||||||
|
|
||||||
if ((pWindow->m_bIsX11 && !pWindow->m_uSurface.xwayland->size_hints) || (!pWindow->m_bIsX11 && !pWindow->m_uSurface.xdg->toplevel))
|
if ((pWindow->m_bIsX11 && !pWindow->m_uSurface.xwayland->size_hints) || (!pWindow->m_bIsX11 && !pWindow->m_uSurface.xdg->toplevel) || pWindow->m_sAdditionalConfigData.noMaxSize)
|
||||||
return Vector2D(99999, 99999);
|
return Vector2D(99999, 99999);
|
||||||
|
|
||||||
auto MAXSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_uSurface.xwayland->size_hints->max_width, pWindow->m_uSurface.xwayland->size_hints->max_height)
|
auto MAXSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_uSurface.xwayland->size_hints->max_width, pWindow->m_uSurface.xwayland->size_hints->max_height)
|
||||||
|
@@ -73,9 +73,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||||||
// XWayland windows sometimes issue constraints weirdly.
|
// XWayland windows sometimes issue constraints weirdly.
|
||||||
// TODO: We probably should search their parent. wlr_xwayland_surface->parent
|
// TODO: We probably should search their parent. wlr_xwayland_surface->parent
|
||||||
const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
|
const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
|
||||||
const auto PCONSTRAINT = g_pCompositor->m_sSeat.mouse->currentConstraint;
|
const auto PCONSTRAINT = constraintFromWlr(g_pCompositor->m_sSeat.mouse->currentConstraint);
|
||||||
|
|
||||||
if (!CONSTRAINTWINDOW) {
|
if (!CONSTRAINTWINDOW || !PCONSTRAINT) {
|
||||||
unconstrainMouse();
|
unconstrainMouse();
|
||||||
} else {
|
} else {
|
||||||
// Native Wayland apps know how 2 constrain themselves.
|
// Native Wayland apps know how 2 constrain themselves.
|
||||||
@@ -86,7 +86,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||||||
if (g_pCompositor->m_sSeat.mouse->currentConstraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) {
|
if (g_pCompositor->m_sSeat.mouse->currentConstraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) {
|
||||||
// we just snap the cursor to where it should be.
|
// we just snap the cursor to where it should be.
|
||||||
|
|
||||||
Vector2D hint = { PCONSTRAINT->current.cursor_hint.x, PCONSTRAINT->current.cursor_hint.y };
|
Vector2D hint = { PCONSTRAINT->positionHint.x, PCONSTRAINT->positionHint.y };
|
||||||
|
|
||||||
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, CONSTRAINTPOS.x + hint.x, CONSTRAINTPOS.y + hint.y);
|
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, CONSTRAINTPOS.x + hint.x, CONSTRAINTPOS.y + hint.y);
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||||||
// these are usually FPS games. They will use the relative motion.
|
// these are usually FPS games. They will use the relative motion.
|
||||||
} else {
|
} else {
|
||||||
// we restrict the cursor to the confined region
|
// we restrict the cursor to the confined region
|
||||||
if (!pixman_region32_contains_point(&PCONSTRAINT->region, mouseCoords.x - CONSTRAINTPOS.x, mouseCoords.y - CONSTRAINTPOS.y, nullptr)) {
|
if (!pixman_region32_contains_point(&PCONSTRAINT->constraint->region, mouseCoords.x - CONSTRAINTPOS.x, mouseCoords.y - CONSTRAINTPOS.y, nullptr)) {
|
||||||
if (g_pCompositor->m_sSeat.mouse->constraintActive) {
|
if (g_pCompositor->m_sSeat.mouse->constraintActive) {
|
||||||
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, NULL, mouseCoords.x, mouseCoords.y);
|
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, NULL, mouseCoords.x, mouseCoords.y);
|
||||||
mouseCoords = getMouseCoordsInternal();
|
mouseCoords = getMouseCoordsInternal();
|
||||||
@@ -960,6 +960,12 @@ void CInputManager::constrainMouse(SMouse* pMouse, wlr_pointer_constraint_v1* co
|
|||||||
wlr_seat_pointer_warp(constraint->seat, constraint->current.cursor_hint.x, constraint->current.cursor_hint.y);
|
wlr_seat_pointer_warp(constraint->seat, constraint->current.cursor_hint.x, constraint->current.cursor_hint.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto PCONSTRAINT = constraintFromWlr(constraint);
|
||||||
|
if (PCONSTRAINT) { // should never be null but who knows
|
||||||
|
PCONSTRAINT->positionHint = Vector2D(constraint->current.cursor_hint.x, constraint->current.cursor_hint.y);
|
||||||
|
PCONSTRAINT->hintSet = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,7 +1011,15 @@ void CInputManager::unconstrainMouse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_commitConstraint(void* owner, void* data) {
|
void Events::listener_commitConstraint(void* owner, void* data) {
|
||||||
//g_pInputManager->recheckConstraint((SMouse*)owner);
|
const auto PMOUSE = (SMouse*)owner;
|
||||||
|
|
||||||
|
if (PMOUSE->currentConstraint->current.committed & WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT) {
|
||||||
|
const auto PCONSTRAINT = g_pInputManager->constraintFromWlr(PMOUSE->currentConstraint);
|
||||||
|
if (PCONSTRAINT) { // should never be null but who knows
|
||||||
|
PCONSTRAINT->positionHint = Vector2D(PMOUSE->currentConstraint->current.cursor_hint.x, PMOUSE->currentConstraint->current.cursor_hint.y);
|
||||||
|
PCONSTRAINT->hintSet = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInputManager::updateCapabilities() {
|
void CInputManager::updateCapabilities() {
|
||||||
@@ -1220,3 +1234,12 @@ std::string CInputManager::getNameForNewDevice(std::string internalName) {
|
|||||||
|
|
||||||
return proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno)));
|
return proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SConstraint* CInputManager::constraintFromWlr(wlr_pointer_constraint_v1* constraint) {
|
||||||
|
for (auto& c : m_lConstraints) {
|
||||||
|
if (c.constraint == constraint)
|
||||||
|
return &c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
@@ -50,6 +50,7 @@ public:
|
|||||||
void constrainMouse(SMouse*, wlr_pointer_constraint_v1*);
|
void constrainMouse(SMouse*, wlr_pointer_constraint_v1*);
|
||||||
void recheckConstraint(SMouse*);
|
void recheckConstraint(SMouse*);
|
||||||
void unconstrainMouse();
|
void unconstrainMouse();
|
||||||
|
SConstraint* constraintFromWlr(wlr_pointer_constraint_v1*);
|
||||||
std::string getActiveLayoutForKeyboard(SKeyboard*);
|
std::string getActiveLayoutForKeyboard(SKeyboard*);
|
||||||
|
|
||||||
Vector2D getMouseCoordsInternal();
|
Vector2D getMouseCoordsInternal();
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "ToplevelExportWlrFuncs.hpp"
|
#include "ToplevelExportWlrFuncs.hpp"
|
||||||
|
|
||||||
#define TOPLEVEL_EXPORT_VERSION 1
|
#define TOPLEVEL_EXPORT_VERSION 2
|
||||||
|
|
||||||
static void bindManagerInt(wl_client* client, void* data, uint32_t version, uint32_t id) {
|
static void bindManagerInt(wl_client* client, void* data, uint32_t version, uint32_t id) {
|
||||||
g_pProtocolManager->m_pToplevelExportProtocolManager->bindManager(client, data, version, id);
|
g_pProtocolManager->m_pToplevelExportProtocolManager->bindManager(client, data, version, id);
|
||||||
@@ -41,8 +41,17 @@ CToplevelExportProtocolManager::CToplevelExportProtocolManager() {
|
|||||||
Debug::log(LOG, "ToplevelExportManager started successfully!");
|
Debug::log(LOG, "ToplevelExportManager started successfully!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wlr_foreign_toplevel_handle_v1* zwlrHandleFromResource(wl_resource* resource) {
|
||||||
|
// we can't assert here, but it doesnt matter.
|
||||||
|
return (wlr_foreign_toplevel_handle_v1*)wl_resource_get_user_data(resource);
|
||||||
|
}
|
||||||
|
|
||||||
void handleCaptureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, uint32_t handle) {
|
void handleCaptureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, uint32_t handle) {
|
||||||
g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, handle);
|
g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, g_pCompositor->getWindowFromHandle(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleCaptureToplevelWithWlr(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, wl_resource* handle) {
|
||||||
|
g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, g_pCompositor->getWindowFromZWLRHandle(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDestroy(wl_client* client, wl_resource* resource) {
|
void handleDestroy(wl_client* client, wl_resource* resource) {
|
||||||
@@ -59,7 +68,8 @@ void handleDestroyFrame(wl_client* client, wl_resource* resource) {
|
|||||||
|
|
||||||
static const struct hyprland_toplevel_export_manager_v1_interface toplevelExportManagerImpl = {
|
static const struct hyprland_toplevel_export_manager_v1_interface toplevelExportManagerImpl = {
|
||||||
.capture_toplevel = handleCaptureToplevel,
|
.capture_toplevel = handleCaptureToplevel,
|
||||||
.destroy = handleDestroy
|
.destroy = handleDestroy,
|
||||||
|
.capture_toplevel_with_wlr_toplevel_handle = handleCaptureToplevelWithWlr,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct hyprland_toplevel_export_frame_v1_interface toplevelFrameImpl = {
|
static const struct hyprland_toplevel_export_frame_v1_interface toplevelFrameImpl = {
|
||||||
@@ -92,7 +102,7 @@ void CToplevelExportProtocolManager::removeClient(SToplevelClient* client, bool
|
|||||||
void handleManagerResourceDestroy(wl_resource* resource) {
|
void handleManagerResourceDestroy(wl_resource* resource) {
|
||||||
const auto PCLIENT = clientFromResource(resource);
|
const auto PCLIENT = clientFromResource(resource);
|
||||||
|
|
||||||
g_pProtocolManager->m_pToplevelExportProtocolManager->removeClient(PCLIENT);
|
g_pProtocolManager->m_pToplevelExportProtocolManager->removeClient(PCLIENT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CToplevelExportProtocolManager::bindManager(wl_client* client, void* data, uint32_t version, uint32_t id) {
|
void CToplevelExportProtocolManager::bindManager(wl_client* client, void* data, uint32_t version, uint32_t id) {
|
||||||
@@ -133,26 +143,24 @@ void CToplevelExportProtocolManager::removeFrame(SToplevelFrame* frame, bool for
|
|||||||
m_lFrames.remove(*frame);
|
m_lFrames.remove(*frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, uint32_t handle) {
|
void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, CWindow* pWindow) {
|
||||||
const auto PCLIENT = clientFromResource(resource);
|
const auto PCLIENT = clientFromResource(resource);
|
||||||
|
|
||||||
const auto PWINDOW = g_pCompositor->getWindowFromHandle(handle);
|
|
||||||
|
|
||||||
// create a frame
|
// create a frame
|
||||||
const auto PFRAME = &m_lFrames.emplace_back();
|
const auto PFRAME = &m_lFrames.emplace_back();
|
||||||
PFRAME->overlayCursor = !!overlay_cursor;
|
PFRAME->overlayCursor = !!overlay_cursor;
|
||||||
PFRAME->resource = wl_resource_create(client, &hyprland_toplevel_export_frame_v1_interface, wl_resource_get_version(resource), frame);
|
PFRAME->resource = wl_resource_create(client, &hyprland_toplevel_export_frame_v1_interface, wl_resource_get_version(resource), frame);
|
||||||
PFRAME->pWindow = PWINDOW;
|
PFRAME->pWindow = pWindow;
|
||||||
|
|
||||||
if (!PWINDOW) {
|
if (!PFRAME->pWindow) {
|
||||||
Debug::log(ERR, "Client requested sharing of window handle %x which does not exist!", handle);
|
Debug::log(ERR, "Client requested sharing of window handle %x which does not exist!", PFRAME->pWindow);
|
||||||
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
|
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
|
||||||
removeFrame(PFRAME);
|
removeFrame(PFRAME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PWINDOW->m_bIsMapped || PWINDOW->isHidden()) {
|
if (!PFRAME->pWindow->m_bIsMapped || PFRAME->pWindow->isHidden()) {
|
||||||
Debug::log(ERR, "Client requested sharing of window handle %x which is not shareable!", handle);
|
Debug::log(ERR, "Client requested sharing of window handle %x which is not shareable!", PFRAME->pWindow);
|
||||||
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
|
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
|
||||||
removeFrame(PFRAME);
|
removeFrame(PFRAME);
|
||||||
return;
|
return;
|
||||||
@@ -170,7 +178,7 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou
|
|||||||
PFRAME->client = PCLIENT;
|
PFRAME->client = PCLIENT;
|
||||||
PCLIENT->ref++;
|
PCLIENT->ref++;
|
||||||
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(PFRAME->pWindow->m_iMonitorID);
|
||||||
|
|
||||||
PFRAME->shmFormat = wlr_output_preferred_read_format(PMONITOR->output);
|
PFRAME->shmFormat = wlr_output_preferred_read_format(PMONITOR->output);
|
||||||
if (PFRAME->shmFormat == DRM_FORMAT_INVALID) {
|
if (PFRAME->shmFormat == DRM_FORMAT_INVALID) {
|
||||||
@@ -194,7 +202,7 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou
|
|||||||
PFRAME->dmabufFormat = DRM_FORMAT_INVALID;
|
PFRAME->dmabufFormat = DRM_FORMAT_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
PFRAME->box = {0, 0, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y};
|
PFRAME->box = { 0, 0, (int)(PFRAME->pWindow->m_vRealSize.vec().x * PMONITOR->scale), (int)(PFRAME->pWindow->m_vRealSize.vec().y * PMONITOR->scale) };
|
||||||
int ow, oh;
|
int ow, oh;
|
||||||
wlr_output_effective_resolution(PMONITOR->output, &ow, &oh);
|
wlr_output_effective_resolution(PMONITOR->output, &ow, &oh);
|
||||||
wlr_box_transform(&PFRAME->box, &PFRAME->box, PMONITOR->transform, ow, oh);
|
wlr_box_transform(&PFRAME->box, &PFRAME->box, PMONITOR->transform, ow, oh);
|
||||||
@@ -215,22 +223,26 @@ void CToplevelExportProtocolManager::copyFrame(wl_client* client, wl_resource* r
|
|||||||
if (!PFRAME->pWindow->m_bIsMapped || PFRAME->pWindow->isHidden()) {
|
if (!PFRAME->pWindow->m_bIsMapped || PFRAME->pWindow->isHidden()) {
|
||||||
Debug::log(ERR, "Client requested sharing of window handle %x which is not shareable (2)!", PFRAME->pWindow);
|
Debug::log(ERR, "Client requested sharing of window handle %x which is not shareable (2)!", PFRAME->pWindow);
|
||||||
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
|
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
|
||||||
|
removeFrame(PFRAME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto PBUFFER = wlr_buffer_from_resource(buffer);
|
const auto PBUFFER = wlr_buffer_from_resource(buffer);
|
||||||
if (!PBUFFER) {
|
if (!PBUFFER) {
|
||||||
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer");
|
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer");
|
||||||
|
removeFrame(PFRAME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PBUFFER->width != PFRAME->box.width || PBUFFER->height != PFRAME->box.height) {
|
if (PBUFFER->width != PFRAME->box.width || PBUFFER->height != PFRAME->box.height) {
|
||||||
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer dimensions");
|
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer dimensions");
|
||||||
|
removeFrame(PFRAME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PFRAME->buffer) {
|
if (PFRAME->buffer) {
|
||||||
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_ALREADY_USED, "frame already used");
|
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_ALREADY_USED, "frame already used");
|
||||||
|
removeFrame(PFRAME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,6 +255,7 @@ void CToplevelExportProtocolManager::copyFrame(wl_client* client, wl_resource* r
|
|||||||
|
|
||||||
if (dmabufAttrs.format != PFRAME->dmabufFormat) {
|
if (dmabufAttrs.format != PFRAME->dmabufFormat) {
|
||||||
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
|
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
|
||||||
|
removeFrame(PFRAME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (wlr_buffer_begin_data_ptr_access(PBUFFER, WLR_BUFFER_DATA_PTR_ACCESS_WRITE, &wlrBufferAccessData, &wlrBufferAccessFormat, &wlrBufferAccessStride)) {
|
} else if (wlr_buffer_begin_data_ptr_access(PBUFFER, WLR_BUFFER_DATA_PTR_ACCESS_WRITE, &wlrBufferAccessData, &wlrBufferAccessFormat, &wlrBufferAccessStride)) {
|
||||||
@@ -250,13 +263,16 @@ void CToplevelExportProtocolManager::copyFrame(wl_client* client, wl_resource* r
|
|||||||
|
|
||||||
if (wlrBufferAccessFormat != PFRAME->shmFormat) {
|
if (wlrBufferAccessFormat != PFRAME->shmFormat) {
|
||||||
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
|
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
|
||||||
|
removeFrame(PFRAME);
|
||||||
return;
|
return;
|
||||||
} else if ((int)wlrBufferAccessStride != PFRAME->shmStride) {
|
} else if ((int)wlrBufferAccessStride != PFRAME->shmStride) {
|
||||||
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer stride");
|
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer stride");
|
||||||
|
removeFrame(PFRAME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer type");
|
wl_resource_post_error(PFRAME->resource, HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer type");
|
||||||
|
removeFrame(PFRAME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
|
#include "wlr-foreign-toplevel-management-unstable-v1-protocol.h"
|
||||||
#include "hyprland-toplevel-export-v1-protocol.h"
|
#include "hyprland-toplevel-export-v1-protocol.h"
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
@@ -45,7 +46,7 @@ public:
|
|||||||
CToplevelExportProtocolManager();
|
CToplevelExportProtocolManager();
|
||||||
|
|
||||||
void bindManager(wl_client* client, void* data, uint32_t version, uint32_t id);
|
void bindManager(wl_client* client, void* data, uint32_t version, uint32_t id);
|
||||||
void captureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, uint32_t handle);
|
void captureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, CWindow* handle);
|
||||||
void removeClient(SToplevelClient* client, bool force = false);
|
void removeClient(SToplevelClient* client, bool force = false);
|
||||||
void removeFrame(SToplevelFrame* frame, bool force = false);
|
void removeFrame(SToplevelFrame* frame, bool force = false);
|
||||||
void copyFrame(wl_client* client, wl_resource* resource, wl_resource* buffer, int32_t ignore_damage);
|
void copyFrame(wl_client* client, wl_resource* resource, wl_resource* buffer, int32_t ignore_damage);
|
||||||
|
@@ -846,10 +846,10 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||||||
pixman_region32_t inverseOpaque;
|
pixman_region32_t inverseOpaque;
|
||||||
pixman_region32_init(&inverseOpaque);
|
pixman_region32_init(&inverseOpaque);
|
||||||
if (a >= 255.f) {
|
if (a >= 255.f) {
|
||||||
pixman_box32_t surfbox = {0, 0, pSurface->current.width, pSurface->current.height};
|
pixman_box32_t surfbox = {0, 0, pSurface->current.width * pSurface->current.scale, pSurface->current.height * pSurface->current.scale};
|
||||||
pixman_region32_copy(&inverseOpaque, &pSurface->current.opaque);
|
pixman_region32_copy(&inverseOpaque, &pSurface->current.opaque);
|
||||||
pixman_region32_inverse(&inverseOpaque, &inverseOpaque, &surfbox);
|
pixman_region32_inverse(&inverseOpaque, &inverseOpaque, &surfbox);
|
||||||
pixman_region32_intersect_rect(&inverseOpaque, &inverseOpaque, 0, 0, pSurface->current.width, pSurface->current.height);
|
pixman_region32_intersect_rect(&inverseOpaque, &inverseOpaque, 0, 0, pSurface->current.width * pSurface->current.scale, pSurface->current.height * pSurface->current.scale);
|
||||||
|
|
||||||
if (!pixman_region32_not_empty(&inverseOpaque)) {
|
if (!pixman_region32_not_empty(&inverseOpaque)) {
|
||||||
pixman_region32_fini(&inverseOpaque);
|
pixman_region32_fini(&inverseOpaque);
|
||||||
@@ -865,8 +865,16 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||||||
|
|
||||||
CFramebuffer* POUTFB = nullptr;
|
CFramebuffer* POUTFB = nullptr;
|
||||||
if (!USENEWOPTIMIZE) {
|
if (!USENEWOPTIMIZE) {
|
||||||
|
if (pSurface->current.scale != 1) {
|
||||||
|
// wlroots prohibits shrinking a region
|
||||||
|
// TODO: just shrink
|
||||||
|
pixman_region32_union_rect(&inverseOpaque, &inverseOpaque, 0, 0, pBox->width, pBox->height);
|
||||||
|
}
|
||||||
|
|
||||||
pixman_region32_translate(&inverseOpaque, pBox->x, pBox->y);
|
pixman_region32_translate(&inverseOpaque, pBox->x, pBox->y);
|
||||||
|
|
||||||
|
pixman_region32_intersect(&inverseOpaque, &inverseOpaque, &damage);
|
||||||
|
|
||||||
POUTFB = blurMainFramebufferWithDamage(a, pBox, &inverseOpaque);
|
POUTFB = blurMainFramebufferWithDamage(a, pBox, &inverseOpaque);
|
||||||
} else {
|
} else {
|
||||||
POUTFB = &m_RenderData.pCurrentMonData->blurFB;
|
POUTFB = &m_RenderData.pCurrentMonData->blurFB;
|
||||||
|
@@ -89,7 +89,7 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) {
|
|||||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */)
|
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */)
|
||||||
return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors
|
return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors
|
||||||
|
|
||||||
if (pMonitor->specialWorkspaceID && g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID))
|
if (pMonitor->specialWorkspaceID == pWindow->m_iWorkspaceID)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -255,12 +255,6 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
|||||||
renderdata.fadeAlpha = 255.f;
|
renderdata.fadeAlpha = 255.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply window special data
|
|
||||||
if (pWindow->m_sSpecialRenderData.alphaInactive == -1)
|
|
||||||
renderdata.alpha *= pWindow->m_sSpecialRenderData.alpha;
|
|
||||||
else
|
|
||||||
renderdata.alpha *= pWindow == g_pCompositor->m_pLastWindow ? pWindow->m_sSpecialRenderData.alpha : pWindow->m_sSpecialRenderData.alphaInactive;
|
|
||||||
|
|
||||||
// apply opaque
|
// apply opaque
|
||||||
if (pWindow->m_sAdditionalConfigData.forceOpaque)
|
if (pWindow->m_sAdditionalConfigData.forceOpaque)
|
||||||
renderdata.alpha = 1.f;
|
renderdata.alpha = 1.f;
|
||||||
@@ -269,7 +263,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
|||||||
|
|
||||||
// clip box for animated offsets
|
// clip box for animated offsets
|
||||||
Vector2D offset;
|
Vector2D offset;
|
||||||
if (!ignorePosition && pWindow->m_bIsFloating) {
|
if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->m_bPinned) {
|
||||||
if (PWORKSPACE->m_vRenderOffset.vec().x != 0) {
|
if (PWORKSPACE->m_vRenderOffset.vec().x != 0) {
|
||||||
const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||||
const auto PROGRESS = PWORKSPACE->m_vRenderOffset.vec().x / PWSMON->vecSize.x;
|
const auto PROGRESS = PWORKSPACE->m_vRenderOffset.vec().x / PWSMON->vecSize.x;
|
||||||
|
Submodule subprojects/hyprland-protocols updated: 0dcff94fc1...301733ae46
Submodule subprojects/wlroots updated: c8eb24d30e...86fc2199f8
Reference in New Issue
Block a user