5ca59bf723293d81add69c5f2169f23f385e5a22

Author
Pete Appleton <pete+git@catcity.me.uk>
Committer
Pete Appleton <pete+git@catcity.me.uk>
Date

Message

Implement `resizeActiveWindow` fully

Diff

This diff is truncated to protect this page.

  1diff --git a/.gitignore b/.gitignore
  2index b159eae01cad89d899b5e90e99e0bd98d6b0d51c..36b6e89cd78ff11ec464460259e820d08e0befe0 100644
  3--- a/.gitignore
  4+++ b/.gitignore
  5@@ -1,2 +1,4 @@
  6 build/
  7-compile_commands.json
  8+compile_commands.json
  9+.vscode/
 10+*.log
 11diff --git a/CHANGELOG.md b/CHANGELOG.md
 12index c6b4c99287e15c7818d10411f23d74aced3aaba1..8fd08359f199039f1e9bb77852a60abc662d169e 100644
 13--- a/CHANGELOG.md
 14+++ b/CHANGELOG.md
 15@@ -1,5 +1,8 @@
 16 # Changelog
 17 
 18+- Implement `resizeactivewindow` for floating windows
 19+- Fully implement `resizeactivewindow` for tiled windows
 20+
 21 ## Upcoming
 22 
 23 - Fixed `hy3:killactive` and `hy3:movetoworkspace` not working in fullscreen.
 24diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
 25index f4c793ff7a491b4b6a43ad123b9cc0c594344c36..012f24060f8d45990b2d742dd7d1336c7f146fb7 100644
 26--- a/src/Hy3Layout.cpp
 27+++ b/src/Hy3Layout.cpp
 28@@ -395,211 +395,141 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW
 29 	if (!g_pCompositor->windowValidMapped(window)) return;
 30 
 31 	auto* node = this->getNodeFromWindow(window);
 32-	if (node == nullptr) return;
 33-	if (node->parent != nullptr && node->parent->data.as_group.focused_child == node)
 34-		node = &node->getExpandActor();
 35-
 36-	bool drag_x;
 37-	bool drag_y;
 38-
 39-	if (corner == CORNER_NONE) {
 40-		drag_x = delta.x > 0;
 41-		drag_y = delta.y > 0;
 42-	} else {
 43-		drag_x = corner == CORNER_TOPRIGHT || corner == CORNER_BOTTOMRIGHT;
 44-		drag_y = corner == CORNER_BOTTOMLEFT || corner == CORNER_BOTTOMRIGHT;
 45-	}
 46-
 47-	const auto animate =
 48-	    &g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes")->intValue;
 49+	if(node != nullptr) {
 50+		if (node->parent != nullptr && node->parent->data.as_group.focused_child == node)
 51+			node = &node->getExpandActor();
 52 
 53-	auto monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID);
 54+		auto monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID);
 55 
 56-	const bool display_left =
 57-	    STICKS(node->position.x, monitor->vecPosition.x + monitor->vecReservedTopLeft.x);
 58-	const bool display_right = STICKS(
 59-	    node->position.x + node->size.x,
 60-	    monitor->vecPosition.x + monitor->vecSize.x - monitor->vecReservedBottomRight.x
 61-	);
 62-	const bool display_top =
 63-	    STICKS(node->position.y, monitor->vecPosition.y + monitor->vecReservedTopLeft.y);
 64-	const bool display_bottom = STICKS(
 65-	    node->position.y + node->size.y,
 66-	    monitor->vecPosition.y + monitor->vecSize.y - monitor->vecReservedBottomRight.y
 67-	);
 68-
 69-	Vector2D allowed_movement = delta;
 70-	if (display_left && display_right) allowed_movement.x = 0;
 71-	if (display_top && display_bottom) allowed_movement.y = 0;
 72-
 73-	auto* inner_node = node;
 74-
 75-	// break into parent groups when encountering a corner we're dragging in or a
 76-	// tab group
 77-	while (inner_node->parent != nullptr) {
 78-		auto& group = inner_node->parent->data.as_group;
 79+		const bool display_left =
 80+			STICKS(node->position.x, monitor->vecPosition.x + monitor->vecReservedTopLeft.x);
 81+		const bool display_right = STICKS(
 82+			node->position.x + node->size.x,
 83+			monitor->vecPosition.x + monitor->vecSize.x - monitor->vecReservedBottomRight.x
 84+		);
 85+		const bool display_top =
 86+			STICKS(node->position.y, monitor->vecPosition.y + monitor->vecReservedTopLeft.y);
 87+		const bool display_bottom = STICKS(
 88+			node->position.y + node->size.y,
 89+			monitor->vecPosition.y + monitor->vecSize.y - monitor->vecReservedBottomRight.y
 90+		);
 91 
 92-		switch (group.layout) {
 93-		case Hy3GroupLayout::Tabbed:
 94-			// treat tabbed layouts as if they dont exist during resizing
 95-			goto cont;
 96-		case Hy3GroupLayout::SplitH:
 97-			if ((drag_x && group.children.back() == inner_node)
 98-			    || (!drag_x && group.children.front() == inner_node))
 99-			{
100-				goto cont;
101-			}
102-			break;
103-		case Hy3GroupLayout::SplitV:
104-			if ((drag_y && group.children.back() == inner_node)
105-			    || (!drag_y && group.children.front() == inner_node))
106-			{
107-				goto cont;
108-			}
109-			break;
110+		Vector2D resize_delta = delta;
111+		if (display_left && display_right) resize_delta.x = 0;
112+		if (display_top && display_bottom) resize_delta.y = 0;
113+
114+		ShiftDirection target_edge_x;
115+		ShiftDirection target_edge_y;
116+
117+		// Determine the direction in which we're going to look for the sibling node
118+		// that will be resized
119+		if(corner == CORNER_NONE) {			// It's probably a keyboard event
120+			// If the horizontal delta is negative & there's space available to the left,
121+			// or if the horizontal delta is positive but space ISN'T available to the right
122+			// then resize against the left-hand sibling.
123+			// Otherwise, resize against the right-hand sibling
124+			target_edge_x = (delta.x < 0 && display_left) || (delta.x > 0 && !display_right)
125+				? ShiftDirection::Left : ShiftDirection::Right;
126+
127+			// If the vertical delta is negative & there's space available above it,
128diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
129index 9409be8df029da446cca43cdf6f7be8bb03bb6d4..29f4e2ac6135bffdaa89eb311d6f97d717ecf018 100644
130--- a/src/Hy3Layout.hpp
131+++ b/src/Hy3Layout.hpp
132@@ -13,9 +13,6 @@ enum class GroupEphemeralityOption {
133 
134 #include <hyprland/src/layout/IHyprLayout.hpp>
135 
136-#include "Hy3Node.hpp"
137-#include "TabGroup.hpp"
138-
139 enum class ShiftDirection {
140 	Left,
141 	Up,
142@@ -23,6 +20,9 @@ enum class ShiftDirection {
143 	Right,
144 };
145 
146+#include "Hy3Node.hpp"
147+#include "TabGroup.hpp"
148+
149 enum class FocusShift {
150 	Top,
151 	Bottom,
152@@ -144,6 +144,7 @@ private:
153 
154 	void updateAutotileWorkspaces();
155 	bool shouldAutotileWorkspace(int);
156+	void resizeNode(Hy3Node*, Vector2D, ShiftDirection resize_edge_x, ShiftDirection resize_edge_y);
157 
158 	struct {
159 		std::string raw_workspaces;
160diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp
161index 84565ee482bf54f76ceab9c0e6e4c1f30aa2f6cc..4640d370d5c68ab13c11d741b3b02e40f27b75f2 100644
162--- a/src/Hy3Node.cpp
163+++ b/src/Hy3Node.cpp
164@@ -808,6 +808,58 @@ bool Hy3Node::swallowGroups(Hy3Node* into) {
165 	return true;
166 }
167 
168+Hy3Node* getOuterChild(Hy3GroupData &group, ShiftDirection direction) {
169+	switch (direction) {
170+		case ShiftDirection::Left:
171+		case ShiftDirection::Up:
172+			return group.children.back();
173+			break;
174+		case ShiftDirection::Right:
175+		case ShiftDirection::Down:
176+			return group.children.front();
177+			break;
178+		default:
179+			return nullptr;
180+	}
181+}
182+
183+Hy3Node* Hy3Node::findSibling(Hy3GroupLayout inner_layout, ShiftDirection direction_x, ShiftDirection direction_y) {
184+	// break into parent groups when encountering a corner we're dragging in, a
185+	// tab group, or a layout matching the inner_parent.
186+
187+	auto current_node = this;
188+	while (current_node->parent != nullptr) {
189+		auto& parent_group = current_node->parent->data.as_group;
190+
191+		// break out of all layouts that match the orientation of the inner_parent
192+		if (parent_group.layout == inner_layout) {
193+			goto cont2;
194+		}
195+
196+		switch (parent_group.layout) {
197+		case Hy3GroupLayout::Tabbed:
198+			// treat tabbed layouts as if they dont exist during resizing
199+			goto cont2;
200+		case Hy3GroupLayout::SplitH:
201+			if(getOuterChild(parent_group, direction_x) == current_node) {
202+				goto cont2;
203+			}
204+			break;
205+		case Hy3GroupLayout::SplitV:
206+			if(getOuterChild(parent_group, direction_y) == current_node) {
207+				goto cont2;
208+			}
209+			break;
210+		}
211+
212+		break;
213+	cont2:
214+		current_node = current_node->parent;
215+	}
216+
217+	return current_node;
218+}
219+
220 void Hy3Node::swapData(Hy3Node& a, Hy3Node& b) {
221 	Hy3NodeData aData = std::move(a.data);
222 	a.data = std::move(b.data);
223diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp
224index bd25556f106e4ddd43b0c0f3baaa482f20998619..77ed7e931eef9af3c7b4bf220b81853ea8c0ec4c 100644
225--- a/src/Hy3Node.hpp
226+++ b/src/Hy3Node.hpp
227@@ -1,6 +1,7 @@
228 #pragma once
229 
230 struct Hy3Node;
231+struct Hy3GroupData;
232 enum class Hy3GroupLayout;
233 
234 #include <list>
235@@ -98,6 +99,7 @@ struct Hy3Node {
236 	void markFocused();
237 	void raiseToTop();
238 	Hy3Node* getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false);
239+	Hy3Node* findSibling(Hy3GroupLayout inner_layout, ShiftDirection direction_x, ShiftDirection direction_y);
240 	bool isIndirectlyFocused();
241 	Hy3Node& getExpandActor();
242