mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-07-27 10:11:55 -07:00
Compare commits
191 Commits
v0.13.1bet
...
v0.15.1bet
Author | SHA1 | Date | |
---|---|---|---|
|
28a6e0ce31 | ||
|
af7d60b3f8 | ||
|
c4487534d2 | ||
|
e4820d1c71 | ||
|
b4a8efc1a7 | ||
|
9480c0fb90 | ||
|
f901c60da5 | ||
|
922e978f56 | ||
|
0508c7d384 | ||
|
ee3b770cfd | ||
|
a29af89545 | ||
|
552c4b7361 | ||
|
d7ef19e2e7 | ||
|
190ddb5697 | ||
|
095688712d | ||
|
d264fbd36a | ||
|
e4527c6b60 | ||
|
32e8eda40a | ||
|
477ad2dd82 | ||
|
e90c5c6347 | ||
|
11ce468996 | ||
|
9c5023ab1a | ||
|
0e4a894edb | ||
|
71e2562a41 | ||
|
9153a81090 | ||
|
0d7f6eac9e | ||
|
6d46ed4011 | ||
|
f825b87c2a | ||
|
44da575ea8 | ||
|
a587909fd5 | ||
|
fd81ba5a4f | ||
|
934f81c93d | ||
|
e8be1507ef | ||
|
60c414ccad | ||
|
0d702b556d | ||
|
9bbae5b8e2 | ||
|
719a5b4f0b | ||
|
7bdfdaa28a | ||
|
a80e0cecfe | ||
|
3e3f6aef5e | ||
|
996938b7e7 | ||
|
f9325b1655 | ||
|
63dfe305dd | ||
|
ec0c6fa22a | ||
|
ff5843bd85 | ||
|
3bb5971c2e | ||
|
a1d9404f9f | ||
|
ab82c4806d | ||
|
49ab3890aa | ||
|
85eea70be4 | ||
|
174b593438 | ||
|
0a08830375 | ||
|
a97621b1cb | ||
|
355366714e | ||
|
590fbf808b | ||
|
bbeed21e62 | ||
|
c6333ba796 | ||
|
6fe103cf06 | ||
|
71733f68ef | ||
|
e6c9e3f81d | ||
|
7579e03b64 | ||
|
1ef23a304a | ||
|
3c27d1ab13 | ||
|
59a3c43913 | ||
|
d867d42366 | ||
|
6eb7d00386 | ||
|
2d73da1a79 | ||
|
45fe185cb9 | ||
|
09268d756f | ||
|
e5dced8b3f | ||
|
b38e7b596f | ||
|
da40bf823f | ||
|
caeb0636fa | ||
|
1424539e4d | ||
|
bdd9680adf | ||
|
ff4c22ca90 | ||
|
9f9129e536 | ||
|
ab42e4bccf | ||
|
425b07d1e5 | ||
|
2636abca2d | ||
|
ead0e74471 | ||
|
dcf5e34bfa | ||
|
65fb526d5c | ||
|
10c4f4ba35 | ||
|
a1319e5110 | ||
|
5233746ac5 | ||
|
0549aa193f | ||
|
168a326609 | ||
|
31cb4c49d9 | ||
|
11ee78f88b | ||
|
7edbaea23d | ||
|
ec5ffe8839 | ||
|
e3b1d3c3c5 | ||
|
458ba3237b | ||
|
5ff44467d7 | ||
|
7a775c0584 | ||
|
87afc8c250 | ||
|
cd2b2c4fba | ||
|
c48336aac3 | ||
|
f70b57f360 | ||
|
bf3f519eb7 | ||
|
190229942f | ||
|
e476382d08 | ||
|
c885afcbc6 | ||
|
fad5fc587d | ||
|
73dbacd16d | ||
|
65fb0cf0f6 | ||
|
5101ddeff1 | ||
|
959557ecc3 | ||
|
bccc81d306 | ||
|
718de0d9fa | ||
|
fd6116c0cd | ||
|
00b16888bf | ||
|
abee2da5bd | ||
|
695411f1bd | ||
|
f9d8b3096a | ||
|
e5d143b238 | ||
|
37f2e1ddbe | ||
|
ef3eb37c7f | ||
|
db551b8970 | ||
|
c08218301b | ||
|
75aaf11a9c | ||
|
c4e782ca5d | ||
|
da2c2ddc21 | ||
|
5272588270 | ||
|
215125bd66 | ||
|
30d16373d0 | ||
|
c1feb683ce | ||
|
d3ffccd45f | ||
|
d49af1cc18 | ||
|
8b46d0b5a9 | ||
|
336883dda3 | ||
|
65ec8c7694 | ||
|
79c645f8cd | ||
|
d44cc9f112 | ||
|
1963da2d47 | ||
|
2b99dbb446 | ||
|
d24f31de51 | ||
|
d51c7ca135 | ||
|
8b11a2e1b1 | ||
|
b4bcba935d | ||
|
7f3750bd75 | ||
|
7a9423c782 | ||
|
6f98b3cbd8 | ||
|
2dd1661aec | ||
|
cde624ec6a | ||
|
b82621c4ec | ||
|
5b6c8d5b0f | ||
|
4dca2b945b | ||
|
a8943246a7 | ||
|
e42de0b778 | ||
|
5146165599 | ||
|
73e19aee6f | ||
|
3780361b95 | ||
|
ec6144e5da | ||
|
b6eaeffcf6 | ||
|
c24b45671a | ||
|
85c7aaf155 | ||
|
696253b348 | ||
|
abb6db9c37 | ||
|
18b483b8e1 | ||
|
7c809a3059 | ||
|
4070e1a148 | ||
|
dd61f88ed1 | ||
|
29626989e7 | ||
|
cf32d28082 | ||
|
5131a4acaf | ||
|
a72a39ebd5 | ||
|
151e013241 | ||
|
fa2d81b649 | ||
|
037d4ed422 | ||
|
9f82278d65 | ||
|
8e0f7b9b11 | ||
|
a96acc8fa4 | ||
|
5a146e9d90 | ||
|
da10022d84 | ||
|
e518adf1ac | ||
|
d8dbe26f31 | ||
|
e9f226797e | ||
|
7d4f0a3199 | ||
|
0062281092 | ||
|
81f267dff9 | ||
|
a09c614c2d | ||
|
b49d7007b5 | ||
|
864e227f5d | ||
|
82aa78916d | ||
|
f024d7114f | ||
|
8808d40008 | ||
|
d94fe3d063 | ||
|
f663fa209c | ||
|
9370c7aa8a |
@@ -29,8 +29,6 @@ input {
|
||||
}
|
||||
|
||||
general {
|
||||
main_mod=SUPER
|
||||
|
||||
gaps_in=5
|
||||
gaps_out=20
|
||||
border_size=2
|
||||
@@ -75,6 +73,10 @@ gestures {
|
||||
#windowrule=pseudo,abc
|
||||
#windowrule=monitor 0,xyz
|
||||
|
||||
# some nice mouse binds
|
||||
bindm=SUPER,mouse:272,movewindow
|
||||
bindm=SUPER,mouse:273,resizewindow
|
||||
|
||||
# example binds
|
||||
bind=SUPER,Q,exec,kitty
|
||||
bind=SUPER,C,killactive,
|
||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1661931183,
|
||||
"narHash": "sha256-0+2KzcexiJCB3Il5t7cZAM2RXNRfm5/gMCwhcZJxLuQ=",
|
||||
"lastModified": 1664989420,
|
||||
"narHash": "sha256-Q8IxomUjjmewsoJgO3htkXLfCckQ7HkDJ/ZhdYVf/fA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "97747d3209efde533f7b1b28f1be11619f556a06",
|
||||
"rev": "37bd39839acf99c5b738319f42478296f827f274",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -26,11 +26,11 @@
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"host": "gitlab.freedesktop.org",
|
||||
"lastModified": 1661882030,
|
||||
"narHash": "sha256-Kw0MG4rXdTnbndVLLCNwkXDmNszwdQZmm7pwI1R3Kds=",
|
||||
"lastModified": 1663507239,
|
||||
"narHash": "sha256-LISZtkPVe8lQ2N8YwVe+KxCkXWLP9mdw6Q2kG93wE8A=",
|
||||
"owner": "wlroots",
|
||||
"repo": "wlroots",
|
||||
"rev": "fd0b0276c9ecc159549acff48b932b83ec3b4f12",
|
||||
"rev": "2ad25b1460400e66ea26bd6489b04072be7d9dbb",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
28
flake.nix
28
flake.nix
@@ -20,7 +20,31 @@
|
||||
"aarch64-linux"
|
||||
"x86_64-linux"
|
||||
];
|
||||
pkgsFor = nixpkgs.legacyPackages;
|
||||
pkgsFor = genSystems (system:
|
||||
import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(_: prev: {
|
||||
libdrm = prev.libdrm.overrideAttrs (old: rec {
|
||||
version = "2.4.113";
|
||||
src = prev.fetchurl {
|
||||
url = "https://dri.freedesktop.org/${old.pname}/${old.pname}-${version}.tar.xz";
|
||||
sha256 = "sha256-f9frKWf2O+tGBvItUOJ32ZNIDQXvdd2Iqb2OZ3Mj5eE=";
|
||||
};
|
||||
mesonFlags =
|
||||
[
|
||||
"-Dinstall-test-programs=true"
|
||||
"-Domap=enabled"
|
||||
"-Dcairo-tests=disabled"
|
||||
]
|
||||
++ lib.optionals prev.stdenv.hostPlatform.isAarch [
|
||||
"-Dtegra=enabled"
|
||||
"-Detnaviv=enabled"
|
||||
];
|
||||
});
|
||||
})
|
||||
];
|
||||
});
|
||||
mkDate = longDate: (lib.concatStringsSep "-" [
|
||||
(__substring 0 4 longDate)
|
||||
(__substring 4 2 longDate)
|
||||
@@ -34,7 +58,7 @@
|
||||
};
|
||||
hyprland = prev.callPackage ./nix/default.nix {
|
||||
stdenv = prev.gcc12Stdenv;
|
||||
version = "0.12.1beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
version = "0.15.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
wlroots = wlroots-hyprland;
|
||||
};
|
||||
hyprland-debug = hyprland.override {debug = true;};
|
||||
|
@@ -19,7 +19,7 @@
|
||||
#include <deque>
|
||||
|
||||
const std::string USAGE = R"#(usage: hyprctl [(opt)flags] [command] [(opt)args]
|
||||
|
||||
|
||||
commands:
|
||||
monitors
|
||||
workspaces
|
||||
@@ -36,7 +36,7 @@ commands:
|
||||
reload
|
||||
setcursor
|
||||
getoption
|
||||
|
||||
|
||||
flags:
|
||||
-j -> output in JSON
|
||||
--batch -> execute a batch of commands, separated by ';'
|
||||
@@ -198,7 +198,7 @@ void setcursorRequest(int argc, char** argv) {
|
||||
|
||||
void batchRequest(std::string arg) {
|
||||
std::string rq = "[[BATCH]]" + arg.substr(arg.find_first_of(" ") + 1);
|
||||
|
||||
|
||||
request(rq);
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
project('Hyprland', 'cpp', 'c',
|
||||
version : '0.12.1beta',
|
||||
version : '0.15.0beta',
|
||||
default_options : [
|
||||
'warning_level=2',
|
||||
'default_library=static',
|
||||
|
@@ -67,6 +67,16 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
recommendedEnvironment = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
defaultText = lib.literalExpression "true";
|
||||
example = lib.literalExpression "false";
|
||||
description = ''
|
||||
Whether to set the recommended environment variables.
|
||||
'';
|
||||
};
|
||||
|
||||
imports = [
|
||||
(
|
||||
lib.mkRenamedOptionModule
|
||||
@@ -81,14 +91,10 @@ in {
|
||||
lib.optional (cfg.package != null) cfg.package
|
||||
++ lib.optional cfg.xwayland.enable pkgs.xwayland;
|
||||
|
||||
home.sessionVariables = {
|
||||
CLUTTER_BACKEND = "wayland";
|
||||
home.sessionVariables = lib.mkIf cfg.recommendedEnvironment {
|
||||
GDK_BACKEND = "wayland";
|
||||
_JAVA_AWT_WM_NONREPARENTING = "1";
|
||||
MOZ_ENABLE_WAYLAND = "1";
|
||||
NIXOS_OZONE_WL = "1";
|
||||
QT_QPA_PLATFORM = "wayland;xcb";
|
||||
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
|
||||
XCURSOR_SIZE = toString config.home.pointerCursor.size or "24";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
};
|
||||
|
@@ -30,21 +30,28 @@ in {
|
||||
Hyprland package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
recommendedEnvironment = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
defaultText = literalExpression "true";
|
||||
example = literalExpression "false";
|
||||
description = ''
|
||||
Whether to set the recommended environment variables.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment = {
|
||||
systemPackages = lib.optional (cfg.package != null) cfg.package;
|
||||
sessionVariables = {
|
||||
CLUTTER_BACKEND = lib.mkDefault "wayland";
|
||||
GDK_BACKEND = lib.mkDefault "wayland";
|
||||
_JAVA_AWT_WM_NONREPARENTING = lib.mkDefault "1";
|
||||
MOZ_ENABLE_WAYLAND = lib.mkDefault "1";
|
||||
NIXOS_OZONE_WL = lib.mkDefault "1";
|
||||
QT_QPA_PLATFORM = lib.mkDefault "wayland;xcb";
|
||||
QT_WAYLAND_DISABLE_WINDOWDECORATION = lib.mkDefault "1";
|
||||
XCURSOR_SIZE = lib.mkDefault "24";
|
||||
XDG_SESSION_TYPE = lib.mkDefault "wayland";
|
||||
|
||||
sessionVariables = mkIf cfg.recommendedEnvironment {
|
||||
GDK_BACKEND = "wayland";
|
||||
_JAVA_AWT_WM_NONREPARENTING = "1";
|
||||
NIXOS_OZONE_WL = "1";
|
||||
XCURSOR_SIZE = "24";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
};
|
||||
};
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
|
@@ -198,6 +198,9 @@ void CCompositor::initAllSignals() {
|
||||
addWLSignal(&m_sWLRCursor->events.touch_down, &Events::listen_touchBegin, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.touch_up, &Events::listen_touchEnd, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.touch_motion, &Events::listen_touchUpdate, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.touch_frame, &Events::listen_touchFrame, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.hold_begin, &Events::listen_holdBegin, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.hold_end, &Events::listen_holdEnd, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRBackend->events.new_input, &Events::listen_newInput, m_sWLRBackend, "Backend");
|
||||
addWLSignal(&m_sSeat.seat->events.request_set_cursor, &Events::listen_requestMouse, &m_sSeat, "Seat");
|
||||
addWLSignal(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel, &m_sSeat, "Seat");
|
||||
@@ -237,19 +240,18 @@ void CCompositor::cleanup() {
|
||||
|
||||
// accumulate all PIDs for killing, also request closing.
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_bIsMapped || !w->m_bIsX11)
|
||||
if (w->m_bIsMapped && !w->m_bHidden)
|
||||
m_dProcessPIDsOnShutdown.push_back(w->getPID());
|
||||
|
||||
closeWindow(w.get());
|
||||
}
|
||||
|
||||
// end threads
|
||||
g_pEventManager->m_tThread = std::thread();
|
||||
HyprCtl::tThread = std::thread();
|
||||
|
||||
m_vWorkspaces.clear();
|
||||
m_vWindows.clear();
|
||||
|
||||
m_bIsShuttingDown = true;
|
||||
|
||||
for (auto& m : m_vMonitors) {
|
||||
g_pHyprOpenGL->destroyMonitorResources(m.get());
|
||||
|
||||
@@ -257,6 +259,8 @@ void CCompositor::cleanup() {
|
||||
wlr_output_commit(m->output);
|
||||
}
|
||||
|
||||
m_vMonitors.clear();
|
||||
|
||||
if (g_pXWaylandManager->m_sWLRXWayland) {
|
||||
wlr_xwayland_destroy(g_pXWaylandManager->m_sWLRXWayland);
|
||||
g_pXWaylandManager->m_sWLRXWayland = nullptr;
|
||||
@@ -264,8 +268,6 @@ void CCompositor::cleanup() {
|
||||
|
||||
wl_display_terminate(m_sWLDisplay);
|
||||
|
||||
m_bIsShuttingDown = true;
|
||||
|
||||
g_pKeybindManager->spawn("sleep 5 && kill -9 " + std::to_string(m_iHyprlandPID)); // this is to prevent that random "freezing"
|
||||
// the PID should not be reused.
|
||||
}
|
||||
@@ -276,7 +278,7 @@ void CCompositor::startCompositor() {
|
||||
//
|
||||
Debug::log(LOG, "Creating the CHyprError!");
|
||||
g_pHyprError = std::make_unique<CHyprError>();
|
||||
|
||||
|
||||
Debug::log(LOG, "Creating the KeybindManager!");
|
||||
g_pKeybindManager = std::make_unique<CKeybindManager>();
|
||||
|
||||
@@ -454,10 +456,17 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
|
||||
}
|
||||
}
|
||||
|
||||
// pinned
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && !(*w)->m_bHidden && (*w)->m_bPinned)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
// first loop over floating cuz they're above, m_vWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden)
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bPinned)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
@@ -517,12 +526,43 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
}
|
||||
}
|
||||
|
||||
// pinned windows on top of floating regardless
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && !(*w)->m_bHidden && !(*w)->m_bX11ShouldntFocus && (*w)->m_bPinned) {
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y))
|
||||
return w->get();
|
||||
|
||||
if (!(*w)->m_bIsX11) {
|
||||
wlr_surface* resultSurf = nullptr;
|
||||
Vector2D origin = (*w)->m_vRealPosition.vec();
|
||||
SExtensionFindingData data = {origin, pos, &resultSurf};
|
||||
wlr_xdg_surface_for_each_popup_surface((*w)->m_uSurface.xdg, findExtensionForVector2D, &data);
|
||||
|
||||
if (resultSurf)
|
||||
return w->get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bX11ShouldntFocus) {
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y))
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bPinned) {
|
||||
// OR windows should add focus to parent
|
||||
if ((*w)->m_bX11ShouldntFocus && (*w)->m_iX11Type != 2)
|
||||
continue;
|
||||
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y)) {
|
||||
|
||||
if ((*w)->m_iX11Type == 2) {
|
||||
// Override Redirect
|
||||
return g_pCompositor->m_pLastWindow; // we kinda trick everything here.
|
||||
// TODO: this is wrong, we should focus the parent, but idk how to get it considering it's nullptr in most cases.
|
||||
}
|
||||
|
||||
return w->get();
|
||||
}
|
||||
|
||||
if (!(*w)->m_bIsX11) {
|
||||
wlr_surface* resultSurf = nullptr;
|
||||
@@ -533,7 +573,7 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
if (resultSurf)
|
||||
return w->get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for windows, we need to check their extensions too, first.
|
||||
@@ -574,10 +614,17 @@ CWindow* CCompositor::windowFromCursor() {
|
||||
}
|
||||
}
|
||||
|
||||
// pinned
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && (*w)->m_bPinned)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID))
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bPinned)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
@@ -593,7 +640,13 @@ CWindow* CCompositor::windowFromCursor() {
|
||||
CWindow* CCompositor::windowFloatingFromCursor() {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden)
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && !(*w)->m_bHidden && (*w)->m_bPinned)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && !(*w)->m_bPinned)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
@@ -608,7 +661,7 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
|
||||
RASSERT(!pWindow->m_bIsX11, "Cannot call vectorWindowToSurface on an X11 window!");
|
||||
|
||||
const auto PSURFACE = pWindow->m_uSurface.xdg;
|
||||
|
||||
|
||||
double subx, suby;
|
||||
|
||||
// calc for oversized windows... fucking bullshit, again.
|
||||
@@ -676,6 +729,9 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
if (m_pLastWindow == pWindow && m_sSeat.seat->keyboard_state.focused_surface == pSurface)
|
||||
return;
|
||||
|
||||
if (pWindow->m_bPinned)
|
||||
pWindow->m_iWorkspaceID = m_pLastMonitor->activeWorkspace;
|
||||
|
||||
if (!isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
||||
g_pKeybindManager->changeworkspace("[internal]" + std::to_string(pWindow->m_iWorkspaceID));
|
||||
|
||||
@@ -703,7 +759,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
|
||||
g_pXWaylandManager->activateWindow(pWindow, true); // sets the m_pLastWindow
|
||||
|
||||
// do pointer focus too
|
||||
// do pointer focus too
|
||||
const auto POINTERLOCAL = g_pInputManager->getMouseCoordsInternal() - pWindow->m_vRealPosition.goalv();
|
||||
wlr_seat_pointer_notify_enter(m_sSeat.seat, PWINDOWSURFACE, POINTERLOCAL.x, POINTERLOCAL.y);
|
||||
|
||||
@@ -731,7 +787,7 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
|
||||
g_pInputManager->m_sIMERelay.onKeyboardFocus(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const auto KEYBOARD = wlr_seat_get_keyboard(m_sSeat.seat);
|
||||
|
||||
@@ -785,7 +841,7 @@ CWindow* CCompositor::getWindowForPopup(wlr_xdg_popup* popup) {
|
||||
|
||||
wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<std::unique_ptr<SLayerSurface>>* layerSurfaces, Vector2D* sCoords, SLayerSurface** ppLayerSurfaceFound) {
|
||||
for (auto it = layerSurfaces->rbegin(); it != layerSurfaces->rend(); it++) {
|
||||
if ((*it)->fadingOut || !(*it)->layerSurface || ((*it)->layerSurface && !(*it)->layerSurface->mapped))
|
||||
if ((*it)->fadingOut || !(*it)->layerSurface || ((*it)->layerSurface && !(*it)->layerSurface->mapped) || (*it)->alpha.fl() == 0.f)
|
||||
continue;
|
||||
|
||||
const auto SURFACEAT = wlr_layer_surface_v1_surface_at((*it)->layerSurface, pos.x - (*it)->geometry.x, pos.y - (*it)->geometry.y, &sCoords->x, &sCoords->y);
|
||||
@@ -821,7 +877,7 @@ bool CCompositor::isWorkspaceVisible(const int& w) {
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (m->activeWorkspace == w)
|
||||
return true;
|
||||
|
||||
|
||||
if (m->specialWorkspaceOpen && w == SPECIAL_WORKSPACE_ID)
|
||||
return true;
|
||||
}
|
||||
@@ -1058,7 +1114,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
||||
switch (dir) {
|
||||
case 'l':
|
||||
if (STICKS(POSA.x, POSB.x + SIZEB.x)) {
|
||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectWindow = w.get();
|
||||
@@ -1067,7 +1123,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
||||
break;
|
||||
case 'r':
|
||||
if (STICKS(POSA.x + SIZEA.x, POSB.x)) {
|
||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectWindow = w.get();
|
||||
@@ -1077,7 +1133,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
||||
case 't':
|
||||
case 'u':
|
||||
if (STICKS(POSA.y, POSB.y + SIZEB.y)) {
|
||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectWindow = w.get();
|
||||
@@ -1087,7 +1143,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
||||
case 'b':
|
||||
case 'd':
|
||||
if (STICKS(POSA.y + SIZEA.y, POSB.y)) {
|
||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectWindow = w.get();
|
||||
@@ -1110,7 +1166,7 @@ void CCompositor::deactivateAllWLRWorkspaces(wlr_ext_workspace_handle_v1* exclud
|
||||
}
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow) {
|
||||
CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow, bool focusableOnly) {
|
||||
bool gotToWindow = false;
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w.get() != pWindow && !gotToWindow)
|
||||
@@ -1121,19 +1177,19 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden)
|
||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden && (!focusableOnly || !w->m_bNoFocus))
|
||||
return w.get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden)
|
||||
if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden && (!focusableOnly || !w->m_bNoFocus))
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow) {
|
||||
CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow, bool focusableOnly) {
|
||||
bool gotToWindow = false;
|
||||
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
||||
if (it->get() != pWindow && !gotToWindow)
|
||||
@@ -1144,12 +1200,12 @@ CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden)
|
||||
if ((*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden && (!focusableOnly || !(*it)->m_bNoFocus))
|
||||
return it->get();
|
||||
}
|
||||
|
||||
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
||||
if (it->get() != pWindow && (*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden)
|
||||
if (it->get() != pWindow && (*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden && (!focusableOnly || !(*it)->m_bNoFocus))
|
||||
return it->get();
|
||||
}
|
||||
|
||||
@@ -1233,7 +1289,7 @@ CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
||||
switch (dir) {
|
||||
case 'l':
|
||||
if (STICKS(POSA.x, POSB.x + SIZEB.x)) {
|
||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = m.get();
|
||||
@@ -1242,7 +1298,7 @@ CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
||||
break;
|
||||
case 'r':
|
||||
if (STICKS(POSA.x + SIZEA.x, POSB.x)) {
|
||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = m.get();
|
||||
@@ -1252,7 +1308,7 @@ CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
||||
case 't':
|
||||
case 'u':
|
||||
if (STICKS(POSA.y, POSB.y + SIZEB.y)) {
|
||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = m.get();
|
||||
@@ -1262,7 +1318,7 @@ CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
||||
case 'b':
|
||||
case 'd':
|
||||
if (STICKS(POSA.y + SIZEA.y, POSB.y)) {
|
||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
const auto INTERSECTLEN = std::max(0.0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = m.get();
|
||||
@@ -1399,6 +1455,17 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
|
||||
}
|
||||
}
|
||||
|
||||
// fix pinned windows
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == pMonitorA->activeWorkspace && w->m_bPinned) {
|
||||
w->m_iWorkspaceID = PWORKSPACEB->m_iID;
|
||||
}
|
||||
|
||||
if (w->m_iWorkspaceID == pMonitorB->activeWorkspace && w->m_bPinned) {
|
||||
w->m_iWorkspaceID = PWORKSPACEA->m_iID;
|
||||
}
|
||||
}
|
||||
|
||||
pMonitorA->activeWorkspace = PWORKSPACEB->m_iID;
|
||||
pMonitorB->activeWorkspace = PWORKSPACEA->m_iID;
|
||||
|
||||
@@ -1431,6 +1498,9 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
if (name == "current")
|
||||
return g_pCompositor->m_pLastMonitor;
|
||||
|
||||
if (isDirection(name)) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorInDirection(name[0]);
|
||||
return PMONITOR;
|
||||
@@ -1536,9 +1606,12 @@ bool CCompositor::workspaceIDOutOfBounds(const int& id) {
|
||||
int highestID = -99999;
|
||||
|
||||
for (auto& w : m_vWorkspaces) {
|
||||
if (w->m_iID == SPECIAL_WORKSPACE_ID)
|
||||
continue;
|
||||
|
||||
if (w->m_iID < lowestID)
|
||||
lowestID = w->m_iID;
|
||||
|
||||
|
||||
if (w->m_iID > highestID)
|
||||
highestID = w->m_iID;
|
||||
}
|
||||
@@ -1550,18 +1623,38 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
|
||||
if (!windowValidMapped(pWindow))
|
||||
return;
|
||||
|
||||
focusWindow(pWindow);
|
||||
if (pWindow->m_bPinned) {
|
||||
Debug::log(LOG, "Pinned windows cannot be fullscreen'd");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID);
|
||||
|
||||
const auto PWORKSPACE = getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && on) {
|
||||
Debug::log(LOG, "Rejecting fullscreen ON on a fullscreen workspace");
|
||||
return;
|
||||
}
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(pWindow, mode, on);
|
||||
|
||||
g_pXWaylandManager->setWindowFullscreen(pWindow, pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL);
|
||||
|
||||
|
||||
// make all windows on the same workspace under the fullscreen window
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID)
|
||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID) {
|
||||
w->m_bCreatedOverFullscreen = false;
|
||||
if (w.get() != pWindow && !w->m_bFadingOut && !w->m_bPinned)
|
||||
w->m_fAlpha = pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL ? 0.f : 255.f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (auto& ls : PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
if (!ls->fadingOut)
|
||||
ls->alpha = pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL ? 0.f : 255.f;
|
||||
}
|
||||
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv(), true);
|
||||
|
||||
forceReportSizesToWindowsOnWorkspace(pWindow->m_iWorkspaceID);
|
||||
@@ -1588,7 +1681,7 @@ CWindow* CCompositor::getX11Parent(CWindow* pWindow) {
|
||||
if (w->m_uSurface.xwayland == pWindow->m_uSurface.xwayland->parent)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1663,25 +1756,6 @@ CWindow* CCompositor::getWindowByRegex(const std::string& regexp) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
wl_event_source* hyprCtlTickSource = nullptr;
|
||||
|
||||
int hyprCtlTick(void* data) {
|
||||
HyprCtl::tickHyprCtl(); // so that we dont get that race condition multithread bullshit
|
||||
|
||||
wl_event_source_timer_update(hyprCtlTickSource, 16); // tick it 60/s, should be enough.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CCompositor::startHyprCtlTick() {
|
||||
if (hyprCtlTickSource)
|
||||
return;
|
||||
|
||||
hyprCtlTickSource = wl_event_loop_add_timer(m_sWLEventLoop, hyprCtlTick, nullptr);
|
||||
|
||||
wl_event_source_timer_update(hyprCtlTickSource, 16);
|
||||
}
|
||||
|
||||
void CCompositor::warpCursorTo(const Vector2D& pos) {
|
||||
|
||||
// warpCursorTo should only be used for warps that
|
||||
|
@@ -86,13 +86,13 @@ public:
|
||||
std::vector<CWindow*> m_vWindowsFadingOut;
|
||||
std::vector<SLayerSurface*> m_vSurfacesFadingOut;
|
||||
|
||||
void startCompositor();
|
||||
void startCompositor();
|
||||
void cleanup();
|
||||
|
||||
wlr_surface* m_pLastFocus = nullptr;
|
||||
CWindow* m_pLastWindow = nullptr;
|
||||
CMonitor* m_pLastMonitor = nullptr;
|
||||
|
||||
|
||||
SSeat m_sSeat;
|
||||
|
||||
bool m_bReadyToProcess = false;
|
||||
@@ -138,8 +138,8 @@ public:
|
||||
void cleanupFadingOut(const int& monid);
|
||||
CWindow* getWindowInDirection(CWindow*, char);
|
||||
void deactivateAllWLRWorkspaces(wlr_ext_workspace_handle_v1* exclude = nullptr);
|
||||
CWindow* getNextWindowOnWorkspace(CWindow*);
|
||||
CWindow* getPrevWindowOnWorkspace(CWindow*);
|
||||
CWindow* getNextWindowOnWorkspace(CWindow*, bool focusableOnly = false);
|
||||
CWindow* getPrevWindowOnWorkspace(CWindow*, bool focusableOnly = false);
|
||||
int getNextAvailableNamedWorkspace();
|
||||
bool isPointOnAnyMonitor(const Vector2D&);
|
||||
CWindow* getConstraintWindow(SMouse*);
|
||||
@@ -165,17 +165,14 @@ public:
|
||||
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
||||
void forceReportSizesToWindowsOnWorkspace(const int&);
|
||||
bool cursorOnReservedArea();
|
||||
|
||||
|
||||
std::string explicitConfigPath;
|
||||
|
||||
void startHyprCtlTick();
|
||||
|
||||
private:
|
||||
void initAllSignals();
|
||||
void setRandomSplash();
|
||||
void setRandomSplash();
|
||||
|
||||
uint64_t m_iHyprlandPID = 0;
|
||||
uint64_t m_iHyprlandPID = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -194,4 +191,4 @@ inline std::map<std::string, xcb_atom_t> HYPRATOMS = {
|
||||
HYPRATOM("_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"),
|
||||
HYPRATOM("_NET_WM_WINDOW_TYPE_POPUP_MENU"),
|
||||
HYPRATOM("_NET_WM_WINDOW_TYPE_TOOLTIP"),
|
||||
HYPRATOM("_NET_WM_WINDOW_TYPE_NOTIFICATION")};
|
||||
HYPRATOM("_NET_WM_WINDOW_TYPE_NOTIFICATION")};
|
||||
|
@@ -48,7 +48,7 @@ wlr_box CWindow::getFullWindowBoundingBox() {
|
||||
m_vRealPosition.vec().y - maxExtents.topLeft.y,
|
||||
m_vRealSize.vec().x + maxExtents.topLeft.x + maxExtents.bottomRight.x,
|
||||
m_vRealSize.vec().y + maxExtents.topLeft.y + maxExtents.bottomRight.y};
|
||||
|
||||
|
||||
return finalBox;
|
||||
}
|
||||
|
||||
@@ -97,8 +97,7 @@ void CWindow::updateWindowDecos() {
|
||||
pid_t CWindow::getPID() {
|
||||
pid_t PID = -1;
|
||||
if (!m_bIsX11) {
|
||||
const auto CLIENT = wl_resource_get_client(m_uSurface.xdg->resource);
|
||||
wl_client_get_credentials(CLIENT, &PID, nullptr, nullptr);
|
||||
wl_client_get_credentials(wl_resource_get_client(m_uSurface.xdg->resource), &PID, nullptr, nullptr);
|
||||
} else {
|
||||
PID = m_uSurface.xwayland->pid;
|
||||
}
|
||||
@@ -120,7 +119,7 @@ void CWindow::createToplevelHandle() {
|
||||
return; // don't create a toplevel
|
||||
|
||||
m_phForeignToplevel = wlr_foreign_toplevel_handle_v1_create(g_pCompositor->m_sWLRToplevelMgr);
|
||||
|
||||
|
||||
wlr_foreign_toplevel_handle_v1_set_app_id(m_phForeignToplevel, g_pXWaylandManager->getAppIDClass(this).c_str());
|
||||
wlr_foreign_toplevel_handle_v1_output_enter(m_phForeignToplevel, g_pCompositor->getMonitorFromID(m_iMonitorID)->output);
|
||||
wlr_foreign_toplevel_handle_v1_set_title(m_phForeignToplevel, m_szTitle.c_str());
|
||||
@@ -212,10 +211,9 @@ void CWindow::moveToWorkspace(int workspaceID) {
|
||||
if (m_iWorkspaceID != workspaceID) {
|
||||
m_iWorkspaceID = workspaceID;
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID);
|
||||
if (PWORKSPACE) {
|
||||
if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); PWORKSPACE) {
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", this, PWORKSPACE->m_szName.c_str())});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -14,7 +14,8 @@ struct SWindowSpecialRenderData {
|
||||
// set by the layout
|
||||
bool rounding = true;
|
||||
bool border = true;
|
||||
};
|
||||
bool decorate = true;
|
||||
};
|
||||
|
||||
struct SWindowAdditionalConfigData {
|
||||
std::string animationStyle = "";
|
||||
@@ -22,6 +23,7 @@ struct SWindowAdditionalConfigData {
|
||||
bool forceNoBlur = false;
|
||||
bool forceOpaque = false;
|
||||
bool forceAllowsInput = false;
|
||||
bool forceNoAnims = false;
|
||||
};
|
||||
|
||||
class CWindow {
|
||||
@@ -119,6 +121,9 @@ public:
|
||||
// For hidden windows and stuff
|
||||
bool m_bHidden = false;
|
||||
|
||||
// For pinned (sticky) windows
|
||||
bool m_bPinned = false;
|
||||
|
||||
// for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
|
||||
CWindow* m_pLastCycledWindow = nullptr;
|
||||
|
||||
@@ -142,6 +147,9 @@ public:
|
||||
// animated tint
|
||||
CAnimatedVariable m_fDimPercent;
|
||||
|
||||
// swallowing
|
||||
CWindow* m_pSwallowed = nullptr;
|
||||
|
||||
// for toplevel monitor events
|
||||
uint64_t m_iLastToplevelMonitorID = -1;
|
||||
uint64_t m_iLastSurfaceMonitorID = -1;
|
||||
|
@@ -48,7 +48,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["general:no_cursor_warps"].intValue = 0;
|
||||
|
||||
configValues["general:layout"].strValue = "dwindle";
|
||||
|
||||
|
||||
configValues["misc:disable_hyprland_logo"].intValue = 0;
|
||||
configValues["misc:disable_splash_rendering"].intValue = 0;
|
||||
configValues["misc:no_vfr"].intValue = 1;
|
||||
@@ -57,6 +57,9 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["misc:always_follow_on_dnd"].intValue = 1;
|
||||
configValues["misc:layers_hog_keyboard_focus"].intValue = 1;
|
||||
configValues["misc:animate_manual_resizes"].intValue = 0;
|
||||
configValues["misc:disable_autoreload"].intValue = 0;
|
||||
configValues["misc:enable_swallow"].intValue = 0;
|
||||
configValues["misc:swallow_regex"].strValue = STRVAL_EMPTY;
|
||||
|
||||
configValues["debug:int"].intValue = 0;
|
||||
configValues["debug:log_damage"].intValue = 0;
|
||||
@@ -80,7 +83,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["decoration:shadow_range"].intValue = 4;
|
||||
configValues["decoration:shadow_render_power"].intValue = 3;
|
||||
configValues["decoration:shadow_ignore_window"].intValue = 1;
|
||||
configValues["decoration:shadow_offset"].strValue = "0 0";
|
||||
configValues["decoration:shadow_offset"].vecValue = Vector2D();
|
||||
configValues["decoration:col.shadow"].intValue = 0xee1a1a1a;
|
||||
configValues["decoration:col.shadow_inactive"].intValue = INT_MAX;
|
||||
configValues["decoration:dim_inactive"].intValue = 0;
|
||||
@@ -122,6 +125,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["animations:workspaces"].intValue = 1;
|
||||
|
||||
configValues["input:sensitivity"].floatValue = 0.f;
|
||||
configValues["input:accel_profile"].strValue = STRVAL_EMPTY;
|
||||
configValues["input:kb_file"].strValue = STRVAL_EMPTY;
|
||||
configValues["input:kb_layout"].strValue = "us";
|
||||
configValues["input:kb_variant"].strValue = STRVAL_EMPTY;
|
||||
@@ -134,14 +138,17 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["input:numlock_by_default"].intValue = 0;
|
||||
configValues["input:force_no_accel"].intValue = 0;
|
||||
configValues["input:float_switch_override_focus"].intValue = 1;
|
||||
configValues["input:left_handed"].intValue = 0;
|
||||
configValues["input:scroll_method"].strValue = STRVAL_EMPTY;
|
||||
configValues["input:touchpad:natural_scroll"].intValue = 0;
|
||||
configValues["input:touchpad:disable_while_typing"].intValue = 1;
|
||||
configValues["input:touchpad:clickfinger_behavior"].intValue = 0;
|
||||
configValues["input:touchpad:middle_button_emulation"].intValue = 0;
|
||||
configValues["input:touchpad:tap-to-click"].intValue = 1;
|
||||
configValues["input:touchpad:drag_lock"].intValue = 0;
|
||||
configValues["input:touchpad:scroll_factor"].floatValue = 1.f;
|
||||
|
||||
configValues["binds:pass_mouse_when_bound"].intValue = 1;
|
||||
configValues["binds:pass_mouse_when_bound"].intValue = 0;
|
||||
configValues["binds:scroll_event_delay"].intValue = 300;
|
||||
configValues["binds:workspace_back_and_forth"].intValue = 0;
|
||||
configValues["binds:allow_workspace_cycles"].intValue = 0;
|
||||
@@ -162,6 +169,7 @@ void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
|
||||
auto& cfgValues = deviceConfigs[dev];
|
||||
|
||||
cfgValues["sensitivity"].floatValue = 0.f;
|
||||
cfgValues["accel_profile"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["kb_file"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["kb_layout"].strValue = "us";
|
||||
cfgValues["kb_variant"].strValue = STRVAL_EMPTY;
|
||||
@@ -177,6 +185,8 @@ void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
|
||||
cfgValues["middle_button_emulation"].intValue = 0;
|
||||
cfgValues["tap-to-click"].intValue = 1;
|
||||
cfgValues["drag_lock"].intValue = 0;
|
||||
cfgValues["left_handed"].intValue = 0;
|
||||
cfgValues["scroll_method"].strValue = STRVAL_EMPTY;
|
||||
}
|
||||
|
||||
void CConfigManager::setDefaultAnimationVars() {
|
||||
@@ -204,7 +214,7 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||
// workspaces
|
||||
INITANIMCFG("specialWorkspace");
|
||||
}
|
||||
|
||||
|
||||
// init the values
|
||||
animationConfig["global"] = {
|
||||
false,
|
||||
@@ -235,7 +245,7 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||
}
|
||||
|
||||
void CConfigManager::init() {
|
||||
|
||||
|
||||
loadConfigLoadVars();
|
||||
|
||||
const char* const ENVHOME = getenv("HOME");
|
||||
@@ -291,7 +301,7 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
||||
|
||||
CONFIGENTRY->set = true;
|
||||
|
||||
if (CONFIGENTRY->intValue != -1) {
|
||||
if (CONFIGENTRY->intValue != -INT64_MAX) {
|
||||
try {
|
||||
if (VALUE.find("0x") == 0) {
|
||||
// Values with 0x are hex
|
||||
@@ -308,7 +318,7 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
}
|
||||
} else if (CONFIGENTRY->floatValue != -1) {
|
||||
} else if (CONFIGENTRY->floatValue != -__FLT_MAX__) {
|
||||
try {
|
||||
CONFIGENTRY->floatValue = stof(VALUE);
|
||||
} catch (...) {
|
||||
@@ -322,6 +332,23 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
}
|
||||
} else if (CONFIGENTRY->vecValue != Vector2D(-__FLT_MAX__, -__FLT_MAX__)) {
|
||||
try {
|
||||
if (const auto SPACEPOS = VALUE.find(' '); SPACEPOS != std::string::npos) {
|
||||
const auto X = VALUE.substr(0, SPACEPOS);
|
||||
const auto Y = VALUE.substr(SPACEPOS + 1);
|
||||
|
||||
if (isNumber(X, true) && isNumber(Y, true)) {
|
||||
CONFIGENTRY->vecValue = Vector2D(std::stof(X), std::stof(Y));
|
||||
}
|
||||
} else {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
}
|
||||
} catch (...) {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,6 +380,11 @@ void CConfigManager::handleRawExec(const std::string& command, const std::string
|
||||
if (child == 0) {
|
||||
// run in child
|
||||
grandchild = fork();
|
||||
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigprocmask(SIG_SETMASK, &set, NULL);
|
||||
|
||||
if (grandchild == 0) {
|
||||
// run in grandchild
|
||||
close(socket[0]);
|
||||
@@ -385,35 +417,15 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
// get the monitor config
|
||||
SMonitorRule newrule;
|
||||
|
||||
std::string curitem = "";
|
||||
const auto ARGS = CVarList(args);
|
||||
|
||||
std::string argZ = args;
|
||||
newrule.name = ARGS[0];
|
||||
|
||||
auto nextItem = [&]() {
|
||||
auto idx = argZ.find_first_of(',');
|
||||
|
||||
if (idx != std::string::npos) {
|
||||
curitem = argZ.substr(0, idx);
|
||||
argZ = argZ.substr(idx + 1);
|
||||
} else {
|
||||
curitem = argZ;
|
||||
argZ = "";
|
||||
}
|
||||
};
|
||||
|
||||
nextItem();
|
||||
|
||||
newrule.name = curitem;
|
||||
|
||||
nextItem();
|
||||
|
||||
if (curitem == "disable" || curitem == "disabled" || curitem == "addreserved" || curitem == "transform") {
|
||||
if (curitem == "disable" || curitem == "disabled")
|
||||
if (ARGS[1] == "disable" || ARGS[1] == "disabled" || ARGS[1] == "addreserved" || ARGS[1] == "transform") {
|
||||
if (ARGS[1] == "disable" || ARGS[1] == "disabled")
|
||||
newrule.disabled = true;
|
||||
else if (curitem == "transform") {
|
||||
nextItem();
|
||||
|
||||
wl_output_transform transform = (wl_output_transform)std::stoi(curitem);
|
||||
else if (ARGS[1] == "transform") {
|
||||
wl_output_transform transform = (wl_output_transform)std::stoi(ARGS[2]);
|
||||
|
||||
// overwrite if exists
|
||||
for (auto& r : m_dMonitorRules) {
|
||||
@@ -424,22 +436,14 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (curitem == "addreserved") {
|
||||
nextItem();
|
||||
} else if (ARGS[1] == "addreserved") {
|
||||
int top = std::stoi(ARGS[2]);
|
||||
|
||||
int top = std::stoi(curitem);
|
||||
int bottom = std::stoi(ARGS[3]);
|
||||
|
||||
nextItem();
|
||||
int left = std::stoi(ARGS[4]);
|
||||
|
||||
int bottom = std::stoi(curitem);
|
||||
|
||||
nextItem();
|
||||
|
||||
int left = std::stoi(curitem);
|
||||
|
||||
nextItem();
|
||||
|
||||
int right = std::stoi(curitem);
|
||||
int right = std::stoi(ARGS[5]);
|
||||
|
||||
m_mAdditionalReservedAreas[newrule.name] = {top, bottom, left, right};
|
||||
|
||||
@@ -449,7 +453,7 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
return;
|
||||
}
|
||||
|
||||
if (std::find_if(m_dMonitorRules.begin(), m_dMonitorRules.end(), [&](const auto& other) { return other.name == newrule.name; }) != m_dMonitorRules.end())
|
||||
if (std::find_if(m_dMonitorRules.begin(), m_dMonitorRules.end(), [&](const auto& other) { return other.name == newrule.name; }) != m_dMonitorRules.end())
|
||||
m_dMonitorRules.erase(std::remove_if(m_dMonitorRules.begin(), m_dMonitorRules.end(), [&](const auto& other) { return other.name == newrule.name; }));
|
||||
|
||||
m_dMonitorRules.push_back(newrule);
|
||||
@@ -457,23 +461,25 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
return;
|
||||
}
|
||||
|
||||
if (curitem.find("pref") == 0) {
|
||||
if (ARGS[1].find("pref") == 0) {
|
||||
newrule.resolution = Vector2D();
|
||||
} else if (ARGS[1].find("highrr") == 0) {
|
||||
newrule.resolution = Vector2D(-1,-1);
|
||||
} else if (ARGS[1].find("highres") == 0) {
|
||||
newrule.resolution = Vector2D(-1,-2);
|
||||
} else {
|
||||
newrule.resolution.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
|
||||
newrule.resolution.y = stoi(curitem.substr(curitem.find_first_of('x') + 1, curitem.find_first_of('@')));
|
||||
newrule.resolution.x = stoi(ARGS[1].substr(0, ARGS[1].find_first_of('x')));
|
||||
newrule.resolution.y = stoi(ARGS[1].substr(ARGS[1].find_first_of('x') + 1, ARGS[1].find_first_of('@')));
|
||||
|
||||
if (curitem.contains("@"))
|
||||
newrule.refreshRate = stof(curitem.substr(curitem.find_first_of('@') + 1));
|
||||
if (ARGS[1].contains("@"))
|
||||
newrule.refreshRate = stof(ARGS[1].substr(ARGS[1].find_first_of('@') + 1));
|
||||
}
|
||||
|
||||
nextItem();
|
||||
|
||||
if (curitem.find("auto") == 0) {
|
||||
if (ARGS[2].find("auto") == 0) {
|
||||
newrule.offset = Vector2D(-1, -1);
|
||||
} else {
|
||||
newrule.offset.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
|
||||
newrule.offset.y = stoi(curitem.substr(curitem.find_first_of('x') + 1));
|
||||
newrule.offset.x = stoi(ARGS[2].substr(0, ARGS[2].find_first_of('x')));
|
||||
newrule.offset.y = stoi(ARGS[2].substr(ARGS[2].find_first_of('x') + 1));
|
||||
|
||||
if (newrule.offset.x < 0 || newrule.offset.y < 0) {
|
||||
parseError = "invalid offset. Offset cannot be negative.";
|
||||
@@ -481,22 +487,26 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
}
|
||||
}
|
||||
|
||||
nextItem();
|
||||
|
||||
newrule.scale = stof(curitem);
|
||||
newrule.scale = stof(ARGS[3]);
|
||||
|
||||
if (newrule.scale < 0.25f) {
|
||||
parseError = "not a valid scale.";
|
||||
newrule.scale = 1;
|
||||
}
|
||||
|
||||
nextItem();
|
||||
int argno = 4;
|
||||
|
||||
if (curitem != "") {
|
||||
// warning for old cfg
|
||||
Debug::log(ERR, "Error in parsing rule for %s, possibly old config!", newrule.name.c_str());
|
||||
parseError = "Error in setting monitor rule. Are you using the old syntax? Confront the wiki.";
|
||||
return;
|
||||
while (ARGS[argno] != "") {
|
||||
if (ARGS[argno] == "mirror") {
|
||||
newrule.mirrorOf = ARGS[argno + 1];
|
||||
argno++;
|
||||
} else {
|
||||
Debug::log(ERR, "Config error: invalid monitor syntax");
|
||||
parseError = "invalid syntax at \"" + ARGS[argno] + "\"";
|
||||
return;
|
||||
}
|
||||
|
||||
argno++;
|
||||
}
|
||||
|
||||
if (std::find_if(m_dMonitorRules.begin(), m_dMonitorRules.end(), [&](const auto& other) { return other.name == newrule.name; }) != m_dMonitorRules.end())
|
||||
@@ -506,44 +516,27 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
}
|
||||
|
||||
void CConfigManager::handleBezier(const std::string& command, const std::string& args) {
|
||||
std::string curitem = "";
|
||||
const auto ARGS = CVarList(args);
|
||||
|
||||
std::string argZ = args;
|
||||
std::string bezierName = ARGS[0];
|
||||
|
||||
auto nextItem = [&]() {
|
||||
auto idx = argZ.find_first_of(',');
|
||||
|
||||
if (idx != std::string::npos) {
|
||||
curitem = argZ.substr(0, idx);
|
||||
argZ = argZ.substr(idx + 1);
|
||||
} else {
|
||||
curitem = argZ;
|
||||
argZ = "";
|
||||
}
|
||||
};
|
||||
|
||||
nextItem();
|
||||
|
||||
std::string bezierName = curitem;
|
||||
|
||||
nextItem();
|
||||
if (curitem == "")
|
||||
if (ARGS[1] == "")
|
||||
parseError = "too few arguments";
|
||||
float p1x = std::stof(curitem);
|
||||
nextItem();
|
||||
if (curitem == "")
|
||||
float p1x = std::stof(ARGS[1]);
|
||||
|
||||
if (ARGS[2] == "")
|
||||
parseError = "too few arguments";
|
||||
float p1y = std::stof(curitem);
|
||||
nextItem();
|
||||
if (curitem == "")
|
||||
float p1y = std::stof(ARGS[2]);
|
||||
|
||||
if (ARGS[3] == "")
|
||||
parseError = "too few arguments";
|
||||
float p2x = std::stof(curitem);
|
||||
nextItem();
|
||||
if (curitem == "")
|
||||
float p2x = std::stof(ARGS[3]);
|
||||
|
||||
if (ARGS[4] == "")
|
||||
parseError = "too few arguments";
|
||||
float p2y = std::stof(curitem);
|
||||
nextItem();
|
||||
if (curitem != "")
|
||||
float p2y = std::stof(ARGS[4]);
|
||||
|
||||
if (ARGS[5] != "")
|
||||
parseError = "too many arguments";
|
||||
|
||||
g_pAnimationManager->addBezierWithName(bezierName, Vector2D(p1x, p1y), Vector2D(p2x, p2y));
|
||||
@@ -561,29 +554,13 @@ void CConfigManager::setAnimForChildren(SAnimationPropertyConfig *const ANIM) {
|
||||
};
|
||||
|
||||
void CConfigManager::handleAnimation(const std::string& command, const std::string& args) {
|
||||
std::string curitem = "";
|
||||
|
||||
std::string argZ = args;
|
||||
|
||||
auto nextItem = [&]() {
|
||||
auto idx = argZ.find_first_of(',');
|
||||
|
||||
if (idx != std::string::npos) {
|
||||
curitem = argZ.substr(0, idx);
|
||||
argZ = argZ.substr(idx + 1);
|
||||
} else {
|
||||
curitem = argZ;
|
||||
argZ = "";
|
||||
}
|
||||
};
|
||||
|
||||
nextItem();
|
||||
const auto ARGS = CVarList(args);
|
||||
|
||||
// Master on/off
|
||||
|
||||
// anim name
|
||||
const auto ANIMNAME = curitem;
|
||||
|
||||
const auto ANIMNAME = ARGS[0];
|
||||
|
||||
const auto PANIM = animationConfig.find(ANIMNAME);
|
||||
|
||||
if (PANIM == animationConfig.end()) {
|
||||
@@ -594,20 +571,16 @@ void CConfigManager::handleAnimation(const std::string& command, const std::stri
|
||||
PANIM->second.overriden = true;
|
||||
PANIM->second.pValues = &PANIM->second;
|
||||
|
||||
nextItem();
|
||||
|
||||
// on/off
|
||||
PANIM->second.internalEnabled = curitem == "1";
|
||||
PANIM->second.internalEnabled = ARGS[1] == "1";
|
||||
|
||||
if (curitem != "0" && curitem != "1") {
|
||||
if (ARGS[1] != "0" && ARGS[1] != "1") {
|
||||
parseError = "invalid animation on/off state";
|
||||
}
|
||||
|
||||
nextItem();
|
||||
|
||||
// speed
|
||||
if (isNumber(curitem, true)) {
|
||||
PANIM->second.internalSpeed = std::stof(curitem);
|
||||
if (isNumber(ARGS[2], true)) {
|
||||
PANIM->second.internalSpeed = std::stof(ARGS[2]);
|
||||
|
||||
if (PANIM->second.internalSpeed <= 0) {
|
||||
parseError = "invalid speed";
|
||||
@@ -618,23 +591,19 @@ void CConfigManager::handleAnimation(const std::string& command, const std::stri
|
||||
parseError = "invalid speed";
|
||||
}
|
||||
|
||||
nextItem();
|
||||
|
||||
// curve
|
||||
PANIM->second.internalBezier = curitem;
|
||||
PANIM->second.internalBezier = ARGS[3];
|
||||
|
||||
if (!g_pAnimationManager->bezierExists(curitem)) {
|
||||
if (!g_pAnimationManager->bezierExists(ARGS[3])) {
|
||||
parseError = "no such bezier";
|
||||
PANIM->second.internalBezier = "default";
|
||||
}
|
||||
|
||||
nextItem();
|
||||
|
||||
// style
|
||||
PANIM->second.internalStyle = curitem;
|
||||
PANIM->second.internalStyle = ARGS[4];
|
||||
|
||||
if (curitem != "") {
|
||||
const auto ERR = g_pAnimationManager->styleValidInConfigVar(ANIMNAME, curitem);
|
||||
if (ARGS[4] != "") {
|
||||
const auto ERR = g_pAnimationManager->styleValidInConfigVar(ANIMNAME, ARGS[4]);
|
||||
|
||||
if (ERR != "")
|
||||
parseError = ERR;
|
||||
@@ -652,15 +621,18 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
||||
bool locked = false;
|
||||
bool release = false;
|
||||
bool repeat = false;
|
||||
const auto ARGS = command.substr(4);
|
||||
bool mouse = false;
|
||||
const auto BINDARGS = command.substr(4);
|
||||
|
||||
for (auto& arg : ARGS) {
|
||||
for (auto& arg : BINDARGS) {
|
||||
if (arg == 'l') {
|
||||
locked = true;
|
||||
} else if (arg == 'r') {
|
||||
release = true;
|
||||
} else if (arg == 'e') {
|
||||
repeat = true;
|
||||
} else if (arg == 'm') {
|
||||
mouse = true;
|
||||
} else {
|
||||
parseError = "bind: invalid flag";
|
||||
return;
|
||||
@@ -672,19 +644,35 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
||||
return;
|
||||
}
|
||||
|
||||
auto valueCopy = value;
|
||||
if (mouse && (repeat || release || locked)) {
|
||||
parseError = "flag m is exclusive";
|
||||
return;
|
||||
}
|
||||
|
||||
const auto MOD = g_pKeybindManager->stringToModMask(valueCopy.substr(0, valueCopy.find_first_of(",")));
|
||||
const auto MODSTR = valueCopy.substr(0, valueCopy.find_first_of(","));
|
||||
valueCopy = valueCopy.substr(valueCopy.find_first_of(",") + 1);
|
||||
const auto ARGS = CVarList(value, 4);
|
||||
|
||||
const auto KEY = valueCopy.substr(0, valueCopy.find_first_of(","));
|
||||
valueCopy = valueCopy.substr(valueCopy.find_first_of(",") + 1);
|
||||
if ((ARGS.size() < 3 && !mouse) || (ARGS.size() < 3 && mouse)) {
|
||||
parseError = "bind: too few args";
|
||||
return;
|
||||
} else if ((ARGS.size() > 4 && !mouse) || (ARGS.size() > 3 && mouse)) {
|
||||
parseError = "bind: too many args";
|
||||
return;
|
||||
}
|
||||
|
||||
const auto HANDLER = valueCopy.substr(0, valueCopy.find_first_of(","));
|
||||
valueCopy = valueCopy.substr(valueCopy.find_first_of(",") + 1);
|
||||
const auto MOD = g_pKeybindManager->stringToModMask(ARGS[0]);
|
||||
const auto MODSTR = ARGS[0];
|
||||
|
||||
const auto COMMAND = valueCopy;
|
||||
const auto KEY = ARGS[1];
|
||||
|
||||
auto HANDLER = ARGS[2];
|
||||
|
||||
const auto COMMAND = mouse ? HANDLER : ARGS[3];
|
||||
|
||||
if (mouse)
|
||||
HANDLER = "mouse";
|
||||
|
||||
// to lower
|
||||
std::transform(HANDLER.begin(), HANDLER.end(), HANDLER.begin(), ::tolower);
|
||||
|
||||
const auto DISPATCHER = g_pKeybindManager->m_mDispatchers.find(HANDLER);
|
||||
|
||||
@@ -707,30 +695,29 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
||||
|
||||
if (KEY != "") {
|
||||
if (isNumber(KEY) && std::stoi(KEY) > 9)
|
||||
g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat});
|
||||
g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse});
|
||||
else
|
||||
g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat});
|
||||
g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CConfigManager::handleUnbind(const std::string& command, const std::string& value) {
|
||||
auto valueCopy = value;
|
||||
const auto ARGS = CVarList(value);
|
||||
|
||||
const auto MOD = g_pKeybindManager->stringToModMask(valueCopy.substr(0, valueCopy.find_first_of(",")));
|
||||
valueCopy = valueCopy.substr(valueCopy.find_first_of(",") + 1);
|
||||
const auto MOD = g_pKeybindManager->stringToModMask(ARGS[0]);
|
||||
|
||||
const auto KEY = valueCopy;
|
||||
const auto KEY = ARGS[1];
|
||||
|
||||
g_pKeybindManager->removeKeybind(MOD, KEY);
|
||||
}
|
||||
|
||||
bool windowRuleValid(const std::string& RULE) {
|
||||
return !(RULE != "float"
|
||||
return !(RULE != "float"
|
||||
&& RULE != "tile"
|
||||
&& RULE.find("opacity") != 0
|
||||
&& RULE.find("move") != 0
|
||||
&& RULE.find("size") != 0
|
||||
&& RULE.find("minsize") != 0
|
||||
&& RULE.find("pseudo") != 0
|
||||
&& RULE.find("monitor") != 0
|
||||
&& RULE != "nofocus"
|
||||
@@ -739,14 +726,16 @@ bool windowRuleValid(const std::string& RULE) {
|
||||
&& RULE != "opaque"
|
||||
&& RULE != "forceinput"
|
||||
&& RULE != "fullscreen"
|
||||
&& RULE != "pin"
|
||||
&& RULE != "noanim"
|
||||
&& RULE.find("animation") != 0
|
||||
&& RULE.find("rounding") != 0
|
||||
&& RULE.find("workspace") != 0);
|
||||
}
|
||||
|
||||
void CConfigManager::handleWindowRule(const std::string& command, const std::string& value) {
|
||||
const auto RULE = value.substr(0, value.find_first_of(","));
|
||||
const auto VALUE = value.substr(value.find_first_of(",") + 1);
|
||||
const auto RULE = removeBeginEndSpacesTabs(value.substr(0, value.find_first_of(",")));
|
||||
const auto VALUE = removeBeginEndSpacesTabs(value.substr(value.find_first_of(",") + 1));
|
||||
|
||||
// check rule and value
|
||||
if (RULE == "" || VALUE == "") {
|
||||
@@ -802,6 +791,8 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s
|
||||
|
||||
result = result.substr(0, min - pos);
|
||||
|
||||
result = removeBeginEndSpacesTabs(result);
|
||||
|
||||
if (result.back() == ',')
|
||||
result.pop_back();
|
||||
|
||||
@@ -829,7 +820,7 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s
|
||||
|
||||
void CConfigManager::handleBlurLS(const std::string& command, const std::string& value) {
|
||||
if (value.find("remove,") == 0) {
|
||||
const auto TOREMOVE = value.substr(7);
|
||||
const auto TOREMOVE = removeBeginEndSpacesTabs(value.substr(7));
|
||||
m_dBlurLSNamespaces.erase(std::remove(m_dBlurLSNamespaces.begin(), m_dBlurLSNamespaces.end(), TOREMOVE));
|
||||
return;
|
||||
}
|
||||
@@ -838,20 +829,18 @@ void CConfigManager::handleBlurLS(const std::string& command, const std::string&
|
||||
}
|
||||
|
||||
void CConfigManager::handleDefaultWorkspace(const std::string& command, const std::string& value) {
|
||||
|
||||
const auto DISPLAY = value.substr(0, value.find_first_of(','));
|
||||
const auto WORKSPACE = value.substr(value.find_first_of(',') + 1);
|
||||
const auto ARGS = CVarList(value);
|
||||
|
||||
for (auto& mr : m_dMonitorRules) {
|
||||
if (mr.name == DISPLAY) {
|
||||
mr.defaultWorkspace = WORKSPACE;
|
||||
if (mr.name == ARGS[0]) {
|
||||
mr.defaultWorkspace = ARGS[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigManager::handleSubmap(const std::string& command, const std::string& submap) {
|
||||
if (submap == "reset")
|
||||
if (submap == "reset")
|
||||
m_szCurrentSubmap = "";
|
||||
else
|
||||
m_szCurrentSubmap = submap;
|
||||
@@ -911,6 +900,19 @@ void CConfigManager::handleSource(const std::string& command, const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigManager::handleBindWS(const std::string& command, const std::string& value) {
|
||||
const auto ARGS = CVarList(value);
|
||||
|
||||
const auto FOUND = std::find_if(boundWorkspaces.begin(), boundWorkspaces.end(), [&](const auto& other) { return other.first == ARGS[0]; });
|
||||
|
||||
if (FOUND != boundWorkspaces.end()) {
|
||||
FOUND->second = ARGS[1];
|
||||
return;
|
||||
}
|
||||
|
||||
boundWorkspaces.push_back({ARGS[0], ARGS[1]});
|
||||
}
|
||||
|
||||
std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::string& VALUE, bool dynamic) {
|
||||
if (dynamic) {
|
||||
parseError = "";
|
||||
@@ -939,6 +941,7 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
||||
else if (COMMAND == "source") handleSource(COMMAND, VALUE);
|
||||
else if (COMMAND == "submap") handleSubmap(COMMAND, VALUE);
|
||||
else if (COMMAND == "blurls") handleBlurLS(COMMAND, VALUE);
|
||||
else if (COMMAND == "wsbind") handleBindWS(COMMAND, VALUE);
|
||||
else
|
||||
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
||||
|
||||
@@ -1012,9 +1015,9 @@ void CConfigManager::parseLine(std::string& line) {
|
||||
|
||||
if (LASTSEP == std::string::npos || currentCategory.contains("device"))
|
||||
currentCategory = "";
|
||||
else
|
||||
else
|
||||
currentCategory = currentCategory.substr(0, LASTSEP);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1039,7 +1042,7 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
Debug::log(LOG, "Reloading the config!");
|
||||
parseError = ""; // reset the error
|
||||
currentCategory = ""; // reset the category
|
||||
|
||||
|
||||
// reset all vars before loading
|
||||
setDefaultVars();
|
||||
m_dMonitorRules.clear();
|
||||
@@ -1050,6 +1053,7 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
configDynamicVars.clear();
|
||||
deviceConfigs.clear();
|
||||
m_dBlurLSNamespaces.clear();
|
||||
boundWorkspaces.clear();
|
||||
setDefaultAnimationVars(); // reset anims
|
||||
|
||||
// paths
|
||||
@@ -1067,7 +1071,7 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
}
|
||||
|
||||
configPaths.push_back(CONFIGPATH);
|
||||
|
||||
|
||||
std::ifstream ifs;
|
||||
ifs.open(CONFIGPATH);
|
||||
|
||||
@@ -1134,7 +1138,7 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
// Update the keyboard layout to the cfg'd one if this is not the first launch
|
||||
if (!isFirstLaunch) {
|
||||
g_pInputManager->setKeyboardLayout();
|
||||
g_pInputManager->setMouseConfigs();
|
||||
g_pInputManager->setPointerConfigs();
|
||||
}
|
||||
|
||||
// Calculate the internal vars
|
||||
@@ -1179,7 +1183,7 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
// Force the compositor to fully re-render all monitors
|
||||
m->forceFullFrames = 2;
|
||||
}
|
||||
|
||||
|
||||
// Reset no monitor reload
|
||||
m_bNoMonitorReload = false;
|
||||
}
|
||||
@@ -1304,11 +1308,11 @@ void CConfigManager::setString(std::string v, std::string val) {
|
||||
configValues[v].strValue = val;
|
||||
}
|
||||
|
||||
SMonitorRule CConfigManager::getMonitorRuleFor(std::string name) {
|
||||
SMonitorRule CConfigManager::getMonitorRuleFor(std::string name, std::string displayName) {
|
||||
SMonitorRule* found = nullptr;
|
||||
|
||||
for (auto& r : m_dMonitorRules) {
|
||||
if (r.name == name) {
|
||||
if (r.name == name || (r.name.find("desc:") == 0 && (r.name.substr(5) == displayName || r.name.substr(5) == removeBeginEndSpacesTabs(displayName.substr(0, displayName.find_first_of('(')))))) {
|
||||
found = &r;
|
||||
break;
|
||||
}
|
||||
@@ -1419,7 +1423,7 @@ void CConfigManager::dispatchExecOnce() {
|
||||
|
||||
// set input, fixes some certain issues
|
||||
g_pInputManager->setKeyboardLayout();
|
||||
g_pInputManager->setMouseConfigs();
|
||||
g_pInputManager->setPointerConfigs();
|
||||
|
||||
// set ws names again
|
||||
for (auto& ws : g_pCompositor->m_vWorkspaces) {
|
||||
@@ -1432,7 +1436,11 @@ void CConfigManager::performMonitorReload() {
|
||||
bool overAgain = false;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||
auto rule = getMonitorRuleFor(m->szName);
|
||||
auto rule = getMonitorRuleFor(m->szName, m->output->description ? m->output->description : "");
|
||||
|
||||
// ensure mirror
|
||||
m->setMirror(rule.mirrorOf);
|
||||
|
||||
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule)) {
|
||||
overAgain = true;
|
||||
break;
|
||||
@@ -1481,7 +1489,7 @@ bool CConfigManager::shouldBlurLS(const std::string& ns) {
|
||||
|
||||
void CConfigManager::ensureDPMS() {
|
||||
for (auto& rm : g_pCompositor->m_vRealMonitors) {
|
||||
auto rule = getMonitorRuleFor(rm->szName);
|
||||
auto rule = getMonitorRuleFor(rm->szName, rm->output->description ? rm->output->description : "");
|
||||
|
||||
if (rule.disabled == rm->m_bEnabled) {
|
||||
rm->m_pThisWrap = &rm;
|
||||
@@ -1498,3 +1506,15 @@ void CConfigManager::addParseError(const std::string& err) {
|
||||
if (parseError == "")
|
||||
parseError = err;
|
||||
}
|
||||
|
||||
CMonitor* CConfigManager::getBoundMonitorForWS(std::string wsname) {
|
||||
for (auto&[ws, mon] : boundWorkspaces) {
|
||||
const auto WSNAME = ws.find("name:") == 0 ? ws.substr(5) : ws;
|
||||
|
||||
if (WSNAME == wsname) {
|
||||
return g_pCompositor->getMonitorFromString(mon);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@@ -20,9 +20,10 @@
|
||||
#define CREATEANIMCFG(name, parent) animationConfig[name] = {false, "", "", 0.f, -1, &animationConfig["global"], &animationConfig[parent]}
|
||||
|
||||
struct SConfigValue {
|
||||
int64_t intValue = -1;
|
||||
float floatValue = -1;
|
||||
int64_t intValue = -INT64_MAX;
|
||||
float floatValue = -__FLT_MAX__;
|
||||
std::string strValue = "";
|
||||
Vector2D vecValue = Vector2D(-__FLT_MAX__, -__FLT_MAX__);
|
||||
|
||||
bool set = false; // used for device configs
|
||||
};
|
||||
@@ -36,6 +37,7 @@ struct SMonitorRule {
|
||||
std::string defaultWorkspace = "";
|
||||
bool disabled = false;
|
||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
std::string mirrorOf = "";
|
||||
};
|
||||
|
||||
struct SMonitorAdditionalReservedArea {
|
||||
@@ -68,6 +70,48 @@ struct SAnimationPropertyConfig {
|
||||
SAnimationPropertyConfig* pParentAnimation = nullptr;
|
||||
};
|
||||
|
||||
class CVarList {
|
||||
public:
|
||||
CVarList(const std::string& in, long unsigned int lastArgNo = 0) {
|
||||
std::string curitem = "";
|
||||
std::string argZ = in;
|
||||
|
||||
auto nextItem = [&]() {
|
||||
auto idx = lastArgNo != 0 && m_vArgs.size() >= lastArgNo - 1 ? std::string::npos : argZ.find_first_of(',');
|
||||
|
||||
if (idx != std::string::npos) {
|
||||
curitem = argZ.substr(0, idx);
|
||||
argZ = argZ.substr(idx + 1);
|
||||
} else {
|
||||
curitem = argZ;
|
||||
argZ = STRVAL_EMPTY;
|
||||
}
|
||||
};
|
||||
|
||||
nextItem();
|
||||
|
||||
while (curitem != STRVAL_EMPTY) {
|
||||
m_vArgs.push_back(removeBeginEndSpacesTabs(curitem));
|
||||
nextItem();
|
||||
}
|
||||
};
|
||||
|
||||
~CVarList() = default;
|
||||
|
||||
int size() const {
|
||||
return m_vArgs.size();
|
||||
}
|
||||
|
||||
std::string operator[](const long unsigned int& idx) const {
|
||||
if (idx >= m_vArgs.size())
|
||||
return "";
|
||||
return m_vArgs[idx];
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_vArgs;
|
||||
};
|
||||
|
||||
class CConfigManager {
|
||||
public:
|
||||
CConfigManager();
|
||||
@@ -91,7 +135,9 @@ public:
|
||||
SConfigValue* getConfigValuePtr(std::string);
|
||||
SConfigValue* getConfigValuePtrSafe(std::string);
|
||||
|
||||
SMonitorRule getMonitorRuleFor(std::string);
|
||||
SMonitorRule getMonitorRuleFor(std::string, std::string displayName = "");
|
||||
|
||||
CMonitor* getBoundMonitorForWS(std::string);
|
||||
|
||||
std::vector<SWindowRule> getMatchingRules(CWindow*);
|
||||
|
||||
@@ -129,6 +175,8 @@ private:
|
||||
|
||||
std::string m_szCurrentSubmap = ""; // For storing the current keybind submap
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> boundWorkspaces;
|
||||
|
||||
bool isFirstLaunch = true; // For exec-once
|
||||
|
||||
std::deque<SMonitorRule> m_dMonitorRules;
|
||||
@@ -164,6 +212,7 @@ private:
|
||||
void handleSource(const std::string&, const std::string&);
|
||||
void handleSubmap(const std::string&, const std::string&);
|
||||
void handleBlurLS(const std::string&, const std::string&);
|
||||
void handleBindWS(const std::string&, const std::string&);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
||||
|
@@ -83,6 +83,10 @@ gestures {
|
||||
#windowrule=pseudo,abc
|
||||
#windowrule=monitor 0,xyz
|
||||
|
||||
# some nice mouse binds
|
||||
bindm=SUPER,mouse:272,movewindow
|
||||
bindm=SUPER,mouse:273,resizewindow
|
||||
|
||||
# example binds
|
||||
bind=SUPER,Q,exec,kitty
|
||||
bind=SUPER,RETURN,exec,alacritty
|
||||
|
@@ -17,12 +17,13 @@ std::string monitorsRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
std::string result = "";
|
||||
if (format == HyprCtl::FORMAT_JSON) {
|
||||
result += "[";
|
||||
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat(
|
||||
R"#({
|
||||
"id": %i,
|
||||
"name": "%s",
|
||||
"description": "%s",
|
||||
"width": %i,
|
||||
"height": %i,
|
||||
"refreshRate": %f,
|
||||
@@ -35,10 +36,12 @@ R"#({
|
||||
"reserved": [%i, %i, %i, %i],
|
||||
"scale": %.2f,
|
||||
"transform": %i,
|
||||
"focused": %s
|
||||
"focused": %s,
|
||||
"dpmsStatus": %s
|
||||
},)#",
|
||||
m->ID,
|
||||
escapeJSONStrings(m->szName).c_str(),
|
||||
escapeJSONStrings(m->output->description ? m->output->description : "").c_str(),
|
||||
(int)m->vecPixelSize.x, (int)m->vecPixelSize.y,
|
||||
m->refreshRate,
|
||||
(int)m->vecPosition.x, (int)m->vecPosition.y,
|
||||
@@ -46,7 +49,8 @@ R"#({
|
||||
(int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y,
|
||||
m->scale,
|
||||
(int)m->transform,
|
||||
(m.get() == g_pCompositor->m_pLastMonitor ? "true" : "false")
|
||||
(m.get() == g_pCompositor->m_pLastMonitor ? "true" : "false"),
|
||||
(m->dpmsStatus ? "true" : "false")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -56,8 +60,8 @@ R"#({
|
||||
result += "]";
|
||||
} else {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\tfocused: %s\n\n",
|
||||
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "yes" : "no"));
|
||||
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tdescription: %s\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\tfocused: %s\n\tdpmsStatus: %i\n\n",
|
||||
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, (m->output->description ? m->output->description : ""), m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,18 +89,24 @@ R"#({
|
||||
"class": "%s",
|
||||
"title": "%s",
|
||||
"pid": %i,
|
||||
"xwayland": %s
|
||||
"xwayland": %s,
|
||||
"pinned": %s,
|
||||
"fullscreen": %s,
|
||||
"fullscreenMode": %i
|
||||
},)#",
|
||||
w.get(),
|
||||
(int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y,
|
||||
(int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y,
|
||||
(int)w->m_vRealPosition.goalv().x, (int)w->m_vRealPosition.goalv().y,
|
||||
(int)w->m_vRealSize.goalv().x, (int)w->m_vRealSize.goalv().y,
|
||||
w->m_iWorkspaceID, escapeJSONStrings(w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID))).c_str(),
|
||||
((int)w->m_bIsFloating == 1 ? "true" : "false"),
|
||||
w->m_iMonitorID,
|
||||
escapeJSONStrings(g_pXWaylandManager->getAppIDClass(w.get())).c_str(),
|
||||
escapeJSONStrings(g_pXWaylandManager->getTitle(w.get())).c_str(),
|
||||
w->getPID(),
|
||||
((int)w->m_bIsX11 == 1 ? "true" : "false")
|
||||
((int)w->m_bIsX11 == 1 ? "true" : "false"),
|
||||
(w->m_bPinned ? "true" : "false"),
|
||||
(w->m_bIsFullscreen ? "true" : "false"),
|
||||
(w->m_bIsFullscreen ? (g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_efFullscreenMode : 0) : 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -109,9 +119,9 @@ R"#({
|
||||
} else {
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsMapped) {
|
||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\txwayland: %i\n\n",
|
||||
w.get(), w->m_szTitle.c_str(), (int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y, (int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w.get()).c_str(), g_pXWaylandManager->getTitle(w.get()).c_str(), w->getPID(), (int)w->m_bIsX11);
|
||||
|
||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\txwayland: %i\n\tpinned: %i\n\tfullscreen: %i\n\tfullscreenmode: %i\n\n",
|
||||
w.get(), w->m_szTitle.c_str(), (int)w->m_vRealPosition.goalv().x, (int)w->m_vRealPosition.goalv().y, (int)w->m_vRealSize.goalv().x, (int)w->m_vRealSize.goalv().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w.get()).c_str(), g_pXWaylandManager->getTitle(w.get()).c_str(), w->getPID(), (int)w->m_bIsX11, (int)w->m_bPinned, (int)w->m_bIsFullscreen, (w->m_bIsFullscreen ? (g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_efFullscreenMode : 0) : 0));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,12 +222,12 @@ R"#("%s": {
|
||||
"levels": {
|
||||
)#",
|
||||
escapeJSONStrings(mon->szName).c_str()
|
||||
);
|
||||
);
|
||||
|
||||
int layerLevel = 0;
|
||||
for (auto& level : mon->m_aLayerSurfaceLists) {
|
||||
result += getFormat(
|
||||
R"#(
|
||||
R"#(
|
||||
"%i": [
|
||||
)#",
|
||||
layerLevel
|
||||
@@ -262,7 +272,7 @@ R"#( {
|
||||
result.pop_back();
|
||||
|
||||
result += "\n}\n";
|
||||
|
||||
|
||||
} else {
|
||||
for (auto& mon : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s:\n", mon->szName.c_str());
|
||||
@@ -294,10 +304,12 @@ std::string devicesRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
result += getFormat(
|
||||
R"#( {
|
||||
"address": "0x%x",
|
||||
"name": "%s"
|
||||
"name": "%s",
|
||||
"defaultSpeed": %f
|
||||
},)#",
|
||||
&m,
|
||||
escapeJSONStrings(m.mouse->name).c_str()
|
||||
escapeJSONStrings(m.mouse->name).c_str(),
|
||||
wlr_input_device_is_libinput(m.mouse) ? libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(m.mouse)) : 0.f
|
||||
);
|
||||
}
|
||||
|
||||
@@ -377,6 +389,41 @@ R"#( {
|
||||
);
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
result.pop_back();
|
||||
result += "\n],\n";
|
||||
|
||||
result += "\"touch\": [\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTouchDevices) {
|
||||
result += getFormat(
|
||||
R"#( {
|
||||
"address": "0x%x",
|
||||
"name": "%s"
|
||||
},)#",
|
||||
&d,
|
||||
d.pWlrDevice ? d.pWlrDevice->name : ""
|
||||
);
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
if (result[result.size() - 1] == ',')
|
||||
result.pop_back();
|
||||
result += "\n],\n";
|
||||
|
||||
result += "\"switches\": [\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lSwitches) {
|
||||
result += getFormat(
|
||||
R"#( {
|
||||
"address": "0x%x",
|
||||
"name": "%s"
|
||||
},)#",
|
||||
&d,
|
||||
d.pWlrDevice ? d.pWlrDevice->name : ""
|
||||
);
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
if (result[result.size() - 1] == ',')
|
||||
result.pop_back();
|
||||
@@ -388,7 +435,7 @@ R"#( {
|
||||
result += "mice:\n";
|
||||
|
||||
for (auto& m : g_pInputManager->m_lMice) {
|
||||
result += getFormat("\tMouse at %x:\n\t\t%s\n", &m, m.mouse->name);
|
||||
result += getFormat("\tMouse at %x:\n\t\t%s\n\t\t\tdefault speed: %f\n", &m, m.mouse->name, (wlr_input_device_is_libinput(m.mouse) ? libinput_device_config_accel_get_default_speed((libinput_device*)wlr_libinput_get_device_handle(m.mouse)) : 0.f));
|
||||
}
|
||||
|
||||
result += "\n\nKeyboards:\n";
|
||||
@@ -411,6 +458,18 @@ R"#( {
|
||||
for (auto& d : g_pInputManager->m_lTabletTools) {
|
||||
result += getFormat("\tTablet Tool at %x (belongs to %x)\n", &d, d.wlrTabletTool ? d.wlrTabletTool->data : 0);
|
||||
}
|
||||
|
||||
result += "\n\nTouch:\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTouchDevices) {
|
||||
result += getFormat("\tTouch Device at %x:\n\t\t%s\n", &d, d.pWlrDevice ? d.pWlrDevice->name : "");
|
||||
}
|
||||
|
||||
result += "\n\nSwitches:\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lSwitches) {
|
||||
result += getFormat("\tSwitch Device at %x:\n\t\t%s\n", &d, d.pWlrDevice ? d.pWlrDevice->name : "");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -502,7 +561,7 @@ std::string dispatchKeyword(std::string in) {
|
||||
|
||||
if (COMMAND.contains("input") || COMMAND.contains("device:")) {
|
||||
g_pInputManager->setKeyboardLayout(); // update kb layout
|
||||
g_pInputManager->setMouseConfigs(); // update mouse cfgs
|
||||
g_pInputManager->setPointerConfigs(); // update mouse cfgs
|
||||
}
|
||||
|
||||
if (COMMAND.contains("general:layout"))
|
||||
@@ -510,14 +569,14 @@ std::string dispatchKeyword(std::string in) {
|
||||
|
||||
Debug::log(LOG, "Hyprctl: keyword %s : %s", COMMAND.c_str(), VALUE.c_str());
|
||||
|
||||
if (retval == "")
|
||||
if (retval == "")
|
||||
return "ok";
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
std::string reloadRequest(std::string request) {
|
||||
|
||||
|
||||
const auto REQMODE = request.substr(request.find_last_of(' ') + 1);
|
||||
|
||||
g_pConfigManager->m_bForceReload = true;
|
||||
@@ -526,6 +585,8 @@ std::string reloadRequest(std::string request) {
|
||||
g_pConfigManager->m_bNoMonitorReload = true;
|
||||
}
|
||||
|
||||
g_pConfigManager->tick();
|
||||
|
||||
return "ok";
|
||||
}
|
||||
|
||||
@@ -676,7 +737,7 @@ std::string getReply(std::string request) {
|
||||
}
|
||||
|
||||
sepIndex++;
|
||||
|
||||
|
||||
if (c == 'j')
|
||||
format = HyprCtl::FORMAT_JSON;
|
||||
}
|
||||
@@ -719,9 +780,21 @@ std::string getReply(std::string request) {
|
||||
return "unknown request";
|
||||
}
|
||||
|
||||
void HyprCtl::tickHyprCtl() {
|
||||
if (!requestMade)
|
||||
return;
|
||||
int hyprCtlFDTick(int fd, uint32_t mask, void* data) {
|
||||
if (mask & WL_EVENT_ERROR || mask & WL_EVENT_HANGUP)
|
||||
return 0;
|
||||
|
||||
sockaddr_in clientAddress;
|
||||
socklen_t clientSize = sizeof(clientAddress);
|
||||
|
||||
const auto ACCEPTEDCONNECTION = accept(HyprCtl::iSocketFD, (sockaddr*)&clientAddress, &clientSize);
|
||||
|
||||
char readBuffer[1024];
|
||||
|
||||
auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024);
|
||||
readBuffer[messageSize == 1024 ? 1023 : messageSize] = '\0';
|
||||
|
||||
std::string request(readBuffer);
|
||||
|
||||
std::string reply = "";
|
||||
|
||||
@@ -732,88 +805,38 @@ void HyprCtl::tickHyprCtl() {
|
||||
reply = "Err: " + std::string(e.what());
|
||||
}
|
||||
|
||||
request = reply;
|
||||
write(ACCEPTEDCONNECTION, reply.c_str(), reply.length());
|
||||
|
||||
requestMade = false;
|
||||
requestReady = true;
|
||||
close(ACCEPTEDCONNECTION);
|
||||
|
||||
if (g_pConfigManager->m_bWantsMonitorReload) {
|
||||
g_pConfigManager->ensureDPMS();
|
||||
}
|
||||
}
|
||||
|
||||
std::string getRequestFromThread(std::string rq) {
|
||||
|
||||
while (HyprCtl::request != "" || HyprCtl::requestMade || HyprCtl::requestReady) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
|
||||
HyprCtl::request = rq;
|
||||
HyprCtl::requestMade = true;
|
||||
|
||||
while (!HyprCtl::requestReady) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
|
||||
HyprCtl::requestReady = false;
|
||||
HyprCtl::requestMade = false;
|
||||
|
||||
std::string toReturn = HyprCtl::request;
|
||||
|
||||
HyprCtl::request = "";
|
||||
|
||||
return toReturn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HyprCtl::startHyprCtlSocket() {
|
||||
tThread = std::thread([&]() {
|
||||
const auto SOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (SOCKET < 0) {
|
||||
Debug::log(ERR, "Couldn't start the Hyprland Socket. (1) IPC will not work.");
|
||||
return;
|
||||
}
|
||||
iSocketFD = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
|
||||
if (iSocketFD < 0) {
|
||||
Debug::log(ERR, "Couldn't start the Hyprland Socket. (1) IPC will not work.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string socketPath = "/tmp/hypr/" + g_pCompositor->m_szInstanceSignature + "/.socket.sock";
|
||||
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
|
||||
|
||||
strcpy(SERVERADDRESS.sun_path, socketPath.c_str());
|
||||
std::string socketPath = "/tmp/hypr/" + g_pCompositor->m_szInstanceSignature + "/.socket.sock";
|
||||
|
||||
bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
|
||||
strcpy(SERVERADDRESS.sun_path, socketPath.c_str());
|
||||
|
||||
// 10 max queued.
|
||||
listen(SOCKET, 10);
|
||||
bind(iSocketFD, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
|
||||
|
||||
sockaddr_in clientAddress;
|
||||
socklen_t clientSize = sizeof(clientAddress);
|
||||
// 10 max queued.
|
||||
listen(iSocketFD, 10);
|
||||
|
||||
char readBuffer[1024] = {0};
|
||||
Debug::log(LOG, "Hypr socket started at %s", socketPath.c_str());
|
||||
|
||||
Debug::log(LOG, "Hypr socket started at %s", socketPath.c_str());
|
||||
|
||||
while(1) {
|
||||
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);
|
||||
|
||||
if (ACCEPTEDCONNECTION < 0) {
|
||||
Debug::log(ERR, "Couldn't listen on the Hyprland Socket. (3) IPC will not work.");
|
||||
break;
|
||||
}
|
||||
|
||||
auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024);
|
||||
readBuffer[messageSize == 1024 ? 1023 : messageSize] = '\0';
|
||||
|
||||
std::string request(readBuffer);
|
||||
|
||||
std::string reply = getRequestFromThread(request);
|
||||
|
||||
write(ACCEPTEDCONNECTION, reply.c_str(), reply.length());
|
||||
|
||||
close(ACCEPTEDCONNECTION);
|
||||
}
|
||||
|
||||
close(SOCKET);
|
||||
});
|
||||
|
||||
tThread.detach();
|
||||
wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, iSocketFD, WL_EVENT_READABLE, hyprCtlFDTick, nullptr);
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@
|
||||
|
||||
namespace HyprCtl {
|
||||
void startHyprCtlSocket();
|
||||
void tickHyprCtl();
|
||||
|
||||
// very simple thread-safe request method
|
||||
inline bool requestMade = false;
|
||||
@@ -15,7 +14,9 @@ namespace HyprCtl {
|
||||
|
||||
inline std::ifstream requestStream;
|
||||
|
||||
inline std::thread tThread;
|
||||
inline wl_event_source* hyprCtlTickSource = nullptr;
|
||||
|
||||
inline int iSocketFD = -1;
|
||||
|
||||
enum eHyprCtlOutputFormat {
|
||||
FORMAT_NORMAL = 0,
|
||||
|
@@ -58,7 +58,7 @@ void Debug::log(LogLevel level, const char* fmt, ...) {
|
||||
if (disableTime && !*disableTime) {
|
||||
auto timet = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
const auto MILLIS = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 1000;
|
||||
|
||||
|
||||
ofs << std::put_time(std::localtime(&timet), "[%H:%M:%S:");
|
||||
|
||||
if (MILLIS > 99)
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#define PIXMAN_DAMAGE_FOREACH(region) int rectsNum = 0; \
|
||||
const auto RECTSARR = pixman_region32_rectangles(region, &rectsNum); \
|
||||
for (int i = 0; i < rectsNum; ++i)
|
||||
|
||||
|
||||
|
||||
#define interface class
|
||||
|
||||
@@ -74,4 +74,4 @@
|
||||
#define GIT_DIRTY "?"
|
||||
#endif
|
||||
|
||||
#define SPECIAL_WORKSPACE_ID -99
|
||||
#define SPECIAL_WORKSPACE_ID -99
|
||||
|
@@ -72,7 +72,7 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
Debug::log(LOG, "Attached a touch device with name %s", DEVICE->name);
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, DEVICE);
|
||||
g_pInputManager->newTouchDevice(DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||
Debug::log(LOG, "Attached a tablet tool with name %s", DEVICE->name);
|
||||
@@ -82,6 +82,10 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
|
||||
Debug::log(LOG, "Attached a tablet pad with name %s", DEVICE->name);
|
||||
g_pInputManager->newTabletPad(DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_SWITCH:
|
||||
Debug::log(LOG, "Attached a switch device with name %s", DEVICE->name);
|
||||
g_pInputManager->newSwitch(DEVICE);
|
||||
break;
|
||||
default:
|
||||
Debug::log(WARN, "Unrecognized input device plugged in: %s", DEVICE->name);
|
||||
break;
|
||||
@@ -206,4 +210,16 @@ void Events::listener_touchEnd(wl_listener* listener, void* data) {
|
||||
|
||||
void Events::listener_touchUpdate(wl_listener* listener, void* data) {
|
||||
g_pInputManager->onTouchMove((wlr_touch_motion_event*)data);
|
||||
}
|
||||
|
||||
void Events::listener_touchFrame(wl_listener* listener, void* data) {
|
||||
wlr_seat_touch_notify_frame(g_pCompositor->m_sSeat.seat);
|
||||
}
|
||||
|
||||
void Events::listener_holdBegin(wl_listener* listener, void* data) {
|
||||
g_pInputManager->onPointerHoldBegin((wlr_pointer_hold_begin_event*)data);
|
||||
}
|
||||
|
||||
void Events::listener_holdEnd(wl_listener* listener, void* data) {
|
||||
g_pInputManager->onPointerHoldEnd((wlr_pointer_hold_end_event*)data);
|
||||
}
|
@@ -67,7 +67,7 @@ namespace Events {
|
||||
LISTENER(mouseButton);
|
||||
LISTENER(mouseAxis);
|
||||
LISTENER(mouseFrame);
|
||||
|
||||
|
||||
LISTENER(newInput);
|
||||
|
||||
// Virt Ptr
|
||||
@@ -77,7 +77,7 @@ namespace Events {
|
||||
DYNLISTENFUNC(keyboardKey);
|
||||
DYNLISTENFUNC(keyboardMod);
|
||||
DYNLISTENFUNC(keyboardDestroy);
|
||||
|
||||
|
||||
DYNLISTENFUNC(commitConstraint);
|
||||
LISTENER(newConstraint);
|
||||
DYNLISTENFUNC(setConstraintRegion);
|
||||
@@ -152,4 +152,8 @@ namespace Events {
|
||||
LISTENER(touchBegin);
|
||||
LISTENER(touchEnd);
|
||||
LISTENER(touchUpdate);
|
||||
};
|
||||
LISTENER(touchFrame);
|
||||
|
||||
LISTENER(holdBegin);
|
||||
LISTENER(holdEnd);
|
||||
};
|
||||
|
@@ -133,8 +133,9 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
|
||||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||
|
||||
wlr_surface_send_enter(layersurface->layerSurface->surface, layersurface->layerSurface->output);
|
||||
|
||||
if (layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint)) { // don't focus if constrained
|
||||
wlr_surface_send_enter(layersurface->layerSurface->surface, layersurface->layerSurface->output);
|
||||
g_pCompositor->focusSurface(layersurface->layerSurface->surface);
|
||||
|
||||
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y);
|
||||
@@ -244,7 +245,7 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
|
||||
|
||||
if (layersurface->layerSurface->current.committed != 0) {
|
||||
if (layersurface->layer != layersurface->layerSurface->current.layer) {
|
||||
|
||||
|
||||
for (auto it = PMONITOR->m_aLayerSurfaceLists[layersurface->layer].begin(); it != PMONITOR->m_aLayerSurfaceLists[layersurface->layer].end(); it++) {
|
||||
if (it->get() == layersurface) {
|
||||
PMONITOR->m_aLayerSurfaceLists[layersurface->layerSurface->current.layer].emplace_back(std::move(*it));
|
||||
@@ -270,4 +271,4 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
|
||||
layersurface->geometry = {layersurface->geometry.x, layersurface->geometry.y, layersurface->layerSurface->surface->current.width, layersurface->layerSurface->surface->current.height};
|
||||
|
||||
g_pHyprRenderer->damageSurface(layersurface->layerSurface->surface, layersurface->position.x, layersurface->position.y);
|
||||
}
|
||||
}
|
||||
|
@@ -87,7 +87,7 @@ void Events::listener_requestDrag(wl_listener* listener, void* data) {
|
||||
}
|
||||
|
||||
void Events::listener_startDrag(wl_listener* listener, void* data) {
|
||||
|
||||
|
||||
if (g_pInputManager->m_sDrag.drag)
|
||||
return; // don't handle multiple drags
|
||||
|
||||
@@ -167,7 +167,7 @@ void Events::listener_commitDragIcon(void* owner, void* data) {
|
||||
|
||||
void Events::listener_InhibitActivate(wl_listener* listener, void* data) {
|
||||
Debug::log(LOG, "Activated exclusive for %x.", g_pCompositor->m_sSeat.exclusiveClient);
|
||||
|
||||
|
||||
g_pInputManager->refocus();
|
||||
g_pCompositor->m_sSeat.exclusiveClient = g_pCompositor->m_sWLRInhibitMgr->active_client;
|
||||
}
|
||||
@@ -195,7 +195,7 @@ void Events::listener_powerMgrSetMode(wl_listener* listener, void* data) {
|
||||
const auto EVENT = (wlr_output_power_v1_set_mode_event*)data;
|
||||
|
||||
wlr_output_enable(EVENT->output, EVENT->mode == 1);
|
||||
|
||||
|
||||
if (!wlr_output_commit(EVENT->output))
|
||||
Debug::log(ERR, "Couldn't set power mode");
|
||||
}
|
||||
@@ -210,4 +210,4 @@ void Events::listener_newTextInput(wl_listener* listener, void* data) {
|
||||
Debug::log(LOG, "New TextInput added!");
|
||||
|
||||
g_pInputManager->m_sIMERelay.onNewTextInput((wlr_text_input_v3*)data);
|
||||
}
|
||||
}
|
||||
|
@@ -99,7 +99,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
Debug::log(WARN, "Attempted to render frame on inactive session!");
|
||||
return; // cannot draw on session inactive (different tty)
|
||||
}
|
||||
|
||||
|
||||
if (!PMONITOR->m_bEnabled)
|
||||
return;
|
||||
|
||||
@@ -190,7 +190,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
}
|
||||
|
||||
// if we have no tracking or full tracking, invalidate the entire monitor
|
||||
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || PMONITOR->forceFullFrames > 0 || damageBlinkCleanup > 0) {
|
||||
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || PMONITOR->forceFullFrames > 0 || damageBlinkCleanup > 0 || PMONITOR->isMirror() /* why??? */) {
|
||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x * 10, (int)PMONITOR->vecTransformedSize.y * 10); // wot?
|
||||
|
||||
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
||||
@@ -218,44 +218,51 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
if (PMONITOR->forceFullFrames > 10)
|
||||
PMONITOR->forceFullFrames = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: this is getting called with extents being 0,0,0,0 should it be?
|
||||
// potentially can save on resources.
|
||||
|
||||
g_pHyprOpenGL->begin(PMONITOR, &damage);
|
||||
g_pHyprOpenGL->clear(CColor(17, 17, 17, 255));
|
||||
g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper"
|
||||
|
||||
g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now);
|
||||
if (PMONITOR->isMirror()) {
|
||||
g_pHyprOpenGL->renderMirrored();
|
||||
|
||||
// if correct monitor draw hyprerror
|
||||
if (PMONITOR->ID == 0)
|
||||
g_pHyprError->draw();
|
||||
Debug::log(LOG, "Mirror frame");
|
||||
} else {
|
||||
g_pHyprOpenGL->clear(CColor(17, 17, 17, 255));
|
||||
g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper"
|
||||
|
||||
// for drawing the debug overlay
|
||||
if (PMONITOR->ID == 0 && *PDEBUGOVERLAY == 1) {
|
||||
startRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
g_pDebugOverlay->draw();
|
||||
endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now);
|
||||
|
||||
// if correct monitor draw hyprerror
|
||||
if (PMONITOR->ID == 0)
|
||||
g_pHyprError->draw();
|
||||
|
||||
// for drawing the debug overlay
|
||||
if (PMONITOR->ID == 0 && *PDEBUGOVERLAY == 1) {
|
||||
startRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
g_pDebugOverlay->draw();
|
||||
endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
if (*PDAMAGEBLINK && damageBlinkCleanup == 0) {
|
||||
wlr_box monrect = {0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
|
||||
g_pHyprOpenGL->renderRect(&monrect, CColor(255, 0, 255, 100), 0);
|
||||
damageBlinkCleanup = 1;
|
||||
} else if (*PDAMAGEBLINK) {
|
||||
damageBlinkCleanup++;
|
||||
if (damageBlinkCleanup > 3)
|
||||
damageBlinkCleanup = 0;
|
||||
}
|
||||
|
||||
wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
|
||||
wlr_output_render_software_cursors(PMONITOR->output, NULL);
|
||||
|
||||
wlr_renderer_end(g_pCompositor->m_sWLRRenderer);
|
||||
}
|
||||
|
||||
if (*PDAMAGEBLINK && damageBlinkCleanup == 0) {
|
||||
wlr_box monrect = {0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
|
||||
g_pHyprOpenGL->renderRect(&monrect, CColor(255,0,255,100), 0);
|
||||
damageBlinkCleanup = 1;
|
||||
} else if (*PDAMAGEBLINK) {
|
||||
damageBlinkCleanup++;
|
||||
if (damageBlinkCleanup > 3)
|
||||
damageBlinkCleanup = 0;
|
||||
}
|
||||
|
||||
wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
|
||||
wlr_output_render_software_cursors(PMONITOR->output, NULL);
|
||||
|
||||
wlr_renderer_end(g_pCompositor->m_sWLRRenderer);
|
||||
|
||||
g_pHyprOpenGL->end();
|
||||
|
||||
// calc frame damage
|
||||
@@ -272,10 +279,15 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
pixman_region32_union(&frameDamage, &frameDamage, &damage);
|
||||
|
||||
wlr_output_set_damage(PMONITOR->output, &frameDamage);
|
||||
|
||||
if (!PMONITOR->mirrors.empty())
|
||||
g_pHyprRenderer->damageMirrorsWith(PMONITOR, &frameDamage);
|
||||
|
||||
pixman_region32_fini(&frameDamage);
|
||||
pixman_region32_fini(&damage);
|
||||
|
||||
wlr_output_commit(PMONITOR->output);
|
||||
if (!wlr_output_commit(PMONITOR->output))
|
||||
return;
|
||||
|
||||
if (*PDAMAGEBLINK || *PNOVFR)
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||
|
@@ -120,7 +120,7 @@ void Events::listener_newPopupFromPopupXDG(void* owner, void* data) {
|
||||
SXDGPopup* PPOPUP = (SXDGPopup*)owner;
|
||||
|
||||
ASSERT(PPOPUP);
|
||||
|
||||
|
||||
if (PPOPUP->parentWindow)
|
||||
Debug::log(LOG, "New popup created from XDG Window popup %x -> %s", PPOPUP, PPOPUP->parentWindow->m_szTitle.c_str());
|
||||
else
|
||||
@@ -201,4 +201,4 @@ void Events::listener_destroyPopupXDG(void* owner, void* data) {
|
||||
}
|
||||
|
||||
g_pCompositor->m_vXDGPopups.erase(std::remove_if(g_pCompositor->m_vXDGPopups.begin(), g_pCompositor->m_vXDGPopups.end(), [&](std::unique_ptr<SXDGPopup>& el) { return el.get() == PPOPUP; }));
|
||||
}
|
||||
}
|
||||
|
@@ -49,6 +49,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
static auto *const PINACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity")->floatValue;
|
||||
static auto *const PACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:active_opacity")->floatValue;
|
||||
static auto *const PDIMSTRENGTH = &g_pConfigManager->getConfigValuePtr("decoration:dim_strength")->floatValue;
|
||||
static auto *const PSWALLOW = &g_pConfigManager->getConfigValuePtr("misc:enable_swallow")->intValue;
|
||||
static auto *const PSWALLOWREGEX = &g_pConfigManager->getConfigValuePtr("misc:swallow_regex")->strValue;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->m_pLastMonitor;
|
||||
const auto PWORKSPACE = PMONITOR->specialWorkspaceOpen ? g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
@@ -162,6 +164,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_sAdditionalConfigData.forceOpaque = true;
|
||||
} else if (r.szRule == "forceinput") {
|
||||
PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true;
|
||||
} else if (r.szRule == "pin") {
|
||||
PWINDOW->m_bPinned = true;
|
||||
} else if (r.szRule == "noanim") {
|
||||
PWINDOW->m_sAdditionalConfigData.forceNoAnims = true;
|
||||
} else if (r.szRule.find("rounding") == 0) {
|
||||
try {
|
||||
PWINDOW->m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
||||
@@ -188,6 +194,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
}
|
||||
}
|
||||
|
||||
// disallow tiled pinned
|
||||
if (PWINDOW->m_bPinned && !PWINDOW->m_bIsFloating)
|
||||
PWINDOW->m_bPinned = false;
|
||||
|
||||
if (requestedWorkspace != "") {
|
||||
// process requested workspace
|
||||
if (requestedWorkspace.contains(' ')) {
|
||||
@@ -227,8 +237,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||
const auto SIZEYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||
|
||||
const auto SIZEX = !SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stoi(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
||||
const auto SIZEY = !SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stoi(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
||||
const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW);
|
||||
|
||||
const auto SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, 20.0, PMONITOR->vecSize.x) : (!SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stoi(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.x);
|
||||
const auto SIZEY = SIZEYSTR == "max" ? std::clamp(MAXSIZE.y, 20.0, PMONITOR->vecSize.y) : (!SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stoi(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y);
|
||||
|
||||
Debug::log(LOG, "Rule size, applying to window %x", PWINDOW);
|
||||
|
||||
@@ -239,14 +251,29 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
} catch (...) {
|
||||
Debug::log(LOG, "Rule size failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str());
|
||||
}
|
||||
} else if (r.szRule.find("minsize") == 0) {
|
||||
try {
|
||||
const auto VALUE = r.szRule.substr(r.szRule.find(" ") + 1);
|
||||
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||
const auto SIZEYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||
|
||||
const auto SIZE = Vector2D(std::max((double)std::stoll(SIZEXSTR), PWINDOW->m_vRealSize.goalv().x), std::max((double)std::stoll(SIZEYSTR), PWINDOW->m_vRealSize.goalv().y));
|
||||
|
||||
PWINDOW->m_vRealSize = SIZE;
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
||||
|
||||
PWINDOW->m_bHidden = false;
|
||||
} catch (...) {
|
||||
Debug::log(LOG, "Rule minsize failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str());
|
||||
}
|
||||
} else if (r.szRule.find("move") == 0) {
|
||||
try {
|
||||
const auto VALUE = r.szRule.substr(r.szRule.find(" ") + 1);
|
||||
const auto POSXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||
const auto POSYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||
|
||||
const auto POSX = !POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
||||
const auto POSY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
||||
const auto POSX = !POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.x;
|
||||
const auto POSY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y;
|
||||
|
||||
Debug::log(LOG, "Rule move, applying to window %x", PWINDOW);
|
||||
|
||||
@@ -264,6 +291,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
// set the pseudo size to the GOAL of our current size
|
||||
// because the windows are animated on RealSize
|
||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv();
|
||||
|
||||
g_pCompositor->moveWindowToTop(PWINDOW);
|
||||
}
|
||||
else {
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
|
||||
@@ -293,7 +322,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
if (!PWINDOW->m_bIsX11) {
|
||||
PWINDOW->hyprListener_commitWindow.initCallback(&PWINDOW->m_uSurface.xdg->surface->events.commit, &Events::listener_commitWindow, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_newPopupXDG.initCallback(&PWINDOW->m_uSurface.xdg->events.new_popup, &Events::listener_newPopupXDG, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_requestMaximize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_maximize, &Events::listener_requestMaximize, PWINDOW, "XDG Window Late");
|
||||
PWINDOW->hyprListener_requestMinimize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_minimize, &Events::listener_requestMinimize, PWINDOW, "XDG Window Late");
|
||||
@@ -305,7 +334,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->hyprListener_activateX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_activate, &Events::listener_activateX11, PWINDOW, "XWayland Window Late");
|
||||
PWINDOW->hyprListener_configureX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_configure, &Events::listener_configureX11, PWINDOW, "XWayland Window Late");
|
||||
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XWayland Window Late");
|
||||
|
||||
|
||||
if (PWINDOW->m_iX11Type == 2)
|
||||
PWINDOW->hyprListener_setGeometryX11U.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_geometry, &Events::listener_unmanagedSetGeometry, PWINDOW, "XWayland Window Late");
|
||||
}
|
||||
@@ -338,8 +367,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
// fix fullscreen on requested (basically do a switcheroo)
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PFULLWINDOW, FULLSCREEN_FULL, false);
|
||||
g_pXWaylandManager->setWindowFullscreen(PFULLWINDOW, PFULLWINDOW->m_bIsFullscreen);
|
||||
g_pCompositor->setWindowFullscreen(PFULLWINDOW, false, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
PWINDOW->m_vRealPosition.warp();
|
||||
@@ -367,9 +395,77 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
g_pCompositor->focusWindow(nullptr);
|
||||
}
|
||||
|
||||
// verify swallowing
|
||||
if (*PSWALLOW) {
|
||||
// check parent
|
||||
int ppid = getPPIDof(PWINDOW->getPID());
|
||||
|
||||
const auto PPPID = getPPIDof(ppid);
|
||||
|
||||
// why? no clue. Blame terminals.
|
||||
if (PPPID > 2) {
|
||||
ppid = PPPID;
|
||||
}
|
||||
|
||||
if (ppid) {
|
||||
// get window by pid
|
||||
std::vector<CWindow*> found;
|
||||
CWindow* finalFound = nullptr;
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (!w->m_bIsMapped || w->m_bHidden)
|
||||
continue;
|
||||
|
||||
if (w->getPID() == ppid) {
|
||||
found.push_back(w.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (found.size() > 1) {
|
||||
for (auto& w : found) {
|
||||
// try get the focus
|
||||
if (w == PFOCUSEDWINDOWPREV) {
|
||||
finalFound = w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!finalFound) {
|
||||
// just get the closest (ws)
|
||||
for (auto& w : found) {
|
||||
if (w->m_iWorkspaceID == g_pCompositor->m_pLastMonitor->activeWorkspace) {
|
||||
finalFound = w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!finalFound) {
|
||||
// what, just use 0
|
||||
finalFound = found[0];
|
||||
}
|
||||
|
||||
} else if (found.size() == 1) {
|
||||
finalFound = found[0];
|
||||
}
|
||||
|
||||
if (finalFound) {
|
||||
// check if it's the window we want
|
||||
std::regex rgx(*PSWALLOWREGEX);
|
||||
if (std::regex_match(g_pXWaylandManager->getAppIDClass(finalFound), rgx)) {
|
||||
// swallow
|
||||
PWINDOW->m_pSwallowed = finalFound;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(finalFound);
|
||||
|
||||
finalFound->m_bHidden = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y);
|
||||
|
||||
auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName;
|
||||
|
||||
auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName;
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"openwindow", getFormat("%x,%s,%s,%s", PWINDOW, workspaceID.c_str(), g_pXWaylandManager->getAppIDClass(PWINDOW).c_str(), PWINDOW->m_szTitle.c_str())});
|
||||
}
|
||||
|
||||
@@ -377,7 +473,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
Debug::log(LOG, "Window %x unmapped (class %s)", PWINDOW, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str());
|
||||
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"closewindow", getFormat("%x", PWINDOW)});
|
||||
|
||||
if (!PWINDOW->m_bIsX11) {
|
||||
@@ -400,14 +496,19 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bIsFullscreen) {
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL, false);
|
||||
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||
g_pCompositor->forceReportSizesToWindowsOnWorkspace(PWINDOW->m_iWorkspaceID);
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
// Allow the renderer to catch the last frame.
|
||||
g_pHyprOpenGL->makeWindowSnapshot(PWINDOW);
|
||||
|
||||
// swallowing
|
||||
if (PWINDOW->m_pSwallowed && g_pCompositor->windowExists(PWINDOW->m_pSwallowed)) {
|
||||
PWINDOW->m_pSwallowed->m_bHidden = false;
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW->m_pSwallowed);
|
||||
PWINDOW->m_pSwallowed = nullptr;
|
||||
}
|
||||
|
||||
bool wasLastWindow = false;
|
||||
|
||||
if (PWINDOW == g_pCompositor->m_pLastWindow) {
|
||||
@@ -453,7 +554,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
|
||||
Debug::log(LOG, "Destroying the SubSurface tree of unmapped window %x", PWINDOW);
|
||||
SubsurfaceTree::destroySurfaceTree(PWINDOW->m_pSurfaceTree);
|
||||
|
||||
|
||||
PWINDOW->m_pSurfaceTree = nullptr;
|
||||
|
||||
PWINDOW->m_bFadingOut = true;
|
||||
@@ -470,7 +571,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
|
||||
if (!PWINDOW->m_bX11DoesntWantBorders) // don't animate out if they weren't animated in.
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.vec() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it
|
||||
|
||||
|
||||
// anims
|
||||
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, true);
|
||||
PWINDOW->m_fAlpha = 0.f;
|
||||
@@ -488,7 +589,7 @@ void Events::listener_commitWindow(void* owner, void* data) {
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_bHidden || (PWINDOW->m_bIsX11 && !PWINDOW->m_bMappedX11))
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageSurface(g_pXWaylandManager->getWindowSurface(PWINDOW), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y);
|
||||
g_pHyprRenderer->damageSurface(g_pXWaylandManager->getWindowSurface(PWINDOW), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y);
|
||||
|
||||
// Debug::log(LOG, "Window %x committed", PWINDOW); // SPAM!
|
||||
}
|
||||
@@ -562,7 +663,7 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
|
||||
PWINDOW->updateToplevel();
|
||||
|
||||
Debug::log(LOG, "Window %x fullscreen to %i", PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||
|
||||
|
||||
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||
}
|
||||
|
||||
@@ -640,7 +741,7 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
|
||||
if (abs(std::floor(POS.x) - PWINDOW->m_uSurface.xwayland->x) > 2 || abs(std::floor(POS.y) - PWINDOW->m_uSurface.xwayland->y) > 2 || abs(std::floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2) {
|
||||
Debug::log(LOG, "Unmanaged window %x requests geometry update to %i %i %i %i", PWINDOW, (int)PWINDOW->m_uSurface.xwayland->x, (int)PWINDOW->m_uSurface.xwayland->y, (int)PWINDOW->m_uSurface.xwayland->width, (int)PWINDOW->m_uSurface.xwayland->height);
|
||||
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y));
|
||||
|
||||
@@ -700,7 +801,10 @@ void Events::listener_NewXDGDeco(wl_listener* listener, void* data) {
|
||||
void Events::listener_requestMaximize(void* owner, void* data) {
|
||||
const auto PWINDOW = (CWindow*)owner;
|
||||
|
||||
// ignore
|
||||
const auto EV = (wlr_foreign_toplevel_handle_v1_maximized_event*)data;
|
||||
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, EV ? EV->maximized : !PWINDOW->m_bIsFullscreen, FULLSCREEN_MAXIMIZED); // this will be rejected if there already is a fullscreen window
|
||||
|
||||
wlr_xdg_surface_schedule_configure(PWINDOW->m_uSurface.xdg);
|
||||
}
|
||||
|
||||
@@ -720,4 +824,4 @@ void Events::listener_requestResize(void* owner, void* data) {
|
||||
|
||||
// ignore
|
||||
wlr_xdg_surface_schedule_configure(PWINDOW->m_uSurface.xdg);
|
||||
}
|
||||
}
|
||||
|
@@ -59,5 +59,5 @@ void CAnimatedVariable::unregister() {
|
||||
}
|
||||
|
||||
int CAnimatedVariable::getDurationLeftMs() {
|
||||
return std::clamp((int)(m_pConfig->pValues->internalSpeed * 100) - (int)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - animationBegin).count(), 0, INT_MAX);
|
||||
return std::max((int)(m_pConfig->pValues->internalSpeed * 100) - (int)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - animationBegin).count(), 0);
|
||||
}
|
||||
|
@@ -125,7 +125,7 @@ public:
|
||||
switch (m_eVarType) {
|
||||
case AVARTYPE_FLOAT:
|
||||
return m_fValue != m_fGoal;
|
||||
case AVARTYPE_VECTOR:
|
||||
case AVARTYPE_VECTOR:
|
||||
return m_vValue != m_vGoal;
|
||||
case AVARTYPE_COLOR:
|
||||
return m_cValue != m_cGoal;
|
||||
@@ -198,4 +198,4 @@ private:
|
||||
friend class CAnimationManager;
|
||||
friend class CWorkspace;
|
||||
friend struct SLayerSurface;
|
||||
};
|
||||
};
|
||||
|
@@ -1,9 +1,7 @@
|
||||
#include "Color.hpp"
|
||||
#include "../defines.hpp"
|
||||
|
||||
CColor::CColor() {
|
||||
|
||||
}
|
||||
CColor::CColor() { }
|
||||
|
||||
CColor::CColor(float r, float g, float b, float a) {
|
||||
this->r = r;
|
||||
|
@@ -23,8 +23,8 @@ public:
|
||||
CColor operator* (const float& v) const {
|
||||
return CColor(r * v, g * v, b * v, a * v);
|
||||
}
|
||||
|
||||
|
||||
bool operator==(const CColor& c2) const {
|
||||
return r == c2.r && g == c2.g && b == c2.b && a == c2.a;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@@ -65,7 +65,7 @@ std::string absolutePath(const std::string& rawpath, const std::string& currentP
|
||||
void addWLSignal(wl_signal* pSignal, wl_listener* pListener, void* pOwner, std::string ownerString) {
|
||||
ASSERT(pSignal);
|
||||
ASSERT(pListener);
|
||||
|
||||
|
||||
wl_signal_add(pSignal, pListener);
|
||||
|
||||
Debug::log(LOG, "Registered signal for owner %x: %x -> %x (owner: %s)", pOwner, pSignal, pListener, ownerString.c_str());
|
||||
@@ -120,14 +120,18 @@ void scaleBox(wlr_box* box, float scale) {
|
||||
}
|
||||
|
||||
std::string removeBeginEndSpacesTabs(std::string str) {
|
||||
while (str[0] == ' ' || str[0] == '\t') {
|
||||
str = str.substr(1);
|
||||
int countBefore = 0;
|
||||
while (str[countBefore] == ' ' || str[countBefore] == '\t') {
|
||||
countBefore++;
|
||||
}
|
||||
|
||||
while (str.length() != 0 && (str[str.length() - 1] == ' ' || str[str.length() - 1] == '\t')) {
|
||||
str = str.substr(0, str.length() - 1);
|
||||
int countAfter = 0;
|
||||
while (str.length() != 0 && (str[str.length() - countAfter - 1] == ' ' || str[str.length() - 1 - countAfter] == '\t')) {
|
||||
countAfter++;
|
||||
}
|
||||
|
||||
str = str.substr(countBefore, str.length() - countBefore - countAfter);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -170,7 +174,28 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
|
||||
}
|
||||
|
||||
bool isNumber(const std::string& str, bool allowfloat) {
|
||||
return std::ranges::all_of(str.begin(), str.end(), [&](char c) { return isdigit(c) != 0 || c == '-' || (allowfloat && c == '.'); });
|
||||
|
||||
std::string copy = str;
|
||||
if (*copy.begin() == '-')
|
||||
copy = copy.substr(1);
|
||||
|
||||
if (copy.empty())
|
||||
return false;
|
||||
|
||||
bool point = !allowfloat;
|
||||
for (auto& c : copy) {
|
||||
if (c == '.') {
|
||||
if (point)
|
||||
return false;
|
||||
point = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!std::isdigit(c))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isDirection(const std::string& arg) {
|
||||
@@ -192,7 +217,7 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
||||
}
|
||||
outName = WORKSPACENAME;
|
||||
} else {
|
||||
if (in[0] == 'm' || in[0] == 'e') {
|
||||
if ((in[0] == 'm' || in[0] == 'e') && (in[1] == '-' || in[1] == '+') && isNumber(in.substr(2))) {
|
||||
bool onAllMonitors = in[0] == 'e';
|
||||
|
||||
if (!g_pCompositor->m_pLastMonitor) {
|
||||
@@ -212,15 +237,18 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
||||
while (remains != 0) {
|
||||
if (remains < 0)
|
||||
searchID--;
|
||||
else
|
||||
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 (w->m_iID == SPECIAL_WORKSPACE_ID)
|
||||
continue;
|
||||
|
||||
if (w->m_iID < lowestID)
|
||||
lowestID = w->m_iID;
|
||||
|
||||
@@ -230,7 +258,7 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
||||
|
||||
if (remains < 0)
|
||||
searchID = highestID;
|
||||
else
|
||||
else
|
||||
searchID = lowestID;
|
||||
}
|
||||
|
||||
@@ -250,24 +278,32 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
||||
outName = g_pCompositor->getWorkspaceByID(currentID)->m_szName;
|
||||
|
||||
} else {
|
||||
if (g_pCompositor->m_pLastMonitor)
|
||||
result = std::clamp((int)getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspace), 1, INT_MAX);
|
||||
else if (isNumber(in))
|
||||
result = std::clamp(std::stoi(in), 1, INT_MAX);
|
||||
if (in[0] == '+' || in[0] == '-') {
|
||||
if (g_pCompositor->m_pLastMonitor)
|
||||
result = std::max((int)getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspace), 1);
|
||||
else {
|
||||
Debug::log(ERR, "Relative workspace on no mon!");
|
||||
result = INT_MAX;
|
||||
}
|
||||
} else if (isNumber(in))
|
||||
result = std::max(std::stoi(in), 1);
|
||||
else {
|
||||
Debug::log(ERR, "Relative workspace on no mon!");
|
||||
result = INT_MAX;
|
||||
// maybe name
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByName(in);
|
||||
if (PWORKSPACE)
|
||||
result = PWORKSPACE->m_iID;
|
||||
}
|
||||
|
||||
outName = std::to_string(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2) {
|
||||
const float DX = std::max((double)0, std::max(p1.x - vec.x, vec.x - p2.x));
|
||||
const float DY = std::max((double)0, std::max(p1.y - vec.y, vec.y - p2.y));
|
||||
const float DX = std::max({0.0, p1.x - vec.x, vec.x - p2.x});
|
||||
const float DY = std::max({0.0, p1.y - vec.y, vec.y - p2.y});
|
||||
return DX * DX + DY * DY;
|
||||
}
|
||||
|
||||
@@ -295,6 +331,15 @@ void logSystemInfo() {
|
||||
Debug::log(LOG, "Node name: %s", unameInfo.nodename);
|
||||
Debug::log(LOG, "Release: %s", unameInfo.release);
|
||||
Debug::log(LOG, "Version: %s", unameInfo.version);
|
||||
|
||||
Debug::log(NONE, "\n");
|
||||
|
||||
const std::string GPUINFO = execAndGet("lspci -vnn | grep VGA");
|
||||
Debug::log(LOG, "GPU information:\n%s\n", GPUINFO.c_str());
|
||||
|
||||
if (GPUINFO.contains("NVIDIA")) {
|
||||
Debug::log(WARN, "Warning: you're using an NVIDIA GPU. Make sure you follow the instructions on the wiki if anything is amiss.\n");
|
||||
}
|
||||
|
||||
// log etc
|
||||
Debug::log(LOG, "os-release:");
|
||||
@@ -322,3 +367,38 @@ void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) {
|
||||
// Identity
|
||||
mat[8] = 1.0f;
|
||||
}
|
||||
|
||||
int64_t getPPIDof(int64_t pid) {
|
||||
std::string dir = "/proc/" + std::to_string(pid) + "/status";
|
||||
FILE* infile;
|
||||
|
||||
infile = fopen(dir.c_str(), "r");
|
||||
if (!infile)
|
||||
return 0;
|
||||
|
||||
char* line = nullptr;
|
||||
size_t len = 0;
|
||||
ssize_t len2 = 0;
|
||||
|
||||
std::string pidstr;
|
||||
|
||||
while ((len2 = getline(&line, &len, infile)) != -1) {
|
||||
if (strstr(line, "PPid:")) {
|
||||
pidstr = std::string(line, len2);
|
||||
const auto tabpos = pidstr.find_last_of('\t');
|
||||
if (tabpos != std::string::npos)
|
||||
pidstr = pidstr.substr(tabpos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(infile);
|
||||
if (line)
|
||||
free(line);
|
||||
|
||||
try {
|
||||
return std::stoll(pidstr);
|
||||
} catch (std::exception& e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -14,6 +14,7 @@ int getWorkspaceIDFromString(const std::string&, std::string&);
|
||||
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2);
|
||||
void logSystemInfo();
|
||||
std::string execAndGet(const char*);
|
||||
int64_t getPPIDof(int64_t pid);
|
||||
|
||||
float getPlusMinusKeywordResult(std::string in, float relative);
|
||||
|
||||
|
@@ -9,7 +9,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
szName = output->name;
|
||||
|
||||
// get monitor rule that matches
|
||||
SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(output->name);
|
||||
SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(output->name, output->description ? output->description : "");
|
||||
|
||||
hyprListener_monitorFrame.initCallback(&output->events.frame, &Events::listener_monitorFrame, this);
|
||||
hyprListener_monitorDestroy.initCallback(&output->events.destroy, &Events::listener_monitorDestroy, this);
|
||||
@@ -31,7 +31,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
|
||||
if (!wlr_output_test(output))
|
||||
continue;
|
||||
|
||||
|
||||
PREFSTATE = mode;
|
||||
break;
|
||||
}
|
||||
@@ -43,7 +43,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
Debug::log(WARN, "No mode found for disabled output %s", output->name);
|
||||
|
||||
wlr_output_enable(output, 0);
|
||||
|
||||
|
||||
if (!wlr_output_commit(output)) {
|
||||
Debug::log(ERR, "Couldn't commit disabled state on output %s", output->name);
|
||||
}
|
||||
@@ -65,6 +65,8 @@ void CMonitor::onConnect(bool noRule) {
|
||||
}
|
||||
|
||||
if (!m_bRenderingInitPassed) {
|
||||
output->allocator = nullptr;
|
||||
output->renderer = nullptr;
|
||||
wlr_output_init_render(output, g_pCompositor->m_sWLRAllocator, g_pCompositor->m_sWLRRenderer);
|
||||
m_bRenderingInitPassed = true;
|
||||
}
|
||||
@@ -83,7 +85,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
if (std::find_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& other) { return other.get() == this; }) == g_pCompositor->m_vMonitors.end()){
|
||||
g_pCompositor->m_vMonitors.push_back(*m_pThisWrap);
|
||||
}
|
||||
|
||||
|
||||
m_bEnabled = true;
|
||||
|
||||
wlr_output_set_scale(output, monitorRule.scale);
|
||||
@@ -113,52 +115,16 @@ void CMonitor::onConnect(bool noRule) {
|
||||
if (!pWLRWorkspaceGroupHandle) {
|
||||
pWLRWorkspaceGroupHandle = wlr_ext_workspace_group_handle_v1_create(g_pCompositor->m_sWLREXTWorkspaceMgr);
|
||||
}
|
||||
|
||||
|
||||
wlr_ext_workspace_group_handle_v1_output_enter(pWLRWorkspaceGroupHandle, output);
|
||||
|
||||
// Workspace
|
||||
std::string newDefaultWorkspaceName = "";
|
||||
auto WORKSPACEID = monitorRule.defaultWorkspace == "" ? g_pCompositor->m_vWorkspaces.size() + 1 : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName);
|
||||
setupDefaultWS(monitorRule);
|
||||
|
||||
if (WORKSPACEID == INT_MAX || WORKSPACEID == (long unsigned int)SPECIAL_WORKSPACE_ID) {
|
||||
WORKSPACEID = g_pCompositor->m_vWorkspaces.size() + 1;
|
||||
newDefaultWorkspaceName = std::to_string(WORKSPACEID);
|
||||
|
||||
Debug::log(LOG, "Invalid workspace= directive name in monitor parsing, workspace name \"%s\" is invalid.", monitorRule.defaultWorkspace.c_str());
|
||||
}
|
||||
|
||||
auto PNEWWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||
|
||||
Debug::log(LOG, "New monitor: WORKSPACEID %d, exists: %d", WORKSPACEID, (int)(PNEWWORKSPACE != nullptr));
|
||||
|
||||
if (PNEWWORKSPACE) {
|
||||
// workspace exists, move it to the newly connected monitor
|
||||
g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, this);
|
||||
activeWorkspace = PNEWWORKSPACE->m_iID;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
|
||||
PNEWWORKSPACE->startAnim(true, true, true);
|
||||
} else {
|
||||
|
||||
if (newDefaultWorkspaceName == "")
|
||||
newDefaultWorkspaceName = std::to_string(WORKSPACEID);
|
||||
|
||||
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(ID, newDefaultWorkspaceName)).get();
|
||||
|
||||
// We are required to set the name here immediately
|
||||
wlr_ext_workspace_handle_v1_set_name(PNEWWORKSPACE->m_pWlrHandle, newDefaultWorkspaceName.c_str());
|
||||
|
||||
PNEWWORKSPACE->m_iID = WORKSPACEID;
|
||||
}
|
||||
|
||||
activeWorkspace = PNEWWORKSPACE->m_iID;
|
||||
scale = monitorRule.scale;
|
||||
|
||||
m_pThisWrap = nullptr;
|
||||
|
||||
forceFullFrames = 3; // force 3 full frames to make sure there is no blinking due to double-buffering.
|
||||
|
||||
g_pCompositor->deactivateAllWLRWorkspaces(PNEWWORKSPACE->m_pWlrHandle);
|
||||
PNEWWORKSPACE->setActive(true);
|
||||
//
|
||||
|
||||
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
|
||||
@@ -174,7 +140,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
|
||||
void CMonitor::onDisconnect() {
|
||||
|
||||
if (!m_bEnabled)
|
||||
if (!m_bEnabled || g_pCompositor->m_bIsShuttingDown)
|
||||
return;
|
||||
|
||||
// Cleanup everything. Move windows back, snap cursor, shit.
|
||||
@@ -186,6 +152,20 @@ void CMonitor::onDisconnect() {
|
||||
}
|
||||
}
|
||||
|
||||
// remove mirror
|
||||
if (pMirrorOf) {
|
||||
pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; }));
|
||||
pMirrorOf = nullptr;
|
||||
}
|
||||
|
||||
if (!mirrors.empty()) {
|
||||
for (auto& m : mirrors) {
|
||||
m->setMirror("");
|
||||
}
|
||||
|
||||
g_pConfigManager->m_bWantsMonitorReload = true;
|
||||
}
|
||||
|
||||
m_bEnabled = false;
|
||||
m_bRenderingInitPassed = false;
|
||||
|
||||
@@ -246,3 +226,136 @@ void CMonitor::addDamage(pixman_region32_t* rg) {
|
||||
void CMonitor::addDamage(wlr_box* box) {
|
||||
wlr_output_damage_add_box(damage, box);
|
||||
}
|
||||
|
||||
bool CMonitor::isMirror() {
|
||||
return pMirrorOf != nullptr;
|
||||
}
|
||||
|
||||
void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
|
||||
// Workspace
|
||||
std::string newDefaultWorkspaceName = "";
|
||||
auto WORKSPACEID = monitorRule.defaultWorkspace == "" ? g_pCompositor->m_vWorkspaces.size() + 1 : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName);
|
||||
|
||||
if (WORKSPACEID == INT_MAX || WORKSPACEID == (long unsigned int)SPECIAL_WORKSPACE_ID) {
|
||||
WORKSPACEID = g_pCompositor->m_vWorkspaces.size() + 1;
|
||||
newDefaultWorkspaceName = std::to_string(WORKSPACEID);
|
||||
|
||||
Debug::log(LOG, "Invalid workspace= directive name in monitor parsing, workspace name \"%s\" is invalid.", monitorRule.defaultWorkspace.c_str());
|
||||
}
|
||||
|
||||
auto PNEWWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||
|
||||
Debug::log(LOG, "New monitor: WORKSPACEID %d, exists: %d", WORKSPACEID, (int)(PNEWWORKSPACE != nullptr));
|
||||
|
||||
if (PNEWWORKSPACE) {
|
||||
// workspace exists, move it to the newly connected monitor
|
||||
g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, this);
|
||||
activeWorkspace = PNEWWORKSPACE->m_iID;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
|
||||
PNEWWORKSPACE->startAnim(true, true, true);
|
||||
} else {
|
||||
if (newDefaultWorkspaceName == "")
|
||||
newDefaultWorkspaceName = std::to_string(WORKSPACEID);
|
||||
|
||||
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(ID, newDefaultWorkspaceName)).get();
|
||||
|
||||
// We are required to set the name here immediately
|
||||
wlr_ext_workspace_handle_v1_set_name(PNEWWORKSPACE->m_pWlrHandle, newDefaultWorkspaceName.c_str());
|
||||
|
||||
PNEWWORKSPACE->m_iID = WORKSPACEID;
|
||||
}
|
||||
|
||||
activeWorkspace = PNEWWORKSPACE->m_iID;
|
||||
|
||||
g_pCompositor->deactivateAllWLRWorkspaces(PNEWWORKSPACE->m_pWlrHandle);
|
||||
PNEWWORKSPACE->setActive(true);
|
||||
}
|
||||
|
||||
void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||
const auto PMIRRORMON = g_pCompositor->getMonitorFromString(mirrorOf);
|
||||
|
||||
if (PMIRRORMON == pMirrorOf)
|
||||
return;
|
||||
|
||||
if (PMIRRORMON && PMIRRORMON->isMirror()) {
|
||||
Debug::log(ERR, "Cannot mirror a mirror!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (PMIRRORMON == this) {
|
||||
Debug::log(ERR, "Cannot mirror self!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PMIRRORMON) {
|
||||
// disable mirroring
|
||||
|
||||
if (pMirrorOf) {
|
||||
pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; }));
|
||||
}
|
||||
|
||||
pMirrorOf = nullptr;
|
||||
|
||||
// set rule
|
||||
const auto RULE = g_pConfigManager->getMonitorRuleFor(this->szName, this->output->description ? this->output->description : "");
|
||||
|
||||
vecPosition = RULE.offset;
|
||||
|
||||
// push to mvmonitors
|
||||
if (!m_pThisWrap) {
|
||||
// find the wrap
|
||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||
if (m->ID == ID) {
|
||||
m_pThisWrap = &m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (std::find_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& other) { return other.get() == this; }) == g_pCompositor->m_vMonitors.end()) {
|
||||
g_pCompositor->m_vMonitors.push_back(*m_pThisWrap);
|
||||
}
|
||||
|
||||
setupDefaultWS(RULE);
|
||||
|
||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, output, (int)vecPosition.x, (int)vecPosition.y);
|
||||
} else {
|
||||
CMonitor* BACKUPMON = nullptr;
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m.get() != this) {
|
||||
BACKUPMON = m.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// move all the WS
|
||||
std::deque<CWorkspace*> wspToMove;
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
if (w->m_iMonitorID == ID) {
|
||||
wspToMove.push_back(w.get());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& w : wspToMove) {
|
||||
g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON);
|
||||
w->startAnim(true, true, true);
|
||||
}
|
||||
|
||||
activeWorkspace = -1;
|
||||
|
||||
wlr_output_layout_remove(g_pCompositor->m_sWLROutputLayout, output);
|
||||
|
||||
vecPosition = Vector2D(-1337420, -1337420);
|
||||
|
||||
pMirrorOf = PMIRRORMON;
|
||||
|
||||
pMirrorOf->mirrors.push_back(this);
|
||||
|
||||
// remove from mvmonitors
|
||||
if (std::find_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& other) { return other.get() == this; }) != g_pCompositor->m_vMonitors.end()) {
|
||||
g_pCompositor->m_vMonitors.erase(std::remove_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](const auto& other) { return other.get() == this; }));
|
||||
}
|
||||
|
||||
g_pCompositor->m_pLastMonitor = g_pCompositor->m_vMonitors.front().get();
|
||||
}
|
||||
}
|
||||
|
@@ -7,6 +7,8 @@
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
struct SMonitorRule;
|
||||
|
||||
class CMonitor {
|
||||
public:
|
||||
Vector2D vecPosition = Vector2D(0,0);
|
||||
@@ -35,9 +37,15 @@ public:
|
||||
bool scheduledRecalc = false;
|
||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
|
||||
bool dpmsStatus = true;
|
||||
|
||||
// mirroring
|
||||
CMonitor* pMirrorOf = nullptr;
|
||||
std::vector<CMonitor*> mirrors;
|
||||
|
||||
// for the special workspace
|
||||
bool specialWorkspaceOpen = false;
|
||||
|
||||
|
||||
// Double-linked list because we need to have constant mem addresses for signals
|
||||
// We have to store pointers and use raw new/delete because they might be moved between them
|
||||
// and I am lazy
|
||||
@@ -57,6 +65,8 @@ public:
|
||||
void onDisconnect();
|
||||
void addDamage(pixman_region32_t* rg);
|
||||
void addDamage(wlr_box* box);
|
||||
void setMirror(const std::string&);
|
||||
bool isMirror();
|
||||
|
||||
std::shared_ptr<CMonitor>* m_pThisWrap = nullptr;
|
||||
bool m_bEnabled = false;
|
||||
@@ -67,4 +77,7 @@ public:
|
||||
bool operator==(const CMonitor& rhs) {
|
||||
return vecPosition == rhs.vecPosition && vecSize == rhs.vecSize && szName == rhs.szName;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
void setupDefaultWS(const SMonitorRule&);
|
||||
};
|
||||
|
@@ -101,6 +101,14 @@ void SubsurfaceTree::destroySurfaceTree(SSurfaceTreeNode* pNode) {
|
||||
g_pHyprRenderer->damageBox(&extents);
|
||||
}
|
||||
|
||||
// remove references to this node
|
||||
for (auto& tn : surfaceTreeNodes) {
|
||||
for (auto& cs : tn.childSubsurfaces) {
|
||||
if (cs.pChild == pNode)
|
||||
cs.pChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
surfaceTreeNodes.remove(*pNode);
|
||||
|
||||
Debug::log(LOG, "SurfaceTree Node removed");
|
||||
@@ -154,6 +162,9 @@ void Events::listener_newSubsurfaceNode(void* owner, void* data) {
|
||||
void Events::listener_mapSubsurface(void* owner, void* data) {
|
||||
SSubsurface* subsurface = (SSubsurface*)owner;
|
||||
|
||||
if (subsurface->pChild)
|
||||
return;
|
||||
|
||||
Debug::log(LOG, "Subsurface %x mapped", subsurface->pSubsurface);
|
||||
|
||||
subsurface->pChild = createSubsurfaceNode(subsurface->pParent, subsurface, subsurface->pSubsurface->surface, subsurface->pWindowOwner);
|
||||
@@ -170,18 +181,16 @@ void Events::listener_unmapSubsurface(void* owner, void* data) {
|
||||
int lx = 0, ly = 0;
|
||||
addSurfaceGlobalOffset(PNODE, &lx, &ly);
|
||||
|
||||
wlr_box extents = {0};
|
||||
wlr_box extents = {lx, ly, 0, 0};
|
||||
if (PNODE->pSurface) {
|
||||
wlr_surface_get_extends(PNODE->pSurface, &extents);
|
||||
|
||||
extents.x += lx;
|
||||
extents.y += ly;
|
||||
extents.width = PNODE->pSurface->current.width;
|
||||
extents.height = PNODE->pSurface->current.height;
|
||||
|
||||
g_pHyprRenderer->damageBox(&extents);
|
||||
}
|
||||
|
||||
SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
|
||||
subsurface->pChild = nullptr;
|
||||
//SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
|
||||
//subsurface->pChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,8 +226,9 @@ void Events::listener_commitSubsurface(void* owner, void* data) {
|
||||
void Events::listener_destroySubsurface(void* owner, void* data) {
|
||||
SSubsurface* subsurface = (SSubsurface*)owner;
|
||||
|
||||
if (subsurface->pChild)
|
||||
listener_destroySubsurfaceNode(subsurface->pChild, nullptr);
|
||||
if (subsurface->pChild) {
|
||||
SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Subsurface %x destroyed", subsurface);
|
||||
|
||||
|
@@ -193,7 +193,7 @@ struct SDrag {
|
||||
bool iconMapped = false;
|
||||
|
||||
wlr_drag_icon* dragIcon = nullptr;
|
||||
|
||||
|
||||
Vector2D pos;
|
||||
|
||||
DYNLISTENER(destroyIcon);
|
||||
@@ -322,3 +322,24 @@ struct SIMEPopup {
|
||||
return pSurface == other.pSurface;
|
||||
}
|
||||
};
|
||||
|
||||
struct STouchDevice {
|
||||
wlr_input_device* pWlrDevice = nullptr;
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
|
||||
bool operator==(const STouchDevice& other) {
|
||||
return pWlrDevice == other.pWlrDevice;
|
||||
}
|
||||
};
|
||||
|
||||
struct SSwitchDevice {
|
||||
wlr_input_device* pWlrDevice = nullptr;
|
||||
|
||||
DYNLISTENER(destroy);
|
||||
DYNLISTENER(toggle);
|
||||
|
||||
bool operator==(const SSwitchDevice& other) {
|
||||
return pWlrDevice == other.pWlrDevice;
|
||||
}
|
||||
};
|
||||
|
@@ -12,7 +12,7 @@ CWorkspace::CWorkspace(int monitorID, std::string name, bool special) {
|
||||
m_iMonitorID = monitorID;
|
||||
m_szName = name;
|
||||
m_bIsSpecialWorkspace = special;
|
||||
|
||||
|
||||
if (!special) {
|
||||
m_pWlrHandle = wlr_ext_workspace_handle_v1_create(PMONITOR->pWLRWorkspaceGroupHandle);
|
||||
|
||||
@@ -91,6 +91,15 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
m_vRenderOffset.warp();
|
||||
m_fAlpha.warp();
|
||||
}
|
||||
|
||||
// check LS-es
|
||||
if (in) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
for (auto& ls : PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
if (!ls->fadingOut)
|
||||
ls->alpha = m_bHasFullscreenWindow && m_efFullscreenMode == FULLSCREEN_FULL ? 0.f : 255.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWorkspace::setActive(bool on) {
|
||||
|
@@ -56,7 +56,7 @@ void CHyprError::createQueued() {
|
||||
cairo_show_text(CAIRO, current.c_str());
|
||||
yoffset += FONTSIZE + (FONTSIZE / 10.f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
cairo_surface_flush(CAIROSURFACE);
|
||||
|
||||
@@ -66,12 +66,12 @@ void CHyprError::createQueued() {
|
||||
glBindTexture(GL_TEXTURE_2D, m_tTexture.m_iTexID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
|
||||
#ifndef GLES2
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
// delete cairo
|
||||
@@ -114,4 +114,4 @@ void CHyprError::draw() {
|
||||
void CHyprError::destroy() {
|
||||
if (m_bIsCreated)
|
||||
m_bQueuedDestroy = true;
|
||||
}
|
||||
}
|
||||
|
@@ -101,6 +101,7 @@ extern "C" {
|
||||
#include <wlr/types/wlr_input_method_v2.h>
|
||||
#include <wlr/types/wlr_text_input_v3.h>
|
||||
#include <wlr/types/wlr_touch.h>
|
||||
#include <wlr/types/wlr_switch.h>
|
||||
}
|
||||
|
||||
#undef delete
|
||||
|
@@ -139,7 +139,7 @@ SDwindleNodeData* CHyprDwindleLayout::getMasterNodeOnWorkspace(const int& id) {
|
||||
|
||||
void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool force) {
|
||||
// Don't set nodes, only windows.
|
||||
if (pNode->isNode)
|
||||
if (pNode->isNode)
|
||||
return;
|
||||
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
@@ -196,12 +196,14 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
||||
|
||||
PWINDOW->m_sSpecialRenderData.rounding = false;
|
||||
PWINDOW->m_sSpecialRenderData.border = false;
|
||||
PWINDOW->m_sSpecialRenderData.decorate = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PWINDOW->m_sSpecialRenderData.rounding = true;
|
||||
PWINDOW->m_sSpecialRenderData.border = true;
|
||||
PWINDOW->m_sSpecialRenderData.decorate = true;
|
||||
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? *PGAPSOUT : *PGAPSIN,
|
||||
DISPLAYTOP ? *PGAPSOUT : *PGAPSIN);
|
||||
@@ -297,7 +299,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
// happens on reserved area
|
||||
if (!OPENINGON && g_pCompositor->getWindowsOnWorkspace(PNODE->workspaceID) > 0)
|
||||
OPENINGON = getFirstNodeOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
|
||||
} else if (*PUSEACTIVE) {
|
||||
if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && !g_pCompositor->m_pLastWindow->m_bIsFloating && g_pCompositor->m_pLastWindow != pWindow && g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsMapped) {
|
||||
OPENINGON = getNodeFromWindow(g_pCompositor->m_pLastWindow);
|
||||
@@ -327,6 +329,13 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
g_pCompositor->setWindowFullscreen(PFULLWINDOW, false, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
// if it's the first, it's easy. Make it fullscreen.
|
||||
if (!OPENINGON || OPENINGON->pWindow == pWindow) {
|
||||
PNODE->position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
||||
@@ -360,7 +369,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// If it's not, get the node under our cursor
|
||||
|
||||
m_lDwindleNodesData.push_back(SDwindleNodeData());
|
||||
@@ -403,7 +412,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
NEWPARENT->children[1] = PNODE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// and update the previous parent if it exists
|
||||
if (OPENINGON->pParent) {
|
||||
if (OPENINGON->pParent->children[0] == OPENINGON) {
|
||||
@@ -414,7 +423,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
// Update the children
|
||||
|
||||
|
||||
|
||||
if (NEWPARENT->size.x * *PWIDTHMULTIPLIER > NEWPARENT->size.y) {
|
||||
// split left/right
|
||||
@@ -448,6 +457,9 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pWindow->m_bIsFullscreen)
|
||||
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
|
||||
|
||||
// check if it was grouped
|
||||
if (PNODE->isGroupMember()) {
|
||||
// get shit
|
||||
@@ -460,7 +472,7 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
if (PNODE->groupHead) {
|
||||
PNEXT->groupHead = true;
|
||||
PNEXT->pParent = PNODE->pParent;
|
||||
|
||||
|
||||
if (PNODE->pParent) {
|
||||
if (PNODE->pParent->children[0] == PNODE) {
|
||||
PNODE->pParent->children[0] = PNEXT;
|
||||
@@ -489,7 +501,7 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
// means we dissolved the group
|
||||
recalculateMonitor(PNEXT->pWindow->m_iMonitorID);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -507,6 +519,17 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
PSIBLING->size = PPARENT->size;
|
||||
PSIBLING->pParent = PPARENT->pParent;
|
||||
|
||||
if (PSIBLING->isGroupMember()) {
|
||||
// apply to all group members
|
||||
SDwindleNodeData* current = PSIBLING->pNextGroupMember;
|
||||
|
||||
while (current != PSIBLING) {
|
||||
current->position = PPARENT->position;
|
||||
current->size = PPARENT->size;
|
||||
current = current->pNextGroupMember;
|
||||
}
|
||||
}
|
||||
|
||||
if (PPARENT->pParent != nullptr) {
|
||||
if (PPARENT->pParent->children[0] == PPARENT) {
|
||||
PPARENT->pParent->children[0] = PSIBLING;
|
||||
@@ -520,7 +543,7 @@ void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
|
||||
if (PSIBLING->pParent)
|
||||
PSIBLING->pParent->recalcSizePosRecursive();
|
||||
else
|
||||
else
|
||||
PSIBLING->recalcSizePosRecursive();
|
||||
|
||||
m_lDwindleNodesData.remove(*PPARENT);
|
||||
@@ -598,7 +621,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
|
||||
if (!PNODE) {
|
||||
PWINDOW->m_vRealSize = Vector2D(std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).x, (double)20, (double)999999), std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).y, (double)20, (double)999999));
|
||||
PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goalv() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goalv() + pixResize).y, 20.0));
|
||||
PWINDOW->updateWindowDecos();
|
||||
return;
|
||||
}
|
||||
@@ -635,11 +658,11 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
||||
if (!PPARENT2) {
|
||||
if (PARENTSIDEBYSIDE) {
|
||||
allowedMovement.x *= 2.f / PPARENT->size.x;
|
||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9);
|
||||
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
||||
} else {
|
||||
allowedMovement.y *= 2.f / PPARENT->size.y;
|
||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9);
|
||||
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
||||
}
|
||||
|
||||
@@ -654,11 +677,11 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
||||
if (!PPARENT2) {
|
||||
if (PARENTSIDEBYSIDE) {
|
||||
allowedMovement.x *= 2.f / PPARENT->size.x;
|
||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9);
|
||||
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
||||
} else {
|
||||
allowedMovement.y *= 2.f / PPARENT->size.y;
|
||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
||||
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9);
|
||||
PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
|
||||
}
|
||||
|
||||
@@ -672,8 +695,8 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
||||
allowedMovement.x *= 2.f / SIDECONTAINER->size.x;
|
||||
allowedMovement.y *= 2.f / TOPCONTAINER->size.y;
|
||||
|
||||
SIDECONTAINER->splitRatio = std::clamp(SIDECONTAINER->splitRatio + allowedMovement.x, (double)0.1f, (double)1.9f);
|
||||
TOPCONTAINER->splitRatio = std::clamp(TOPCONTAINER->splitRatio + allowedMovement.y, (double)0.1f, (double)1.9f);
|
||||
SIDECONTAINER->splitRatio = std::clamp(SIDECONTAINER->splitRatio + allowedMovement.x, 0.1, 1.9);
|
||||
TOPCONTAINER->splitRatio = std::clamp(TOPCONTAINER->splitRatio + allowedMovement.y, 0.1, 1.9);
|
||||
SIDECONTAINER->recalcSizePosRecursive(*PANIMATE == 0);
|
||||
TOPCONTAINER->recalcSizePosRecursive(*PANIMATE == 0);
|
||||
}
|
||||
@@ -682,10 +705,7 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
|
||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||
return;
|
||||
|
||||
if (!g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
||||
return;
|
||||
|
||||
if (on == pWindow->m_bIsFullscreen)
|
||||
if (on == pWindow->m_bIsFullscreen || pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
return; // ignore
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
@@ -785,12 +805,13 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PNODE->workspaceID);
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow)
|
||||
fullscreenRequestForWindow(g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID), FULLSCREEN_FULL, false);
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !PNODE->isGroupMember()) {
|
||||
Debug::log(ERR, "Cannot enable group on fullscreen window");
|
||||
return;
|
||||
}
|
||||
|
||||
if (PNODE->isGroupMember()) {
|
||||
// dissolve group
|
||||
|
||||
const auto PHEAD = PNODE->getGroupHead();
|
||||
|
||||
SDwindleNodeData* current = PNODE->pNextGroupMember;
|
||||
@@ -798,7 +819,7 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
PNODE->pWindow->m_bIsFloating = PHEAD->pWindow->m_bIsFloating;
|
||||
|
||||
std::deque<CWindow*> toAddWindows;
|
||||
|
||||
|
||||
const auto PWINDOWNODE = PNODE->pWindow;
|
||||
toAddWindows.push_back(PWINDOWNODE);
|
||||
|
||||
@@ -811,8 +832,15 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
PWINDOW->m_bHidden = false;
|
||||
}
|
||||
|
||||
PHEAD->pPreviousGroupMember = nullptr;
|
||||
PHEAD->pNextGroupMember = nullptr;
|
||||
if (PHEAD->pPreviousGroupMember)
|
||||
PHEAD->pPreviousGroupMember->pNextGroupMember = PHEAD->pNextGroupMember;
|
||||
|
||||
if (PHEAD->pNextGroupMember)
|
||||
PHEAD->pNextGroupMember->pPreviousGroupMember = PHEAD->pPreviousGroupMember;
|
||||
|
||||
PHEAD->pPreviousGroupMember = nullptr;
|
||||
PHEAD->pNextGroupMember = nullptr;
|
||||
|
||||
onWindowRemoved(PHEAD->pWindow);
|
||||
|
||||
for (auto& pw : toAddWindows) {
|
||||
@@ -903,7 +931,7 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
std::deque<CWindow*> CHyprDwindleLayout::getGroupMembers(CWindow* pWindow) {
|
||||
|
||||
|
||||
std::deque<CWindow*> result;
|
||||
|
||||
if (!g_pCompositor->windowExists(pWindow))
|
||||
@@ -928,7 +956,7 @@ std::deque<CWindow*> CHyprDwindleLayout::getGroupMembers(CWindow* pWindow) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward) {
|
||||
void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward, CWindow* forceTo) {
|
||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||
return; // reject
|
||||
|
||||
@@ -946,10 +974,18 @@ void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward) {
|
||||
else
|
||||
pNewNode = PNODE->pPreviousGroupMember;
|
||||
|
||||
if (forceTo) {
|
||||
const auto NODETO = getNodeFromWindow(forceTo);
|
||||
|
||||
if (NODETO)
|
||||
pNewNode = NODETO;
|
||||
}
|
||||
|
||||
PNODE->setGroupFocusedNode(pNewNode);
|
||||
|
||||
pNewNode->position = PNODE->position;
|
||||
pNewNode->size = PNODE->size;
|
||||
pNewNode->workspaceID = PNODE->workspaceID;
|
||||
|
||||
applyNodeDataToWindow(pNewNode);
|
||||
|
||||
@@ -959,7 +995,7 @@ void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward) {
|
||||
g_pCompositor->focusWindow(pNewNode->pWindow);
|
||||
|
||||
pNewNode->pWindow->m_bIsFloating = PNODE->pWindow->m_bIsFloating;
|
||||
|
||||
|
||||
if (PNODE->pWindow->m_bIsFullscreen) {
|
||||
PNODE->pWindow->m_bHidden = false;
|
||||
g_pCompositor->setWindowFullscreen(PNODE->pWindow, false, PWORKSPACE->m_efFullscreenMode);
|
||||
@@ -1001,58 +1037,101 @@ SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow
|
||||
void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
|
||||
// windows should be valid, insallah
|
||||
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
const auto PNODE2 = getNodeFromWindow(pWindow2);
|
||||
auto PNODE = getNodeFromWindow(pWindow);
|
||||
auto PNODE2 = getNodeFromWindow(pWindow2);
|
||||
|
||||
if (!PNODE2 || !PNODE)
|
||||
return;
|
||||
if (!PNODE2 || !PNODE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||
Debug::log(ERR, "Dwindle: Rejecting a swap between workspaces");
|
||||
return;
|
||||
}
|
||||
SDwindleNodeData* ACTIVE1 = nullptr;
|
||||
SDwindleNodeData* ACTIVE2 = nullptr;
|
||||
|
||||
// we will not delete the nodes, just fix the tree
|
||||
if (PNODE2->pParent == PNODE->pParent) {
|
||||
const auto PPARENT = PNODE->pParent;
|
||||
if (PNODE2->isGroupMember() || PNODE->isGroupMember()) {
|
||||
|
||||
if (PPARENT->children[0] == PNODE) {
|
||||
PPARENT->children[0] = PNODE2;
|
||||
PPARENT->children[1] = PNODE;
|
||||
} else {
|
||||
PPARENT->children[0] = PNODE;
|
||||
PPARENT->children[1] = PNODE2;
|
||||
}
|
||||
} else {
|
||||
if (PNODE->pParent) {
|
||||
const auto PPARENT = PNODE->pParent;
|
||||
|
||||
if (PPARENT->children[0] == PNODE) {
|
||||
PPARENT->children[0] = PNODE2;
|
||||
} else {
|
||||
PPARENT->children[1] = PNODE2;
|
||||
}
|
||||
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||
Debug::log(ERR, "Groups are confined to a monitor");
|
||||
return;
|
||||
}
|
||||
|
||||
if (PNODE2->pParent) {
|
||||
const auto PPARENT = PNODE2->pParent;
|
||||
if (PNODE->isGroupMember()) {
|
||||
ACTIVE1 = PNODE;
|
||||
PNODE = PNODE->getGroupHead();
|
||||
}
|
||||
|
||||
if (PPARENT->children[0] == PNODE2) {
|
||||
PPARENT->children[0] = PNODE;
|
||||
} else {
|
||||
PPARENT->children[1] = PNODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PNODE2->isGroupMember()) {
|
||||
ACTIVE2 = PNODE2;
|
||||
PNODE2 = PNODE2->getGroupHead();
|
||||
}
|
||||
|
||||
const auto PPARENTNODE2 = PNODE2->pParent;
|
||||
PNODE2->pParent = PNODE->pParent;
|
||||
PNODE->pParent = PPARENTNODE2;
|
||||
if (PNODE2->pParent == PNODE->pParent) {
|
||||
const auto PPARENT = PNODE->pParent;
|
||||
|
||||
// these are window nodes, so no children.
|
||||
if (PPARENT->children[0] == PNODE) {
|
||||
PPARENT->children[0] = PNODE2;
|
||||
PPARENT->children[1] = PNODE;
|
||||
} else {
|
||||
PPARENT->children[0] = PNODE;
|
||||
PPARENT->children[1] = PNODE2;
|
||||
}
|
||||
} else {
|
||||
if (PNODE->pParent) {
|
||||
const auto PPARENT = PNODE->pParent;
|
||||
|
||||
// recalc the workspace
|
||||
if (PPARENT->children[0] == PNODE) {
|
||||
PPARENT->children[0] = PNODE2;
|
||||
} else {
|
||||
PPARENT->children[1] = PNODE2;
|
||||
}
|
||||
}
|
||||
|
||||
if (PNODE2->pParent) {
|
||||
const auto PPARENT = PNODE2->pParent;
|
||||
|
||||
if (PPARENT->children[0] == PNODE2) {
|
||||
PPARENT->children[0] = PNODE;
|
||||
} else {
|
||||
PPARENT->children[1] = PNODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto PPARENTNODE2 = PNODE2->pParent;
|
||||
PNODE2->pParent = PNODE->pParent;
|
||||
PNODE->pParent = PPARENTNODE2;
|
||||
|
||||
std::swap(PNODE2->workspaceID, PNODE->workspaceID);
|
||||
} else {
|
||||
// swap the windows and recalc
|
||||
PNODE2->pWindow = pWindow;
|
||||
PNODE->pWindow = pWindow2;
|
||||
}
|
||||
|
||||
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
|
||||
std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID);
|
||||
}
|
||||
|
||||
// recalc the workspace
|
||||
getMasterNodeOnWorkspace(PNODE->workspaceID)->recalcSizePosRecursive();
|
||||
|
||||
if (PNODE2->workspaceID != PNODE->workspaceID) {
|
||||
getMasterNodeOnWorkspace(PNODE2->workspaceID)->recalcSizePosRecursive();
|
||||
}
|
||||
|
||||
if (ACTIVE1) {
|
||||
ACTIVE1->position = PNODE->position;
|
||||
ACTIVE1->size = PNODE->size;
|
||||
ACTIVE1->pWindow->m_vPosition = ACTIVE1->position;
|
||||
ACTIVE1->pWindow->m_vSize = ACTIVE1->size;
|
||||
}
|
||||
|
||||
if (ACTIVE2) {
|
||||
ACTIVE2->position = PNODE2->position;
|
||||
ACTIVE2->size = PNODE2->size;
|
||||
ACTIVE2->pWindow->m_vPosition = ACTIVE2->position;
|
||||
ACTIVE2->pWindow->m_vSize = ACTIVE2->size;
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
||||
@@ -1060,7 +1139,7 @@ void CHyprDwindleLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
||||
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
|
||||
if (!PNODE || !PNODE->pParent)
|
||||
if (!PNODE || !PNODE->pParent || (PNODE->isGroupMember() && PNODE->getGroupMemberCount() == g_pCompositor->getWindowsOnWorkspace(PNODE->workspaceID)))
|
||||
return;
|
||||
|
||||
PNODE->pParent->splitRatio = std::clamp(PNODE->pParent->splitRatio + ratio, 0.1f, 1.9f);
|
||||
@@ -1078,10 +1157,10 @@ std::any CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::str
|
||||
else if (message == "togglesplit")
|
||||
toggleSplit(header.pWindow);
|
||||
else if (message == "groupinfo") {
|
||||
auto res = getGroupMembers(g_pCompositor->m_pLastWindow);
|
||||
auto res = getGroupMembers(header.pWindow ? header.pWindow : g_pCompositor->m_pLastWindow);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@@ -75,7 +75,7 @@ private:
|
||||
SDwindleNodeData* getMasterNodeOnWorkspace(const int&);
|
||||
|
||||
void toggleWindowGroup(CWindow*);
|
||||
void switchGroupWindow(CWindow*, bool forward);
|
||||
void switchGroupWindow(CWindow*, bool forward, CWindow* to = nullptr);
|
||||
void toggleSplit(CWindow*);
|
||||
std::deque<CWindow*> getGroupMembers(CWindow*);
|
||||
|
||||
|
@@ -50,7 +50,7 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
pWindow->m_bHidden = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// reject any windows with size <= 5x5
|
||||
if (pWindow->m_vRealSize.goalv().x <= 5 || pWindow->m_vRealSize.goalv().y <= 5) {
|
||||
pWindow->m_vRealSize = PMONITOR->vecSize / 2.f;
|
||||
@@ -64,8 +64,24 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
// check if it's on the correct monitor!
|
||||
Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f;
|
||||
|
||||
// check if it's visible on any monitor (only for XDG)
|
||||
bool visible = pWindow->m_bIsX11;
|
||||
|
||||
if (!pWindow->m_bIsX11) {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (VECINRECT(Vector2D(desiredGeometry.x, desiredGeometry.y), m->vecPosition.x, m->vecPosition.y, m->vecPosition.x + m->vecSize.x, m->vecPosition.y + m->vecPosition.y)
|
||||
|| VECINRECT(Vector2D(desiredGeometry.x + desiredGeometry.width, desiredGeometry.y), m->vecPosition.x, m->vecPosition.y, m->vecPosition.x + m->vecSize.x, m->vecPosition.y + m->vecPosition.y)
|
||||
|| VECINRECT(Vector2D(desiredGeometry.x, desiredGeometry.y + desiredGeometry.height), m->vecPosition.x, m->vecPosition.y, m->vecPosition.x + m->vecSize.x, m->vecPosition.y + m->vecPosition.y)
|
||||
|| VECINRECT(Vector2D(desiredGeometry.x + desiredGeometry.width, desiredGeometry.y + desiredGeometry.height), m->vecPosition.x, m->vecPosition.y, m->vecPosition.x + m->vecSize.x, m->vecPosition.y + m->vecPosition.y)) {
|
||||
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: detect a popup in a more consistent way.
|
||||
if ((desiredGeometry.x == 0 && desiredGeometry.y == 0)) {
|
||||
if ((desiredGeometry.x == 0 && desiredGeometry.y == 0) || !visible) {
|
||||
// if it's not, fall back to the center placement
|
||||
pWindow->m_vRealPosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f);
|
||||
} else {
|
||||
@@ -121,7 +137,7 @@ void IHyprLayout::onBeginDragWindow() {
|
||||
DRAGGINGWINDOW->m_bDraggingTiled = false;
|
||||
|
||||
if (!DRAGGINGWINDOW->m_bIsFloating) {
|
||||
if (g_pInputManager->dragButton == BTN_LEFT) {
|
||||
if (g_pInputManager->dragMode == MBIND_MOVE) {
|
||||
changeWindowFloatingMode(DRAGGINGWINDOW);
|
||||
DRAGGINGWINDOW->m_bIsFloating = true;
|
||||
DRAGGINGWINDOW->m_bDraggingTiled = true;
|
||||
@@ -135,6 +151,21 @@ void IHyprLayout::onBeginDragWindow() {
|
||||
m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.goalv();
|
||||
m_vLastDragXY = m_vBeginDragXY;
|
||||
|
||||
// get the grab corner
|
||||
if (m_vBeginDragXY.x < m_vBeginDragPositionXY.x + m_vBeginDragSizeXY.x / 2.0) {
|
||||
// left
|
||||
if (m_vBeginDragXY.y < m_vBeginDragPositionXY.y + m_vBeginDragSizeXY.y / 2.0)
|
||||
m_iGrabbedCorner = 0;
|
||||
else
|
||||
m_iGrabbedCorner = 4;
|
||||
} else {
|
||||
// right
|
||||
if (m_vBeginDragXY.y < m_vBeginDragPositionXY.y + m_vBeginDragSizeXY.y / 2.0)
|
||||
m_iGrabbedCorner = 1;
|
||||
else
|
||||
m_iGrabbedCorner = 3;
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
|
||||
// shadow to ignore any bound to MAIN_MOD
|
||||
@@ -176,22 +207,43 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
|
||||
if (g_pInputManager->dragButton == BTN_LEFT) {
|
||||
if (g_pInputManager->dragMode == MBIND_MOVE) {
|
||||
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA);
|
||||
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||
} else {
|
||||
} else if (g_pInputManager->dragMode == MBIND_RESIZE) {
|
||||
if (DRAGGINGWINDOW->m_bIsFloating) {
|
||||
|
||||
const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW);
|
||||
|
||||
if (*PANIMATE) {
|
||||
DRAGGINGWINDOW->m_vRealSize = Vector2D(std::clamp(m_vBeginDragSizeXY.x + DELTA.x, (double)20, (double)MAXSIZE.x), std::clamp(m_vBeginDragSizeXY.y + DELTA.y, (double)20, (double)MAXSIZE.y));
|
||||
} else {
|
||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(m_vBeginDragSizeXY + DELTA);
|
||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(Vector2D(std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().x, (double)20, (double)MAXSIZE.x), std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().y, (double)20, (double)MAXSIZE.y)));
|
||||
// calc the new size and pos
|
||||
|
||||
Vector2D newSize = m_vBeginDragSizeXY;
|
||||
Vector2D newPos = m_vBeginDragPositionXY;
|
||||
|
||||
if (m_iGrabbedCorner == 3) {
|
||||
newSize = newSize + DELTA;
|
||||
} else if (m_iGrabbedCorner == 0) {
|
||||
newSize = newSize - DELTA;
|
||||
newPos = newPos + DELTA;
|
||||
} else if (m_iGrabbedCorner == 1) {
|
||||
newSize = newSize + Vector2D(DELTA.x, -DELTA.y);
|
||||
newPos = newPos + Vector2D(0, DELTA.y);
|
||||
} else if (m_iGrabbedCorner == 4) {
|
||||
newSize = newSize + Vector2D(-DELTA.x, DELTA.y);
|
||||
newPos = newPos + Vector2D(DELTA.x, 0);
|
||||
}
|
||||
|
||||
|
||||
newSize = newSize.clamp(Vector2D(20,20), MAXSIZE);
|
||||
|
||||
if (*PANIMATE) {
|
||||
DRAGGINGWINDOW->m_vRealSize = newSize;
|
||||
DRAGGINGWINDOW->m_vRealPosition = newPos;
|
||||
} else {
|
||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(newSize);
|
||||
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(newPos);
|
||||
}
|
||||
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||
} else {
|
||||
resizeActiveWindow(TICKDELTA, DRAGGINGWINDOW);
|
||||
@@ -207,7 +259,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
if (PMONITOR) {
|
||||
DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
DRAGGINGWINDOW->moveToWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
|
||||
DRAGGINGWINDOW->updateToplevel();
|
||||
}
|
||||
|
||||
@@ -226,6 +278,8 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
pWindow->m_bPinned = false;
|
||||
|
||||
const auto TILED = isWindowTiled(pWindow);
|
||||
|
||||
if (!TILED) {
|
||||
@@ -284,4 +338,4 @@ void IHyprLayout::moveActiveWindow(const Vector2D& delta, CWindow* pWindow) {
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goalv() + delta;
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ public:
|
||||
*/
|
||||
virtual void onEndDragWindow();
|
||||
/*
|
||||
Called whenever the mouse moves, should the layout want to
|
||||
Called whenever the mouse moves, should the layout want to
|
||||
do anything with it.
|
||||
Useful for dragging.
|
||||
*/
|
||||
@@ -94,19 +94,19 @@ public:
|
||||
|
||||
/*
|
||||
Called when a dispatcher requests a custom message
|
||||
The layout is free to ignore.
|
||||
The layout is free to ignore.
|
||||
std::any is the reply. Can be empty.
|
||||
*/
|
||||
virtual std::any layoutMessage(SLayoutMessageHeader, std::string) = 0;
|
||||
|
||||
/*
|
||||
/*
|
||||
Required to be handled, but may return just SWindowRenderLayoutHints()
|
||||
Called when the renderer requests any special draw flags for
|
||||
a specific window, e.g. border color for groups.
|
||||
*/
|
||||
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*) = 0;
|
||||
|
||||
/*
|
||||
/*
|
||||
Called when the user requests two windows to be swapped places.
|
||||
The layout is free to ignore.
|
||||
*/
|
||||
@@ -128,4 +128,5 @@ private:
|
||||
Vector2D m_vLastDragXY;
|
||||
Vector2D m_vBeginDragPositionXY;
|
||||
Vector2D m_vBeginDragSizeXY;
|
||||
};
|
||||
int m_iGrabbedCorner = 0;
|
||||
};
|
||||
|
@@ -84,6 +84,13 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
g_pCompositor->setWindowFullscreen(PFULLWINDOW, false, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
// recalc
|
||||
recalculateMonitor(pWindow->m_iMonitorID);
|
||||
}
|
||||
@@ -94,6 +101,9 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
if (!PNODE)
|
||||
return;
|
||||
|
||||
if (pWindow->m_bIsFullscreen)
|
||||
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
|
||||
|
||||
if (PNODE->isMaster) {
|
||||
// find new one
|
||||
for (auto& nd : m_lMasterNodesData) {
|
||||
@@ -123,7 +133,7 @@ void CHyprMasterLayout::recalculateMonitor(const int& monid) {
|
||||
}
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL)
|
||||
if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL)
|
||||
return;
|
||||
|
||||
// massive hack from the fullscreen func
|
||||
@@ -242,12 +252,14 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||
|
||||
PWINDOW->m_sSpecialRenderData.rounding = false;
|
||||
PWINDOW->m_sSpecialRenderData.border = false;
|
||||
PWINDOW->m_sSpecialRenderData.decorate = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PWINDOW->m_sSpecialRenderData.rounding = true;
|
||||
PWINDOW->m_sSpecialRenderData.border = true;
|
||||
PWINDOW->m_sSpecialRenderData.decorate = true;
|
||||
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? *PGAPSOUT : *PGAPSIN,
|
||||
DISPLAYTOP ? *PGAPSOUT : *PGAPSIN);
|
||||
@@ -297,7 +309,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* p
|
||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||
|
||||
if (!PNODE) {
|
||||
PWINDOW->m_vRealSize = Vector2D(std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).x, (double)20, (double)999999), std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).y, (double)20, (double)999999));
|
||||
PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goalv() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goalv() + pixResize).y, 20.0));
|
||||
PWINDOW->updateWindowDecos();
|
||||
return;
|
||||
}
|
||||
@@ -326,10 +338,7 @@ void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreen
|
||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||
return;
|
||||
|
||||
if (!g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
||||
return;
|
||||
|
||||
if (on == pWindow->m_bIsFullscreen)
|
||||
if (on == pWindow->m_bIsFullscreen || pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
return; // ignore
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
@@ -425,16 +434,17 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
|
||||
return;
|
||||
|
||||
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||
Debug::log(ERR, "Master: Rejecting a swap between workspaces");
|
||||
return;
|
||||
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
|
||||
std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID);
|
||||
}
|
||||
|
||||
// massive hack: just swap window pointers, lol
|
||||
const auto PWINDOW1 = PNODE->pWindow;
|
||||
PNODE->pWindow = PNODE2->pWindow;
|
||||
PNODE2->pWindow = PWINDOW1;
|
||||
PNODE->pWindow = pWindow2;
|
||||
PNODE2->pWindow = pWindow;
|
||||
|
||||
recalculateMonitor(PWINDOW1->m_iMonitorID);
|
||||
recalculateMonitor(pWindow->m_iMonitorID);
|
||||
if (PNODE2->workspaceID != PNODE->workspaceID)
|
||||
recalculateMonitor(pWindow2->m_iMonitorID);
|
||||
}
|
||||
|
||||
void CHyprMasterLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
||||
@@ -602,4 +612,4 @@ void CHyprMasterLayout::onEnable() {
|
||||
|
||||
void CHyprMasterLayout::onDisable() {
|
||||
m_lMasterNodesData.clear();
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,12 @@ int main(int argc, char** argv) {
|
||||
if (!getenv("XDG_RUNTIME_DIR"))
|
||||
throw std::runtime_error("XDG_RUNTIME_DIR is not set!");
|
||||
|
||||
// export HYPRLAND_CMD
|
||||
std::string cmd = "";
|
||||
for (auto i = 0; i < argc; ++i)
|
||||
cmd += std::string(i == 0 ? "" : " ") + argv[i];
|
||||
setenv("HYPRLAND_CMD", cmd.c_str(), 1);
|
||||
|
||||
// parse some args
|
||||
std::string configPath;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
@@ -50,7 +56,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
// let's init the compositor.
|
||||
// it initializes basic Wayland stuff in the constructor.
|
||||
g_pCompositor = std::make_unique<CCompositor>();
|
||||
g_pCompositor = std::make_unique<CCompositor>();
|
||||
g_pCompositor->explicitConfigPath = configPath;
|
||||
|
||||
Debug::log(LOG, "Hyprland init finished.");
|
||||
|
@@ -21,12 +21,12 @@ void CAnimationManager::addBezierWithName(std::string name, const Vector2D& p1,
|
||||
|
||||
void CAnimationManager::tick() {
|
||||
|
||||
bool animationsDisabled = false;
|
||||
bool animGlobalDisabled = false;
|
||||
|
||||
static auto *const PANIMENABLED = &g_pConfigManager->getConfigValuePtr("animations:enabled")->intValue;
|
||||
|
||||
if (!*PANIMENABLED)
|
||||
animationsDisabled = true;
|
||||
animGlobalDisabled = true;
|
||||
|
||||
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
static auto *const PSHADOWSENABLED = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||
@@ -56,11 +56,13 @@ void CAnimationManager::tick() {
|
||||
const auto PWORKSPACE = (CWorkspace*)av->m_pWorkspace;
|
||||
const auto PLAYER = (SLayerSurface*)av->m_pLayer;
|
||||
CMonitor* PMONITOR = nullptr;
|
||||
bool animationsDisabled = animGlobalDisabled;
|
||||
|
||||
wlr_box WLRBOXPREV = {0,0,0,0};
|
||||
if (PWINDOW) {
|
||||
WLRBOXPREV = PWINDOW->getFullWindowBoundingBox();
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
animationsDisabled = animationsDisabled || PWINDOW->m_sAdditionalConfigData.forceNoAnims;
|
||||
} else if (PWORKSPACE) {
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
WLRBOXPREV = {(int)PMONITOR->vecPosition.x, (int)PMONITOR->vecPosition.y, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y};
|
||||
@@ -167,7 +169,7 @@ void CAnimationManager::tick() {
|
||||
}
|
||||
case AVARDAMAGE_BORDER: {
|
||||
RASSERT(PWINDOW, "Tried to AVARDAMAGE_BORDER a non-window AVAR!");
|
||||
|
||||
|
||||
// damage only the border.
|
||||
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
const auto ROUNDINGSIZE = *PROUNDING + 1;
|
||||
@@ -222,7 +224,7 @@ void CAnimationManager::tick() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// set size and pos if valid, but only if damage policy entire (dont if border for example)
|
||||
if (g_pCompositor->windowValidMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE && PWINDOW->m_iX11Type != 2)
|
||||
@@ -438,4 +440,4 @@ std::string CAnimationManager::styleValidInConfigVar(const std::string& config,
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
@@ -36,19 +36,12 @@ void CEventManager::startThread() {
|
||||
// 10 max queued.
|
||||
listen(SOCKET, 10);
|
||||
|
||||
char readBuf[1024] = {0};
|
||||
|
||||
sockaddr_in clientAddress;
|
||||
socklen_t clientSize = sizeof(clientAddress);
|
||||
|
||||
Debug::log(LOG, "Hypr socket 2 started at %s", socketPath.c_str());
|
||||
|
||||
// set the socket nonblock
|
||||
int flags = fcntl(SOCKET, F_GETFL, 0);
|
||||
fcntl(SOCKET, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
while (1) {
|
||||
|
||||
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);
|
||||
|
||||
if (ACCEPTEDCONNECTION > 0) {
|
||||
@@ -61,43 +54,7 @@ void CEventManager::startThread() {
|
||||
Debug::log(LOG, "Socket 2 accepted a new client at FD %d", ACCEPTEDCONNECTION);
|
||||
}
|
||||
|
||||
// pong if all FDs valid
|
||||
for (auto it = m_dAcceptedSocketFDs.begin(); it != m_dAcceptedSocketFDs.end();) {
|
||||
auto sizeRead = recv(*it, &readBuf, 1024, 0);
|
||||
|
||||
if (sizeRead != 0) {
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// invalid!
|
||||
Debug::log(LOG, "Removed invalid socket (2) FD: %d", *it);
|
||||
it = m_dAcceptedSocketFDs.erase(it);
|
||||
}
|
||||
|
||||
// valid FDs, check the queue
|
||||
// don't do anything if main thread is writing to the eventqueue
|
||||
eventQueueMutex.lock();
|
||||
|
||||
if (m_dQueuedEvents.empty()){ // if queue empty, sleep and ignore
|
||||
eventQueueMutex.unlock();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
continue;
|
||||
}
|
||||
|
||||
// write all queued events
|
||||
for (auto& ev : m_dQueuedEvents) {
|
||||
std::string eventString = (ev.event + ">>" + ev.data).substr(0, 1022) + "\n";
|
||||
for (auto& fd : m_dAcceptedSocketFDs) {
|
||||
write(fd, eventString.c_str(), eventString.length());
|
||||
}
|
||||
}
|
||||
|
||||
m_dQueuedEvents.clear();
|
||||
|
||||
eventQueueMutex.unlock();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
ensureFDsValid();
|
||||
}
|
||||
|
||||
close(SOCKET);
|
||||
@@ -106,6 +63,42 @@ void CEventManager::startThread() {
|
||||
m_tThread.detach();
|
||||
}
|
||||
|
||||
void CEventManager::ensureFDsValid() {
|
||||
static char readBuf[1024] = {0};
|
||||
|
||||
// pong if all FDs valid
|
||||
for (auto it = m_dAcceptedSocketFDs.begin(); it != m_dAcceptedSocketFDs.end();) {
|
||||
auto sizeRead = recv(*it, &readBuf, 1024, 0);
|
||||
|
||||
if (sizeRead != 0) {
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// invalid!
|
||||
Debug::log(LOG, "Removed invalid socket (2) FD: %d", *it);
|
||||
it = m_dAcceptedSocketFDs.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void CEventManager::flushEvents() {
|
||||
|
||||
ensureFDsValid();
|
||||
|
||||
eventQueueMutex.lock();
|
||||
|
||||
for (auto& ev : m_dQueuedEvents) {
|
||||
std::string eventString = (ev.event + ">>" + ev.data).substr(0, 1022) + "\n";
|
||||
for (auto& fd : m_dAcceptedSocketFDs) {
|
||||
write(fd, eventString.c_str(), eventString.length());
|
||||
}
|
||||
}
|
||||
|
||||
m_dQueuedEvents.clear();
|
||||
|
||||
eventQueueMutex.unlock();
|
||||
}
|
||||
|
||||
void CEventManager::postEvent(const SHyprIPCEvent event, bool force) {
|
||||
|
||||
if ((m_bIgnoreEvents && !force) || g_pCompositor->m_bIsShuttingDown) {
|
||||
@@ -117,5 +110,7 @@ void CEventManager::postEvent(const SHyprIPCEvent event, bool force) {
|
||||
eventQueueMutex.lock();
|
||||
m_dQueuedEvents.push_back(ev);
|
||||
eventQueueMutex.unlock();
|
||||
|
||||
flushEvents();
|
||||
}, event).detach();
|
||||
}
|
||||
|
@@ -25,6 +25,9 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void flushEvents();
|
||||
void ensureFDsValid();
|
||||
|
||||
std::mutex eventQueueMutex;
|
||||
std::deque<SHyprIPCEvent> m_dQueuedEvents;
|
||||
|
||||
|
@@ -42,6 +42,8 @@ CKeybindManager::CKeybindManager() {
|
||||
m_mDispatchers["resizewindowpixel"] = resizeWindow;
|
||||
m_mDispatchers["swapnext"] = swapnext;
|
||||
m_mDispatchers["swapactiveworkspaces"] = swapActiveWorkspaces;
|
||||
m_mDispatchers["pin"] = pinActive;
|
||||
m_mDispatchers["mouse"] = mouse;
|
||||
|
||||
m_tScrollTimer.reset();
|
||||
}
|
||||
@@ -121,12 +123,39 @@ void CKeybindManager::updateXKBTranslationState() {
|
||||
|
||||
const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
const auto PKEYMAP = FILEPATH == "" ? xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS) : xkb_keymap_new_from_file(PCONTEXT, fopen(FILEPATH.c_str(), "r"), XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
auto PKEYMAP = FILEPATH == "" ? xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS) : xkb_keymap_new_from_file(PCONTEXT, fopen(FILEPATH.c_str(), "r"), XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
if (!PKEYMAP) {
|
||||
g_pHyprError->queueCreate("[Runtime Error] Invalid keyboard layout passed. ( rules: " + RULES + ", model: " + MODEL + ", variant: " + VARIANT + ", options: " + OPTIONS + ", layout: " + LAYOUT + " )", CColor(255, 50, 50, 255));
|
||||
|
||||
Debug::log(ERR, "[XKBTranslationState] Keyboard layout %s with variant %s (rules: %s, model: %s, options: %s) couldn't have been loaded.", rules.layout, rules.variant, rules.rules, rules.model, rules.options);
|
||||
memset(&rules, 0, sizeof(rules));
|
||||
|
||||
PKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
|
||||
xkb_context_unref(PCONTEXT);
|
||||
m_pXKBTranslationState = xkb_state_new(PKEYMAP);
|
||||
}
|
||||
|
||||
bool CKeybindManager::ensureMouseBindState() {
|
||||
if (!m_bIsMouseBindActive)
|
||||
return false;
|
||||
|
||||
if (g_pInputManager->currentlyDraggedWindow) {
|
||||
m_bIsMouseBindActive = false;
|
||||
g_pLayoutManager->getCurrentLayout()->onEndDragWindow();
|
||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||
g_pInputManager->dragMode = MBIND_INVALID;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
m_bIsMouseBindActive = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
|
||||
if (!g_pCompositor->m_bSessionActive) {
|
||||
m_dPressedKeycodes.clear();
|
||||
@@ -159,6 +188,8 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||
m_uLastCode = KEYCODE;
|
||||
m_uLastMouseCode = 0;
|
||||
|
||||
bool mouseBindWasActive = ensureMouseBindState();
|
||||
|
||||
bool found = false;
|
||||
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
// clean repeat
|
||||
@@ -171,9 +202,9 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||
m_dPressedKeycodes.push_back(KEYCODE);
|
||||
m_dPressedKeysyms.push_back(keysym);
|
||||
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "", keysym, 0, true, e->time_msec) || found;
|
||||
found = handleKeybinds(MODS, "", keysym, 0, true, e->time_msec) || found;
|
||||
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "", 0, KEYCODE, true, e->time_msec) || found;
|
||||
found = handleKeybinds(MODS, "", 0, KEYCODE, true, e->time_msec) || found;
|
||||
|
||||
if (found)
|
||||
shadowKeybinds(keysym, KEYCODE);
|
||||
@@ -185,17 +216,17 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||
m_pActiveKeybind = nullptr;
|
||||
}
|
||||
|
||||
m_dPressedKeycodes.erase(std::remove(m_dPressedKeycodes.begin(), m_dPressedKeycodes.end(), KEYCODE));
|
||||
m_dPressedKeysyms.erase(std::remove(m_dPressedKeysyms.begin(), m_dPressedKeysyms.end(), keysym));
|
||||
m_dPressedKeycodes.erase(std::remove(m_dPressedKeycodes.begin(), m_dPressedKeycodes.end(), KEYCODE), m_dPressedKeycodes.end());
|
||||
m_dPressedKeysyms.erase(std::remove(m_dPressedKeysyms.begin(), m_dPressedKeysyms.end(), keysym), m_dPressedKeysyms.end());
|
||||
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "", keysym, 0, false, e->time_msec) || found;
|
||||
found = handleKeybinds(MODS, "", keysym, 0, false, e->time_msec) || found;
|
||||
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "", 0, KEYCODE, false, e->time_msec) || found;
|
||||
found = handleKeybinds(MODS, "", 0, KEYCODE, false, e->time_msec) || found;
|
||||
|
||||
shadowKeybinds();
|
||||
}
|
||||
|
||||
return !found;
|
||||
return !found && !mouseBindWasActive;
|
||||
}
|
||||
|
||||
bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) {
|
||||
@@ -212,10 +243,10 @@ bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) {
|
||||
|
||||
bool found = false;
|
||||
if (e->source == WLR_AXIS_SOURCE_WHEEL && e->orientation == WLR_AXIS_ORIENTATION_VERTICAL) {
|
||||
if (e->delta < 0) {
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "mouse_down", 0, 0, true, 0);
|
||||
if (e->delta < 0) {
|
||||
found = handleKeybinds(MODS, "mouse_down", 0, 0, true, 0);
|
||||
} else {
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "mouse_up", 0, 0, true, 0);
|
||||
found = handleKeybinds(MODS, "mouse_up", 0, 0, true, 0);
|
||||
}
|
||||
|
||||
if (found)
|
||||
@@ -234,18 +265,24 @@ bool CKeybindManager::onMouseEvent(wlr_pointer_button_event* e) {
|
||||
m_uLastCode = 0;
|
||||
m_uTimeLastMs = e->time_msec;
|
||||
|
||||
bool mouseBindWasActive = ensureMouseBindState();
|
||||
|
||||
if (e->state == WLR_BUTTON_PRESSED) {
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, true, 0);
|
||||
found = handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, true, 0);
|
||||
|
||||
if (found)
|
||||
shadowKeybinds();
|
||||
} else {
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, false, 0);
|
||||
found = handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, false, 0);
|
||||
|
||||
shadowKeybinds();
|
||||
}
|
||||
|
||||
return !found;
|
||||
return !found && !mouseBindWasActive;
|
||||
}
|
||||
|
||||
void CKeybindManager::onSwitchEvent(const std::string& switchName) {
|
||||
handleKeybinds(0, "switch:" + switchName, 0, 0, true, 0);
|
||||
}
|
||||
|
||||
int repeatKeyHandler(void* data) {
|
||||
@@ -277,7 +314,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
||||
}
|
||||
|
||||
for (auto& k : m_lKeybinds) {
|
||||
if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || (!pressed && !k.release && k.handler != "pass") || k.shadowed)
|
||||
if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || (!pressed && !k.release && k.handler != "pass" && k.handler != "mouse") || k.shadowed)
|
||||
continue;
|
||||
|
||||
if (!key.empty()) {
|
||||
@@ -306,7 +343,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto DISPATCHER = m_mDispatchers.find(k.handler);
|
||||
const auto DISPATCHER = m_mDispatchers.find(k.mouse ? "mouse" : k.handler);
|
||||
|
||||
// Should never happen, as we check in the ConfigManager, but oh well
|
||||
if (DISPATCHER == m_mDispatchers.end()) {
|
||||
@@ -317,7 +354,10 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
||||
|
||||
m_iPassPressed = (int)pressed;
|
||||
|
||||
DISPATCHER->second(k.arg);
|
||||
if (k.handler == "mouse")
|
||||
DISPATCHER->second((pressed ? "1" : "0") + k.arg);
|
||||
else
|
||||
DISPATCHER->second(k.arg);
|
||||
|
||||
m_iPassPressed = -1;
|
||||
|
||||
@@ -355,7 +395,7 @@ void CKeybindManager::shadowKeybinds(const xkb_keysym_t& doesntHave, const int&
|
||||
for (auto& pk : m_dPressedKeysyms) {
|
||||
if ((pk == KBKEY || pk == KBKEYUPPER)) {
|
||||
shadow = true;
|
||||
|
||||
|
||||
if (pk == doesntHave && doesntHave != 0) {
|
||||
shadow = false;
|
||||
break;
|
||||
@@ -383,10 +423,29 @@ bool CKeybindManager::handleVT(xkb_keysym_t keysym) {
|
||||
if (!(keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12))
|
||||
return false;
|
||||
|
||||
const auto PSESSION = wlr_backend_get_session(g_pCompositor->m_sWLRBackend);
|
||||
if (PSESSION) {
|
||||
const int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
||||
wlr_session_change_vt(PSESSION, TTY);
|
||||
// beyond this point, return true to not handle anything else.
|
||||
// we'll avoid printing shit to active windows.
|
||||
|
||||
if (g_pCompositor->m_sWLRSession) {
|
||||
const unsigned int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
||||
|
||||
// vtnr is bugged for some reason.
|
||||
const std::string TTYSTR = execAndGet("head -n 1 /sys/devices/virtual/tty/tty0/active").substr(3);
|
||||
unsigned int ttynum = 0;
|
||||
try {
|
||||
ttynum = std::stoll(TTYSTR);
|
||||
} catch (std::exception &e) {
|
||||
; // oops?
|
||||
}
|
||||
|
||||
if (ttynum == TTY)
|
||||
return true;
|
||||
|
||||
Debug::log(LOG, "Switching from VT %i to VT %i", ttynum, TTY);
|
||||
|
||||
if (!wlr_session_change_vt(g_pCompositor->m_sWLRSession, TTY))
|
||||
return true; // probably same session
|
||||
|
||||
g_pCompositor->m_bSessionActive = false;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
@@ -399,7 +458,7 @@ bool CKeybindManager::handleVT(xkb_keysym_t keysym) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) {
|
||||
@@ -444,6 +503,11 @@ void CKeybindManager::spawn(std::string args) {
|
||||
}
|
||||
if (child == 0) {
|
||||
// run in child
|
||||
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigprocmask(SIG_SETMASK, &set, NULL);
|
||||
|
||||
grandchild = fork();
|
||||
if (grandchild == 0) {
|
||||
// run in grandchild
|
||||
@@ -524,7 +588,8 @@ void CKeybindManager::toggleActivePseudo(std::string args) {
|
||||
|
||||
ACTIVEWINDOW->m_bIsPseudotiled = !ACTIVEWINDOW->m_bIsPseudotiled;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(ACTIVEWINDOW);
|
||||
if (!ACTIVEWINDOW->m_bIsFullscreen)
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(ACTIVEWINDOW);
|
||||
}
|
||||
|
||||
void CKeybindManager::changeworkspace(std::string args) {
|
||||
@@ -572,24 +637,34 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Workspace_back_and_forth being enabled means that an attempt to switch to
|
||||
// Workspace_back_and_forth being enabled means that an attempt to switch to
|
||||
// the current workspace will instead switch to the previous.
|
||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(
|
||||
g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
static auto *const PBACKANDFORTH = &g_pConfigManager->getConfigValuePtr("binds:workspace_back_and_forth")->intValue;
|
||||
|
||||
if (*PBACKANDFORTH && PCURRENTWORKSPACE->m_iID == workspaceToChangeTo && PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1 && !internal) {
|
||||
|
||||
const auto PPREVWORKSPACE = g_pCompositor->getWorkspaceByID(PCURRENTWORKSPACE->m_iPrevWorkspaceID);
|
||||
|
||||
workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID;
|
||||
|
||||
if (PPREVWORKSPACE)
|
||||
workspaceName = PPREVWORKSPACE->m_szName;
|
||||
else
|
||||
workspaceName = std::to_string(workspaceToChangeTo);
|
||||
|
||||
isSwitchingToPrevious = true;
|
||||
|
||||
// If the previous workspace ID isn't reset, cycles can form when continually going
|
||||
// to the previous workspace again and again.
|
||||
static auto *const PALLOWWORKSPACECYCLES = &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue;
|
||||
static auto* const PALLOWWORKSPACECYCLES = &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue;
|
||||
if (!*PALLOWWORKSPACECYCLES)
|
||||
PCURRENTWORKSPACE->m_iPrevWorkspaceID = -1;
|
||||
}
|
||||
|
||||
// remove constraints
|
||||
} else if (PCURRENTWORKSPACE->m_iID == workspaceToChangeTo && !internal)
|
||||
return;
|
||||
|
||||
// remove constraints
|
||||
g_pInputManager->unconstrainMouse();
|
||||
|
||||
// if it's not internal, we will unfocus to prevent stuck focus
|
||||
@@ -613,6 +688,13 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
if (!g_pCompositor->isWorkspaceVisible(workspaceToChangeTo)) {
|
||||
const auto OLDWORKSPACEID = PMONITOR->activeWorkspace;
|
||||
|
||||
// fix pinned windows
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == PMONITOR->activeWorkspace && w->m_bPinned) {
|
||||
w->m_iWorkspaceID = workspaceToChangeTo;
|
||||
}
|
||||
}
|
||||
|
||||
// change it
|
||||
if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID)
|
||||
PMONITOR->activeWorkspace = workspaceToChangeTo;
|
||||
@@ -653,7 +735,7 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
// warp and focus
|
||||
if (anotherMonitor)
|
||||
g_pCompositor->warpCursorTo(PWINDOW->m_vRealPosition.vec() + PWINDOW->m_vRealSize.vec() / 2.f);
|
||||
|
||||
|
||||
g_pCompositor->focusWindow(PWINDOW, g_pXWaylandManager->getWindowSurface(PWINDOW));
|
||||
|
||||
if (g_pCompositor->cursorOnReservedArea()) // fix focus on bars etc
|
||||
@@ -671,7 +753,9 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
}
|
||||
|
||||
// Workspace doesn't exist, create and switch
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||
const auto BOUNDMON = g_pConfigManager->getBoundMonitorForWS(workspaceName);
|
||||
|
||||
const auto PMONITOR = BOUNDMON ? BOUNDMON : g_pCompositor->getMonitorFromCursor();
|
||||
|
||||
const auto OLDWORKSPACE = PMONITOR->activeWorkspace;
|
||||
|
||||
@@ -700,6 +784,13 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
|
||||
PMONITOR->specialWorkspaceOpen = false;
|
||||
|
||||
// fix pinned windows
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == PMONITOR->activeWorkspace && w->m_bPinned) {
|
||||
w->m_iWorkspaceID = workspaceToChangeTo;
|
||||
}
|
||||
}
|
||||
|
||||
if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID)
|
||||
PMONITOR->activeWorkspace = workspaceToChangeTo;
|
||||
else
|
||||
@@ -712,6 +803,12 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
// mark the monitor dirty
|
||||
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||
|
||||
// some stuf with the cursor and focus
|
||||
if (g_pCompositor->m_pLastMonitor != PMONITOR)
|
||||
g_pCompositor->warpCursorTo(PMONITOR->vecPosition + PMONITOR->vecSize / 2.f);
|
||||
|
||||
g_pCompositor->m_pLastMonitor = PMONITOR;
|
||||
|
||||
// focus (clears the last)
|
||||
g_pInputManager->refocus();
|
||||
|
||||
@@ -758,8 +855,8 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto PSAVEDSIZE = PWINDOW->m_vRealSize.vec();
|
||||
auto PSAVEDPOS = PWINDOW->m_vRealPosition.vec();
|
||||
auto PSAVEDSIZE = PWINDOW->m_vRealSize.goalv();
|
||||
auto PSAVEDPOS = PWINDOW->m_vRealPosition.goalv();
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
|
||||
|
||||
@@ -781,22 +878,18 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
|
||||
PWINDOW->moveToWorkspace(PWORKSPACE->m_iID);
|
||||
PWINDOW->m_iMonitorID = PWORKSPACE->m_iMonitorID;
|
||||
PWINDOW->m_bIsFullscreen = false;
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID)->m_bIsFullscreen = false;
|
||||
PWORKSPACE->m_bHasFullscreenWindow = false;
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bIsFullscreen) {
|
||||
PWINDOW->m_bIsFullscreen = false;
|
||||
PSAVEDPOS = PSAVEDPOS + Vector2D(10, 10);
|
||||
PSAVEDSIZE = PSAVEDSIZE - Vector2D(20, 20);
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
g_pCompositor->setWindowFullscreen(g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID), false, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
// Hack: So that the layout doesnt find our window at the cursor
|
||||
PWINDOW->m_vPosition = Vector2D(-42069, -42069);
|
||||
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
|
||||
|
||||
// and restore it
|
||||
@@ -815,10 +908,10 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
m->specialWorkspaceOpen = false;
|
||||
} else {
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
}
|
||||
|
||||
g_pInputManager->refocus();
|
||||
|
||||
PWINDOW->updateToplevel();
|
||||
}
|
||||
|
||||
@@ -857,7 +950,12 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||
// may be null until later!
|
||||
auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToMoveTo);
|
||||
|
||||
const auto PMONITORNEW = PWORKSPACE ? g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID) : PMONITOR;
|
||||
auto PMONITORNEW = PWORKSPACE ? g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID) : PMONITOR;
|
||||
if (!PWORKSPACE) {
|
||||
const auto BOUNDMON = g_pConfigManager->getBoundMonitorForWS(workspaceName);
|
||||
if (BOUNDMON)
|
||||
PMONITORNEW = BOUNDMON;
|
||||
}
|
||||
|
||||
const auto OLDWORKSPACEIDONMONITOR = PMONITORNEW->activeWorkspace;
|
||||
const auto OLDWORKSPACEIDRETURN = PMONITOR->activeWorkspace;
|
||||
@@ -886,6 +984,9 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||
|
||||
g_pEventManager->m_bIgnoreEvents = false;
|
||||
|
||||
// manually post event cuz it got ignored above
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", PWINDOW, PWORKSPACE->m_szName.c_str())});
|
||||
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
@@ -910,16 +1011,27 @@ void CKeybindManager::moveFocusTo(std::string args) {
|
||||
if (PLASTWINDOW->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && PLASTWINDOW->m_bIsFullscreen) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PLASTWINDOW->m_iWorkspaceID);
|
||||
const auto FSMODE = PWORKSPACE->m_efFullscreenMode;
|
||||
g_pCompositor->setWindowFullscreen(PLASTWINDOW, false, FULLSCREEN_FULL);
|
||||
|
||||
if (!PWINDOWTOCHANGETO->m_bPinned)
|
||||
g_pCompositor->setWindowFullscreen(PLASTWINDOW, false, FULLSCREEN_FULL);
|
||||
|
||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||
|
||||
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
|
||||
if (!PWINDOWTOCHANGETO->m_bPinned)
|
||||
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
|
||||
} else {
|
||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||
Vector2D middle = PWINDOWTOCHANGETO->m_vRealPosition.goalv() + PWINDOWTOCHANGETO->m_vRealSize.goalv() / 2.f;
|
||||
g_pCompositor->warpCursorTo(middle);
|
||||
g_pCompositor->m_pLastMonitor = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID); // update last monitor
|
||||
|
||||
if (PLASTWINDOW->m_iMonitorID != PWINDOWTOCHANGETO->m_iMonitorID) {
|
||||
// event
|
||||
const auto PNEWMON = g_pCompositor->getMonitorFromID(PWINDOWTOCHANGETO->m_iMonitorID);
|
||||
const auto PNEWWS = g_pCompositor->getWorkspaceByID(PNEWMON->activeWorkspace);
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", PNEWMON->szName + "," + PNEWWS->m_szName});
|
||||
|
||||
g_pCompositor->m_pLastMonitor = PNEWMON;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -932,13 +1044,13 @@ void CKeybindManager::moveFocusTo(std::string args) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg);
|
||||
|
||||
if (PWINDOWTOCHANGETO) {
|
||||
switchToWindow(PWINDOWTOCHANGETO);
|
||||
} else {
|
||||
const auto PWINDOWNEXT = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW);
|
||||
const auto PWINDOWNEXT = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true);
|
||||
if (PWINDOWNEXT) {
|
||||
switchToWindow(PWINDOWNEXT);
|
||||
}
|
||||
@@ -1082,7 +1194,7 @@ void CKeybindManager::moveCursorToCorner(std::string arg) {
|
||||
}
|
||||
|
||||
void CKeybindManager::workspaceOpt(std::string args) {
|
||||
|
||||
|
||||
// current workspace
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
|
||||
@@ -1248,7 +1360,7 @@ void CKeybindManager::forceRendererReload(std::string args) {
|
||||
bool overAgain = false;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
auto rule = g_pConfigManager->getMonitorRuleFor(m->szName);
|
||||
auto rule = g_pConfigManager->getMonitorRuleFor(m->szName, m->output->description ? m->output->description : "");
|
||||
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule, true)) {
|
||||
overAgain = true;
|
||||
break;
|
||||
@@ -1260,7 +1372,7 @@ void CKeybindManager::forceRendererReload(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::resizeActive(std::string args) {
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||
return;
|
||||
|
||||
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealSize.goalv());
|
||||
@@ -1272,8 +1384,8 @@ void CKeybindManager::resizeActive(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::moveActive(std::string args) {
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||
return;
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||
return;
|
||||
|
||||
const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealPosition.goalv());
|
||||
|
||||
@@ -1292,6 +1404,9 @@ void CKeybindManager::moveWindow(std::string args) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bIsFullscreen)
|
||||
return;
|
||||
|
||||
const auto POS = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealPosition.goalv());
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PWINDOW->m_vRealPosition.goalv(), PWINDOW);
|
||||
@@ -1309,7 +1424,10 @@ void CKeybindManager::resizeWindow(std::string args) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealSize.goalv());
|
||||
if (PWINDOW->m_bIsFullscreen)
|
||||
return;
|
||||
|
||||
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealSize.goalv());
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goalv(), PWINDOW);
|
||||
|
||||
@@ -1328,11 +1446,14 @@ void CKeybindManager::circleNext(std::string arg) {
|
||||
if (g_pCompositor->m_pLastWindow->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsFullscreen) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastWindow->m_iWorkspaceID);
|
||||
const auto FSMODE = PWORKSPACE->m_efFullscreenMode;
|
||||
g_pCompositor->setWindowFullscreen(g_pCompositor->m_pLastWindow, false, FULLSCREEN_FULL);
|
||||
|
||||
if (!PWINDOWTOCHANGETO->m_bPinned)
|
||||
g_pCompositor->setWindowFullscreen(g_pCompositor->m_pLastWindow, false, FULLSCREEN_FULL);
|
||||
|
||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||
|
||||
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
|
||||
if (!PWINDOWTOCHANGETO->m_bPinned)
|
||||
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
|
||||
} else {
|
||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
||||
Vector2D middle = PWINDOWTOCHANGETO->m_vRealPosition.goalv() + PWINDOWTOCHANGETO->m_vRealSize.goalv() / 2.f;
|
||||
@@ -1341,9 +1462,9 @@ void CKeybindManager::circleNext(std::string arg) {
|
||||
};
|
||||
|
||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||
switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
||||
switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow, true));
|
||||
else
|
||||
switchToWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
||||
switchToWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow, true));
|
||||
}
|
||||
|
||||
void CKeybindManager::focusWindow(std::string regexp) {
|
||||
@@ -1410,7 +1531,7 @@ void CKeybindManager::pass(std::string regexp) {
|
||||
else
|
||||
wlr_seat_pointer_enter(g_pCompositor->m_sSeat.seat, g_pXWaylandManager->getWindowSurface(PWINDOW), 1, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
wlr_keyboard_modifiers kbmods = {g_pInputManager->accumulateModsFromAllKBs(), 0, 0, 0};
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &kbmods);
|
||||
@@ -1433,7 +1554,7 @@ void CKeybindManager::pass(std::string regexp) {
|
||||
} else {
|
||||
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WLR_BUTTON_PRESSED);
|
||||
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WLR_BUTTON_RELEASED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (XWTOXW)
|
||||
@@ -1475,11 +1596,22 @@ void CKeybindManager::toggleOpaque(std::string unused) {
|
||||
}
|
||||
|
||||
void CKeybindManager::dpms(std::string arg) {
|
||||
bool enable = arg == "on";
|
||||
bool enable = arg.find("on") == 0;
|
||||
std::string port = "";
|
||||
|
||||
if (arg.find_first_of(' ') != std::string::npos) {
|
||||
port = arg.substr(arg.find_first_of(' ') + 1);
|
||||
}
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
|
||||
if (!port.empty() && m->szName != port)
|
||||
continue;
|
||||
|
||||
wlr_output_enable(m->output, enable);
|
||||
|
||||
|
||||
m->dpmsStatus = enable;
|
||||
|
||||
if (!wlr_output_commit(m->output)) {
|
||||
Debug::log(ERR, "Couldn't commit output %s", m->szName.c_str());
|
||||
}
|
||||
@@ -1503,16 +1635,16 @@ void CKeybindManager::swapnext(std::string arg) {
|
||||
const auto PLASTCYCLED = g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow->m_pLastCycledWindow) && g_pCompositor->m_pLastWindow->m_pLastCycledWindow->m_iWorkspaceID == PLASTWINDOW->m_iWorkspaceID ? g_pCompositor->m_pLastWindow->m_pLastCycledWindow : nullptr;
|
||||
|
||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW);
|
||||
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true);
|
||||
else
|
||||
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW);
|
||||
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true);
|
||||
|
||||
// sometimes we may come back to ourselves.
|
||||
if (toSwap == PLASTWINDOW) {
|
||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW);
|
||||
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW), true;
|
||||
else
|
||||
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW);
|
||||
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true);
|
||||
}
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, toSwap);
|
||||
@@ -1534,3 +1666,56 @@ void CKeybindManager::swapActiveWorkspaces(std::string args) {
|
||||
|
||||
g_pCompositor->swapActiveWorkspaces(PMON1, PMON2);
|
||||
}
|
||||
|
||||
void CKeybindManager::pinActive(std::string args) {
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) || !g_pCompositor->m_pLastWindow->m_bIsFloating || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
|
||||
return;
|
||||
|
||||
g_pCompositor->m_pLastWindow->m_bPinned = !g_pCompositor->m_pLastWindow->m_bPinned;
|
||||
g_pCompositor->m_pLastWindow->m_iWorkspaceID = g_pCompositor->getMonitorFromID(g_pCompositor->m_pLastWindow->m_iMonitorID)->activeWorkspace;
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastWindow->m_iWorkspaceID);
|
||||
|
||||
PWORKSPACE->m_pLastFocusedWindow = g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal());
|
||||
}
|
||||
|
||||
void CKeybindManager::mouse(std::string args) {
|
||||
const auto TRUEARG = args.substr(1);
|
||||
const auto PRESSED = args[0] == '1';
|
||||
|
||||
if (TRUEARG == "movewindow") {
|
||||
if (PRESSED) {
|
||||
g_pKeybindManager->m_bIsMouseBindActive = true;
|
||||
|
||||
g_pInputManager->currentlyDraggedWindow = g_pCompositor->vectorToWindowIdeal(g_pInputManager->getMouseCoordsInternal());
|
||||
g_pInputManager->dragMode = MBIND_MOVE;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onBeginDragWindow();
|
||||
} else {
|
||||
g_pKeybindManager->m_bIsMouseBindActive = false;
|
||||
|
||||
if (g_pInputManager->currentlyDraggedWindow) {
|
||||
g_pLayoutManager->getCurrentLayout()->onEndDragWindow();
|
||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||
g_pInputManager->dragMode = MBIND_INVALID;
|
||||
}
|
||||
}
|
||||
} else if (TRUEARG == "resizewindow") {
|
||||
if (PRESSED) {
|
||||
g_pKeybindManager->m_bIsMouseBindActive = true;
|
||||
|
||||
g_pInputManager->currentlyDraggedWindow = g_pCompositor->vectorToWindowIdeal(g_pInputManager->getMouseCoordsInternal());
|
||||
g_pInputManager->dragMode = MBIND_RESIZE;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onBeginDragWindow();
|
||||
} else {
|
||||
g_pKeybindManager->m_bIsMouseBindActive = false;
|
||||
|
||||
if (g_pInputManager->currentlyDraggedWindow) {
|
||||
g_pLayoutManager->getCurrentLayout()->onEndDragWindow();
|
||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||
g_pInputManager->dragMode = MBIND_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@ struct SKeybind {
|
||||
std::string submap = "";
|
||||
bool release = false;
|
||||
bool repeat = false;
|
||||
bool mouse = false;
|
||||
|
||||
// DO NOT INITIALIZE
|
||||
bool shadowed = false;
|
||||
@@ -37,7 +38,8 @@ public:
|
||||
bool onKeyEvent(wlr_keyboard_key_event*, SKeyboard*);
|
||||
bool onAxisEvent(wlr_pointer_axis_event*);
|
||||
bool onMouseEvent(wlr_pointer_button_event*);
|
||||
|
||||
void onSwitchEvent(const std::string&);
|
||||
|
||||
void addKeybind(SKeybind);
|
||||
void removeKeybind(uint32_t, const std::string&);
|
||||
uint32_t stringToModMask(std::string);
|
||||
@@ -63,6 +65,8 @@ private:
|
||||
uint32_t m_uLastCode = 0;
|
||||
uint32_t m_uLastMouseCode = 0;
|
||||
|
||||
bool m_bIsMouseBindActive = false;
|
||||
|
||||
int m_iPassPressed = -1; // used for pass
|
||||
|
||||
CTimer m_tScrollTimer;
|
||||
@@ -75,6 +79,7 @@ private:
|
||||
xkb_state* m_pXKBTranslationState = nullptr;
|
||||
|
||||
void updateXKBTranslationState();
|
||||
bool ensureMouseBindState();
|
||||
|
||||
// -------------- Dispatchers -------------- //
|
||||
static void killActive(std::string);
|
||||
@@ -113,6 +118,8 @@ private:
|
||||
static void dpms(std::string);
|
||||
static void swapnext(std::string);
|
||||
static void swapActiveWorkspaces(std::string);
|
||||
static void pinActive(std::string);
|
||||
static void mouse(std::string);
|
||||
|
||||
friend class CCompositor;
|
||||
friend class CInputManager;
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
IHyprLayout* CLayoutManager::getCurrentLayout() {
|
||||
switch (m_iCurrentLayoutID) {
|
||||
case DWINDLE:
|
||||
case DWINDLE:
|
||||
return &m_cDwindleLayout;
|
||||
case MASTER:
|
||||
return &m_cMasterLayout;
|
||||
@@ -28,4 +28,4 @@ void CLayoutManager::switchToLayout(std::string layout) {
|
||||
} else {
|
||||
Debug::log(ERR, "Unknown layout %s!", layout.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,10 @@ int slowUpdate = 0;
|
||||
int handleTimer(void* data) {
|
||||
const auto PTM = (CThreadManager*)data;
|
||||
|
||||
g_pConfigManager->tick();
|
||||
static auto *const PDISABLECFGRELOAD = &g_pConfigManager->getConfigValuePtr("misc:disable_autoreload")->intValue;
|
||||
|
||||
if (*PDISABLECFGRELOAD != 1)
|
||||
g_pConfigManager->tick();
|
||||
|
||||
wl_event_source_timer_update(PTM->m_esConfigTimer, 1000);
|
||||
|
||||
@@ -19,8 +22,6 @@ CThreadManager::CThreadManager() {
|
||||
|
||||
HyprCtl::startHyprCtlSocket();
|
||||
|
||||
g_pCompositor->startHyprCtlTick();
|
||||
|
||||
m_esConfigTimer = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, handleTimer, this);
|
||||
|
||||
wl_event_source_timer_update(m_esConfigTimer, 1000);
|
||||
|
@@ -46,7 +46,7 @@ void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate)
|
||||
if (activate)
|
||||
wlr_xwayland_surface_restack(wlr_xwayland_surface_from_wlr_surface(pSurface), NULL, XCB_STACK_MODE_ABOVE);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
|
||||
@@ -63,7 +63,8 @@ void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
|
||||
g_pCompositor->m_pLastFocus = getWindowSurface(pWindow);
|
||||
g_pCompositor->m_pLastWindow = pWindow;
|
||||
|
||||
g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_pLastFocusedWindow = pWindow;
|
||||
if (!pWindow->m_bPinned)
|
||||
g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_pLastFocusedWindow = pWindow;
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::getGeometryForWindow(CWindow* pWindow, wlr_box* pbox) {
|
||||
@@ -165,7 +166,7 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) {
|
||||
{
|
||||
if (pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"])
|
||||
pWindow->m_bX11ShouldntFocus = true;
|
||||
|
||||
|
||||
pWindow->m_bNoInitialFocus = true;
|
||||
return true;
|
||||
}
|
||||
@@ -195,7 +196,7 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) {
|
||||
return true;
|
||||
} else {
|
||||
const auto PSTATE = &pWindow->m_uSurface.xdg->toplevel->current;
|
||||
|
||||
|
||||
if ((PSTATE->min_width != 0 && PSTATE->min_height != 0 && (PSTATE->min_width == PSTATE->max_width || PSTATE->min_height == PSTATE->max_height)) || pWindow->m_uSurface.xdg->toplevel->parent)
|
||||
return true;
|
||||
}
|
||||
@@ -206,7 +207,7 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) {
|
||||
void CHyprXWaylandManager::moveXWaylandWindow(CWindow* pWindow, const Vector2D& pos) {
|
||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||
return;
|
||||
|
||||
|
||||
if (pWindow->m_bIsX11) {
|
||||
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pos.x, pos.y, pWindow->m_vRealSize.vec().x, pWindow->m_vRealSize.vec().y);
|
||||
}
|
||||
@@ -221,7 +222,7 @@ void CHyprXWaylandManager::checkBorders(CWindow* pWindow) {
|
||||
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_COMBO"] ||
|
||||
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_SPLASH"] ||
|
||||
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLTIP"]) {
|
||||
|
||||
|
||||
pWindow->m_bX11DoesntWantBorders = true;
|
||||
return;
|
||||
}
|
||||
|
@@ -29,7 +29,6 @@ void CInputManager::onMouseWarp(wlr_pointer_motion_absolute_event* e) {
|
||||
}
|
||||
|
||||
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||
static auto *const PMOUSEDPMS = &g_pConfigManager->getConfigValuePtr("misc:mouse_move_enables_dpms")->intValue;
|
||||
static auto *const PFOLLOWONDND = &g_pConfigManager->getConfigValuePtr("misc:always_follow_on_dnd")->intValue;
|
||||
@@ -140,6 +139,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
if (!foundSurface)
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
if (!foundSurface)
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
// then, we check if the workspace doesnt have a fullscreen window
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !foundSurface && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) {
|
||||
@@ -157,7 +159,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
// only check floating because tiled cant be over fullscreen
|
||||
for (auto w = g_pCompositor->m_vWindows.rbegin(); w != g_pCompositor->m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((((*w)->m_bIsFloating && (*w)->m_bIsMapped && (*w)->m_bCreatedOverFullscreen) || ((*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden) {
|
||||
if ((((*w)->m_bIsFloating && (*w)->m_bIsMapped && ((*w)->m_bCreatedOverFullscreen || (*w)->m_bPinned)) || ((*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden) {
|
||||
pFoundWindow = (*w).get();
|
||||
|
||||
if (!pFoundWindow->m_bIsX11) {
|
||||
@@ -173,9 +175,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundSurface)
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
// then windows
|
||||
if (!foundSurface) {
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) {
|
||||
@@ -287,7 +286,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
}
|
||||
|
||||
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
|
||||
if (*PFOLLOWMOUSE != 0 || pFoundWindow == g_pCompositor->m_pLastWindow)
|
||||
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
|
||||
|
||||
m_bLastFocusOnLS = false;
|
||||
return; // don't enter any new surfaces
|
||||
} else {
|
||||
@@ -371,7 +372,7 @@ void CInputManager::setClickMode(eClickBehaviorMode mode) {
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
|
||||
@@ -384,7 +385,6 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
|
||||
|
||||
// notify the keybind manager
|
||||
static auto *const PPASSMOUSE = &g_pConfigManager->getConfigValuePtr("binds:pass_mouse_when_bound")->intValue;
|
||||
static auto *const PMAINMODINTERNAL = &g_pConfigManager->getConfigValuePtr("general:main_mod_internal")->intValue;
|
||||
const auto PASS = g_pKeybindManager->onMouseEvent(e);
|
||||
|
||||
if (!PASS && !*PPASSMOUSE)
|
||||
@@ -399,22 +399,8 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
|
||||
if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_bIsFloating)
|
||||
g_pCompositor->moveWindowToTop(g_pCompositor->m_pLastWindow);
|
||||
|
||||
if ((e->button == BTN_LEFT || e->button == BTN_RIGHT) && wlr_keyboard_get_modifiers(PKEYBOARD) == (uint32_t)*PMAINMODINTERNAL) {
|
||||
currentlyDraggedWindow = g_pCompositor->windowFromCursor();
|
||||
dragButton = e->button;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onBeginDragWindow();
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WLR_BUTTON_RELEASED:
|
||||
if (currentlyDraggedWindow) {
|
||||
g_pLayoutManager->getCurrentLayout()->onEndDragWindow();
|
||||
currentlyDraggedWindow = nullptr;
|
||||
dragButton = -1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -449,12 +435,17 @@ void CInputManager::processMouseDownKill(wlr_pointer_button_event* e) {
|
||||
}
|
||||
|
||||
void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) {
|
||||
static auto *const PSCROLLFACTOR = &g_pConfigManager->getConfigValuePtr("input:touchpad:scroll_factor")->floatValue;
|
||||
|
||||
auto factor = (*PSCROLLFACTOR <= 0.f || e->source != WLR_AXIS_SOURCE_FINGER ? 1.f : *PSCROLLFACTOR);
|
||||
|
||||
bool passEvent = g_pKeybindManager->onAxisEvent(e);
|
||||
|
||||
wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat);
|
||||
|
||||
if (passEvent) {
|
||||
wlr_seat_pointer_notify_axis(g_pCompositor->m_sSeat.seat, e->time_msec, e->orientation, e->delta, e->delta_discrete, e->source);
|
||||
wlr_seat_pointer_notify_axis(g_pCompositor->m_sSeat.seat, e->time_msec, e->orientation, factor * e->delta,
|
||||
std::round(factor * e->delta_discrete), e->source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,11 +472,11 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
||||
const auto PKEYBOARD = (SKeyboard*)owner;
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," +getActiveLayoutForKeyboard(PKEYBOARD)}, true); // force as this should ALWAYS be sent
|
||||
|
||||
|
||||
}, PNEWKEYBOARD, "Keyboard");
|
||||
|
||||
disableAllKeyboards(false);
|
||||
|
||||
|
||||
m_pActiveKeyboard = PNEWKEYBOARD;
|
||||
|
||||
PNEWKEYBOARD->active = true;
|
||||
@@ -516,7 +507,7 @@ void CInputManager::newVirtualKeyboard(wlr_input_device* keyboard) {
|
||||
const auto PKEYBOARD = (SKeyboard*)owner;
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," +getActiveLayoutForKeyboard(PKEYBOARD)}, true); // force as this should ALWAYS be sent
|
||||
|
||||
|
||||
}, PNEWKEYBOARD, "Keyboard");
|
||||
|
||||
disableAllKeyboards(true);
|
||||
@@ -613,7 +604,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
} else {
|
||||
KEYMAP = xkb_keymap_new_from_file(CONTEXT, fopen(path.c_str(), "r"), XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!KEYMAP) {
|
||||
KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
@@ -656,7 +647,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," +getActiveLayoutForKeyboard(pKeyboard)}, true); // force as this should ALWAYS be sent
|
||||
|
||||
Debug::log(LOG, "Set the keyboard layout to %s and variant to %s for keyboard \"%s\"", rules.layout, rules.variant, pKeyboard->keyboard->name);
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
|
||||
m_lMice.emplace_back();
|
||||
@@ -676,7 +667,7 @@ void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
|
||||
Debug::log(LOG, "New mouse has libinput sens %.2f (%.2f) with accel profile %i (%i)", libinput_device_config_accel_get_speed(LIBINPUTDEV), libinput_device_config_accel_get_default_speed(LIBINPUTDEV), libinput_device_config_accel_get_profile(LIBINPUTDEV), libinput_device_config_accel_get_default_profile(LIBINPUTDEV));
|
||||
}
|
||||
|
||||
setMouseConfigs();
|
||||
setPointerConfigs();
|
||||
|
||||
PMOUSE->hyprListener_destroyMouse.initCallback(&mouse->events.destroy, &Events::listener_destroyMouse, PMOUSE, "Mouse");
|
||||
|
||||
@@ -689,11 +680,11 @@ void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
|
||||
Debug::log(LOG, "New mouse created, pointer WLR: %x", mouse);
|
||||
}
|
||||
|
||||
void CInputManager::setMouseConfigs() {
|
||||
void CInputManager::setPointerConfigs() {
|
||||
for (auto& m : m_lMice) {
|
||||
const auto PMOUSE = &m;
|
||||
const auto PPOINTER = &m;
|
||||
|
||||
auto devname = PMOUSE->name;
|
||||
auto devname = PPOINTER->name;
|
||||
transform(devname.begin(), devname.end(), devname.begin(), ::tolower);
|
||||
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(devname);
|
||||
@@ -706,6 +697,11 @@ void CInputManager::setMouseConfigs() {
|
||||
else
|
||||
libinput_device_config_click_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
|
||||
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "left_handed") : g_pConfigManager->getInt("input:left_handed")) == 0)
|
||||
libinput_device_config_left_handed_set(LIBINPUTDEV, 0);
|
||||
else
|
||||
libinput_device_config_left_handed_set(LIBINPUTDEV, 1);
|
||||
|
||||
if (libinput_device_config_middle_emulation_is_available(LIBINPUTDEV)) { // middleclick on r+l mouse button pressed
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "middle_button_emulation") : g_pConfigManager->getInt("input:touchpad:middle_button_emulation")) == 1)
|
||||
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
|
||||
@@ -713,6 +709,21 @@ void CInputManager::setMouseConfigs() {
|
||||
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
|
||||
}
|
||||
|
||||
const auto SCROLLMETHOD = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "scroll_method") : g_pConfigManager->getString("input:scroll_method");
|
||||
if (SCROLLMETHOD == "" || SCROLLMETHOD == STRVAL_EMPTY) {
|
||||
libinput_device_config_scroll_set_method(LIBINPUTDEV, libinput_device_config_scroll_get_default_method(LIBINPUTDEV));
|
||||
} else if (SCROLLMETHOD == "no_scroll") {
|
||||
libinput_device_config_scroll_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
|
||||
} else if (SCROLLMETHOD == "2fg") {
|
||||
libinput_device_config_scroll_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_SCROLL_2FG);
|
||||
} else if (SCROLLMETHOD == "edge") {
|
||||
libinput_device_config_scroll_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_SCROLL_EDGE);
|
||||
} else if (SCROLLMETHOD == "on_button_down") {
|
||||
libinput_device_config_scroll_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
|
||||
} else {
|
||||
Debug::log(WARN, "Scroll method unknown");
|
||||
}
|
||||
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(devname, "drag_lock") : g_pConfigManager->getInt("input:touchpad:drag_lock")) == 0)
|
||||
libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
|
||||
else
|
||||
@@ -737,10 +748,20 @@ void CInputManager::setMouseConfigs() {
|
||||
}
|
||||
|
||||
const auto LIBINPUTSENS = std::clamp((HASCONFIG ? g_pConfigManager->getDeviceFloat(devname, "sensitivity") : g_pConfigManager->getFloat("input:sensitivity")), -1.f, 1.f);
|
||||
|
||||
libinput_device_config_accel_set_profile(LIBINPUTDEV, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
|
||||
libinput_device_config_accel_set_speed(LIBINPUTDEV, LIBINPUTSENS);
|
||||
|
||||
const auto ACCELPROFILE = HASCONFIG ? g_pConfigManager->getDeviceString(devname, "accel_profile") : g_pConfigManager->getString("input:accel_profile");
|
||||
|
||||
if (ACCELPROFILE == "" || ACCELPROFILE == STRVAL_EMPTY) {
|
||||
libinput_device_config_accel_set_profile(LIBINPUTDEV, libinput_device_config_accel_get_default_profile(LIBINPUTDEV));
|
||||
} else if (ACCELPROFILE == "adaptive") {
|
||||
libinput_device_config_accel_set_profile(LIBINPUTDEV, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
|
||||
} else if (ACCELPROFILE == "flat") {
|
||||
libinput_device_config_accel_set_profile(LIBINPUTDEV, LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
|
||||
} else {
|
||||
Debug::log(WARN, "Unknown acceleration profile, falling back to default");
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Applied config to mouse %s, sens %.2f", m.name.c_str(), LIBINPUTSENS);
|
||||
}
|
||||
}
|
||||
@@ -893,7 +914,7 @@ void CInputManager::constrainMouse(SMouse* pMouse, wlr_pointer_constraint_v1* co
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wlr_pointer_constraint_v1_send_deactivated(pMouse->currentConstraint);
|
||||
}
|
||||
|
||||
@@ -983,7 +1004,7 @@ std::string CInputManager::getActiveLayoutForKeyboard(SKeyboard* pKeyboard) {
|
||||
if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
|
||||
const auto LAYOUTNAME = xkb_keymap_layout_get_name(KEYMAP, i);
|
||||
|
||||
if (LAYOUTNAME)
|
||||
if (LAYOUTNAME)
|
||||
return std::string(LAYOUTNAME);
|
||||
return "error";
|
||||
}
|
||||
@@ -1001,3 +1022,48 @@ void CInputManager::disableAllKeyboards(bool virt) {
|
||||
k.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::newTouchDevice(wlr_input_device* pDevice) {
|
||||
const auto PNEWDEV = &m_lTouchDevices.emplace_back();
|
||||
PNEWDEV->pWlrDevice = pDevice;
|
||||
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, pDevice);
|
||||
|
||||
Debug::log(LOG, "New touch device added at %x", PNEWDEV);
|
||||
|
||||
PNEWDEV->hyprListener_destroy.initCallback(&pDevice->events.destroy, [&](void* owner, void* data) {
|
||||
destroyTouchDevice((STouchDevice*)data);
|
||||
}, PNEWDEV, "TouchDevice");
|
||||
}
|
||||
|
||||
void CInputManager::destroyTouchDevice(STouchDevice* pDevice) {
|
||||
Debug::log(LOG, "Touch device at %x removed", pDevice);
|
||||
|
||||
m_lTouchDevices.remove(*pDevice);
|
||||
}
|
||||
|
||||
void CInputManager::newSwitch(wlr_input_device* pDevice) {
|
||||
const auto PNEWDEV = &m_lSwitches.emplace_back();
|
||||
PNEWDEV->pWlrDevice = pDevice;
|
||||
|
||||
Debug::log(LOG, "New switch with name \"%s\" added", pDevice->name);
|
||||
|
||||
PNEWDEV->hyprListener_destroy.initCallback(&pDevice->events.destroy, [&](void* owner, void* data) {
|
||||
destroySwitch((SSwitchDevice*)owner);
|
||||
}, PNEWDEV, "SwitchDevice");
|
||||
|
||||
const auto PSWITCH = wlr_switch_from_input_device(pDevice);
|
||||
|
||||
PNEWDEV->hyprListener_toggle.initCallback(&PSWITCH->events.toggle, [&](void* owner, void* data) {
|
||||
const auto PDEVICE = (SSwitchDevice*)owner;
|
||||
const auto NAME = std::string(PDEVICE->pWlrDevice->name);
|
||||
|
||||
Debug::log(LOG, "Switch %s fired, triggering binds.", NAME.c_str());
|
||||
|
||||
g_pKeybindManager->onSwitchEvent(NAME);
|
||||
}, PNEWDEV, "SwitchDevice");
|
||||
}
|
||||
|
||||
void CInputManager::destroySwitch(SSwitchDevice* pDevice) {
|
||||
m_lSwitches.remove(*pDevice);
|
||||
}
|
||||
|
@@ -12,6 +12,12 @@ enum eClickBehaviorMode {
|
||||
CLICKMODE_KILL
|
||||
};
|
||||
|
||||
enum eMouseBindMode {
|
||||
MBIND_INVALID = -1,
|
||||
MBIND_MOVE = 0,
|
||||
MBIND_RESIZE
|
||||
};
|
||||
|
||||
struct STouchData {
|
||||
CWindow* touchFocusWindow = nullptr;
|
||||
Vector2D touchSurfaceOrigin;
|
||||
@@ -23,15 +29,19 @@ public:
|
||||
void onMouseMoved(wlr_pointer_motion_event*);
|
||||
void onMouseWarp(wlr_pointer_motion_absolute_event*);
|
||||
void onMouseButton(wlr_pointer_button_event*);
|
||||
void onMouseWheel(wlr_pointer_axis_event*);
|
||||
void onMouseWheel(wlr_pointer_axis_event*);
|
||||
void onKeyboardKey(wlr_keyboard_key_event*, SKeyboard*);
|
||||
void onKeyboardMod(void*, SKeyboard*);
|
||||
|
||||
void newKeyboard(wlr_input_device*);
|
||||
void newVirtualKeyboard(wlr_input_device*);
|
||||
void newMouse(wlr_input_device*, bool virt = false);
|
||||
void newTouchDevice(wlr_input_device*);
|
||||
void newSwitch(wlr_input_device*);
|
||||
void destroyTouchDevice(STouchDevice*);
|
||||
void destroyKeyboard(SKeyboard*);
|
||||
void destroyMouse(wlr_input_device*);
|
||||
void destroySwitch(SSwitchDevice*);
|
||||
|
||||
void constrainMouse(SMouse*, wlr_pointer_constraint_v1*);
|
||||
void recheckConstraint(SMouse*);
|
||||
@@ -42,7 +52,7 @@ public:
|
||||
void refocus();
|
||||
|
||||
void setKeyboardLayout();
|
||||
void setMouseConfigs();
|
||||
void setPointerConfigs();
|
||||
|
||||
void updateDragIcon();
|
||||
void updateCapabilities(wlr_input_device*);
|
||||
@@ -55,11 +65,14 @@ public:
|
||||
void onTouchUp(wlr_touch_up_event*);
|
||||
void onTouchMove(wlr_touch_motion_event*);
|
||||
|
||||
void onPointerHoldBegin(wlr_pointer_hold_begin_event*);
|
||||
void onPointerHoldEnd(wlr_pointer_hold_end_event*);
|
||||
|
||||
STouchData m_sTouchData;
|
||||
|
||||
// for dragging floating windows
|
||||
CWindow* currentlyDraggedWindow = nullptr;
|
||||
int dragButton = -1;
|
||||
eMouseBindMode dragMode = MBIND_INVALID;
|
||||
|
||||
SDrag m_sDrag;
|
||||
|
||||
@@ -75,6 +88,12 @@ public:
|
||||
// idle inhibitors
|
||||
std::list<SIdleInhibitor> m_lIdleInhibitors;
|
||||
|
||||
// Touch devices
|
||||
std::list<STouchDevice> m_lTouchDevices;
|
||||
|
||||
// Switches
|
||||
std::list<SSwitchDevice> m_lSwitches;
|
||||
|
||||
void newTabletTool(wlr_input_device*);
|
||||
void newTabletPad(wlr_input_device*);
|
||||
void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false);
|
||||
@@ -122,4 +141,4 @@ private:
|
||||
void applyConfigToKeyboard(SKeyboard*);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CInputManager> g_pInputManager;
|
||||
inline std::unique_ptr<CInputManager> g_pInputManager;
|
||||
|
@@ -2,9 +2,7 @@
|
||||
#include "InputManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
CInputMethodRelay::CInputMethodRelay() {
|
||||
|
||||
}
|
||||
CInputMethodRelay::CInputMethodRelay() { }
|
||||
|
||||
void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) {
|
||||
if (m_pWLRIME) {
|
||||
@@ -99,7 +97,7 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) {
|
||||
}, this, "IMERelay");
|
||||
|
||||
hyprListener_IMENewPopup.initCallback(&m_pWLRIME->events.new_popup_surface, [&](void* owner, void* data) {
|
||||
|
||||
|
||||
const auto PNEWPOPUP = &m_lIMEPopups.emplace_back();
|
||||
|
||||
PNEWPOPUP->pSurface = (wlr_input_popup_surface_v2*)data;
|
||||
@@ -122,7 +120,7 @@ void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) {
|
||||
}
|
||||
|
||||
void CInputMethodRelay::updateInputPopup(SIMEPopup* pPopup) {
|
||||
if (!pPopup->pSurface->mapped)
|
||||
if (!pPopup->pSurface->mapped)
|
||||
return;
|
||||
|
||||
// damage last known pos & size
|
||||
@@ -406,7 +404,7 @@ void CInputMethodRelay::onKeyboardFocus(wlr_surface* pSurface) {
|
||||
for (auto& ti : m_lTextInputs) {
|
||||
if (ti.pPendingSurface) {
|
||||
|
||||
if (pSurface != ti.pPendingSurface)
|
||||
if (pSurface != ti.pPendingSurface)
|
||||
setPendingSurface(&ti, nullptr);
|
||||
|
||||
} else if (ti.pWlrInput->focused_surface) {
|
||||
@@ -448,4 +446,4 @@ void CInputMethodRelay::setPendingSurface(STextInput* pInput, wlr_surface* pSurf
|
||||
} else {
|
||||
pInput->hyprListener_pendingSurfaceDestroy.removeCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,6 @@
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
||||
|
||||
static auto *const PSWIPE = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe")->intValue;
|
||||
static auto *const PSWIPEFINGERS = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_fingers")->intValue;
|
||||
|
||||
@@ -11,7 +10,7 @@ void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
||||
|
||||
int onMonitor = 0;
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
if (w->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID) {
|
||||
if (w->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID && w->m_iID != SPECIAL_WORKSPACE_ID) {
|
||||
onMonitor++;
|
||||
}
|
||||
}
|
||||
@@ -28,10 +27,15 @@ void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
||||
m_sActiveSwipe.pMonitor = g_pCompositor->m_pLastMonitor;
|
||||
m_sActiveSwipe.avgSpeed = 0;
|
||||
m_sActiveSwipe.speedPoints = 0;
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
for (auto& ls : g_pCompositor->m_pLastMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
ls->alpha = 255.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
|
||||
if (!m_sActiveSwipe.pWorkspaceBegin)
|
||||
return; // no valid swipe
|
||||
|
||||
@@ -49,6 +53,8 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
|
||||
const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.vec();
|
||||
|
||||
CWorkspace* pSwitchedTo = nullptr;
|
||||
|
||||
if ((abs(m_sActiveSwipe.delta) < *PSWIPEDIST * *PSWIPEPERC && (*PSWIPEFORC == 0 || (*PSWIPEFORC != 0 && m_sActiveSwipe.avgSpeed < *PSWIPEFORC))) || abs(m_sActiveSwipe.delta) < 2) {
|
||||
// revert
|
||||
if (abs(m_sActiveSwipe.delta) < 2) {
|
||||
@@ -66,6 +72,8 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D();
|
||||
}
|
||||
|
||||
pSwitchedTo = m_sActiveSwipe.pWorkspaceBegin;
|
||||
} else if (m_sActiveSwipe.delta < 0) {
|
||||
// switch to left
|
||||
const auto RENDEROFFSET = PWORKSPACEL->m_vRenderOffset.vec();
|
||||
@@ -82,6 +90,8 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
g_pInputManager->unconstrainMouse();
|
||||
|
||||
Debug::log(LOG, "Ended swipe to the left");
|
||||
|
||||
pSwitchedTo = PWORKSPACEL;
|
||||
} else {
|
||||
// switch to right
|
||||
const auto RENDEROFFSET = PWORKSPACER->m_vRenderOffset.vec();
|
||||
@@ -98,6 +108,8 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
g_pInputManager->unconstrainMouse();
|
||||
|
||||
Debug::log(LOG, "Ended swipe to the right");
|
||||
|
||||
pSwitchedTo = PWORKSPACER;
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||
@@ -109,6 +121,11 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
m_sActiveSwipe.pWorkspaceBegin = nullptr;
|
||||
|
||||
g_pInputManager->refocus();
|
||||
|
||||
// apply alpha
|
||||
for (auto& ls : g_pCompositor->m_pLastMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
ls->alpha = pSwitchedTo->m_bHasFullscreenWindow ? 0.f : 255.f;
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
@@ -127,8 +144,10 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
|
||||
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
|
||||
|
||||
if (workspaceIDLeft == INT_MAX || workspaceIDRight == INT_MAX || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID)
|
||||
if (workspaceIDLeft == INT_MAX || workspaceIDRight == INT_MAX || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID) {
|
||||
m_sActiveSwipe.pWorkspaceBegin = nullptr; // invalidate the swipe
|
||||
return;
|
||||
}
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = true;
|
||||
|
||||
|
@@ -66,7 +66,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_SLIDER)
|
||||
wlr_tablet_v2_tablet_tool_notify_slider(PTOOL->wlrTabletToolV2, EVENT->slider);
|
||||
|
||||
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_WHEEL)
|
||||
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_WHEEL)
|
||||
wlr_tablet_v2_tablet_tool_notify_wheel(PTOOL->wlrTabletToolV2, EVENT->wheel_delta, 0);
|
||||
|
||||
if (EVENT->updated_axes & WLR_TABLET_TOOL_AXIS_TILT_X)
|
||||
@@ -95,7 +95,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
else {
|
||||
wlr_send_tablet_v2_tablet_tool_up(PTOOL->wlrTabletToolV2);
|
||||
}
|
||||
|
||||
|
||||
}, PNEWTABLET, "Tablet");
|
||||
|
||||
PNEWTABLET->hyprListener_Button.initCallback(&wlr_tablet_from_input_device(pDevice)->events.button, [](void* owner, void* data) {
|
||||
@@ -104,7 +104,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool);
|
||||
|
||||
wlr_tablet_v2_tablet_tool_notify_button(PTOOL->wlrTabletToolV2, (zwp_tablet_pad_v2_button_state)EVENT->button, (zwp_tablet_pad_v2_button_state)EVENT->state);
|
||||
|
||||
|
||||
}, PNEWTABLET, "Tablet");
|
||||
|
||||
PNEWTABLET->hyprListener_Proximity.initCallback(&wlr_tablet_from_input_device(pDevice)->events.proximity, [](void* owner, void* data) {
|
||||
@@ -120,13 +120,13 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
wlr_tablet_v2_tablet_tool_notify_proximity_out(PTOOL->wlrTabletToolV2);
|
||||
PTOOL->pSurface = nullptr;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
PTOOL->active = true;
|
||||
g_pInputManager->refocus();
|
||||
g_pInputManager->focusTablet(PTAB, EVENT->tool);
|
||||
}
|
||||
|
||||
|
||||
}, PNEWTABLET, "Tablet");
|
||||
}
|
||||
|
||||
|
@@ -2,8 +2,10 @@
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
void CInputManager::onTouchDown(wlr_touch_down_event* e) {
|
||||
auto PMONITOR = g_pCompositor->getMonitorFromName(e->touch->output_name ? e->touch->output_name : "");
|
||||
PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_pLastMonitor;
|
||||
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, g_pCompositor->m_pLastMonitor->vecPosition.x + e->x * g_pCompositor->m_pLastMonitor->vecSize.x, g_pCompositor->m_pLastMonitor->vecPosition.y + e->y * g_pCompositor->m_pLastMonitor->vecSize.y);
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PMONITOR->vecPosition.x + e->x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e->y * PMONITOR->vecSize.y);
|
||||
|
||||
refocus();
|
||||
|
||||
@@ -26,7 +28,6 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) {
|
||||
}
|
||||
|
||||
void CInputManager::onTouchUp(wlr_touch_up_event* e){
|
||||
|
||||
if (m_sTouchData.touchFocusWindow) {
|
||||
wlr_seat_touch_notify_up(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id);
|
||||
}
|
||||
@@ -42,4 +43,12 @@ void CInputManager::onTouchMove(wlr_touch_motion_event* e){
|
||||
|
||||
wlr_seat_touch_notify_motion(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id, local.x, local.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::onPointerHoldBegin(wlr_pointer_hold_begin_event* e) {
|
||||
wlr_pointer_gestures_v1_send_hold_begin(g_pCompositor->m_sWLRPointerGestures, g_pCompositor->m_sSeat.seat, e->time_msec, e->fingers);
|
||||
}
|
||||
|
||||
void CInputManager::onPointerHoldEnd(wlr_pointer_hold_end_event* e) {
|
||||
wlr_pointer_gestures_v1_send_hold_end(g_pCompositor->m_sWLRPointerGestures, g_pCompositor->m_sSeat.seat, e->time_msec, e->cancelled);
|
||||
}
|
||||
|
@@ -3,7 +3,8 @@
|
||||
|
||||
bool CFramebuffer::alloc(int w, int h) {
|
||||
bool firstAlloc = false;
|
||||
|
||||
RASSERT((w > 1 && h > 1), "cannot alloc a FB with negative / zero size! (attempted %ix%i)", w, h);
|
||||
|
||||
if (m_iFb == (uint32_t)-1) {
|
||||
firstAlloc = true;
|
||||
glGenFramebuffers(1, &m_iFb);
|
||||
@@ -77,4 +78,4 @@ void CFramebuffer::release() {
|
||||
|
||||
CFramebuffer::~CFramebuffer() {
|
||||
release();
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#include "Shaders.hpp"
|
||||
#include "OpenGL.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
#include "Shaders.hpp"
|
||||
|
||||
CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||
RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL)), "Couldn't unset current EGL!");
|
||||
@@ -102,6 +104,7 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, pixman_region32_t* pDamage, bool
|
||||
m_RenderData.pCurrentMonData->primaryFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
m_RenderData.pCurrentMonData->mirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
m_RenderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
m_RenderData.pCurrentMonData->monitorMirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
|
||||
createBGTextureForMonitor(pMonitor);
|
||||
}
|
||||
@@ -120,11 +123,14 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, pixman_region32_t* pDamage, bool
|
||||
void CHyprOpenGLImpl::end() {
|
||||
// end the render, copy the data to the WLR framebuffer
|
||||
if (!m_bFakeFrame) {
|
||||
pixman_region32_copy(m_RenderData.pDamage, &m_rOriginalDamageRegion);
|
||||
|
||||
if (!m_RenderData.pMonitor->mirrors.empty())
|
||||
g_pHyprOpenGL->saveBufferForMirror(); // save with original damage region
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iWLROutputFb);
|
||||
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
|
||||
pixman_region32_copy(m_RenderData.pDamage, &m_rOriginalDamageRegion);
|
||||
|
||||
clear(CColor(11, 11, 11, 255));
|
||||
|
||||
m_bEndFrame = true;
|
||||
@@ -145,9 +151,7 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.proj = glGetUniformLocation(prog, "proj");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.color = glGetUniformLocation(prog, "color");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
@@ -161,7 +165,6 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.discardOpaque = glGetUniformLocation(prog, "discardOpaque");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
@@ -177,7 +180,6 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.discardOpaque = glGetUniformLocation(prog, "discardOpaque");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
@@ -193,7 +195,6 @@ void CHyprOpenGLImpl::initShaders() {
|
||||
m_RenderData.pCurrentMonData->m_shEXT.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.discardOpaque = glGetUniformLocation(prog, "discardOpaque");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
|
||||
@@ -333,15 +334,13 @@ void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixm
|
||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shQUAD.proj, 1, GL_FALSE, glMatrix);
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shQUAD.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f);
|
||||
|
||||
const auto TOPLEFT = Vector2D(round, round);
|
||||
const auto BOTTOMRIGHT = Vector2D(box->width - round, box->height - round);
|
||||
const auto TOPLEFT = Vector2D(box->x, box->y);
|
||||
const auto FULLSIZE = Vector2D(box->width, box->height);
|
||||
|
||||
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shQUAD.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shQUAD.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shQUAD.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shQUAD.radius, round);
|
||||
glUniform1i(m_RenderData.pCurrentMonData->m_shQUAD.primitiveMultisample, (int)(*PMULTISAMPLEEDGES == 1 && round != 0));
|
||||
@@ -437,9 +436,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(shader->topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(shader->bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(shader->fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform2f(shader->topLeft, pBox->x, pBox->y);
|
||||
glUniform2f(shader->fullSize, pBox->width, pBox->height);
|
||||
glUniform1f(shader->radius, round);
|
||||
glUniform1i(shader->primitiveMultisample, (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !noAA));
|
||||
|
||||
@@ -451,8 +449,6 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
glUniform1i(shader->applyTint, 0);
|
||||
}
|
||||
|
||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
const float verts[] = {
|
||||
m_RenderData.primarySurfaceUVBottomRight.x, m_RenderData.primarySurfaceUVTopLeft.y, // top right
|
||||
m_RenderData.primarySurfaceUVTopLeft.x, m_RenderData.primarySurfaceUVTopLeft.y, // top left
|
||||
@@ -460,6 +456,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
m_RenderData.primarySurfaceUVTopLeft.x, m_RenderData.primarySurfaceUVBottomRight.y, // bottom left
|
||||
};
|
||||
|
||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
if (allowCustomUV && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
|
||||
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, verts);
|
||||
} else {
|
||||
@@ -513,7 +511,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||
pixman_region32_copy(&damage, originalDamage);
|
||||
wlr_region_transform(&damage, &damage, wlr_output_transform_invert(m_RenderData.pMonitor->transform), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y);
|
||||
wlr_region_expand(&damage, &damage, pow(2, *PBLURPASSES) * *PBLURSIZE);
|
||||
|
||||
|
||||
// helper
|
||||
const auto PMIRRORFB = &m_RenderData.pCurrentMonData->mirrorFB;
|
||||
const auto PMIRRORSWAPFB = &m_RenderData.pCurrentMonData->mirrorSwapFB;
|
||||
@@ -577,7 +575,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||
pixman_region32_t tempDamage;
|
||||
pixman_region32_init(&tempDamage);
|
||||
wlr_region_scale(&tempDamage, &damage, 1.f / 2.f); // when DOWNscaling, we make the region twice as small because it's the TARGET
|
||||
|
||||
|
||||
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage);
|
||||
|
||||
// and draw
|
||||
@@ -659,7 +657,7 @@ void CHyprOpenGLImpl::preWindowPass() {
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == m_RenderData.pMonitor->activeWorkspace && !w->m_bHidden && w->m_bIsMapped && !w->m_bIsFloating) {
|
||||
hasWindows = true;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -776,27 +774,29 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
|
||||
if (*PBORDERSIZE < 1)
|
||||
return;
|
||||
|
||||
int scaledBorderSize = *PBORDERSIZE * m_RenderData.pMonitor->scale;
|
||||
|
||||
if (round < 1) {
|
||||
// zero rounding, just lines
|
||||
wlr_box borderbox = {box->x - *PBORDERSIZE, box->y - *PBORDERSIZE, *PBORDERSIZE, box->height + 2 * *PBORDERSIZE};
|
||||
wlr_box borderbox = {box->x - scaledBorderSize, box->y - scaledBorderSize, scaledBorderSize, box->height + 2 * scaledBorderSize};
|
||||
renderRect(&borderbox, col, 0); // left
|
||||
borderbox = {box->x, box->y - (int)*PBORDERSIZE, box->width + (int)*PBORDERSIZE, (int)*PBORDERSIZE};
|
||||
borderbox = {box->x, box->y - (int)scaledBorderSize, box->width + (int)scaledBorderSize, (int)scaledBorderSize};
|
||||
renderRect(&borderbox, col, 0); // top
|
||||
borderbox = {box->x + box->width, box->y, (int)*PBORDERSIZE, box->height + (int)*PBORDERSIZE};
|
||||
borderbox = {box->x + box->width, box->y, (int)scaledBorderSize, box->height + (int)scaledBorderSize};
|
||||
renderRect(&borderbox, col, 0); // right
|
||||
borderbox = {box->x, box->y + box->height, box->width, (int)*PBORDERSIZE};
|
||||
borderbox = {box->x, box->y + box->height, box->width, (int)scaledBorderSize};
|
||||
renderRect(&borderbox, col, 0); // bottom
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// adjust box
|
||||
box->x -= *PBORDERSIZE;
|
||||
box->y -= *PBORDERSIZE;
|
||||
box->width += 2 * *PBORDERSIZE;
|
||||
box->height += 2 * *PBORDERSIZE;
|
||||
box->x -= scaledBorderSize;
|
||||
box->y -= scaledBorderSize;
|
||||
box->width += 2 * scaledBorderSize;
|
||||
box->height += 2 * scaledBorderSize;
|
||||
|
||||
round += *PBORDERSIZE;
|
||||
round += scaledBorderSize;
|
||||
|
||||
float matrix[9];
|
||||
wlr_matrix_project_box(matrix, box, wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
||||
@@ -823,7 +823,7 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radius, round);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.thick, *PBORDERSIZE);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.thick, scaledBorderSize);
|
||||
glUniform1i(m_RenderData.pCurrentMonData->m_shBORDER1.primitiveMultisample, *PMULTISAMPLE);
|
||||
|
||||
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
@@ -1088,18 +1088,40 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const CAIROSURFACE) {
|
||||
void CHyprOpenGLImpl::saveBufferForMirror() {
|
||||
m_RenderData.pCurrentMonData->monitorMirrorFB.bind();
|
||||
|
||||
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
||||
|
||||
renderTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex, &monbox, 255.f, 0, false, false);
|
||||
|
||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderMirrored() {
|
||||
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
||||
|
||||
const auto PFB = &m_mMonitorRenderResources[m_RenderData.pMonitor->pMirrorOf].monitorMirrorFB;
|
||||
|
||||
if (PFB->m_cTex.m_iTexID <= 0)
|
||||
return;
|
||||
|
||||
renderTexture(PFB->m_cTex, &monbox, 255.f, 0, false, false);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const CAIROSURFACE, double offsetY) {
|
||||
cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
||||
|
||||
const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76);
|
||||
const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76);
|
||||
cairo_set_font_size(CAIRO, FONTSIZE);
|
||||
|
||||
cairo_set_source_rgba(CAIRO, 1.f, 1.f, 1.f, 0.32f);
|
||||
cairo_set_source_rgba(CAIRO, 1.0, 1.0, 1.0, 0.32);
|
||||
|
||||
cairo_text_extents_t textExtents;
|
||||
cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &textExtents);
|
||||
|
||||
cairo_move_to(CAIRO, m_RenderData.pMonitor->vecPixelSize.x / 2.f - textExtents.width / 2.f, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height - 1);
|
||||
cairo_move_to(CAIRO, (m_RenderData.pMonitor->vecPixelSize.x - textExtents.width) / 2.0, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height + offsetY);
|
||||
|
||||
cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str());
|
||||
|
||||
cairo_surface_flush(CAIROSURFACE);
|
||||
@@ -1141,13 +1163,37 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
|
||||
|
||||
PTEX->m_vSize = textureSize;
|
||||
|
||||
// calc the target box
|
||||
const double MONRATIO = m_RenderData.pMonitor->vecTransformedSize.x / m_RenderData.pMonitor->vecTransformedSize.y;
|
||||
const double WPRATIO = 1.77;
|
||||
|
||||
Vector2D origin;
|
||||
double scale;
|
||||
|
||||
if (MONRATIO > WPRATIO) {
|
||||
scale = m_RenderData.pMonitor->vecTransformedSize.x / PTEX->m_vSize.x;
|
||||
|
||||
origin.y = (m_RenderData.pMonitor->vecTransformedSize.y - PTEX->m_vSize.y * scale) / 2.0;
|
||||
} else {
|
||||
scale = m_RenderData.pMonitor->vecTransformedSize.y / PTEX->m_vSize.y;
|
||||
|
||||
origin.x = (m_RenderData.pMonitor->vecTransformedSize.x - PTEX->m_vSize.x * scale) / 2.0;
|
||||
}
|
||||
|
||||
wlr_box box = {origin.x, origin.y, PTEX->m_vSize.x * scale, PTEX->m_vSize.y * scale};
|
||||
|
||||
m_mMonitorRenderResources[pMonitor].backgroundTexBox = box;
|
||||
|
||||
// create a new one with cairo
|
||||
const auto CAIROSURFACE = cairo_image_surface_create_from_png(texPath.c_str());
|
||||
|
||||
const auto CAIRO = cairo_create(CAIROSURFACE);
|
||||
|
||||
// scale it to fit the current monitor
|
||||
cairo_scale(CAIRO, textureSize.x / pMonitor->vecTransformedSize.x, textureSize.y / pMonitor->vecTransformedSize.y);
|
||||
|
||||
// render splash on wallpaper
|
||||
if (!*PNOSPLASH)
|
||||
renderSplash(CAIRO, CAIROSURFACE);
|
||||
renderSplash(CAIRO, CAIROSURFACE, origin.y * WPRATIO / MONRATIO);
|
||||
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
||||
@@ -1163,28 +1209,6 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
|
||||
cairo_surface_destroy(CAIROSURFACE);
|
||||
cairo_destroy(CAIRO);
|
||||
|
||||
// calc the target box
|
||||
|
||||
const float MONRATIO = m_RenderData.pMonitor->vecTransformedSize.x / m_RenderData.pMonitor->vecTransformedSize.y;
|
||||
const float WPRATIO = 1.77f;
|
||||
|
||||
Vector2D origin;
|
||||
float scale;
|
||||
|
||||
if (MONRATIO > WPRATIO) {
|
||||
scale = m_RenderData.pMonitor->vecTransformedSize.x / PTEX->m_vSize.x;
|
||||
|
||||
origin.y = -(PTEX->m_vSize.y * scale - m_RenderData.pMonitor->vecTransformedSize.y) / 2.f / scale;
|
||||
} else {
|
||||
scale = m_RenderData.pMonitor->vecTransformedSize.y / PTEX->m_vSize.y;
|
||||
|
||||
origin.x = -(PTEX->m_vSize.x * scale - m_RenderData.pMonitor->vecTransformedSize.x) / 2.f / scale;
|
||||
}
|
||||
|
||||
wlr_box box = {origin.x * scale, origin.y * scale, PTEX->m_vSize.x * scale, PTEX->m_vSize.y * scale};
|
||||
|
||||
m_mMonitorRenderResources[pMonitor].backgroundTexBox = box;
|
||||
|
||||
Debug::log(LOG, "Background created for monitor %s", pMonitor->szName.c_str());
|
||||
}
|
||||
|
||||
|
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
|
||||
#include "Shaders.hpp"
|
||||
#include "Shader.hpp"
|
||||
#include "Texture.hpp"
|
||||
#include "Framebuffer.hpp"
|
||||
@@ -33,8 +32,10 @@ inline const float fanVertsFull[] = {
|
||||
|
||||
struct SMonitorRenderData {
|
||||
CFramebuffer primaryFB;
|
||||
CFramebuffer mirrorFB;
|
||||
CFramebuffer mirrorSwapFB;
|
||||
CFramebuffer mirrorFB; // these are used for some effects,
|
||||
CFramebuffer mirrorSwapFB; // etc
|
||||
|
||||
CFramebuffer monitorMirrorFB; // used for mirroring outputs
|
||||
|
||||
CTexture stencilTex;
|
||||
|
||||
@@ -102,6 +103,9 @@ public:
|
||||
void preWindowPass();
|
||||
void preRender(CMonitor*);
|
||||
|
||||
void saveBufferForMirror();
|
||||
void renderMirrored();
|
||||
|
||||
SCurrentRenderData m_RenderData;
|
||||
|
||||
GLint m_iCurrentOutputFb = 0;
|
||||
@@ -135,10 +139,9 @@ private:
|
||||
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
||||
|
||||
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowCustomUV = false, bool allowDim = false);
|
||||
|
||||
void renderSplash(cairo_t *const, cairo_surface_t *const);
|
||||
void renderSplash(cairo_t *const, cairo_surface_t *const, double);
|
||||
|
||||
void preBlurForCurrentMonitor();
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;
|
||||
inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;
|
||||
|
@@ -15,8 +15,8 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
if (RDATA->surface && surface == RDATA->surface)
|
||||
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h};
|
||||
else // here we clamp to 2, these might be some tiny specks
|
||||
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::clamp(surface->current.width, 2, 1337420), std::clamp(surface->current.height, 2, 1337420)};
|
||||
|
||||
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::max(surface->current.width, 2), std::max(surface->current.height, 2)};
|
||||
|
||||
if (RDATA->squishOversized) {
|
||||
if (x + windowBox.width > RDATA->w)
|
||||
windowBox.width = RDATA->w - x;
|
||||
@@ -26,7 +26,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
|
||||
if (RDATA->pWindow)
|
||||
g_pHyprRenderer->calculateUVForWindowSurface(RDATA->pWindow, surface, RDATA->squishOversized);
|
||||
|
||||
|
||||
scaleBox(&windowBox, RDATA->output->scale);
|
||||
|
||||
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
@@ -65,11 +65,14 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) {
|
||||
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, &geometry))
|
||||
return false;
|
||||
|
||||
if (pWindow->m_bPinned)
|
||||
return true;
|
||||
|
||||
// now check if it has the same workspace
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID) {
|
||||
if (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated()) {
|
||||
if (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated() || PWORKSPACE->m_bForceRendering) {
|
||||
return true;
|
||||
} else {
|
||||
if (!(!PWORKSPACE->m_bHasFullscreenWindow || pWindow->m_bIsFullscreen || (pWindow->m_bIsFloating && pWindow->m_bCreatedOverFullscreen)))
|
||||
@@ -99,6 +102,9 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) {
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (pWindow->m_bPinned || PWORKSPACE->m_bForceRendering)
|
||||
return true;
|
||||
|
||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
||||
return true;
|
||||
|
||||
@@ -116,11 +122,39 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) {
|
||||
void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time) {
|
||||
CWindow* pWorkspaceWindow = nullptr;
|
||||
|
||||
// loop over the tiled windows that are fading out
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID != pMonitor->activeWorkspace)
|
||||
continue;
|
||||
|
||||
if (w->m_fAlpha.fl() == 0.f)
|
||||
continue;
|
||||
|
||||
if (w->m_bIsFullscreen || w->m_bIsFloating)
|
||||
continue;
|
||||
|
||||
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
||||
}
|
||||
|
||||
// and floating ones too
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID != pMonitor->activeWorkspace)
|
||||
continue;
|
||||
|
||||
if (w->m_fAlpha.fl() == 0.f)
|
||||
continue;
|
||||
|
||||
if (w->m_bIsFullscreen || !w->m_bIsFloating)
|
||||
continue;
|
||||
|
||||
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
||||
}
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID);
|
||||
|
||||
if (w->m_iWorkspaceID != pWorkspace->m_iID || !w->m_bIsFullscreen){
|
||||
if (!(PWORKSPACE && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
||||
if (!(PWORKSPACE && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated() || PWORKSPACE->m_bForceRendering)))
|
||||
continue;
|
||||
|
||||
if (w->m_iMonitorID != pMonitor->ID)
|
||||
@@ -135,9 +169,9 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWor
|
||||
pWorkspaceWindow = w.get();
|
||||
}
|
||||
|
||||
// then render windows over fullscreen
|
||||
// then render windows over fullscreen.
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || !w->m_bCreatedOverFullscreen || !w->m_bIsMapped)
|
||||
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || !w->m_bIsMapped)
|
||||
continue;
|
||||
|
||||
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
||||
@@ -159,13 +193,12 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWor
|
||||
}
|
||||
|
||||
// and the overlay layers
|
||||
if (pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL) {
|
||||
// on non-full we draw the bar and shit
|
||||
for (auto& ls : pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
for (auto& ls : pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
if (ls->alpha.fl() != 0.f)
|
||||
renderLayer(ls.get(), pMonitor, time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (auto& ls : pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) {
|
||||
renderLayer(ls.get(), pMonitor, time);
|
||||
}
|
||||
@@ -186,17 +219,17 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||
g_pHyprOpenGL->renderSnapshot(&pWindow);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
const auto REALPOS = pWindow->m_vRealPosition.vec() + PWORKSPACE->m_vRenderOffset.vec();
|
||||
const auto REALPOS = pWindow->m_vRealPosition.vec() + (pWindow->m_bPinned ? Vector2D{} : PWORKSPACE->m_vRenderOffset.vec());
|
||||
static const auto PNOFLOATINGBORDERS = &g_pConfigManager->getConfigValuePtr("general:no_border_on_floating")->intValue;
|
||||
|
||||
SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y};
|
||||
renderdata.surface = g_pXWaylandManager->getWindowSurface(pWindow);
|
||||
renderdata.w = std::clamp(pWindow->m_vRealSize.vec().x, (double)5, (double)1337420); // clamp the size to min 5,
|
||||
renderdata.h = std::clamp(pWindow->m_vRealSize.vec().y, (double)5, (double)1337420); // otherwise we'll have issues later with invalid boxes
|
||||
renderdata.w = std::max(pWindow->m_vRealSize.vec().x, 5.0); // clamp the size to min 5,
|
||||
renderdata.h = std::max(pWindow->m_vRealSize.vec().y, 5.0); // otherwise we'll have issues later with invalid boxes
|
||||
renderdata.dontRound = (pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) || (!pWindow->m_sSpecialRenderData.rounding);
|
||||
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f);
|
||||
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (pWindow->m_bPinned ? 1.f : (PWORKSPACE->m_fAlpha.fl() / 255.f));
|
||||
renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl();
|
||||
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
|
||||
@@ -374,7 +407,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
|
||||
if (w->m_iWorkspaceID != SPECIAL_WORKSPACE_ID)
|
||||
continue;
|
||||
|
||||
@@ -459,8 +492,8 @@ void CHyprRenderer::calculateUVForWindowSurface(CWindow* pWindow, wlr_surface* p
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(0, 0);
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x * ((double)pWindow->m_vRealSize.vec().x / ((double)geom.width / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x)),
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y * ((double)pWindow->m_vRealSize.vec().y / ((double)geom.height / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y)));
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x * (pWindow->m_vRealSize.vec().x / ((double)geom.width / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x)),
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y * (pWindow->m_vRealSize.vec().y / ((double)geom.height / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y)));
|
||||
}
|
||||
} else {
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
@@ -772,7 +805,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
void CHyprRenderer::damageMonitor(CMonitor* pMonitor) {
|
||||
if (g_pCompositor->m_bUnsafeState)
|
||||
if (g_pCompositor->m_bUnsafeState || pMonitor->isMirror())
|
||||
return;
|
||||
|
||||
wlr_box damageBox = {0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y};
|
||||
@@ -789,6 +822,9 @@ void CHyprRenderer::damageBox(wlr_box* pBox) {
|
||||
return;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->isMirror())
|
||||
continue; // don't damage mirrors traditionally
|
||||
|
||||
wlr_box damageBox = {pBox->x - m->vecPosition.x, pBox->y - m->vecPosition.y, pBox->width, pBox->height};
|
||||
scaleBox(&damageBox, m->scale);
|
||||
m->addDamage(&damageBox);
|
||||
@@ -812,6 +848,19 @@ void CHyprRenderer::damageRegion(pixman_region32_t* rg) {
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprRenderer::damageMirrorsWith(CMonitor* pMonitor, pixman_region32_t* pRegion) {
|
||||
for (auto& mirror : pMonitor->mirrors) {
|
||||
Vector2D scale = {mirror->vecSize.x / pMonitor->vecSize.x, mirror->vecSize.y / pMonitor->vecSize.y};
|
||||
|
||||
pixman_region32_t rg;
|
||||
pixman_region32_init(&rg);
|
||||
pixman_region32_copy(&rg, pRegion);
|
||||
wlr_region_scale_xy(&rg, &rg, scale.x, scale.y);
|
||||
pMonitor->addDamage(&rg);
|
||||
pixman_region32_fini(&rg);
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderDragIcon(CMonitor* pMonitor, timespec* time) {
|
||||
if (!(g_pInputManager->m_sDrag.dragIcon && g_pInputManager->m_sDrag.iconMapped && g_pInputManager->m_sDrag.dragIcon->surface))
|
||||
return;
|
||||
@@ -875,7 +924,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
pMonitor->vecPosition = pMonitorRule->offset;
|
||||
|
||||
// loop over modes and choose an appropriate one.
|
||||
if (pMonitorRule->resolution != Vector2D()) {
|
||||
if (pMonitorRule->resolution != Vector2D() && pMonitorRule->resolution != Vector2D(-1,-1) && pMonitorRule->resolution != Vector2D(-1,-2)) {
|
||||
if (!wl_list_empty(&pMonitor->output->modes)) {
|
||||
wlr_output_mode* mode;
|
||||
bool found = false;
|
||||
@@ -908,6 +957,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
if (!found) {
|
||||
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
||||
pMonitor->vecSize = pMonitorRule->resolution;
|
||||
pMonitor->refreshRate = pMonitorRule->refreshRate;
|
||||
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
Debug::log(ERR, "Custom resolution FAILED, falling back to preferred");
|
||||
@@ -936,8 +986,95 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
} else {
|
||||
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
||||
pMonitor->vecSize = pMonitorRule->resolution;
|
||||
pMonitor->refreshRate = pMonitorRule->refreshRate;
|
||||
|
||||
Debug::log(LOG, "Setting custom mode for %s", pMonitor->output->name);
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
Debug::log(ERR, "Custom resolution FAILED, falling back to preferred");
|
||||
|
||||
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
|
||||
|
||||
if (!PREFERREDMODE) {
|
||||
Debug::log(ERR, "Monitor %s has NO PREFERRED MODE, and an INVALID one was requested: %ix%i@%2f", (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Preferred is valid
|
||||
wlr_output_set_mode(pMonitor->output, PREFERREDMODE);
|
||||
|
||||
Debug::log(ERR, "Monitor %s got an invalid requested mode: %ix%i@%2f, using the preferred one instead: %ix%i@%2f", pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f);
|
||||
|
||||
pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f;
|
||||
pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height);
|
||||
} else {
|
||||
Debug::log(LOG, "Set a custom mode %ix%i@%2f (mode not found in monitor modes)", (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate);
|
||||
}
|
||||
}
|
||||
} else if (pMonitorRule->resolution != Vector2D()) {
|
||||
if (!wl_list_empty(&pMonitor->output->modes)) {
|
||||
wlr_output_mode* mode;
|
||||
float currentWidth = 0;
|
||||
float currentHeight = 0;
|
||||
float currentRefresh = 0;
|
||||
bool success = false;
|
||||
|
||||
//(-1,-1) indicates a preference to refreshrate over resolution, (-1,-2) preference to resolution
|
||||
if(pMonitorRule->resolution == Vector2D(-1,-1)) {
|
||||
wl_list_for_each(mode, &pMonitor->output->modes, link) {
|
||||
if( ( mode->width >= currentWidth && mode->height >= currentHeight && mode->refresh >= ( currentRefresh - 1000.f ) ) || mode->refresh > ( currentRefresh + 3000.f ) ) {
|
||||
wlr_output_set_mode(pMonitor->output, mode);
|
||||
if (wlr_output_test(pMonitor->output)) {
|
||||
currentWidth = mode->width;
|
||||
currentHeight = mode->height;
|
||||
currentRefresh = mode->refresh;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wl_list_for_each(mode, &pMonitor->output->modes, link) {
|
||||
if( ( mode->width >= currentWidth && mode->height >= currentHeight && mode->refresh >= ( currentRefresh - 1000.f ) ) || ( mode->width > currentWidth && mode->height > currentHeight ) ) {
|
||||
wlr_output_set_mode(pMonitor->output, mode);
|
||||
if (wlr_output_test(pMonitor->output)) {
|
||||
currentWidth = mode->width;
|
||||
currentHeight = mode->height;
|
||||
currentRefresh = mode->refresh;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
Debug::log(LOG, "Monitor %s: REJECTED mode: %ix%i@%2f! Falling back to preferred.",
|
||||
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||
mode->width, mode->height, mode->refresh / 1000.f);
|
||||
|
||||
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
|
||||
|
||||
if (!PREFERREDMODE) {
|
||||
Debug::log(ERR, "Monitor %s has NO PREFERRED MODE, and an INVALID one was requested: %ix%i@%2f",
|
||||
(int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Preferred is valid
|
||||
wlr_output_set_mode(pMonitor->output, PREFERREDMODE);
|
||||
|
||||
Debug::log(ERR, "Monitor %s got an invalid requested mode: %ix%i@%2f, using the preferred one instead: %ix%i@%2f",
|
||||
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||
PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f);
|
||||
|
||||
pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f;
|
||||
pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height);
|
||||
} else {
|
||||
|
||||
Debug::log(LOG, "Monitor %s: Applying highest mode %ix%i@%2f.",
|
||||
pMonitor->output->name, (int)currentWidth, (int)currentHeight, (int)currentRefresh / 1000.f,
|
||||
mode->width, mode->height, mode->refresh / 1000.f);
|
||||
|
||||
pMonitor->refreshRate = currentRefresh / 1000.f;
|
||||
pMonitor->vecSize = Vector2D(currentWidth, currentHeight);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
|
||||
@@ -979,7 +1116,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
Debug::log(LOG, "Setting preferred mode for %s", pMonitor->output->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
wlr_output_set_transform(pMonitor->output, pMonitorRule->transform);
|
||||
pMonitor->transform = pMonitorRule->transform;
|
||||
@@ -1023,7 +1160,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
pMonitor->vecPosition = finalPos;
|
||||
}
|
||||
|
||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitor->vecPosition.x, (int)pMonitor->vecPosition.y);
|
||||
if (!pMonitor->isMirror())
|
||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitor->vecPosition.x, (int)pMonitor->vecPosition.y);
|
||||
|
||||
wlr_output_enable(pMonitor->output, true);
|
||||
|
||||
@@ -1036,6 +1174,9 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
// frame skip
|
||||
pMonitor->framesToSkip = 1;
|
||||
|
||||
// reload to fix mirrors
|
||||
g_pConfigManager->m_bWantsMonitorReload = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,7 @@ public:
|
||||
void damageBox(const int& x, const int& y, const int& w, const int& h);
|
||||
void damageRegion(pixman_region32_t*);
|
||||
void damageMonitor(CMonitor*);
|
||||
void damageMirrorsWith(CMonitor*, pixman_region32_t*);
|
||||
bool applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false);
|
||||
bool shouldRenderWindow(CWindow*, CMonitor*);
|
||||
bool shouldRenderWindow(CWindow*);
|
||||
|
@@ -38,7 +38,7 @@ void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
const auto WORKSPACEOFFSET = PWORKSPACE ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
||||
const auto WORKSPACEOFFSET = PWORKSPACE && !pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
||||
|
||||
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
|
||||
@@ -56,38 +56,26 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
if (m_pWindow->m_cRealShadowColor.col() == CColor(0, 0, 0, 0))
|
||||
return; // don't draw invisible shadows
|
||||
|
||||
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
||||
return;
|
||||
|
||||
static auto *const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||
static auto *const PSHADOWSIZE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_range")->intValue;
|
||||
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
static auto *const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
|
||||
static auto *const PSHADOWOFFSET = &g_pConfigManager->getConfigValuePtr("decoration:shadow_offset")->strValue;
|
||||
static auto *const PSHADOWOFFSET = &g_pConfigManager->getConfigValuePtr("decoration:shadow_offset")->vecValue;
|
||||
|
||||
if (*PSHADOWS != 1)
|
||||
return; // disabled
|
||||
|
||||
// get the real offset
|
||||
Vector2D offset;
|
||||
try {
|
||||
if (const auto SPACEPOS = PSHADOWOFFSET->find(' '); SPACEPOS != std::string::npos) {
|
||||
const auto X = PSHADOWOFFSET->substr(0, SPACEPOS);
|
||||
const auto Y = PSHADOWOFFSET->substr(SPACEPOS + 1);
|
||||
|
||||
if (isNumber(X, true) && isNumber(Y, true)) {
|
||||
offset = Vector2D(std::stof(X), std::stof(Y));
|
||||
}
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
return; // cannot parse
|
||||
}
|
||||
|
||||
const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ? 0 : (m_pWindow->m_sAdditionalConfigData.rounding == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding);
|
||||
|
||||
// update the extents
|
||||
m_seExtents = {{*PSHADOWSIZE + 2 - offset.x, *PSHADOWSIZE + 2 - offset.y}, {*PSHADOWSIZE + 2 + offset.x, *PSHADOWSIZE + 2 + offset.y}};
|
||||
m_seExtents = {{*PSHADOWSIZE + 2 - PSHADOWOFFSET->x, *PSHADOWSIZE + 2 - PSHADOWOFFSET->y}, {*PSHADOWSIZE + 2 + PSHADOWOFFSET->x, *PSHADOWSIZE + 2 + PSHADOWOFFSET->y}};
|
||||
|
||||
// draw the shadow
|
||||
wlr_box fullBox = {m_vLastWindowPos.x - m_seExtents.topLeft.x + 2, m_vLastWindowPos.y - m_seExtents.topLeft.y + 2, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x - 4, m_vLastWindowSize.y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y - 4};
|
||||
|
||||
|
||||
fullBox.x -= pMonitor->vecPosition.x;
|
||||
fullBox.y -= pMonitor->vecPosition.y;
|
||||
|
||||
@@ -108,7 +96,7 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
wlr_box windowBox = {m_vLastWindowPos.x - pMonitor->vecPosition.x, m_vLastWindowPos.y - pMonitor->vecPosition.y, m_vLastWindowSize.x, m_vLastWindowSize.y};
|
||||
|
||||
scaleBox(&windowBox, pMonitor->scale);
|
||||
|
||||
|
||||
if (windowBox.width < 1 || windowBox.height < 1) {
|
||||
glClearStencil(0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
|
@@ -22,7 +22,7 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
const auto WORKSPACEOFFSET = PWORKSPACE ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
||||
const auto WORKSPACEOFFSET = PWORKSPACE && !pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
||||
|
||||
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
||||
// we draw 3px above the window's border with 3px
|
||||
@@ -45,7 +45,7 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
||||
|
||||
// get the group info
|
||||
SLayoutMessageHeader header;
|
||||
header.pWindow = g_pCompositor->m_pLastWindow;
|
||||
header.pWindow = m_pWindow;
|
||||
|
||||
m_dwGroupMembers = std::any_cast<std::deque<CWindow*>>(g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "groupinfo"));
|
||||
|
||||
@@ -70,6 +70,9 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
if (barsToDraw < 1 || m_pWindow->m_bHidden || !g_pCompositor->windowValidMapped(m_pWindow))
|
||||
return;
|
||||
|
||||
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
||||
return;
|
||||
|
||||
const int PAD = 2; //2px
|
||||
|
||||
const int BARW = (m_vLastWindowSize.x - PAD * (barsToDraw - 1)) / barsToDraw;
|
||||
@@ -82,6 +85,8 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
||||
if (rect.width <= 0 || rect.height <= 0)
|
||||
break;
|
||||
|
||||
scaleBox(&rect, pMonitor->scale);
|
||||
|
||||
static auto *const PGROUPCOLACTIVE = &g_pConfigManager->getConfigValuePtr("dwindle:col.group_border_active")->intValue;
|
||||
static auto *const PGROUPCOLINACTIVE = &g_pConfigManager->getConfigValuePtr("dwindle:col.group_border")->intValue;
|
||||
|
||||
|
@@ -3,5 +3,5 @@
|
||||
#include "../../Window.hpp"
|
||||
|
||||
IHyprWindowDecoration::~IHyprWindowDecoration() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -42,7 +42,7 @@ void main() {
|
||||
vec4 pixColor = v_color;
|
||||
|
||||
bool done = false;
|
||||
|
||||
|
||||
// check for edges
|
||||
if (pixCoord[0] < topLeft[0]) {
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
@@ -88,4 +88,4 @@ void main() {
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
||||
)#";
|
||||
)#";
|
||||
|
@@ -59,7 +59,7 @@ void main() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
if (!done) {
|
||||
// distance to all straight bb borders
|
||||
float distanceT = pixCoord[1];
|
||||
float distanceB = fullSize[1] - pixCoord[1];
|
||||
@@ -79,4 +79,4 @@ void main() {
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
})#";
|
||||
})#";
|
||||
|
@@ -3,140 +3,38 @@
|
||||
#include <string>
|
||||
|
||||
inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVarName) -> std::string {
|
||||
return R"#(
|
||||
if (pixCoord[0] < topLeft[0]) {
|
||||
// we're close left
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
return R"#(
|
||||
|
||||
if (ignoreCorners == 1) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
// branchless baby!
|
||||
highp vec2 pixCoord = vec2(gl_FragCoord);
|
||||
pixCoord -= topLeft + fullSize * 0.5;
|
||||
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
|
||||
pixCoord -= fullSize * 0.5 - radius;
|
||||
|
||||
float topLeftDistance = distance(topLeft, pixCoord);
|
||||
if (pixCoord.x + pixCoord.y > radius) {
|
||||
|
||||
if (topLeftDistance > radius - 1.0) {
|
||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||
discard;
|
||||
return;
|
||||
} else if (primitiveMultisample == 1) {
|
||||
float distances = 0.0;
|
||||
if (distance(topLeft, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(topLeft, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(topLeft, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(topLeft, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
float dist = length(pixCoord);
|
||||
|
||||
if (distances == 0.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
if (dist > radius)
|
||||
discard;
|
||||
|
||||
distances = distances / 4.0;
|
||||
if (primitiveMultisample == 1 && dist > radius - 1.0) {
|
||||
float distances = 0.0;
|
||||
distances += float(length(pixCoord + vec2(0.25, 0.25)) < radius);
|
||||
distances += float(length(pixCoord + vec2(0.75, 0.25)) < radius);
|
||||
distances += float(length(pixCoord + vec2(0.25, 0.75)) < radius);
|
||||
distances += float(length(pixCoord + vec2(0.75, 0.75)) < radius);
|
||||
|
||||
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
|
||||
}
|
||||
}
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom
|
||||
if (distances == 0.0)
|
||||
discard;
|
||||
|
||||
if (ignoreCorners == 1) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
distances /= 4.0;
|
||||
|
||||
float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
|
||||
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
|
||||
}
|
||||
|
||||
if (topLeftDistance > radius - 1.0) {
|
||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||
discard;
|
||||
return;
|
||||
} else if (primitiveMultisample == 1) {
|
||||
float distances = 0.0;
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
|
||||
if (distances == 0.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
distances = distances / 4.0;
|
||||
|
||||
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pixCoord[0] > bottomRight[0]) {
|
||||
// we're close right
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
|
||||
if (ignoreCorners == 1) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
|
||||
|
||||
if (topLeftDistance > radius - 1.0) {
|
||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||
discard;
|
||||
return;
|
||||
} else if (primitiveMultisample == 1) {
|
||||
float distances = 0.0;
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
|
||||
if (distances == 0.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
distances = distances / 4.0;
|
||||
|
||||
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
|
||||
}
|
||||
}
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom
|
||||
|
||||
if (ignoreCorners == 1) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
float topLeftDistance = distance(bottomRight, pixCoord);
|
||||
|
||||
if (topLeftDistance > radius - 1.0) {
|
||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||
discard;
|
||||
return;
|
||||
} else if (primitiveMultisample == 1) {
|
||||
float distances = 0.0;
|
||||
if (distance(bottomRight, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(bottomRight, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(bottomRight, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
if (distance(bottomRight, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||
|
||||
if (distances == 0.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
distances = distances / 4.0;
|
||||
|
||||
)#" + colorVarName + R"#( = )#" + colorVarName + R"#( * distances;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)#";
|
||||
}
|
||||
)#";
|
||||
};
|
||||
|
||||
inline const std::string QUADVERTSRC = R"#(
|
||||
@@ -156,29 +54,22 @@ void main() {
|
||||
inline const std::string QUADFRAGSRC = R"#(
|
||||
precision mediump float;
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texcoord;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
void main() {
|
||||
if (radius == 0.0) {
|
||||
gl_FragColor = v_color;
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 pixColor = v_color;
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
vec4 pixColor = v_color;
|
||||
|
||||
if (radius > 0.0) {
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
gl_FragColor = pixColor;
|
||||
})#";
|
||||
|
||||
inline const std::string TEXVERTSRC = R"#(
|
||||
@@ -188,8 +79,8 @@ attribute vec2 texcoord;
|
||||
varying vec2 v_texcoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||
v_texcoord = texcoord;
|
||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||
v_texcoord = texcoord;
|
||||
})#";
|
||||
|
||||
inline const std::string TEXFRAGSRCRGBA = R"#(
|
||||
@@ -199,7 +90,6 @@ uniform sampler2D tex;
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
|
||||
@@ -209,29 +99,24 @@ uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||
R"#(
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
|
||||
inline const std::string TEXFRAGSRCRGBX = R"#(
|
||||
@@ -241,7 +126,6 @@ uniform sampler2D tex;
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
|
||||
@@ -251,29 +135,23 @@ uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
void main() {
|
||||
|
||||
if (discardOpaque == 1 && alpha == 1.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
if (discardOpaque == 1 && alpha == 1.0)
|
||||
discard;
|
||||
|
||||
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||
R"#(
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
|
||||
inline const std::string FRAGBLUR1 = R"#(
|
||||
@@ -286,13 +164,14 @@ uniform float radius;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
void main() {
|
||||
vec2 uv = v_texcoord * 2.0;
|
||||
vec2 uv = v_texcoord * 2.0;
|
||||
|
||||
vec4 sum = texture2D(tex, uv) * 4.0;
|
||||
sum += texture2D(tex, uv - halfpixel.xy * radius);
|
||||
sum += texture2D(tex, uv + halfpixel.xy * radius);
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||
sum += texture2D(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||
|
||||
gl_FragColor = sum / 8.0;
|
||||
}
|
||||
)#";
|
||||
@@ -307,10 +186,10 @@ uniform float radius;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
void main() {
|
||||
vec2 uv = v_texcoord / 2.0;
|
||||
vec2 uv = v_texcoord / 2.0;
|
||||
|
||||
vec4 sum = texture2D(tex, uv + vec2(-halfpixel.x * 2.0, 0.0) * radius);
|
||||
|
||||
|
||||
sum += texture2D(tex, uv + vec2(-halfpixel.x, halfpixel.y) * radius) * 2.0;
|
||||
sum += texture2D(tex, uv + vec2(0.0, halfpixel.y * 2.0) * radius);
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x, halfpixel.y) * radius) * 2.0;
|
||||
@@ -332,7 +211,6 @@ uniform samplerExternalOES texture0;
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
|
||||
@@ -342,27 +220,22 @@ uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
uniform int ignoreCorners;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
|
||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||
R"#(
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
gl_FragColor = pixColor * alpha;
|
||||
}
|
||||
)#";
|
||||
|
Submodule subprojects/wlroots updated: fd0b0276c9...2ad25b1460
Reference in New Issue
Block a user