87f664f1ead0718716b9b1a5dc290630b6df1556

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

Message

Add `node_collapse_policy` setting

The original behavior was to always collapse (`node_collapse_policy = 0`)

Diff

 1diff --git a/README.md b/README.md
 2index 8b000e83073d4370f513d815bc46d8f2ba2842c8..8982679bb687561ff08eed3f185cbbe94d0440af 100644
 3--- a/README.md
 4+++ b/README.md
 5@@ -44,6 +44,13 @@ plugin {
 6     # disable gaps when only one window is onscreen
 7     no_gaps_when_only = <bool>
 8 
 9+    # policy controlling what happens when a node is removed from a group,
10+    # leaving only a group
11+    # 0 = remove the nested group
12+    # 1 = keep the nested group
13+    # 2 = keep the nested group only if its parent is a tab group (default)
14+    node_collapse_policy = <int>
15+
16     # offset from group split direction when only one window is in a group
17     group_inset = <int>
18 
19diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
20index e00394e76e8d0e6a0cc24f409061c6b4bb51b272..097b11e3a98a756a30c2e0a36a9390e2805a4d03 100644
21--- a/src/Hy3Layout.cpp
22+++ b/src/Hy3Layout.cpp
23@@ -193,6 +193,9 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window) {
24 }
25 
26 void Hy3Layout::onWindowRemovedTiling(CWindow* window) {
27+	static const auto* node_collapse_policy
28+	    = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:node_collapse_policy")->intValue;
29+
30 	auto* node = this->getNodeFromWindow(window);
31 	Debug::log(LOG, "remove tiling %p (window %p)", node, window);
32 
33@@ -217,8 +220,16 @@ void Hy3Layout::onWindowRemovedTiling(CWindow* window) {
34 	if (parent != nullptr) {
35 		parent->recalcSizePosRecursive();
36 
37+		// returns if a given node is a group that can be collapsed given the current config
38+		auto node_is_collapsible = [](Hy3Node* node) {
39+			if (node->data.type != Hy3NodeType::Group) return false;
40+			if (*node_collapse_policy == 0) return true;
41+			else if (*node_collapse_policy == 1) return false;
42+			return node->parent->data.as_group.layout != Hy3GroupLayout::Tabbed;
43+		};
44+
45 		if (group.children.size() == 1
46-		    && (group.ephemeral || group.children.front()->data.type == Hy3NodeType::Group))
47+		    && (group.ephemeral || node_is_collapsible(group.children.front())))
48 		{
49 			auto* target_parent = parent;
50 			while (target_parent != nullptr && Hy3Node::swallowGroups(target_parent)) {
51diff --git a/src/main.cpp b/src/main.cpp
52index 85e91e5bc96965185fd034a72ce858af5805642d..3bacbc79200db4ce4586586381d58a3f217950a8 100644
53--- a/src/main.cpp
54+++ b/src/main.cpp
55@@ -19,6 +19,11 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
56 	    "plugin:hy3:no_gaps_when_only",
57 	    SConfigValue {.intValue = 0}
58 	);
59+	HyprlandAPI::addConfigValue(
60+	    PHANDLE,
61+	    "plugin:hy3:node_collapse_policy",
62+	    SConfigValue {.intValue = 2}
63+	);
64 	HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:group_inset", SConfigValue {.intValue = 10});
65 	HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:height", SConfigValue {.intValue = 15});
66 	HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:padding", SConfigValue {.intValue = 5});