ecf6dc5cba0fcb848f75bc7b4de9a1603f4113ca

Author
DJ <dbnpv2@gmail.com>
Committer
outfoxxed <outfoxxed@outfoxxed.me>
Date

Message

feat: add hy3:equalize dispatcher

Add a new dispatcher to equalize window sizes within a group or
recursively across the entire workspace tree.

Usage:
  hy3:equalize           - equalize siblings of focused window
  hy3:equalize workspace - equalize all windows in workspace

This resets size_ratio to 1.0 for affected nodes and triggers
a single recalculation, providing instant equalization without
the overhead of iterative resizing via hyprctl.

Diff

 1diff --git a/README.md b/README.md
 2index 466fe9e004b49298ace4865cf63521d5f1b11d8d..36cbc0e93eae0d389ffbc6c405b0f6b6af72cdc3 100644
 3--- a/README.md
 4+++ b/README.md
 5@@ -390,3 +390,6 @@ plugin {
 6    - `expand` - expand by one node
 7    - `shrink` - shrink by one node
 8    - `base` - undo all expansions
 9+ - `hy3:equalize, [workspace]` - equalize window sizes in group
10+   - no argument: equalizes immediate siblings of the focused window
11+   - `workspace`: equalizes all windows across the entire workspace tree
12diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
13index 0e120100fe83a848feeca71a9b078ca64a4e7d71..5b379f5f91c6d0acd33441bbc5c744513caf6a10 100644
14--- a/src/Hy3Layout.cpp
15+++ b/src/Hy3Layout.cpp
16@@ -1514,6 +1514,39 @@ void Hy3Layout::setTabLock(const CWorkspace* workspace, TabLockMode mode) {
17 	node->updateTabBar();
18 }
19 
20+static void equalizeRecursive(Hy3Node* node, bool recursive) {
21+	node->size_ratio = 1.0f;
22+
23+	if (recursive && node->data.is_group()) {
24+		for (auto* child: node->data.as_group().children) {
25+			equalizeRecursive(child, true);
26+		}
27+	}
28+}
29+
30+void Hy3Layout::equalize(const CWorkspace* workspace, bool recursive) {
31+	auto* focused = this->getWorkspaceFocusedNode(workspace);
32+	if (focused == nullptr) return;
33+
34+	Hy3Node* target = nullptr;
35+
36+	if (recursive) {
37+		target = this->getWorkspaceRootGroup(workspace);
38+		if (target != nullptr) {
39+			equalizeRecursive(target, true);
40+		}
41+	} else {
42+		if (focused->parent == nullptr) return;
43+		auto* parent = focused->parent;
44+		equalizeRecursive(parent, false);
45+		target = parent;
46+	}
47+
48+	if (target != nullptr) {
49+		target->recalcSizePosRecursive();
50+	}
51+}
52+
53 void Hy3Layout::warpCursorToBox(const Vector2D& pos, const Vector2D& size) {
54 	auto cursorpos = g_pPointerManager->position();
55 
56diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
57index 784c0ac51f832769ff742f0e50d910974d53f603..f894ec580dedb5b21d677478d223fa3a3c527bcf 100644
58--- a/src/Hy3Layout.hpp
59+++ b/src/Hy3Layout.hpp
60@@ -151,6 +151,7 @@ public:
61 	void killFocusedNode(const CWorkspace* workspace);
62 	void expand(const CWorkspace* workspace, ExpandOption, ExpandFullscreenOption);
63 	void setTabLock(const CWorkspace* workspace, TabLockMode);
64+	void equalize(const CWorkspace* workspace, bool recursive = false);
65 	static void warpCursorToBox(const Vector2D& pos, const Vector2D& size);
66 	static void warpCursorWithFocus(const Vector2D& pos, bool force = false);
67 
68diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp
69index e0c359fdf317b8f7acea8da1470c53403d006292..847417d4c6042aeb63062ce838d72b2f689f2a56 100644
70--- a/src/dispatchers.cpp
71+++ b/src/dispatchers.cpp
72@@ -264,6 +264,14 @@ void dispatch_locktab(std::string arg) {
73 	g_Hy3Layout->setTabLock(workspace.get(), mode);
74 }
75 
76+void dispatch_equalize(std::string arg) {
77+	auto workspace = workspace_for_action();
78+	if (!valid(workspace)) return;
79+
80+	bool recursive = (arg == "workspace");
81+	g_Hy3Layout->equalize(workspace.get(), recursive);
82+}
83+
84 SDispatchResult dispatch_debug(std::string arg) {
85 	auto workspace = workspace_for_action();
86 
87@@ -292,5 +300,6 @@ void registerDispatchers() {
88 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:killactive", dispatch_killactive);
89 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:expand", dispatch_expand);
90 	HyprlandAPI::addDispatcher(PHANDLE, "hy3:locktab", dispatch_locktab);
91+	HyprlandAPI::addDispatcher(PHANDLE, "hy3:equalize", dispatch_equalize);
92 	HyprlandAPI::addDispatcherV2(PHANDLE, "hy3:debugnodes", dispatch_debug);
93 }