131a51be6209e7c2e308517e119ece88faec1a21
- Author
- outfoxxed <outfoxxed@outfoxxed.me>
- Committer
- outfoxxed <outfoxxed@outfoxxed.me>
- Date
Message
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