0e854287ffb800ff8c9a999779ce1e774b5b3a81

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

Message

Visual indication for single-window groups & more

- Fix being able to create multiple levels of groups around a single
window
- Destroy single-member groups when they loose focus

Diff

  1diff --git a/CMakeLists.txt b/CMakeLists.txt
  2index 89ce72b1c7d8db197fdc980fa928ec034a0e11f7..7a7a9d412f49290dfbb8b50bdef6c16af9dba30c 100644
  3--- a/CMakeLists.txt
  4+++ b/CMakeLists.txt
  5@@ -20,7 +20,6 @@ pkg_check_modules(DEPS REQUIRED pixman-1 libdrm)
  6 add_library(hy3 SHARED
  7 	src/main.cpp
  8 	src/Hy3Layout.cpp
  9-	src/Hy3SpawnLocDecoration.cpp
 10 )
 11 
 12 target_include_directories(hy3 PRIVATE
 13diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
 14index 339496db1c3285e3662b42f5be6931bf75f0018e..c0217fcea010ad0b49b7d83884378da398d47ce4 100644
 15--- a/src/Hy3Layout.cpp
 16+++ b/src/Hy3Layout.cpp
 17@@ -103,6 +103,47 @@ void Hy3Node::recalcSizePosRecursive(bool force) {
 18 	}
 19 
 20 	auto* group = &this->data.as_group;
 21+
 22+	if (group->children.size() == 1 && this->parent != nullptr) {
 23+		auto& child = group->children.front();
 24+
 25+		double distortOut;
 26+		double distortIn;
 27+
 28+		const auto* gaps_in     = &g_pConfigManager->getConfigValuePtr("general:gaps_in")->intValue;
 29+		const auto* gaps_out    = &g_pConfigManager->getConfigValuePtr("general:gaps_out")->intValue;
 30+
 31+		if (gaps_in > gaps_out) {
 32+			distortOut = *gaps_out - 1.0;
 33+		} else {
 34+			distortOut = *gaps_in - 1.0;
 35+		}
 36+
 37+		if (distortOut < 0) distortOut = 0.0;
 38+
 39+		distortIn = *gaps_in * 2;
 40+
 41+		switch (group->layout) {
 42+		case Hy3GroupLayout::SplitH:
 43+			child->position.x = this->position.x - distortOut;
 44+			child->size.x = this->size.x - distortIn;
 45+			child->position.y = this->position.y;
 46+			child->size.y = this->size.y;
 47+			break;
 48+		case Hy3GroupLayout::SplitV:
 49+			child->position.y = this->position.y - distortOut;
 50+			child->size.y = this->size.y - distortIn;
 51+			child->position.x = this->position.x;
 52+			child->size.x = this->size.x;
 53+		case Hy3GroupLayout::Tabbed:
 54+			// TODO
 55+			break;
 56+		}
 57+
 58+		child->recalcSizePosRecursive();
 59+		return;
 60+	}
 61+
 62 	int constraint;
 63 	switch (group->layout) {
 64 	case Hy3GroupLayout::SplitH:
 65@@ -371,6 +412,28 @@ void Hy3Layout::onWindowRemovedTiling(CWindow* window) {
 66 	if (parent != nullptr) parent->recalcSizePosRecursive();
 67 }
 68 
 69+void Hy3Layout::onWindowFocusChange(CWindow* window) {
 70+	Debug::log(LOG, "Switched windows from %p to %p", this->lastActiveWindow, window);
 71+	auto* node = this->getNodeFromWindow(this->lastActiveWindow);
 72+
 73+	while (node != nullptr
 74+		&& node->parent != nullptr
 75+		&& node->parent->parent != nullptr
 76+		&& node->parent->data.as_group.children.size() == 1)
 77+	{
 78+		auto parent = node->parent;
 79+		std::swap(parent->data, node->data);
 80+		this->nodes.remove(*node);
 81+		node = parent;
 82+	}
 83+
 84+	if (node != nullptr) {
 85+		node->recalcSizePosRecursive();
 86+	}
 87+
 88+	this->lastActiveWindow = window;
 89+}
 90+
 91 bool Hy3Layout::isWindowTiled(CWindow* window) {
 92 	return this->getNodeFromWindow(window) != nullptr;
 93 }
 94@@ -402,6 +465,16 @@ std::any Hy3Layout::layoutMessage(SLayoutMessageHeader header, std::string conte
 95 			layout = Hy3GroupLayout::SplitV;
 96 		}
 97 
 98+		if (node->parent != nullptr
 99+			&& node->parent->data.as_group.children.size() == 1
100+			&& (node->parent->data.as_group.layout == Hy3GroupLayout::SplitH
101+				|| node->parent->data.as_group.layout == Hy3GroupLayout::SplitV))
102+		{
103+			node->parent->data.as_group.layout = layout;
104+			node->parent->recalcSizePosRecursive();
105+			return "";
106+		}
107+
108 		Hy3NodeData node_data = Hy3NodeData(Hy3GroupData(layout));
109 		std::swap(node->data, node_data);
110 
111diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
112index 7d23e8054abadd2b20e316f515cb5553f7eddfb5..c6907cb45544d0fcc6e6d99b8103a336d5ea1f18 100644
113--- a/src/Hy3Layout.hpp
114+++ b/src/Hy3Layout.hpp
115@@ -56,6 +56,7 @@ class Hy3Layout: public IHyprLayout {
116 public:
117 	virtual void onWindowCreatedTiling(CWindow*);
118 	virtual void onWindowRemovedTiling(CWindow*);
119+	virtual void onWindowFocusChange(CWindow*);
120 	virtual bool isWindowTiled(CWindow*);
121 	virtual void recalculateMonitor(const int&);
122 	virtual void recalculateWindow(CWindow*);
123@@ -75,6 +76,7 @@ private:
124 	// std::list is used over std::vector because it does not invalidate references
125 	// when mutated.
126 	std::list<Hy3Node> nodes;
127+	CWindow* lastActiveWindow = nullptr;
128 
129 	int getWorkspaceNodeCount(const int&);
130 	Hy3Node* getNodeFromWindow(CWindow*);