ea43c609916945d913ff2278c55269009b33881c

Author
outfoxxed <outfoxxed@outfoxxed.me>
Committer
outfoxxed <outfoxxed@outfoxxed.me>
Date

Message

Change `hy3:raisefocus` to `hy3:changefocus` and add more options

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