131a51be6209e7c2e308517e119ece88faec1a21

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

Message

Implement damage

Diff

This diff is truncated to protect this page.

  1diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
  2index 831f02ce75796b2a6db514d7e282450e6e04f461..7371b891e510a5051983a521fb3173465f318f82 100644
  3--- a/src/Hy3Layout.cpp
  4+++ b/src/Hy3Layout.cpp
  5@@ -1229,6 +1229,7 @@ void Hy3Layout::replaceWindowDataWith(CWindow* from, CWindow* to) {
  6 }
  7 
  8 std::unique_ptr<HOOK_CALLBACK_FN> renderHookPtr = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::renderHook);
  9+std::unique_ptr<HOOK_CALLBACK_FN> tickHookPtr = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::tickHook);
 10 
 11 void Hy3Layout::onEnable() {
 12 	for (auto &window : g_pCompositor->m_vWindows) {
 13@@ -1242,11 +1243,13 @@ void Hy3Layout::onEnable() {
 14 	}
 15 
 16 	HyprlandAPI::registerCallbackStatic(PHANDLE, "render", renderHookPtr.get());
 17+	HyprlandAPI::registerCallbackStatic(PHANDLE, "tick", tickHookPtr.get());
 18 	selection_hook::enable();
 19 }
 20 
 21 void Hy3Layout::onDisable() {
 22 	HyprlandAPI::unregisterCallback(PHANDLE, renderHookPtr.get());
 23+	HyprlandAPI::unregisterCallback(PHANDLE, tickHookPtr.get());
 24 	selection_hook::disable();
 25 	this->nodes.clear();
 26 }
 27@@ -1531,6 +1534,57 @@ bool Hy3Layout::shouldRenderSelected(CWindow* window) {
 28 	}
 29 }
 30 
 31+void Hy3Layout::renderHook(void*, std::any data) {
 32+	static bool rendering_normally = false;
 33+	static std::vector<Hy3TabGroup*> rendered_groups;
 34+
 35+	auto render_stage = std::any_cast<eRenderStage>(data);
 36+
 37+	switch (render_stage) {
 38+	case RENDER_PRE_WINDOWS:
 39+		rendering_normally = true;
 40+		rendered_groups.clear();
 41+		break;
 42+	case RENDER_POST_WINDOW:
 43+		if (!rendering_normally) break;
 44+
 45+		for (auto& entry: g_Hy3Layout->tab_groups) {
 46+			if (entry.target_window == g_pHyprOpenGL->m_pCurrentWindow
 47+					&& std::find(rendered_groups.begin(), rendered_groups.end(), &entry) == rendered_groups.end()
 48+			) {
 49+				entry.renderTabBar();
 50+				rendered_groups.push_back(&entry);
 51+			}
 52+		}
 53+
 54+		break;
 55+	case RENDER_POST_WINDOWS:
 56+		rendering_normally = false;
 57+
 58+		for (auto& entry: g_Hy3Layout->tab_groups) {
 59+			if (entry.target_window->m_iMonitorID == g_pHyprOpenGL->m_RenderData.pMonitor->ID
 60+					&& std::find(rendered_groups.begin(), rendered_groups.end(), &entry) == rendered_groups.end()
 61+			) {
 62+				entry.renderTabBar();
 63+			}
 64+		}
 65+
 66+		break;
 67+	default:
 68+		break;
 69+	}
 70+}
 71+
 72+void Hy3Layout::tickHook(void*, std::any) {
 73+	auto& tab_groups = g_Hy3Layout->tab_groups;
 74+	auto entry = tab_groups.begin();
 75+	while (entry != tab_groups.end()) {
 76+		entry->damageIfRequired();
 77+		if (entry->bar.destroy) tab_groups.erase(entry++);
 78+		else entry = std::next(entry);
 79+	}
 80+}
 81+
 82 std::string Hy3Node::debugNode() {
 83 	std::stringstream buf;
 84 	std::string addr = "0x" + std::to_string((size_t)this);
 85@@ -1580,55 +1634,3 @@ std::string Hy3Node::debugNode() {
 86 
 87 	return buf.str();
 88 }
 89-
 90-// Recursively render tabs on all tab groups.
 91-void renderTabsRecursive(Hy3Node& node);
 92-
 93-// Render tabs for the provided node, blindly assuming it is a tab group.
 94-void renderTabs(Hy3Node& node);
 95-
 96-void Hy3Layout::renderHook(void*, std::any data) {
 97-	static bool rendering_normally = false;
 98-	static std::vector<Hy3TabGroup*> rendered_groups;
 99-
100-	auto render_stage = std::any_cast<eRenderStage>(data);
101-
102-	switch (render_stage) {
103-	case RENDER_PRE_WINDOWS:
104-		rendering_normally = true;
105diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
106index 1196471413edd4b9ae550e370eb16de9abfe8387..d065d06d4b3726400694231cbf515e7206185e5b 100644
107--- a/src/Hy3Layout.hpp
108+++ b/src/Hy3Layout.hpp
109@@ -139,6 +139,7 @@ public:
110 	Hy3Node* getWorkspaceFocusedNode(const int&);
111 
112 	static void renderHook(void*, std::any);
113+	static void tickHook(void*, std::any);
114 
115 	std::list<Hy3Node> nodes;
116 	std::list<Hy3TabGroup> tab_groups;
117diff --git a/src/TabGroup.cpp b/src/TabGroup.cpp
118index b9eb99e26073fcbfaa052abb8244532262f0f7a4..32ddfb6cbaa93446afd5e9f6f46bc2e74fb63d70 100644
119--- a/src/TabGroup.cpp
120+++ b/src/TabGroup.cpp
121@@ -14,7 +14,7 @@ Hy3TabBarEntry::Hy3TabBarEntry(Hy3TabBar& tab_bar, Hy3Node& node): tab_bar(tab_b
122 	this->offset.registerVar();
123 	this->width.registerVar();
124 
125-	auto update_callback = [this](void*) { this->tab_bar.needs_redraw = true; };
126+	auto update_callback = [this](void*) { this->tab_bar.dirty = true; };
127 
128 	this->offset.setUpdateCallback(update_callback);
129 	this->width.setUpdateCallback(update_callback);
130@@ -34,14 +34,14 @@ bool Hy3TabBarEntry::operator==(const Hy3TabBarEntry& entry) const {
131 void Hy3TabBarEntry::setFocused(bool focused) {
132 	if (this->focused != focused) {
133 		this->focused = focused;
134-		this->tab_bar.needs_redraw = true;
135+		this->tab_bar.dirty = true;
136 	}
137 }
138 
139 void Hy3TabBarEntry::setUrgent(bool urgent) {
140 	if (this->urgent != urgent) {
141 		this->urgent = urgent;
142-		this->tab_bar.needs_redraw = true;
143+		this->tab_bar.dirty = true;
144 	}
145 }
146 
147@@ -121,7 +121,7 @@ Hy3TabBar::Hy3TabBar() {
148 	this->vertical_pos.registerVar();
149 	this->fade_opacity.registerVar();
150 
151-	auto update_callback = [this](void*) { this->needs_redraw = true; };
152+	auto update_callback = [this](void*) { this->dirty = true; };
153 
154 	this->vertical_pos.setUpdateCallback(update_callback);
155 	this->fade_opacity.setUpdateCallback(update_callback);
156@@ -280,6 +280,31 @@ void Hy3TabGroup::updateWithGroup(Hy3Node& node) {
157 	}
158 }
159 
160+void Hy3TabGroup::damageIfRequired() {
161+	static const auto* enter_from_top = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:from_top")->intValue;
162+
163+	auto pos = this->pos.vec();
164+	auto size = this->size.vec();
165+	pos.y += (this->bar.vertical_pos.fl() * size.y) * (*enter_from_top ? -1 : 1);
166+
167+	if (this->last_pos != pos || this->last_size != size) {
168+		wlr_box damage_box = { this->last_pos.x, this->last_pos.y, this->last_size.x, this->last_size.y };
169+		g_pHyprRenderer->damageBox(&damage_box);
170+
171+		this->bar.damaged = true;
172+		this->last_pos = pos;
173+		this->last_size = size;
174+	}
175+
176+	if (this->bar.destroy || this->bar.dirty) {
177+		wlr_box damage_box = { pos.x, pos.y, size.x, size.y };
178+		g_pHyprRenderer->damageBox(&damage_box);
179+
180+		this->bar.damaged = true;
181+		this->bar.dirty = false;
182+	}
183+}
184+
185 void Hy3TabGroup::renderTabBar() {
186 	static const auto* window_rounding = &HyprlandAPI::getConfigValue(PHANDLE, "decoration:rounding")->intValue;
187 	static const auto* enter_from_top = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:from_top")->intValue;
188@@ -296,25 +321,16 @@ void Hy3TabGroup::renderTabBar() {
189 	auto scaled_size = Vector2D(std::round(size.x * scale), std::round(size.y * scale));
190 	wlr_box box = { scaled_pos.x, scaled_pos.y, scaled_size.x, scaled_size.y };
191 
192-	this->bar.needs_redraw = true;
193-	/*if (!this->bar.needs_redraw) {
194+	if (!this->bar.damaged) {
195 		pixman_region32 damage;
196 		pixman_region32_init(&damage);
197 		pixman_region32_intersect_rect(&damage, g_pHyprOpenGL->m_RenderData.pDamage, box.x, box.y, box.width, box.height);
198-		this->bar.needs_redraw = pixman_region32_not_empty(&damage);
199+		this->bar.damaged = pixman_region32_not_empty(&damage);
200 		pixman_region32_fini(&damage);
201-	}*/
202-
203-	if (this->bar.destroy || this->last_pos != scaled_pos || this->last_size != scaled_size) {
204-		wlr_box damage_box = { this->last_pos.x, this->last_pos.y, this->last_size.x, this->last_size.y };
205-		monitor->addDamage(&damage_box);
206-		this->last_pos = scaled_pos;
207-		this->last_size = scaled_size;
208-		this->bar.needs_redraw = true;
209 	}
210 
211-	if (!this->bar.needs_redraw || this->bar.destroy) return;
212-	this->bar.needs_redraw = false;
213+	if (!this->bar.damaged || this->bar.destroy) return;
214+	this->bar.damaged = false;
215 
216 	this->bar.setSize(scaled_size);
217 
218@@ -379,8 +395,6 @@ void Hy3TabGroup::renderTabBar() {
219 		glStencilMask(0xff);
220 		glStencilFunc(GL_ALWAYS, 1, 0xff);
221diff --git a/src/TabGroup.hpp b/src/TabGroup.hpp
222index e01daa2b9cce1854864873b057b7d42f6f33b466..2834a3cdd290accf85a0651ebcac8f95cfb55084 100644
223--- a/src/TabGroup.hpp
224+++ b/src/TabGroup.hpp
225@@ -38,7 +38,8 @@ struct Hy3TabBarEntry {
226 class Hy3TabBar {
227 public:
228 	bool destroy = false;
229-	bool needs_redraw = true;
230+	bool dirty = true;
231+	bool damaged = true;
232 	CAnimatedVariable vertical_pos;
233 	CAnimatedVariable fade_opacity;
234 
235@@ -71,6 +72,7 @@ public:
236 
237 	// update tab bar with node position and data. UB if node is not a group.
238 	void updateWithGroup(Hy3Node&);
239+	void damageIfRequired();
240 	// render the scaled tab bar on the current monitor.
241 	void renderTabBar();
242