443081ab24aed8fdda63526361217444c143897f

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

Message

Add split opposite mode

Also fix multiple likely segfaults

Diff

This diff is truncated to protect this page.

  1diff --git a/README.md b/README.md
  2index fd7e46166b7f7a5c934b084edf33eb3dc4ee79a3..a89f0691db3d27b6f06075779a51d4805a95cd95 100644
  3--- a/README.md
  4+++ b/README.md
  5@@ -32,7 +32,7 @@ In your hyprland config replace the following dispatchers:
  6 You can use `hy3:makegroup` to create a new split.
  7 
  8 ### Dispatcher list
  9- - `hy3:makegroup, <h | v>` - make a vertical or horizontal split
 10+ - `hy3:makegroup, <h | v | opposite>` - make a vertical or horizontal split
 11  - `hy3:movefocus, <l | u | d | r>` - move the focus left, up, down, or right
 12  - `hy3:movewindow, <l | u | d | r>` - move a window left, up, down, or right
 13  - `hy3:raisefocus` - raise the active focus one level
 14diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
 15index 97e41e823a8f2c00cf54a44f8d2c4cb74e9d5876..155aa5ba8bed74d10982f2d481b12b7ebe707cbb 100644
 16--- a/src/Hy3Layout.cpp
 17+++ b/src/Hy3Layout.cpp
 18@@ -352,6 +352,24 @@ Hy3Node* Hy3Node::removeFromParentRecursive() {
 19 	return parent;
 20 }
 21 
 22+Hy3Node* Hy3Node::intoGroup(Hy3GroupLayout layout) {
 23+	this->layout->nodes.push_back({
 24+		.parent = this,
 25+		.data = this->data,
 26+		.workspace_id = this->workspace_id,
 27+		.layout = this->layout,
 28+	});
 29+
 30+	auto* node = &this->layout->nodes.back();
 31+
 32+	this->data = layout;
 33+	this->data.as_group.children.push_back(node);
 34+	this->data.as_group.lastFocusedChild = node;
 35+	this->recalcSizePosRecursive();
 36+
 37+	return node;
 38+}
 39+
 40 bool Hy3GroupData::hasChild(Hy3Node* node) {
 41 	Debug::log(LOG, "Searching for child %p of %p", this, node);
 42 	for (auto child: this->children) {
 43@@ -655,6 +673,7 @@ void Hy3Layout::onWindowRemovedTiling(CWindow* window) {
 44 
 45 CWindow* Hy3Layout::getNextWindowCandidate(CWindow* window) {
 46 	auto* node = this->getWorkspaceFocusedNode(window->m_iWorkspaceID);
 47+	if (node == nullptr) return nullptr;
 48 
 49 	switch (node->data.type) {
 50 	case Hy3NodeData::Window:
 51@@ -1059,32 +1078,52 @@ void Hy3Layout::onDisable() {
 52 	this->nodes.clear();
 53 }
 54 
 55-void Hy3Layout::makeGroupOn(int workspace, Hy3GroupLayout layout) {
 56+void Hy3Layout::makeGroupOnWorkspace(int workspace, Hy3GroupLayout layout) {
 57+	auto* node = this->getWorkspaceFocusedNode(workspace);
 58+	this->makeGroupOn(node, layout);
 59+}
 60+
 61+void Hy3Layout::makeOppositeGroupOnWorkspace(int workspace) {
 62 	auto* node = this->getWorkspaceFocusedNode(workspace);
 63+	this->makeOppositeGroupOn(node);
 64+}
 65+
 66+void Hy3Layout::makeGroupOn(Hy3Node* node, Hy3GroupLayout layout) {
 67 	if (node == nullptr) return;
 68 
 69-	if (node->parent->data.as_group.children.size() == 1
 70-			&& (node->parent->data.as_group.layout == Hy3GroupLayout::SplitH
 71-			|| node->parent->data.as_group.layout == Hy3GroupLayout::SplitV))
 72-	{
 73-			node->parent->data.as_group.layout = layout;
 74-			node->parent->recalcSizePosRecursive();
 75-			return;
 76+	if (node->parent != nullptr) {
 77+		auto& group = node->parent->data.as_group;
 78+		if (group.children.size() == 1
 79+				&& (group.layout == Hy3GroupLayout::SplitH
 80+				|| group.layout == Hy3GroupLayout::SplitV))
 81+		{
 82+				group.layout = layout;
 83+				node->parent->recalcSizePosRecursive();
 84+				return;
 85+		}
 86 	}
 87 
 88-	this->nodes.push_back({
 89-			.parent = node,
 90-			.data = node->data,
 91-			.workspace_id = node->workspace_id,
 92-			.layout = this,
 93-	});
 94+	node->intoGroup(layout);
 95+}
 96 
 97-	node->data = layout;
 98-	node->data.as_group.children.push_back(&this->nodes.back());
 99-	node->data.as_group.lastFocusedChild = &this->nodes.back();
100-	node->recalcSizePosRecursive();
101+void Hy3Layout::makeOppositeGroupOn(Hy3Node* node) {
102+	if (node == nullptr) return;
103 
104-	return;
105+	if (node->parent == nullptr) {
106+		node->intoGroup(Hy3GroupLayout::SplitH);
107+	} else {
108+		auto& group = node->parent->data.as_group;
109+		auto layout = group.layout == Hy3GroupLayout::SplitH
110+			? Hy3GroupLayout::SplitV
111+			: Hy3GroupLayout::SplitH;
112+
113+		if (group.children.size() == 1) {
114+			group.layout = layout;
115+			node->parent->recalcSizePosRecursive();
116+		} else {
117+			node->intoGroup(layout);
118diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
119index a40e8033f98761d7e26a029ef1f87ee8ed90d8cf..02637afe8af3b9ad37c0338d502d986876698f6b 100644
120--- a/src/Hy3Layout.hpp
121+++ b/src/Hy3Layout.hpp
122@@ -85,6 +85,9 @@ struct Hy3Node {
123 	// the only child and recursing if the parent was the only child of it's parent.
124 	Hy3Node* removeFromParentRecursive();
125 
126+	// Replace this node with a group, returning this node's new address.
127+	Hy3Node* intoGroup(Hy3GroupLayout);
128+
129 	static void swapData(Hy3Node&, Hy3Node&);
130 };
131 
132@@ -110,7 +113,10 @@ public:
133 	virtual void onEnable();
134 	virtual void onDisable();
135 
136-	void makeGroupOn(int, Hy3GroupLayout);
137+	void makeGroupOnWorkspace(int, Hy3GroupLayout);
138+	void makeOppositeGroupOnWorkspace(int);
139+	void makeGroupOn(Hy3Node*, Hy3GroupLayout);
140+	void makeOppositeGroupOn(Hy3Node*);
141 	void shiftWindow(int, ShiftDirection);
142 	void shiftFocus(int, ShiftDirection);
143 	void raiseFocus(int);
144diff --git a/src/main.cpp b/src/main.cpp
145index 1f2677e5b22aa9f16c6f9f0e7c1bf7a5613f6159..6c6c47697344617a257aa2e308be26928bef5e22 100644
146--- a/src/main.cpp
147+++ b/src/main.cpp
148@@ -40,9 +40,11 @@ void dispatch_makegroup(std::string arg) {
149 	if (workspace < 0) return;
150 
151 	if (arg == "h") {
152-		g_Hy3Layout->makeGroupOn(workspace, Hy3GroupLayout::SplitH);
153+		g_Hy3Layout->makeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitH);
154 	} else if (arg == "v") {
155-		g_Hy3Layout->makeGroupOn(workspace, Hy3GroupLayout::SplitV);
156+		g_Hy3Layout->makeGroupOnWorkspace(workspace, Hy3GroupLayout::SplitV);
157+	} else if (arg == "opposite") {
158+		g_Hy3Layout->makeOppositeGroupOnWorkspace(workspace);
159 	}
160 }
161