a15a058250120241b9d3588b455a553f0b5eb77c

Author
outfoxxed <outfoxxed@outfoxxed.me>
Committer
GitHub <noreply@github.com>
Date

Message

Merge pull request #21 from sekhat/feature/change-group

Add a changegroup and setephemeral dispatchers

Diff

This diff is truncated to protect this page.

  1diff --git a/README.md b/README.md
  2index 757bba2eeeeb1d8ede8d5bf58ca47aec025269b9..8ceec53439e4fcbed6548b461a379a7c83e5c0ce 100644
  3--- a/README.md
  4+++ b/README.md
  5@@ -215,6 +215,10 @@ plugin {
  6  - `hy3:makegroup, <h | v | opposite | tab>, [ephemeral | force_ephemeral]` - make a vertical / horizontal split or tab group
  7    - `ephemeral` - the group will be removed once it contains only one node. does not affect existing groups.
  8    - `force_ephemeral` - same as ephemeral, but converts existing single windows groups.
  9+ - `hy3:changegroup, <h | v | tab | untab | opposite>` - change the group the node belongs to, to a different layout
 10+   - `untab` will untab the group if it was previously tabbed
 11+   - `opposite` will toggle between horizontal and vertical layouts if the group is not tabbed.
 12+ - `hy3:setephemeral, <true | false>` - change the ephemerality of the group the node belongs to
 13  - `hy3:movefocus, <l | u | d | r | left | down | up | right>, [visible]` - move the focus left, up, down, or right
 14    - `visible` - only move between visible nodes, not hidden tabs
 15  - `hy3:movewindow, <l | u | d | r | left | down | up | right>, [once]` - move a window left, up, down, or right
 16diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
 17index d627af406d01c511158be0f1349d6f6286f50233..76231c54d995009418171e4fc6f124a8b1a710a5 100644
 18--- a/src/Hy3Layout.cpp
 19+++ b/src/Hy3Layout.cpp
 20@@ -748,6 +748,34 @@ void Hy3Layout::makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOpt
 21 	this->makeOppositeGroupOn(node, ephemeral);
 22 }
 23 
 24+void Hy3Layout::changeGroupOnWorkspace(int workspace, Hy3GroupLayout layout) {
 25+	auto* node = this->getWorkspaceFocusedNode(workspace);
 26+	if (node == nullptr) return;
 27+
 28+	this->changeGroupOn(*node, layout);
 29+}
 30+
 31+void Hy3Layout::untabGroupOnWorkspace(int workspace) {
 32+	auto* node = this->getWorkspaceFocusedNode(workspace);
 33+	if (node == nullptr) return;
 34+
 35+	this->untabGroupOn(*node);
 36+}
 37+
 38+void Hy3Layout::changeGroupToOppositeOnWorkspace(int workspace) {
 39+	auto* node = this->getWorkspaceFocusedNode(workspace);
 40+	if (node == nullptr) return;
 41+
 42+	this->changeGroupToOppositeOn(*node);
 43+}
 44+
 45+void Hy3Layout::changeGroupEphemeralityOnWorkspace(int workspace, bool ephemeral) {
 46+	auto* node = this->getWorkspaceFocusedNode(workspace);
 47+	if (node == nullptr) return;
 48+
 49+	this->changeGroupEphemeralityOn(*node, ephemeral);
 50+}
 51+
 52 void Hy3Layout::makeGroupOn(
 53     Hy3Node* node,
 54     Hy3GroupLayout layout,
 55@@ -758,10 +786,8 @@ void Hy3Layout::makeGroupOn(
 56 	if (node->parent != nullptr) {
 57 		auto& group = node->parent->data.as_group;
 58 		if (group.children.size() == 1) {
 59-			group.layout = layout;
 60-			group.ephemeral = ephemeral == GroupEphemeralityOption::ForceEphemeral ? true
 61-			                : ephemeral == GroupEphemeralityOption::Ephemeral      ? group.ephemeral
 62-			                                                                       : false;
 63+			group.setLayout(layout);
 64+			group.setEphemeral(ephemeral);
 65 			node->parent->recalcSizePosRecursive();
 66 			return;
 67 		}
 68@@ -775,21 +801,62 @@ void Hy3Layout::makeOppositeGroupOn(Hy3Node* node, GroupEphemeralityOption ephem
 69 
 70 	if (node->parent == nullptr) {
 71 		node->intoGroup(Hy3GroupLayout::SplitH, ephemeral);
 72-	} else {
 73-		auto& group = node->parent->data.as_group;
 74-		auto layout
 75-		    = group.layout == Hy3GroupLayout::SplitH ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH;
 76+		return;
 77+	}
 78 
 79-		if (group.children.size() == 1) {
 80-			group.layout = layout;
 81-			group.ephemeral = ephemeral == GroupEphemeralityOption::ForceEphemeral ? true
 82-			                : ephemeral == GroupEphemeralityOption::Ephemeral      ? group.ephemeral
 83-			                                                                       : false;
 84-			node->parent->recalcSizePosRecursive();
 85-		} else {
 86-			node->intoGroup(layout, ephemeral);
 87-		}
 88+	auto& group = node->parent->data.as_group;
 89+	auto layout
 90+	    = group.layout == Hy3GroupLayout::SplitH ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH;
 91+
 92+	if (group.children.size() == 1) {
 93+		group.setLayout(layout);
 94+		group.setEphemeral(ephemeral);
 95+		node->parent->recalcSizePosRecursive();
 96+		return;
 97 	}
 98+
 99+	node->intoGroup(layout, ephemeral);
100+}
101+
102+void Hy3Layout::changeGroupOn(Hy3Node& node, Hy3GroupLayout layout) {
103+	if (node.parent == nullptr) {
104+		makeGroupOn(&node, layout, GroupEphemeralityOption::Ephemeral);
105+		return;
106+	}
107+
108+	auto& group = node.parent->data.as_group;
109+	group.setLayout(layout);
110+	node.parent->recalcSizePosRecursive();
111+}
112+
113+void Hy3Layout::untabGroupOn(Hy3Node& node) {
114+	if (node.parent == nullptr) return;
115+
116+	auto& group = node.parent->data.as_group;
117+	if (group.layout != Hy3GroupLayout::Tabbed) return;
118+
119+	changeGroupOn(node, group.previous_nontab_layout);
120diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
121index ee91b23f4014df828862ea0280654856ae3a1974..e5148cc4ab1e53dcc416d2994bbe143aee5400b6 100644
122--- a/src/Hy3Layout.hpp
123+++ b/src/Hy3Layout.hpp
124@@ -90,8 +90,16 @@ public:
125 
126 	void makeGroupOnWorkspace(int workspace, Hy3GroupLayout, GroupEphemeralityOption);
127 	void makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOption);
128+	void changeGroupOnWorkspace(int workspace, Hy3GroupLayout);
129+	void untabGroupOnWorkspace(int workspace);
130+	void changeGroupToOppositeOnWorkspace(int workspace);
131+	void changeGroupEphemeralityOnWorkspace(int workspace, bool ephemeral);
132 	void makeGroupOn(Hy3Node*, Hy3GroupLayout, GroupEphemeralityOption);
133 	void makeOppositeGroupOn(Hy3Node*, GroupEphemeralityOption);
134+	void changeGroupOn(Hy3Node&, Hy3GroupLayout);
135+	void untabGroupOn(Hy3Node&);
136+	void changeGroupToOppositeOn(Hy3Node&);
137+	void changeGroupEphemeralityOn(Hy3Node&, bool ephemeral);
138 	void shiftWindow(int workspace, ShiftDirection, bool once);
139 	void shiftFocus(int workspace, ShiftDirection, bool visible);
140 	void changeFocus(int workspace, FocusShift);
141diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp
142index 3c8f99aab338fecff3f0cb0a9654b9fa7ec3a850..4c44880d004a3cbfa96a3f900827c422c9f46f43 100644
143--- a/src/Hy3Node.cpp
144+++ b/src/Hy3Node.cpp
145@@ -8,10 +8,15 @@
146 
147 // Hy3GroupData //
148 
149-Hy3GroupData::Hy3GroupData(Hy3GroupLayout layout): layout(layout) {}
150+Hy3GroupData::Hy3GroupData(Hy3GroupLayout layout): layout(layout) {
151+	if (layout != Hy3GroupLayout::Tabbed) {
152+		this->previous_nontab_layout = layout;
153+	}
154+}
155 
156 Hy3GroupData::Hy3GroupData(Hy3GroupData&& from) {
157 	this->layout = from.layout;
158+	this->previous_nontab_layout = from.previous_nontab_layout;
159 	this->children = std::move(from.children);
160 	this->group_focused = from.group_focused;
161 	this->expand_focused = from.expand_focused;
162@@ -52,6 +57,24 @@ void Hy3GroupData::collapseExpansions() {
163 	}
164 }
165 
166+void Hy3GroupData::setLayout(Hy3GroupLayout layout) {
167+	this->layout = layout;
168+
169+	if (layout != Hy3GroupLayout::Tabbed) {
170+		this->previous_nontab_layout = layout;
171+	}
172+}
173+
174+void Hy3GroupData::setEphemeral(GroupEphemeralityOption ephemeral) {
175+	switch (ephemeral) {
176+	case GroupEphemeralityOption::Standard: this->ephemeral = false; break;
177+	case GroupEphemeralityOption::ForceEphemeral: this->ephemeral = true; break;
178+	case GroupEphemeralityOption::Ephemeral:
179+		// no change
180+		break;
181+	}
182+}
183+
184 // Hy3NodeData //
185 
186 Hy3NodeData::Hy3NodeData(): Hy3NodeData((CWindow*) nullptr) {}
187diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp
188index 111d8cdf3746349b9075b01fc0fd628d417c295d..0f81b4464fb3599a4edbfdd648c5c4d38dc7051e 100644
189--- a/src/Hy3Node.hpp
190+++ b/src/Hy3Node.hpp
191@@ -29,6 +29,7 @@ enum class ExpandFocusType {
192 
193 struct Hy3GroupData {
194 	Hy3GroupLayout layout = Hy3GroupLayout::SplitH;
195+	Hy3GroupLayout previous_nontab_layout = Hy3GroupLayout::SplitH;
196 	std::list<Hy3Node*> children;
197 	bool group_focused = true;
198 	Hy3Node* focused_child = nullptr;
199@@ -42,6 +43,8 @@ struct Hy3GroupData {
200 
201 	bool hasChild(Hy3Node* child);
202 	void collapseExpansions();
203+	void setLayout(Hy3GroupLayout layout);
204+	void setEphemeral(GroupEphemeralityOption ephemeral);
205 
206 private:
207 	Hy3GroupData(Hy3GroupData&&);
208diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp
209index d6568e4412b89898f04f9b682f6d0d3fda1a5813..f2ae3d4a09eb15d77e8aaac02ac80c555d9a3430 100644
210--- a/src/dispatchers.cpp
211+++ b/src/dispatchers.cpp
212@@ -43,6 +43,36 @@ void dispatch_makegroup(std::string value) {
213 	}
214 }
215 
216+void dispatch_changegroup(std::string value) {
217+	int workspace = workspace_for_action();
218+	if (workspace == -1) return;
219+
220+	auto args = CVarList(value);
221+
222+	if (args[0] == "h") {
223+		g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitH);
224+	} else if (args[0] == "v") {
225+		g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitV);
226+	} else if (args[0] == "tab") {
227+		g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::Tabbed);
228+	} else if (args[0] == "untab") {
229+		g_Hy3Layout->untabGroupOnWorkspace(workspace);
230+	} else if (args[0] == "opposite") {
231+		g_Hy3Layout->changeGroupToOppositeOnWorkspace(workspace);
232+	}
233+}
234+
235+void dispatch_setephemeral(std::string value) {
236+	int workspace = workspace_for_action();
237+	if (workspace == -1) return;
238+
239+	auto args = CVarList(value);
240+
241+	bool ephemeral = args[0] == "true";
242+
243+	g_Hy3Layout->changeGroupEphemeralityOnWorkspace(workspace, ephemeral);
244+}
245+
246 std::optional<ShiftDirection> parseShiftArg(std::string arg) {
247 	if (arg == "l" || arg == "left") return ShiftDirection::Left;
248 	else if (arg == "r" || arg == "right") return ShiftDirection::Right;
249@@ -188,6 +218,8 @@ void dispatch_debug(std::string arg) {
250 
251 void registerDispatchers() {
252 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:makegroup", dispatch_makegroup);
253+	HyprlandAPI::addDispatcher(PHANDLE, "hy3:changegroup", dispatch_changegroup);
254+	HyprlandAPI::addDispatcher(PHANDLE, "hy3:setephemeral", dispatch_setephemeral);
255 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:movefocus", dispatch_movefocus);
256 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow);
257 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);