ea43c609916945d913ff2278c55269009b33881c
- Author
- outfoxxed <outfoxxed@outfoxxed.me>
- Committer
- outfoxxed <outfoxxed@outfoxxed.me>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/README.md b/README.md
2index c1eed0c24ab4fd6297628a1b26aeacd683f6d149..492151308c9f72cbc7bc63383891eab338ad5a02 100644
3--- a/README.md
4+++ b/README.md
5@@ -94,7 +94,13 @@ plugin {
6 - `hy3:movefocus, <l | u | d | r | left | down | up | right>` - move the focus left, up, down, or right
7 - `hy3:movewindow, <l | u | d | r | left | down | up | right> [, once]` - move a window left, up, down, or right
8 - `once` - only move directly to the neighboring group, without moving into any of its subgroups
9- - `hy3:raisefocus` - raise the active focus one level
10+ - `hy3:changefocus <top | bottom | raise | lower | tab | tabnode>`
11+ - `top` - focus all nodes in the workspace
12+ - `bottom` - focus the single root selection window
13+ - `raise` - raise focus one level
14+ - `lower` - lower focus one level
15+ - `tab` - raise focus to the nearest tab
16+ - `tabnode` - raise focus to the nearest node under the tab
17 - `hy3:debugnodes` - print the node tree into the hyprland log
18
19 ## Installing
20diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
21index dde6aece2b020c5847a9dcb100b6592196898113..e984437f7f37b8287ed9dc7a0727d108325faecf 100644
22--- a/src/Hy3Layout.cpp
23+++ b/src/Hy3Layout.cpp
24@@ -264,7 +264,9 @@ bool Hy3Node::isIndirectlyFocused() {
25 Hy3Node* node = this;
26
27 while (node->parent != nullptr) {
28- if (node->parent->data.as_group.focused_child != node) return false;
29+ if (!node->parent->data.as_group.group_focused
30+ && node->parent->data.as_group.focused_child != node)
31+ return false;
32 node = node->parent;
33 }
34
35@@ -295,17 +297,23 @@ std::string Hy3Node::getTitle() {
36 return "";
37 }
38
39+void markGroupFocusedRecursive(Hy3GroupData& group) {
40+ group.group_focused = true;
41+ for (auto& child: group.children) {
42+ if (child->data.type == Hy3NodeData::Group) markGroupFocusedRecursive(child->data.as_group);
43+ }
44+}
45+
46 void Hy3Node::markFocused() {
47 Hy3Node* node = this;
48
49 // undo decos for root focus
50 auto* root = node;
51 while (root->parent != nullptr) root = root->parent;
52- auto* oldfocus = root->getFocusedNode();
53
54 // update focus
55 if (this->data.type == Hy3NodeData::Group) {
56- this->data.as_group.group_focused = true;
57+ markGroupFocusedRecursive(this->data.as_group);
58 }
59
60 auto* node2 = node;
61@@ -315,26 +323,7 @@ void Hy3Node::markFocused() {
62 node2 = node2->parent;
63 }
64
65- while (node->parent != nullptr) {
66- node->parent->updateTabBar();
67- node = node->parent;
68- }
69-
70- while (node2->parent != nullptr) {
71- node2->parent->data.as_group.focused_child = node2;
72- node2->parent->data.as_group.group_focused = false;
73- node2->parent->updateTabBar();
74- node2 = node2->parent;
75- }
76-
77- if (oldfocus != nullptr) {
78- oldfocus->updateDecos();
79-
80- while (oldfocus != nullptr) {
81- oldfocus->updateTabBar();
82- oldfocus = oldfocus->parent;
83- }
84- }
85+ root->updateDecos();
86 }
87
88 void Hy3Node::focus() {
89@@ -615,6 +604,8 @@ void Hy3Node::updateDecos() {
90 for (auto* child: this->data.as_group.children) {
91 child->updateDecos();
92 }
93+
94+ this->updateTabBar();
95 }
96 }
97
98@@ -1616,21 +1607,62 @@ Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift,
99 return nullptr;
100 }
101
102-void Hy3Layout::raiseFocus(int workspace) {
103+void Hy3Layout::changeFocus(int workspace, FocusShift shift) {
104 auto* node = this->getWorkspaceFocusedNode(workspace);
105 if (node == nullptr) return;
106
107- if (node->parent != nullptr) {
108- node->parent->focus();
109- node->parent->updateDecos();
110- } else {
111- // trace focus as far as possible
112- while (node->data.type == Hy3NodeData::Group && node->data.as_group.focused_child != nullptr) {
113- node = node->data.as_group.focused_child;
114+ switch (shift) {
115+ case FocusShift::Bottom: goto bottom;
116+ case FocusShift::Top:
117+ while (node->parent != nullptr) {
118+ node = node->parent;
119 }
120
121 node->focus();
122+ return;
123+ case FocusShift::Raise:
124diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
125index 5e1bd4bca90f3e63d44618b497e900158546f434..dee25d790372cb4d56c24c1cd0bb1d0e0702ee90 100644
126--- a/src/Hy3Layout.hpp
127+++ b/src/Hy3Layout.hpp
128@@ -22,6 +22,15 @@ enum class ShiftDirection {
129 Right,
130 };
131
132+enum class FocusShift {
133+ Top,
134+ Bottom,
135+ Raise,
136+ Lower,
137+ Tab,
138+ TabNode,
139+};
140+
141 struct Hy3GroupData {
142 Hy3GroupLayout layout = Hy3GroupLayout::SplitH;
143 std::list<Hy3Node*> children;
144@@ -136,7 +145,7 @@ public:
145 void makeOppositeGroupOn(Hy3Node*);
146 void shiftWindow(int, ShiftDirection, bool);
147 void shiftFocus(int, ShiftDirection);
148- void raiseFocus(int);
149+ void changeFocus(int, FocusShift);
150 void focusTab(int);
151
152 bool shouldRenderSelected(CWindow*);
153diff --git a/src/main.cpp b/src/main.cpp
154index 3c4374acbd89dc708eeb2726be3a3054f5e225de..909365191455eaa41b4af1c8c38bb6881383820e 100644
155--- a/src/main.cpp
156+++ b/src/main.cpp
157@@ -79,11 +79,16 @@ void dispatch_movefocus(std::string arg) {
158 }
159 }
160
161-void dispatch_raisefocus(std::string arg) {
162+void dispatch_changefocus(std::string arg) {
163 int workspace = workspace_for_action();
164 if (workspace == -1) return;
165
166- g_Hy3Layout->raiseFocus(workspace);
167+ if (arg == "top") g_Hy3Layout->changeFocus(workspace, FocusShift::Top);
168+ else if (arg == "bottom") g_Hy3Layout->changeFocus(workspace, FocusShift::Bottom);
169+ else if (arg == "raise") g_Hy3Layout->changeFocus(workspace, FocusShift::Raise);
170+ else if (arg == "lower") g_Hy3Layout->changeFocus(workspace, FocusShift::Lower);
171+ else if (arg == "tab") g_Hy3Layout->changeFocus(workspace, FocusShift::Tab);
172+ else if (arg == "tabnode") g_Hy3Layout->changeFocus(workspace, FocusShift::TabNode);
173 }
174
175 void dispatch_focustab(std::string arg) {
176@@ -169,7 +174,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
177 HyprlandAPI::addDispatcher(PHANDLE, "hy3:makegroup", dispatch_makegroup);
178 HyprlandAPI::addDispatcher(PHANDLE, "hy3:movefocus", dispatch_movefocus);
179 HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow);
180- HyprlandAPI::addDispatcher(PHANDLE, "hy3:raisefocus", dispatch_raisefocus);
181+ HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);
182 HyprlandAPI::addDispatcher(PHANDLE, "hy3:focustab", dispatch_focustab);
183 HyprlandAPI::addDispatcher(PHANDLE, "hy3:debugnodes", dispatch_debug);
184