90b50d5b1ac149448b635b9de889bd20f3f26ec1
- 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 d80cf1c593fafa1d91ca872a285c2bb898d92659..176fd8a3adcc9d3121617293b45fccde05ac8968 100644
3--- a/src/Hy3Layout.cpp
4+++ b/src/Hy3Layout.cpp
5@@ -1588,36 +1588,46 @@ void renderTabsRecursive(Hy3Node& node);
6 void renderTabs(Hy3Node& node);
7
8 void Hy3Layout::renderHook(void*, std::any data) {
9+ static bool rendering_normally = false;
10+ static std::vector<Hy3TabGroup*> rendered_groups;
11+
12 auto render_stage = std::any_cast<eRenderStage>(data);
13- if (render_stage == RENDER_POST_WINDOW) {
14+
15+ switch (render_stage) {
16+ case RENDER_PRE_WINDOWS:
17+ rendering_normally = true;
18+ rendered_groups.clear();
19+ break;
20+ case RENDER_POST_WINDOW: {
21+ if (!rendering_normally) break;
22+
23 auto& tab_groups = g_Hy3Layout->tab_groups;
24 auto entry = tab_groups.begin();
25 while (entry != tab_groups.end()) {
26- if (entry->bar.destroy) tab_groups.erase(entry++);
27- else if (entry->target_window == g_pHyprOpenGL->m_pCurrentWindow) entry++->renderTabBar();
28- else entry++;
29+ if (entry->target_window == g_pHyprOpenGL->m_pCurrentWindow && std::find(rendered_groups.begin(), rendered_groups.end(), &*entry) == rendered_groups.end()) {
30+ entry->renderTabBar();
31+ rendered_groups.push_back(&*entry);
32+ }
33+
34+ entry = std::next(entry);
35 }
36- }
37-}
38+ } break;
39+ case RENDER_POST_WINDOWS: {
40+ rendering_normally = false;
41
42-void renderTabsRecursive(Hy3Node& node) {
43- if (node.data.type == Hy3NodeData::Group) {
44- for (auto* child: node.data.as_group.children) {
45- if (node.data.as_group.layout != Hy3GroupLayout::Tabbed
46- || node.data.as_group.focused_child == child)
47- {
48- renderTabsRecursive(*child);
49+ auto& tab_groups = g_Hy3Layout->tab_groups;
50+ auto entry = tab_groups.begin();
51+ while (entry != tab_groups.end()) {
52+ if (std::find(rendered_groups.begin(), rendered_groups.end(), &*entry) == rendered_groups.end()) {
53+ entry->renderTabBar();
54+ if (entry->bar.destroy) tab_groups.erase(entry++);
55 }
56- }
57
58- if (node.data.as_group.layout == Hy3GroupLayout::Tabbed) {
59- renderTabs(node);
60+ entry = std::next(entry);
61 }
62- }
63-}
64
65-void renderTabs(Hy3Node& node) {
66- auto& group = node.data.as_group;
67-
68- group.tab_bar->renderTabBar();
69+ } break;
70+ default:
71+ break;
72+ }
73 }
74diff --git a/src/TabGroup.cpp b/src/TabGroup.cpp
75index a85f5e47fcbc7d5885b88e6394196808fe8bdbbd..a2403d0904e58f93da530b4787da28f9b54e017a 100644
76--- a/src/TabGroup.cpp
77+++ b/src/TabGroup.cpp
78@@ -4,6 +4,8 @@
79
80 #include <hyprland/src/Compositor.hpp>
81 #include <cairo/cairo.h>
82+#include <hyprland/src/render/OpenGL.hpp>
83+#include <pixman.h>
84
85 Hy3TabBarEntry::Hy3TabBarEntry(Hy3TabBar& tab_bar, Hy3Node& node): tab_bar(tab_bar), node(node) {
86 this->offset.create(AVARTYPE_FLOAT, -1.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
87@@ -12,6 +14,11 @@ Hy3TabBarEntry::Hy3TabBarEntry(Hy3TabBar& tab_bar, Hy3Node& node): tab_bar(tab_b
88 this->offset.registerVar();
89 this->width.registerVar();
90
91+ auto update_callback = [this](void*) { this->tab_bar.needs_redraw = true; };
92+
93+ this->offset.setUpdateCallback(update_callback);
94+ this->width.setUpdateCallback(update_callback);
95+
96 this->window_title = node.getTitle();
97 this->urgent = node.isUrgent();
98 }
99@@ -24,6 +31,20 @@ bool Hy3TabBarEntry::operator==(const Hy3TabBarEntry& entry) const {
100 return this->node == entry.node;
101 }
102
103+void Hy3TabBarEntry::setFocused(bool focused) {
104+ if (this->focused != focused) {
105+ this->focused = focused;
106+ this->tab_bar.needs_redraw = true;
107+ }
108+}
109+
110+void Hy3TabBarEntry::setUrgent(bool urgent) {
111+ if (this->urgent != urgent) {
112+ this->urgent = urgent;
113+ this->tab_bar.needs_redraw = true;
114+ }
115+}
116+
117 void Hy3TabBarEntry::prepareTexture(float scale, wlr_box& box) {
118 static const auto* rounding_setting = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:rounding")->intValue;
119
120@@ -96,13 +117,14 @@ void Hy3TabBarEntry::prepareTexture(float scale, wlr_box& box) {
121
122 Hy3TabBar::Hy3TabBar() {
123 this->vertical_pos.create(AVARTYPE_FLOAT, 1.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
124- this->fade_opacity.create(AVARTYPE_FLOAT, 1.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
125- this->focus_start.create(AVARTYPE_FLOAT, 0.0f, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), nullptr, AVARDAMAGE_NONE);
126- this->focus_end.create(AVARTYPE_FLOAT, 1.0f, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), nullptr, AVARDAMAGE_NONE);
127+ this->fade_opacity.create(AVARTYPE_FLOAT, 0.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
128 this->vertical_pos.registerVar();
129 this->fade_opacity.registerVar();
130- this->focus_start.registerVar();
131- this->focus_end.registerVar();
132+
133+ auto update_callback = [this](void*) { this->needs_redraw = true; };
134+
135+ this->vertical_pos.setUpdateCallback(update_callback);
136+ this->fade_opacity.setUpdateCallback(update_callback);
137
138 this->vertical_pos = 0.0;
139 this->fade_opacity = 1.0;
140@@ -114,22 +136,6 @@ void Hy3TabBar::beginDestroy() {
141 this->fade_opacity.setCallbackOnEnd([this](void*) { this->destroy = true; });
142 }
143
144-void Hy3TabBar::focusNode(Hy3Node* node) {
145- this->focused_node = node;
146-
147- if (this->focused_node == nullptr) {
148- this->focus_start = 0.0;
149- this->focus_end = 1.0;
150- } else {
151- auto entry = std::find(this->entries.begin(), this->entries.end(), *node);
152-
153- if (entry != this->entries.end()) {
154- this->focus_start = entry->offset.goalf();
155- this->focus_end = entry->offset.goalf() + entry->width.goalf();
156- }
157- }
158-}
159-
160 void Hy3TabBar::updateNodeList(std::list<Hy3Node*>& nodes) {
161 std::list<std::list<Hy3TabBarEntry>::iterator> removed_entries;
162
163@@ -184,8 +190,8 @@ void Hy3TabBar::updateNodeList(std::list<Hy3Node*>& nodes) {
164 }
165
166 // set stats from node data
167- entry->focused = (*node)->isIndirectlyFocused();
168- entry->urgent = (*node)->isUrgent();
169+ entry->setFocused((*node)->isIndirectlyFocused());
170+ entry->setUrgent((*node)->isUrgent());
171
172 node = std::next(node);
173 if (entry != this->entries.end()) entry = std::next(entry);
174@@ -288,7 +294,27 @@ void Hy3TabGroup::renderTabBar() {
175
176 auto scaled_pos = Vector2D(std::round(pos.x * scale), std::round(pos.y * scale));
177 auto scaled_size = Vector2D(std::round(size.x * scale), std::round(size.y * scale));
178diff --git a/src/TabGroup.hpp b/src/TabGroup.hpp
179index 7daf1ec55c3dacba1da86cf31e0aed2d4c291856..e01daa2b9cce1854864873b057b7d42f6f33b466 100644
180--- a/src/TabGroup.hpp
181+++ b/src/TabGroup.hpp
182@@ -30,19 +30,21 @@ struct Hy3TabBarEntry {
183 bool operator==(const Hy3Node&) const;
184 bool operator==(const Hy3TabBarEntry&) const;
185
186+ void setFocused(bool);
187+ void setUrgent(bool);
188 void prepareTexture(float, wlr_box&);
189 };
190
191 class Hy3TabBar {
192 public:
193 bool destroy = false;
194+ bool needs_redraw = true;
195 CAnimatedVariable vertical_pos;
196 CAnimatedVariable fade_opacity;
197
198 Hy3TabBar();
199 void beginDestroy();
200
201- void focusNode(Hy3Node*);
202 void updateNodeList(std::list<Hy3Node*>& nodes);
203 void updateAnimations(bool warp = false);
204 void setSize(Vector2D);
205@@ -50,10 +52,6 @@ public:
206 std::list<Hy3TabBarEntry> entries;
207 private:
208 Hy3Node* focused_node = nullptr;
209- CAnimatedVariable focus_opacity;
210- CAnimatedVariable focus_start;
211- CAnimatedVariable focus_end;
212-
213 Vector2D size;
214
215 // Tab bar entries take a reference to `this`.
216@@ -78,6 +76,8 @@ public:
217
218 private:
219 std::vector<CWindow*> stencil_windows;
220+ Vector2D last_pos;
221+ Vector2D last_size;
222
223 Hy3TabGroup();
224