6870b14a25670a09307761facae99d5213ffca19
- Author
- outfoxxed <outfoxxed@outfoxxed.me>
- Committer
- outfoxxed <outfoxxed@outfoxxed.me>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/CHANGELOG.md b/CHANGELOG.md
2index 27678e2d1dd1313f348da23796b37847f889a210..d663f21ff0eeef48f8803a29a49df6b6da212f03 100644
3--- a/CHANGELOG.md
4+++ b/CHANGELOG.md
5@@ -10,6 +10,7 @@
6 - Fixed bugs when moving nodes across workspaces.
7 - Added warp option to `hy3:movetoworkspace`.
8 - Fixed broken tab damage tracking (artifacts when tabs animate).
9+- Replaced `hy3:focustab mouse` with an unconditional hook that works better.
10
11 # hl0.46.0 and before
12
13diff --git a/README.md b/README.md
14index 57dfef4ac7c44497b6fea48dcafe36dcfc520870..18bb890daddf39554dfaf530903df5e8fffe94e3 100644
15--- a/README.md
16+++ b/README.md
17@@ -351,12 +351,7 @@ plugin {
18 - `tabnode` - raise focus to the nearest node under the tab
19 - `hy3:togglefocuslayer, [nowarp]` - toggle focus between tiled and floating layers
20 - `nowarp` - do not warp the mouse to the newly focused window
21- - `hy3:focustab <mouse | [l | r | left | right | index, <index>], [prioritize_hovered | require_hovered], [wrap]>`
22- - `mouse` - focus the tab under the mouse, works well with a non consuming bind, e.g.
23- ```conf
24- # binds hy3:focustab to lmb and still allows windows to receive clicks
25- bindn = , mouse:272, hy3:focustab, mouse
26- ```
27+ - `hy3:focustab [l | r | left | right | index, <index>], [prioritize_hovered | require_hovered], [wrap]`
28 - `l | r | left | right` - direction to change focus towards
29 - `index, <index>` - select the `index`th tab
30 - `prioritize_hovered` - prioritize the tab group under the mouse when multiple are stacked. use the lowest group if none is under the mouse.
31diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
32index 7c5ac6f63ba4358504d6e3a82df214e17ea6b40f..baf31510449e7af5915c8575dd046d2bda4cdb2c 100644
33--- a/src/Hy3Layout.cpp
34+++ b/src/Hy3Layout.cpp
35@@ -1,3 +1,5 @@
36+#include <any>
37+#include <cstdint>
38 #include <regex>
39 #include <set>
40
41@@ -6,6 +8,7 @@
42 #include <hyprland/src/config/ConfigManager.hpp>
43 #include <hyprland/src/desktop/DesktopTypes.hpp>
44 #include <hyprland/src/desktop/Workspace.hpp>
45+#include <hyprland/src/managers/LayoutManager.hpp>
46 #include <hyprland/src/managers/PointerManager.hpp>
47 #include <hyprland/src/managers/SeatManager.hpp>
48 #include <hyprland/src/managers/input/InputManager.hpp>
49@@ -18,8 +21,22 @@
50 #include "SelectionHook.hpp"
51 #include "TabGroup.hpp"
52 #include "globals.hpp"
53+#include "src/SharedDefs.hpp"
54 #include "src/desktop/WLSurface.hpp"
55 #include "src/desktop/Window.hpp"
56+#include "src/devices/IPointer.hpp"
57+
58+PHLWORKSPACE workspace_for_action(bool allow_fullscreen) {
59+ if (g_pLayoutManager->getCurrentLayout() != g_Hy3Layout.get()) return nullptr;
60+
61+ auto workspace = g_pCompositor->m_pLastMonitor->activeSpecialWorkspace;
62+ if (!valid(workspace)) workspace = g_pCompositor->m_pLastMonitor->activeWorkspace;
63+
64+ if (!valid(workspace)) return nullptr;
65+ if (!allow_fullscreen && workspace->m_bHasFullscreenWindow) return nullptr;
66+
67+ return workspace;
68+}
69
70 std::string operationWorkspaceForName(const std::string& workspace) {
71 typedef std::string (*PHYPRSPLIT_GET_WORKSPACE_FN)(const std::string& workspace);
72@@ -44,6 +61,7 @@ SP<HOOK_CALLBACK_FN> renderHookPtr;
73 SP<HOOK_CALLBACK_FN> windowTitleHookPtr;
74 SP<HOOK_CALLBACK_FN> urgentHookPtr;
75 SP<HOOK_CALLBACK_FN> tickHookPtr;
76+SP<HOOK_CALLBACK_FN> mouseButtonPtr;
77
78 bool performContainment(Hy3Node& node, bool contained, PHLWINDOW& window) {
79 if (node.data.is_group()) {
80@@ -705,14 +723,21 @@ void Hy3Layout::onEnable() {
81 }
82
83 renderHookPtr = HyprlandAPI::registerCallbackDynamic(PHANDLE, "render", &Hy3Layout::renderHook);
84+
85 windowTitleHookPtr = HyprlandAPI::registerCallbackDynamic(
86 PHANDLE,
87 "windowTitle",
88 &Hy3Layout::windowGroupUpdateRecursiveHook
89 );
90+
91 urgentHookPtr =
92 HyprlandAPI::registerCallbackDynamic(PHANDLE, "urgent", &Hy3Layout::windowGroupUrgentHook);
93+
94 tickHookPtr = HyprlandAPI::registerCallbackDynamic(PHANDLE, "tick", &Hy3Layout::tickHook);
95+
96+ mouseButtonPtr =
97+ HyprlandAPI::registerCallbackDynamic(PHANDLE, "mouseButton", &Hy3Layout::mouseButtonHook);
98+
99 selection_hook::enable();
100 }
101
102@@ -721,6 +746,7 @@ void Hy3Layout::onDisable() {
103 windowTitleHookPtr.reset();
104 urgentHookPtr.reset();
105 tickHookPtr.reset();
106+ mouseButtonPtr.reset();
107 selection_hook::disable();
108
109 for (auto& node: this->nodes) {
110@@ -1593,6 +1619,41 @@ void Hy3Layout::tickHook(void*, SCallbackInfo&, std::any) {
111 }
112 }
113
114+void Hy3Layout::mouseButtonHook(void*, SCallbackInfo& info, std::any data) {
115+ auto event = std::any_cast<IPointer::SButtonEvent>(data);
116+ if (event.state != 1 || event.button != 272) return;
117+
118+ auto ptr_surface_resource = g_pSeatManager->state.pointerFocus.lock();
119+ if (!ptr_surface_resource) return;
120+
121+ auto ptr_surface = CWLSurface::fromResource(ptr_surface_resource);
122+ if (!ptr_surface) return;
123+
124+ // non window-parented surface focused, cant have a tab
125+ auto window = ptr_surface->getWindow();
126+ if (!window || window->m_bIsFloating) return;
127+
128+ auto* node = g_Hy3Layout->getNodeFromWindow(window);
129+ if (!node) return;
130+
131+ auto* root = node;
132+ while (root->parent) root = root->parent;
133+
134+ Hy3Node* focus = nullptr;
135diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
136index 54937d6715594445dd3099d3ff72da3c3bbf5416..81c99d3f3cb1d398e378f92277bc367afb006a43 100644
137--- a/src/Hy3Layout.hpp
138+++ b/src/Hy3Layout.hpp
139@@ -74,6 +74,8 @@ enum class ExpandFullscreenOption {
140 MaximizeAsFullscreen,
141 };
142
143+PHLWORKSPACE workspace_for_action(bool allow_fullscreen = false);
144+
145 class Hy3Layout: public IHyprLayout {
146 public:
147 void onWindowCreated(PHLWINDOW, eDirection = DIRECTION_DEFAULT) override;
148@@ -155,6 +157,7 @@ public:
149 static void windowGroupUrgentHook(void*, SCallbackInfo&, std::any);
150 static void windowGroupUpdateRecursiveHook(void*, SCallbackInfo&, std::any);
151 static void tickHook(void*, SCallbackInfo&, std::any);
152+ static void mouseButtonHook(void*, SCallbackInfo&, std::any);
153
154 std::list<Hy3Node> nodes;
155 std::list<Hy3TabGroup> tab_groups;
156diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp
157index 0df213a21fac32d57f98c60b93eb58186fb776ac..6d54d304cb42c9ae377166d982293377dd07ed2e 100644
158--- a/src/dispatchers.cpp
159+++ b/src/dispatchers.cpp
160@@ -2,25 +2,12 @@
161
162 #include <hyprland/src/Compositor.hpp>
163 #include <hyprland/src/desktop/DesktopTypes.hpp>
164-#include <hyprland/src/managers/LayoutManager.hpp>
165 #include <hyprland/src/plugins/PluginAPI.hpp>
166 #include <hyprutils/string/String.hpp>
167
168 #include "dispatchers.hpp"
169 #include "globals.hpp"
170
171-PHLWORKSPACE workspace_for_action(bool allow_fullscreen = false) {
172- if (g_pLayoutManager->getCurrentLayout() != g_Hy3Layout.get()) return nullptr;
173-
174- auto workspace = g_pCompositor->m_pLastMonitor->activeSpecialWorkspace;
175- if (!valid(workspace)) workspace = g_pCompositor->m_pLastMonitor->activeWorkspace;
176-
177- if (!valid(workspace)) return nullptr;
178- if (!allow_fullscreen && workspace->m_bHasFullscreenWindow) return nullptr;
179-
180- return workspace;
181-}
182-
183 void dispatch_makegroup(std::string value) {
184 auto workspace = workspace_for_action();
185 if (!valid(workspace)) return;
186@@ -197,9 +184,6 @@ void dispatch_focustab(std::string value) {
187 if (!isNumber(args[i])) return;
188 index = std::stoi(args[i]);
189 Debug::log(LOG, "Focus index '%s' -> %d, errno: %d", args[i].c_str(), index, errno);
190- } else if (args[i] == "mouse") {
191- g_Hy3Layout->focusTab(workspace, TabFocus::MouseLocation, mouse, false, 0);
192- return;
193 } else return;
194
195 i++;