0a889b39006f64002d3567a163f86b17b01f511b

Author
Sekhat Temporus <sekhat@temporus.me>
Committer
Sekhat Temporus <sekhat@temporus.me>
Date

Message

Add change group to support switching type of the current group

Diff

This diff is truncated to protect this page.

  1diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
  2index 5a7973df084b41c9a909343f4d951709a1ab306b..134a86fe5da36a9ca52766ae5bde18c64e002c28 100644
  3--- a/src/Hy3Layout.cpp
  4+++ b/src/Hy3Layout.cpp
  5@@ -746,6 +746,23 @@ void Hy3Layout::makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOpt
  6 	this->makeOppositeGroupOn(node, ephemeral);
  7 }
  8 
  9+void Hy3Layout::changeGroupOnWorkspace(
 10+	int workspace,
 11+	Hy3GroupLayout layout,
 12+	GroupEphemeralityOption ephemeral
 13+) {
 14+	auto* node = this->getWorkspaceFocusedNode(workspace);
 15+	this->changeGroupOn(node, layout, ephemeral);
 16+}
 17+
 18+void Hy3Layout::untabGroupOnWorkspace(
 19+	int workspace,
 20+	GroupEphemeralityOption ephemeral
 21+) {
 22+	auto* node = this->getWorkspaceFocusedNode(workspace);
 23+	this->untabGroupOn(node, ephemeral);
 24+}
 25+
 26 void Hy3Layout::makeGroupOn(
 27     Hy3Node* node,
 28     Hy3GroupLayout layout,
 29@@ -756,10 +773,7 @@ void Hy3Layout::makeGroupOn(
 30 	if (node->parent != nullptr) {
 31 		auto& group = node->parent->data.as_group;
 32 		if (group.children.size() == 1) {
 33-			group.layout = layout;
 34-			group.ephemeral = ephemeral == GroupEphemeralityOption::ForceEphemeral ? true
 35-			                : ephemeral == GroupEphemeralityOption::Ephemeral      ? group.ephemeral
 36-			                                                                       : false;
 37+			group.updateLayout(layout, ephemeral);
 38 			node->parent->recalcSizePosRecursive();
 39 			return;
 40 		}
 41@@ -768,26 +782,57 @@ void Hy3Layout::makeGroupOn(
 42 	node->intoGroup(layout, ephemeral);
 43 }
 44 
 45-void Hy3Layout::makeOppositeGroupOn(Hy3Node* node, GroupEphemeralityOption ephemeral) {
 46+void Hy3Layout::makeOppositeGroupOn(
 47+	Hy3Node* node,
 48+	GroupEphemeralityOption ephemeral
 49+) {
 50 	if (node == nullptr) return;
 51 
 52 	if (node->parent == nullptr) {
 53 		node->intoGroup(Hy3GroupLayout::SplitH, ephemeral);
 54-	} else {
 55-		auto& group = node->parent->data.as_group;
 56-		auto layout
 57-		    = group.layout == Hy3GroupLayout::SplitH ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH;
 58+		return;
 59+	}
 60 
 61-		if (group.children.size() == 1) {
 62-			group.layout = layout;
 63-			group.ephemeral = ephemeral == GroupEphemeralityOption::ForceEphemeral ? true
 64-			                : ephemeral == GroupEphemeralityOption::Ephemeral      ? group.ephemeral
 65-			                                                                       : false;
 66-			node->parent->recalcSizePosRecursive();
 67-		} else {
 68-			node->intoGroup(layout, ephemeral);
 69-		}
 70+	auto& group = node->parent->data.as_group;
 71+	auto layout
 72+		= group.layout == Hy3GroupLayout::SplitH ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH;
 73+
 74+	if (group.children.size() == 1) {
 75+		group.updateLayout(layout, ephemeral);
 76+		node->parent->recalcSizePosRecursive();
 77+		return;
 78 	}
 79+
 80+	node->intoGroup(layout, ephemeral);
 81+}
 82+
 83+void Hy3Layout::changeGroupOn(
 84+	Hy3Node* node,
 85+	Hy3GroupLayout layout,
 86+	GroupEphemeralityOption ephemeral
 87+) {
 88+	if (node == nullptr) return;
 89+
 90+	if (node->parent == nullptr) {
 91+		makeGroupOn(node, layout, ephemeral);
 92+		return;
 93+	}
 94+
 95+	auto& group = node->parent->data.as_group;
 96+	group.updateLayout(layout, ephemeral);
 97+	node->parent->recalcSizePosRecursive();
 98+}
 99+
100+void Hy3Layout::untabGroupOn(Hy3Node* node, GroupEphemeralityOption ephemeral) {
101+	if (node == nullptr) return;
102+
103+	if (node->parent == nullptr) return;
104+
105diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
106index ee91b23f4014df828862ea0280654856ae3a1974..ace2ffe1000a723f5d3599169ffdd59c66e4023a 100644
107--- a/src/Hy3Layout.hpp
108+++ b/src/Hy3Layout.hpp
109@@ -90,8 +90,12 @@ public:
110 
111 	void makeGroupOnWorkspace(int workspace, Hy3GroupLayout, GroupEphemeralityOption);
112 	void makeOppositeGroupOnWorkspace(int workspace, GroupEphemeralityOption);
113+	void changeGroupOnWorkspace(int workspace, Hy3GroupLayout, GroupEphemeralityOption);
114+	void untabGroupOnWorkspace(int workspace, GroupEphemeralityOption);
115 	void makeGroupOn(Hy3Node*, Hy3GroupLayout, GroupEphemeralityOption);
116 	void makeOppositeGroupOn(Hy3Node*, GroupEphemeralityOption);
117+	void changeGroupOn(Hy3Node*, Hy3GroupLayout, GroupEphemeralityOption);
118+	void untabGroupOn(Hy3Node*, GroupEphemeralityOption);
119 	void shiftWindow(int workspace, ShiftDirection, bool once);
120 	void shiftFocus(int workspace, ShiftDirection, bool visible);
121 	void changeFocus(int workspace, FocusShift);
122diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp
123index 9e68cc253b3157c7c5a9a8321d0b926e211af6dc..084d6a5d71407dbe9d8bd7739bc750c11a0efb62 100644
124--- a/src/Hy3Node.cpp
125+++ b/src/Hy3Node.cpp
126@@ -8,10 +8,15 @@
127 
128 // Hy3GroupData //
129 
130-Hy3GroupData::Hy3GroupData(Hy3GroupLayout layout): layout(layout) {}
131+Hy3GroupData::Hy3GroupData(Hy3GroupLayout layout): layout(layout) {
132+	if (layout != Hy3GroupLayout::Tabbed) {
133+		this->previous_nontab_layout = layout;
134+	}
135+}
136 
137 Hy3GroupData::Hy3GroupData(Hy3GroupData&& from) {
138 	this->layout = from.layout;
139+	this->previous_nontab_layout = from.previous_nontab_layout;
140 	this->children = std::move(from.children);
141 	this->group_focused = from.group_focused;
142 	this->expand_focused = from.expand_focused;
143@@ -52,6 +57,29 @@ void Hy3GroupData::collapseExpansions() {
144 	}
145 }
146 
147+void Hy3GroupData::updateLayout(
148+	Hy3GroupLayout layout,
149+	GroupEphemeralityOption ephemeral
150+) {
151+	this->layout = layout;
152+
153+	if (layout != Hy3GroupLayout::Tabbed) {
154+		this->previous_nontab_layout = layout;
155+	}
156+
157+	switch (ephemeral) {
158+		case GroupEphemeralityOption::ForceEphemeral:
159+			this->ephemeral = true;
160+			break;
161+		case GroupEphemeralityOption::Standard:
162+			this->ephemeral = false;
163+			break;
164+		case GroupEphemeralityOption::Ephemeral:
165+			// this->ephemeral stays the same
166+			break;
167+	}
168+}
169+
170 // Hy3NodeData //
171 
172 Hy3NodeData::Hy3NodeData(): Hy3NodeData((CWindow*) nullptr) {}
173diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp
174index 29d84f024d7091fb51fc89b3c697d9b95e9fa512..6f38276da9bcff9b325ec4e6a1f937000d110fb7 100644
175--- a/src/Hy3Node.hpp
176+++ b/src/Hy3Node.hpp
177@@ -29,6 +29,7 @@ enum class ExpandFocusType {
178 
179 struct Hy3GroupData {
180 	Hy3GroupLayout layout = Hy3GroupLayout::SplitH;
181+	Hy3GroupLayout previous_nontab_layout = Hy3GroupLayout::SplitH;
182 	std::list<Hy3Node*> children;
183 	bool group_focused = true;
184 	Hy3Node* focused_child = nullptr;
185@@ -42,6 +43,7 @@ struct Hy3GroupData {
186 
187 	bool hasChild(Hy3Node* child);
188 	void collapseExpansions();
189+	void updateLayout(Hy3GroupLayout layout, GroupEphemeralityOption ephemeral);
190 
191 private:
192 	Hy3GroupData(Hy3GroupData&&);
193diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp
194index d6568e4412b89898f04f9b682f6d0d3fda1a5813..04b3c1135112e86a6dbe4756d81a6daeb92c497b 100644
195--- a/src/dispatchers.cpp
196+++ b/src/dispatchers.cpp
197@@ -43,6 +43,35 @@ void dispatch_makegroup(std::string value) {
198 	}
199 }
200 
201+void dispatch_changegroup(std::string value) {
202+	int workspace = workspace_for_action();
203+	if (workspace == -1) return;
204+
205+	auto args = CVarList(value);
206+
207+	GroupEphemeralityOption ephemeral = GroupEphemeralityOption::Standard;
208+	if (args[1] == "ephemeral") {
209+		ephemeral = GroupEphemeralityOption::Ephemeral;
210+	} else if (args[1] == "force_ephemeral") {
211+		ephemeral = GroupEphemeralityOption::ForceEphemeral;
212+	}
213+
214+	if (args[0] == "h") {
215+		g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitH, ephemeral);
216+	} else if (args[0] == "v") {
217+		g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitV, ephemeral);
218+	} else if (args[0] == "tab") {
219+		g_Hy3Layout->changeGroupOnWorkspace(workspace, Hy3GroupLayout::Tabbed, ephemeral);
220+	} else if (args[0] == "untab") {
221+		g_Hy3Layout->untabGroupOnWorkspace(workspace, ephemeral);
222+	}
223+	// TODO
224+	//else if (args[0] == "opposite") {
225+	//	g_Hy3Layout->makeOppositeGroupOnWorkspace(workspace, ephemeral);
226+	//}
227+}
228+
229+
230 std::optional<ShiftDirection> parseShiftArg(std::string arg) {
231 	if (arg == "l" || arg == "left") return ShiftDirection::Left;
232 	else if (arg == "r" || arg == "right") return ShiftDirection::Right;
233@@ -188,6 +217,7 @@ void dispatch_debug(std::string arg) {
234 
235 void registerDispatchers() {
236 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:makegroup", dispatch_makegroup);
237+	HyprlandAPI::addDispatcher(PHANDLE, "hy3:changegroup", dispatch_changegroup);
238 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:movefocus", dispatch_movefocus);
239 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow);
240 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);