1435be18d41008fc1d52e16316faa49b752ecbbe
- Author
- outfoxxed <outfoxxed@outfoxxed.me>
- Committer
- outfoxxed <outfoxxed@outfoxxed.me>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/CMakeLists.txt b/CMakeLists.txt
2index 5ad5ce0cfeaecc65293900920107a56ee1928868..d886f50a8d00eb7ab5d2e6a046555b2fd004fea1 100644
3--- a/CMakeLists.txt
4+++ b/CMakeLists.txt
5@@ -15,7 +15,9 @@ pkg_check_modules(DEPS REQUIRED hyprland pixman-1 libdrm pango pangocairo)
6
7 add_library(hy3 SHARED
8 src/main.cpp
9+ src/dispatchers.cpp
10 src/Hy3Layout.cpp
11+ src/Hy3Node.cpp
12 src/TabGroup.cpp
13 src/SelectionHook.cpp
14 )
15diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
16index a73796d897d6fd3021409b2a26f980573bc7036d..02f1e33dc1c435db573141e58dc6cc4379563f37 100644
17--- a/src/Hy3Layout.cpp
18+++ b/src/Hy3Layout.cpp
19@@ -1,1487 +1,1170 @@
20-#include "Hy3Layout.hpp"
21-#include "globals.hpp"
22-#include "SelectionHook.hpp"
23+#include <sstream>
24
25 #include <hyprland/src/Compositor.hpp>
26 #include <hyprland/src/plugins/PluginAPI.hpp>
27
28-#include <sstream>
29-
30-void errorNotif() {
31- HyprlandAPI::addNotificationV2(
32- PHANDLE,
33- {
34- {"text", "Something has gone very wrong. Check the log for details."},
35- {"time", (uint64_t) 10000},
36- {"color", CColor(1.0, 0.0, 0.0, 1.0)},
37- {"icon", ICON_ERROR},
38- }
39- );
40-}
41-
42-Hy3GroupData::Hy3GroupData(Hy3GroupLayout layout): layout(layout) {}
43+#include "globals.hpp"
44+#include "Hy3Layout.hpp"
45+#include "SelectionHook.hpp"
46
47-Hy3GroupData::Hy3GroupData(Hy3GroupData&& from) {
48- this->layout = from.layout;
49- this->children = std::move(from.children);
50- this->group_focused = from.group_focused;
51- this->focused_child = from.focused_child;
52- from.focused_child = nullptr;
53- this->tab_bar = from.tab_bar;
54- from.tab_bar = nullptr;
55-}
56+std::unique_ptr<HOOK_CALLBACK_FN> renderHookPtr
57+ = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::renderHook);
58+std::unique_ptr<HOOK_CALLBACK_FN> windowTitleHookPtr
59+ = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::windowGroupUpdateRecursiveHook);
60+std::unique_ptr<HOOK_CALLBACK_FN> urgentHookPtr
61+ = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::windowGroupUrgentHook);
62+std::unique_ptr<HOOK_CALLBACK_FN> tickHookPtr
63+ = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::tickHook);
64
65-Hy3GroupData::~Hy3GroupData() {
66- if (this->tab_bar != nullptr) this->tab_bar->bar.beginDestroy();
67-}
68+void Hy3Layout::onWindowCreatedTiling(CWindow* window) {
69+ if (window->m_bIsFloating) return;
70
71-Hy3NodeData::Hy3NodeData(): Hy3NodeData((CWindow*) nullptr) {}
72+ auto* existing = this->getNodeFromWindow(window);
73+ if (existing != nullptr) {
74+ Debug::log(
75+ WARN,
76+ "Attempted to add a window(%p) that is already tiled(as %p) to the "
77+ "layout",
78+ window,
79+ existing
80+ );
81+ return;
82+ }
83
84-Hy3NodeData::Hy3NodeData(CWindow* window): type(Hy3NodeType::Window) { this->as_window = window; }
85+ auto* monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID);
86
87-Hy3NodeData::Hy3NodeData(Hy3GroupData group): type(Hy3NodeType::Group) {
88- new (&this->as_group) Hy3GroupData(std::move(group));
89-}
90+ Hy3Node* opening_into;
91+ Hy3Node* opening_after = nullptr;
92
93-Hy3NodeData::Hy3NodeData(Hy3GroupLayout layout): Hy3NodeData(Hy3GroupData(layout)) {}
94+ if (monitor->activeWorkspace != -1) {
95+ auto* root = this->getWorkspaceRootGroup(monitor->activeWorkspace);
96
97-Hy3NodeData::~Hy3NodeData() {
98- switch (this->type) {
99- case Hy3NodeType::Window: break;
100- case Hy3NodeType::Group:
101- this->as_group.~Hy3GroupData();
102+ if (root != nullptr) {
103+ opening_after = root->getFocusedNode();
104
105- // who ever thought calling the dtor after a move was a good idea?
106- this->type = Hy3NodeType::Window;
107- break;
108+ // opening_after->parent cannot be nullptr
109+ if (opening_after == root) {
110+ opening_after = root->data.as_group.focused_child;
111+ }
112+ }
113 }
114-}
115
116-Hy3NodeData::Hy3NodeData(Hy3NodeData&& from): type(from.type) {
117- Debug::log(
118- LOG,
119diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
120index bc4e6c6e4941d96dc9be5051f089b956f24bb3d4..d6d4186a3dd2128a53d03be764a778d86f88aff2 100644
121--- a/src/Hy3Layout.hpp
122+++ b/src/Hy3Layout.hpp
123@@ -1,24 +1,13 @@
124 #pragma once
125
126-#include <hyprland/src/layout/IHyprLayout.hpp>
127-#include <list>
128-
129-struct Hy3Node;
130-#include "TabGroup.hpp"
131-
132 class Hy3Layout;
133-struct Hy3Node;
134
135-enum class Hy3GroupLayout {
136- SplitH,
137- SplitV,
138- Tabbed,
139-};
140+#include <list>
141
142-enum class Hy3NodeType {
143- Window,
144- Group,
145-};
146+#include <hyprland/src/layout/IHyprLayout.hpp>
147+
148+#include "Hy3Node.hpp"
149+#include "TabGroup.hpp"
150
151 enum class ShiftDirection {
152 Left,
153@@ -49,93 +38,6 @@ enum class TabFocusMousePriority {
154 Require,
155 };
156
157-struct Hy3GroupData {
158- Hy3GroupLayout layout = Hy3GroupLayout::SplitH;
159- std::list<Hy3Node*> children;
160- bool group_focused = true;
161- Hy3Node* focused_child = nullptr;
162- Hy3TabGroup* tab_bar = nullptr;
163-
164- bool hasChild(Hy3Node* child);
165-
166- Hy3GroupData(Hy3GroupLayout layout);
167- ~Hy3GroupData();
168-
169-private:
170- Hy3GroupData(Hy3GroupData&&);
171- Hy3GroupData(const Hy3GroupData&) = delete;
172-
173- friend class Hy3NodeData;
174-};
175-
176-class Hy3NodeData {
177-public:
178- Hy3NodeType type;
179- union {
180- Hy3GroupData as_group;
181- CWindow* as_window;
182- };
183-
184- bool operator==(const Hy3NodeData&) const;
185-
186- Hy3NodeData();
187- ~Hy3NodeData();
188- Hy3NodeData(CWindow* window);
189- Hy3NodeData(Hy3GroupLayout layout);
190- Hy3NodeData& operator=(CWindow*);
191- Hy3NodeData& operator=(Hy3GroupLayout);
192-
193- // private: - I give up, C++ wins
194- Hy3NodeData(Hy3GroupData);
195- Hy3NodeData(Hy3NodeData&&);
196- Hy3NodeData& operator=(Hy3NodeData&&);
197-};
198-
199-struct Hy3Node {
200- Hy3Node* parent = nullptr;
201- Hy3NodeData data;
202- Vector2D position;
203- Vector2D size;
204- Vector2D gap_pos_offset;
205- Vector2D gap_size_offset;
206- float size_ratio = 1.0;
207- int workspace_id = -1;
208- bool hidden = false;
209- bool valid = true;
210- Hy3Layout* layout = nullptr;
211-
212- void recalcSizePosRecursive(bool no_animation = false);
213- std::string debugNode();
214- void markFocused();
215- void focus();
216- bool focusWindow();
217- void raiseToTop();
218- Hy3Node* getFocusedNode();
219- void updateDecos();
220- void setHidden(bool);
221- void updateTabBar(bool no_animation = false);
222- void updateTabBarRecursive();
223diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp
224new file mode 100644
225index 0000000000000000000000000000000000000000..7264cdf55c73d7d191f4993f082b634dad665a09
226--- /dev/null
227+++ b/src/Hy3Node.cpp
228@@ -0,0 +1,680 @@
229+#include <hyprland/src/Compositor.hpp>
230+#include <hyprland/src/plugins/PluginAPI.hpp>
231+
232+#include "globals.hpp"
233+#include "Hy3Node.hpp"
234+
235+// Hy3GroupData //
236+
237+Hy3GroupData::Hy3GroupData(Hy3GroupLayout layout): layout(layout) {}
238+
239+Hy3GroupData::Hy3GroupData(Hy3GroupData&& from) {
240+ this->layout = from.layout;
241+ this->children = std::move(from.children);
242+ this->group_focused = from.group_focused;
243+ this->focused_child = from.focused_child;
244+ from.focused_child = nullptr;
245+ this->tab_bar = from.tab_bar;
246+ from.tab_bar = nullptr;
247+}
248+
249+Hy3GroupData::~Hy3GroupData() {
250+ if (this->tab_bar != nullptr) this->tab_bar->bar.beginDestroy();
251+}
252+
253+bool Hy3GroupData::hasChild(Hy3Node* node) {
254+ Debug::log(LOG, "Searching for child %p of %p", this, node);
255+ for (auto child: this->children) {
256+ if (child == node) return true;
257+
258+ if (child->data.type == Hy3NodeType::Group) {
259+ if (child->data.as_group.hasChild(node)) return true;
260+ }
261+ }
262+
263+ return false;
264+}
265+
266+// Hy3NodeData //
267+
268+Hy3NodeData::Hy3NodeData(): Hy3NodeData((CWindow*) nullptr) {}
269+
270+Hy3NodeData::Hy3NodeData(CWindow* window): type(Hy3NodeType::Window) { this->as_window = window; }
271+
272+Hy3NodeData::Hy3NodeData(Hy3GroupLayout layout): Hy3NodeData(Hy3GroupData(layout)) {}
273+
274+Hy3NodeData::Hy3NodeData(Hy3GroupData group): type(Hy3NodeType::Group) {
275+ new (&this->as_group) Hy3GroupData(std::move(group));
276+}
277+
278+Hy3NodeData::Hy3NodeData(Hy3NodeData&& from): type(from.type) {
279+ Debug::log(
280+ LOG,
281+ "Move CTor type matches? %d is group? %d",
282+ this->type == from.type,
283+ this->type == Hy3NodeType::Group
284+ );
285+
286+ switch (from.type) {
287+ case Hy3NodeType::Window: this->as_window = from.as_window; break;
288+ case Hy3NodeType::Group: new (&this->as_group) Hy3GroupData(std::move(from.as_group)); break;
289+ }
290+}
291+
292+Hy3NodeData::~Hy3NodeData() {
293+ switch (this->type) {
294+ case Hy3NodeType::Window: break;
295+ case Hy3NodeType::Group:
296+ this->as_group.~Hy3GroupData();
297+
298+ // who ever thought calling the dtor after a move was a good idea?
299+ this->type = Hy3NodeType::Window;
300+ break;
301+ }
302+}
303+
304+Hy3NodeData& Hy3NodeData::operator=(CWindow* window) {
305+ *this = Hy3NodeData(window);
306+
307+ return *this;
308+}
309+
310+Hy3NodeData& Hy3NodeData::operator=(Hy3GroupLayout layout) {
311+ *this = Hy3NodeData(layout);
312+
313+ return *this;
314+}
315+
316+Hy3NodeData& Hy3NodeData::operator=(Hy3NodeData&& from) {
317+ Debug::log(
318+ LOG,
319+ "operator= type matches? %d is group? %d",
320+ this->type == from.type,
321+ this->type == Hy3NodeType::Group
322+ );
323+
324+ if (this->type == Hy3NodeType::Group) {
325+ this->as_group.~Hy3GroupData();
326+ }
327+
328diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp
329new file mode 100644
330index 0000000000000000000000000000000000000000..449486a4159bd65f3001400d4f71a5dc07fc5acf
331--- /dev/null
332+++ b/src/Hy3Node.hpp
333@@ -0,0 +1,112 @@
334+#pragma once
335+
336+struct Hy3Node;
337+enum class Hy3GroupLayout;
338+
339+#include <list>
340+
341+#include <hyprland/src/Window.hpp>
342+
343+#include "Hy3Layout.hpp"
344+#include "TabGroup.hpp"
345+
346+enum class Hy3GroupLayout {
347+ SplitH,
348+ SplitV,
349+ Tabbed,
350+};
351+
352+enum class Hy3NodeType {
353+ Window,
354+ Group,
355+};
356+
357+struct Hy3GroupData {
358+ Hy3GroupLayout layout = Hy3GroupLayout::SplitH;
359+ std::list<Hy3Node*> children;
360+ bool group_focused = true;
361+ Hy3Node* focused_child = nullptr;
362+ Hy3TabGroup* tab_bar = nullptr;
363+
364+ Hy3GroupData(Hy3GroupLayout layout);
365+ ~Hy3GroupData();
366+
367+ bool hasChild(Hy3Node* child);
368+
369+private:
370+ Hy3GroupData(Hy3GroupData&&);
371+ Hy3GroupData(const Hy3GroupData&) = delete;
372+
373+ friend class Hy3NodeData;
374+};
375+
376+class Hy3NodeData {
377+public:
378+ Hy3NodeType type;
379+ union {
380+ Hy3GroupData as_group;
381+ CWindow* as_window;
382+ };
383+
384+ Hy3NodeData();
385+ Hy3NodeData(CWindow* window);
386+ Hy3NodeData(Hy3GroupLayout layout);
387+ ~Hy3NodeData();
388+
389+ Hy3NodeData& operator=(CWindow*);
390+ Hy3NodeData& operator=(Hy3GroupLayout);
391+
392+ bool operator==(const Hy3NodeData&) const;
393+
394+ // private: - I give up, C++ wins
395+ Hy3NodeData(Hy3GroupData);
396+ Hy3NodeData(Hy3NodeData&&);
397+ Hy3NodeData& operator=(Hy3NodeData&&);
398+};
399+
400+struct Hy3Node {
401+ Hy3Node* parent = nullptr;
402+ Hy3NodeData data;
403+ Vector2D position;
404+ Vector2D size;
405+ Vector2D gap_pos_offset;
406+ Vector2D gap_size_offset;
407+ float size_ratio = 1.0;
408+ int workspace_id = -1;
409+ bool hidden = false;
410+ Hy3Layout* layout = nullptr;
411+
412+ bool operator==(const Hy3Node&) const;
413+
414+ void focus();
415+ bool focusWindow();
416+ void markFocused();
417+ void raiseToTop();
418+ Hy3Node* getFocusedNode();
419+ bool isIndirectlyFocused();
420+
421+ void recalcSizePosRecursive(bool no_animation = false);
422+ void updateTabBar(bool no_animation = false);
423+ void updateTabBarRecursive();
424+ void updateDecos();
425+
426+ std::string getTitle();
427+ bool isUrgent();
428+ void setHidden(bool);
429+
430+ Hy3Node* findNodeForTabGroup(Hy3TabGroup&);
431+ void appendAllWindows(std::vector<CWindow*>&);
432+ std::string debugNode();
433diff --git a/src/SelectionHook.cpp b/src/SelectionHook.cpp
434index bbf63ae1a4a7c41410ffdad35850ef11f94b1a98..a99f0b6fa7806ecfe79ce6976c903944612cab77 100644
435--- a/src/SelectionHook.cpp
436+++ b/src/SelectionHook.cpp
437@@ -1,7 +1,8 @@
438-#include "globals.hpp"
439 #include <hyprland/src/Compositor.hpp>
440 #include <hyprland/src/plugins/PluginAPI.hpp>
441
442+#include "globals.hpp"
443+
444 namespace selection_hook {
445 inline CFunctionHook* g_LastSelectionHook = nullptr;
446
447diff --git a/src/TabGroup.cpp b/src/TabGroup.cpp
448index e0942eb013a32086c90c3e4ee6e530feb135e281..89fd18ceafd3fe9c78066c891ed677abe950ac52 100644
449--- a/src/TabGroup.cpp
450+++ b/src/TabGroup.cpp
451@@ -1,7 +1,3 @@
452-#include "TabGroup.hpp"
453-#include "globals.hpp"
454-#include "Hy3Layout.hpp"
455-
456 #include <cairo/cairo.h>
457 #include <hyprland/src/Compositor.hpp>
458 #include <hyprland/src/helpers/Color.hpp>
459@@ -10,6 +6,10 @@
460 #include <pango/pangocairo.h>
461 #include <pixman.h>
462
463+#include "globals.hpp"
464+#include "Hy3Layout.hpp"
465+#include "TabGroup.hpp"
466+
467 Hy3TabBarEntry::Hy3TabBarEntry(Hy3TabBar& tab_bar, Hy3Node& node): tab_bar(tab_bar), node(node) {
468 this->focused.create(
469 AVARTYPE_FLOAT,
470diff --git a/src/TabGroup.hpp b/src/TabGroup.hpp
471index 3e016febcdfe86be435d6a2bd240b2e1f34ffa58..04952762464e522aed0540cecce0d72c3a37480c 100644
472--- a/src/TabGroup.hpp
473+++ b/src/TabGroup.hpp
474@@ -1,14 +1,15 @@
475 #pragma once
476
477-#include <hyprland/src/Compositor.hpp>
478+class Hy3TabGroup;
479+class Hy3TabBar;
480+
481 #include <list>
482 #include <memory>
483 #include <vector>
484
485-class Hy3TabGroup;
486-class Hy3TabBar;
487+#include <hyprland/src/render/Texture.hpp>
488
489-#include "Hy3Layout.hpp"
490+#include "Hy3Node.hpp"
491
492 struct Hy3TabBarEntry {
493 std::string window_title;
494diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp
495new file mode 100644
496index 0000000000000000000000000000000000000000..5937bd79ca687c0f307a660f7b81dd55a558e370
497--- /dev/null
498+++ b/src/dispatchers.cpp
499@@ -0,0 +1,147 @@
500+#include <optional>
501+
502+#include <hyprland/src/Compositor.hpp>
503+#include <hyprland/src/plugins/PluginAPI.hpp>
504+
505+#include "dispatchers.hpp"
506+#include "globals.hpp"
507+
508+int workspace_for_action() {
509+ if (g_pLayoutManager->getCurrentLayout() != g_Hy3Layout.get()) return -1;
510+
511+ int workspace_id = g_pCompositor->m_pLastMonitor->activeWorkspace;
512+
513+ if (workspace_id == -1) return -1;
514+ auto* workspace = g_pCompositor->getWorkspaceByID(workspace_id);
515+ if (workspace == nullptr) return -1;
516+ if (workspace->m_bHasFullscreenWindow) return -1;
517+
518+ return workspace_id;
519+}
520+
521+void dispatch_makegroup(std::string arg) {
522+ int workspace = workspace_for_action();
523+ if (workspace == -1) return;
524+
525+ if (arg == "h") {
526+ g_Hy3Layout->makeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitH);
527+ } else if (arg == "v") {
528+ g_Hy3Layout->makeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitV);
529+ } else if (arg == "tab") {
530+ g_Hy3Layout->makeGroupOnWorkspace(workspace, Hy3GroupLayout::Tabbed);
531+ } else if (arg == "opposite") {
532+ g_Hy3Layout->makeOppositeGroupOnWorkspace(workspace);
533+ }
534+}
535+
536+std::optional<ShiftDirection> parseShiftArg(std::string arg) {
537+ if (arg == "l" || arg == "left") return ShiftDirection::Left;
538+ else if (arg == "r" || arg == "right") return ShiftDirection::Right;
539+ else if (arg == "u" || arg == "up") return ShiftDirection::Up;
540+ else if (arg == "d" || arg == "down") return ShiftDirection::Down;
541+ else return {};
542+}
543+
544+void dispatch_movewindow(std::string value) {
545+ int workspace = workspace_for_action();
546+ if (workspace == -1) return;
547+
548+ auto args = CVarList(value);
549+
550+ if (auto shift = parseShiftArg(args[0])) {
551+ auto once = args[1] == "once";
552+ g_Hy3Layout->shiftWindow(workspace, shift.value(), once);
553+ }
554+}
555+
556+void dispatch_movefocus(std::string value) {
557+ int workspace = workspace_for_action();
558+ if (workspace == -1) return;
559+
560+ auto args = CVarList(value);
561+
562+ if (auto shift = parseShiftArg(args[0])) {
563+ g_Hy3Layout->shiftFocus(workspace, shift.value(), args[1] == "visible");
564+ }
565+}
566+
567+void dispatch_changefocus(std::string arg) {
568+ int workspace = workspace_for_action();
569+ if (workspace == -1) return;
570+
571+ if (arg == "top") g_Hy3Layout->changeFocus(workspace, FocusShift::Top);
572+ else if (arg == "bottom") g_Hy3Layout->changeFocus(workspace, FocusShift::Bottom);
573+ else if (arg == "raise") g_Hy3Layout->changeFocus(workspace, FocusShift::Raise);
574+ else if (arg == "lower") g_Hy3Layout->changeFocus(workspace, FocusShift::Lower);
575+ else if (arg == "tab") g_Hy3Layout->changeFocus(workspace, FocusShift::Tab);
576+ else if (arg == "tabnode") g_Hy3Layout->changeFocus(workspace, FocusShift::TabNode);
577+}
578+
579+void dispatch_focustab(std::string value) {
580+ int workspace = workspace_for_action();
581+ if (workspace == -1) return;
582+
583+ auto i = 0;
584+ auto args = CVarList(value);
585+
586+ TabFocus focus;
587+ auto mouse = TabFocusMousePriority::Ignore;
588+ bool wrap_scroll = false;
589+ int index = 0;
590+
591+ if (args[i] == "l" || args[i] == "left") focus = TabFocus::Left;
592+ else if (args[i] == "r" || args[i] == "right") focus = TabFocus::Right;
593+ else if (args[i] == "index") {
594+ i++;
595+ focus = TabFocus::Index;
596+ if (!isNumber(args[i])) return;
597+ index = std::stoi(args[i]);
598+ Debug::log(LOG, "Focus index '%s' -> %d, errno: %d", args[i].c_str(), index, errno);
599diff --git a/src/dispatchers.hpp b/src/dispatchers.hpp
600new file mode 100644
601index 0000000000000000000000000000000000000000..be858c46edb38a6e0de9c9901dc9045e050747a6
602--- /dev/null
603+++ b/src/dispatchers.hpp
604@@ -0,0 +1,3 @@
605+#pragma once
606+
607+void registerDispatchers();
608diff --git a/src/globals.hpp b/src/globals.hpp
609index ed7522fef96055c56c7629d770f20e9b46a4c2e5..856f1936573d8add87f9c7d1b76e9e2a9e515a97 100644
610--- a/src/globals.hpp
611+++ b/src/globals.hpp
612@@ -3,3 +3,15 @@
613
614 inline HANDLE PHANDLE = nullptr;
615 inline std::unique_ptr<Hy3Layout> g_Hy3Layout;
616+
617+inline void errorNotif() {
618+ HyprlandAPI::addNotificationV2(
619+ PHANDLE,
620+ {
621+ {"text", "Something has gone very wrong. Check the log for details."},
622+ {"time", (uint64_t) 10000},
623+ {"color", CColor(1.0, 0.0, 0.0, 1.0)},
624+ {"icon", ICON_ERROR},
625+ }
626+ );
627+}
628diff --git a/src/main.cpp b/src/main.cpp
629index 3b5b322aac93de0fba4453bdfcfba33a34b63690..85e91e5bc96965185fd034a72ce858af5805642d 100644
630--- a/src/main.cpp
631+++ b/src/main.cpp
632@@ -3,155 +3,12 @@
633 #include <hyprland/src/Compositor.hpp>
634 #include <hyprland/src/plugins/PluginAPI.hpp>
635
636+#include "dispatchers.hpp"
637 #include "globals.hpp"
638 #include "SelectionHook.hpp"
639
640 APICALL EXPORT std::string PLUGIN_API_VERSION() { return HYPRLAND_API_VERSION; }
641
642-// return a window if a window action makes sense now
643-CWindow* window_for_action() {
644- if (g_pLayoutManager->getCurrentLayout() != g_Hy3Layout.get()) return nullptr;
645-
646- auto* window = g_pCompositor->m_pLastWindow;
647-
648- if (!window) return nullptr;
649-
650- const auto workspace = g_pCompositor->getWorkspaceByID(window->m_iWorkspaceID);
651- if (workspace->m_bHasFullscreenWindow) return nullptr;
652-
653- return window;
654-}
655-
656-int workspace_for_action() {
657- if (g_pLayoutManager->getCurrentLayout() != g_Hy3Layout.get()) return -1;
658-
659- int workspace_id = g_pCompositor->m_pLastMonitor->activeWorkspace;
660-
661- if (workspace_id == -1) return -1;
662- auto* workspace = g_pCompositor->getWorkspaceByID(workspace_id);
663- if (workspace == nullptr) return -1;
664- if (workspace->m_bHasFullscreenWindow) return -1;
665-
666- return workspace_id;
667-}
668-
669-void dispatch_makegroup(std::string arg) {
670- int workspace = workspace_for_action();
671- if (workspace == -1) return;
672-
673- if (arg == "h") {
674- g_Hy3Layout->makeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitH);
675- } else if (arg == "v") {
676- g_Hy3Layout->makeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitV);
677- } else if (arg == "tab") {
678- g_Hy3Layout->makeGroupOnWorkspace(workspace, Hy3GroupLayout::Tabbed);
679- } else if (arg == "opposite") {
680- g_Hy3Layout->makeOppositeGroupOnWorkspace(workspace);
681- }
682-}
683-
684-std::optional<ShiftDirection> parseShiftArg(std::string arg) {
685- if (arg == "l" || arg == "left") return ShiftDirection::Left;
686- else if (arg == "r" || arg == "right") return ShiftDirection::Right;
687- else if (arg == "u" || arg == "up") return ShiftDirection::Up;
688- else if (arg == "d" || arg == "down") return ShiftDirection::Down;
689- else return {};
690-}
691-
692-void dispatch_movewindow(std::string value) {
693- int workspace = workspace_for_action();
694- if (workspace == -1) return;
695-
696- auto args = CVarList(value);
697-
698- if (auto shift = parseShiftArg(args[0])) {
699- auto once = args[1] == "once";
700- g_Hy3Layout->shiftWindow(workspace, shift.value(), once);
701- }
702-}
703-
704-void dispatch_movefocus(std::string value) {
705- int workspace = workspace_for_action();
706- if (workspace == -1) return;
707-
708- auto args = CVarList(value);
709-
710- if (auto shift = parseShiftArg(args[0])) {
711- g_Hy3Layout->shiftFocus(workspace, shift.value(), args[1] == "visible");
712- }
713-}
714-
715-void dispatch_changefocus(std::string arg) {
716- int workspace = workspace_for_action();
717- if (workspace == -1) return;
718-
719- if (arg == "top") g_Hy3Layout->changeFocus(workspace, FocusShift::Top);
720- else if (arg == "bottom") g_Hy3Layout->changeFocus(workspace, FocusShift::Bottom);
721- else if (arg == "raise") g_Hy3Layout->changeFocus(workspace, FocusShift::Raise);
722- else if (arg == "lower") g_Hy3Layout->changeFocus(workspace, FocusShift::Lower);
723- else if (arg == "tab") g_Hy3Layout->changeFocus(workspace, FocusShift::Tab);
724- else if (arg == "tabnode") g_Hy3Layout->changeFocus(workspace, FocusShift::TabNode);
725-}
726-
727-void dispatch_focustab(std::string value) {
728- int workspace = workspace_for_action();
729- if (workspace == -1) return;
730-
731- auto i = 0;