1a490734bad8f5e0d8296374f40425585dbd3b46
- 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 b93c18172b59de588eaaa12163d1749fdab01326..7c3956fcc4824f6606becb39e3ca9205ea598834 100644
3--- a/src/Hy3Layout.cpp
4+++ b/src/Hy3Layout.cpp
5@@ -496,6 +496,7 @@ Hy3Node* Hy3Node::intoGroup(Hy3GroupLayout layout) {
6 this->data.as_group.group_focused = false;
7 this->data.as_group.focused_child = node;
8 this->recalcSizePosRecursive();
9+ this->updateTabBarRecursive();
10
11 return node;
12 }
13@@ -583,6 +584,15 @@ void Hy3Node::updateTabBar() {
14 }
15 }
16
17+void Hy3Node::updateTabBarRecursive() {
18+ auto* node = this;
19+
20+ while (node != nullptr) {
21+ node->updateTabBar();
22+ node = node->parent;
23+ }
24+}
25+
26 void Hy3Node::updateDecos() {
27 switch (this->data.type) {
28 case Hy3NodeData::Window:
29@@ -1243,6 +1253,7 @@ void Hy3Layout::replaceWindowDataWith(CWindow* from, CWindow* to) {
30 }
31
32 std::unique_ptr<HOOK_CALLBACK_FN> renderHookPtr = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::renderHook);
33+std::unique_ptr<HOOK_CALLBACK_FN> windowTitleHookPtr = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::windowTitleHook);
34 std::unique_ptr<HOOK_CALLBACK_FN> tickHookPtr = std::make_unique<HOOK_CALLBACK_FN>(Hy3Layout::tickHook);
35
36 void Hy3Layout::onEnable() {
37@@ -1257,12 +1268,14 @@ void Hy3Layout::onEnable() {
38 }
39
40 HyprlandAPI::registerCallbackStatic(PHANDLE, "render", renderHookPtr.get());
41+ HyprlandAPI::registerCallbackStatic(PHANDLE, "windowTitle", windowTitleHookPtr.get());
42 HyprlandAPI::registerCallbackStatic(PHANDLE, "tick", tickHookPtr.get());
43 selection_hook::enable();
44 }
45
46 void Hy3Layout::onDisable() {
47 HyprlandAPI::unregisterCallback(PHANDLE, renderHookPtr.get());
48+ HyprlandAPI::unregisterCallback(PHANDLE, windowTitleHookPtr.get());
49 HyprlandAPI::unregisterCallback(PHANDLE, tickHookPtr.get());
50 selection_hook::disable();
51 this->nodes.clear();
52@@ -1594,6 +1607,14 @@ void Hy3Layout::renderHook(void*, std::any data) {
53 }
54 }
55
56+void Hy3Layout::windowTitleHook(void*, std::any data) {
57+ CWindow* window = std::any_cast<CWindow*>(data);
58+ if (window == nullptr) return;
59+ auto* node = g_Hy3Layout->getNodeFromWindow(window);
60+
61+ node->updateTabBarRecursive();
62+}
63+
64 void Hy3Layout::tickHook(void*, std::any) {
65 auto& tab_groups = g_Hy3Layout->tab_groups;
66 auto entry = tab_groups.begin();
67diff --git a/src/Hy3Layout.hpp b/src/Hy3Layout.hpp
68index a373fab7cb5a6046fdd591b704918c8f9d99e6e6..0a75f065713070c6bfc4ea1e85524092b5eb1ad2 100644
69--- a/src/Hy3Layout.hpp
70+++ b/src/Hy3Layout.hpp
71@@ -84,6 +84,8 @@ struct Hy3Node {
72 Hy3Node* getFocusedNode();
73 void updateDecos();
74 void setHidden(bool hidden);
75+ void updateTabBar();
76+ void updateTabBarRecursive();
77 bool isUrgent();
78 bool isIndirectlyFocused();
79 std::string getTitle();
80@@ -100,9 +102,6 @@ struct Hy3Node {
81 Hy3Node* intoGroup(Hy3GroupLayout);
82
83 static void swapData(Hy3Node&, Hy3Node&);
84-
85-private:
86- void updateTabBar();
87 };
88
89 class Hy3Layout: public IHyprLayout {
90@@ -141,6 +140,7 @@ public:
91 Hy3Node* getWorkspaceFocusedNode(const int&);
92
93 static void renderHook(void*, std::any);
94+ static void windowTitleHook(void*, std::any);
95 static void tickHook(void*, std::any);
96
97 std::list<Hy3Node> nodes;
98diff --git a/src/TabGroup.cpp b/src/TabGroup.cpp
99index 3c002a05620c5d4e117d77151b5521e500b1025d..90cc744bb0cc435280ebe954b9f40825e4dbeb71 100644
100--- a/src/TabGroup.cpp
101+++ b/src/TabGroup.cpp
102@@ -4,6 +4,7 @@
103
104 #include <hyprland/src/Compositor.hpp>
105 #include <cairo/cairo.h>
106+#include <pango/pangocairo.h>
107 #include <hyprland/src/helpers/Color.hpp>
108 #include <hyprland/src/plugins/PluginAPI.hpp>
109 #include <hyprland/src/render/OpenGL.hpp>
110@@ -47,27 +48,63 @@ void Hy3TabBarEntry::setUrgent(bool urgent) {
111 }
112 }
113
114+void Hy3TabBarEntry::setWindowTitle(std::string title) {
115+ if (this->window_title != title) {
116+ this->window_title = title;
117+ this->tab_bar.dirty = true;
118+ }
119+}
120+
121 void Hy3TabBarEntry::prepareTexture(float scale, wlr_box& box) {
122- static const auto* rounding_setting = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:rounding")->intValue;
123+ static const auto* s_rounding = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:rounding")->intValue;
124+ static const auto* render_text = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:render_text")->intValue;
125+ static const auto* text_font = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_font")->strValue;
126+ static const auto* text_height = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_height")->intValue;
127+ static const auto* text_padding = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:text_padding")->intValue;
128 static const auto* col_active = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.active")->intValue;
129 static const auto* col_urgent = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.urgent")->intValue;
130 static const auto* col_inactive = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.inactive")->intValue;
131+ static const auto* col_text_active = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.text.active")->intValue;
132+ static const auto* col_text_urgent = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.text.urgent")->intValue;
133+ static const auto* col_text_inactive = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:col.text.inactive")->intValue;
134
135 auto width = box.width;
136 auto height = box.height;
137
138- auto rounding = std::min((double) *rounding_setting, std::min(width * 0.5, height * 0.5));
139+ auto rounding = std::min((double) *s_rounding, std::min(width * 0.5, height * 0.5));
140
141 if (this->texture.m_iTexID == 0
142- || this->last_render_rounding != rounding
143- || this->last_render_focused != focused
144- || this->last_render_urgent != urgent
145- || !wlr_box_equal(&this->last_render_box, &box)
146+ || this->last_render.x != box.x
147+ || this->last_render.y != box.y
148+ || this->last_render.focused != this->focused
149+ || this->last_render.urgent != this->urgent
150+ || this->last_render.window_title != this->window_title
151+ || this->last_render.rounding != rounding
152+ || this->last_render.text_font != *text_font
153+ || this->last_render.text_height != *text_height
154+ || this->last_render.text_padding != *text_padding
155+ || this->last_render.col_active != *col_active
156+ || this->last_render.col_urgent != *col_urgent
157+ || this->last_render.col_inactive != *col_inactive
158+ || this->last_render.col_text_active != *col_text_active
159+ || this->last_render.col_text_urgent != *col_text_urgent
160+ || this->last_render.col_text_inactive != *col_text_inactive
161 ) {
162- this->last_render_rounding = rounding;
163- this->last_render_focused = this->focused;
164- this->last_render_urgent = this->urgent;
165- this->last_render_box = box;
166+ this->last_render.x = box.x;
167+ this->last_render.y = box.y;
168+ this->last_render.focused = this->focused;
169+ this->last_render.urgent = this->urgent;
170+ this->last_render.window_title = this->window_title;
171+ this->last_render.rounding = rounding;
172+ this->last_render.text_font = *text_font;
173+ this->last_render.text_height = *text_height;
174+ this->last_render.text_padding = *text_padding;
175+ this->last_render.col_active = *col_active;
176+ this->last_render.col_urgent = *col_urgent;
177+ this->last_render.col_inactive = *col_inactive;
178+ this->last_render.col_text_active = *col_text_active;
179+ this->last_render.col_text_urgent = *col_text_urgent;
180+ this->last_render.col_text_inactive = *col_text_inactive;
181
182 auto cairo_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
183 auto cairo = cairo_create(cairo_surface);
184@@ -104,6 +141,45 @@ void Hy3TabBarEntry::prepareTexture(float scale, wlr_box& box) {
185 // draw
186 cairo_fill(cairo);
187
188+ // render window title
189+ if (*render_text) {
190+ PangoLayout* layout = pango_cairo_create_layout(cairo);
191+ pango_layout_set_text(layout, this->window_title.c_str(), -1);
192+
193+ PangoFontDescription* font_desc = pango_font_description_from_string(text_font->c_str());
194+ pango_font_description_set_size(font_desc, *text_height * scale * PANGO_SCALE);
195+ pango_layout_set_font_description(layout, font_desc);
196+ pango_font_description_free(font_desc);
197+
198+ int padding = *text_padding * scale;
199+ int width = box.width - padding * 2;
200+
201+ pango_layout_set_width(layout, width * PANGO_SCALE);
202diff --git a/src/TabGroup.hpp b/src/TabGroup.hpp
203index 7e43e9575e4920562d7562f6404b928759b23f1b..e463f92030b523d5d50b80a0fe74c2b5e9f8ae90 100644
204--- a/src/TabGroup.hpp
205+++ b/src/TabGroup.hpp
206@@ -21,10 +21,25 @@ struct Hy3TabBarEntry {
207 CAnimatedVariable width; // 0.0-1.0 of total bar
208 Hy3TabBar& tab_bar;
209 Hy3Node& node; // only used for comparioson. do not deref.
210- wlr_box last_render_box;
211- float last_render_rounding = 0.0;
212- bool last_render_focused = false;
213- bool last_render_urgent = false;
214+
215+ struct {
216+ int x, y;
217+ float rounding = 0.0;
218+ float scale = 0.0;
219+ bool focused = false;
220+ bool urgent = false;
221+ std::string window_title;
222+
223+ std::string text_font;
224+ int text_height = 0;
225+ int text_padding = 0;
226+ int col_active = 0;
227+ int col_urgent = 0;
228+ int col_inactive = 0;
229+ int col_text_active = 0;
230+ int col_text_urgent = 0;
231+ int col_text_inactive = 0;
232+ } last_render;
233
234 Hy3TabBarEntry(Hy3TabBar&, Hy3Node&);
235 bool operator==(const Hy3Node&) const;
236@@ -32,6 +47,7 @@ struct Hy3TabBarEntry {
237
238 void setFocused(bool);
239 void setUrgent(bool);
240+ void setWindowTitle(std::string);
241 void prepareTexture(float, wlr_box&);
242 };
243
244diff --git a/src/main.cpp b/src/main.cpp
245index e2cc10afa14bfecb3f9e1eb0b9900eedd3f7c04a..a572c6c8e69c980baafb558a5fedec4a63550778 100644
246--- a/src/main.cpp
247+++ b/src/main.cpp
248@@ -108,11 +108,18 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
249 HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:no_gaps_when_only", SConfigValue{.intValue = 0});
250 HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:height", SConfigValue{.intValue = 15});
251 HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:padding", SConfigValue{.intValue = 5});
252+ HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:from_top", SConfigValue{.intValue = 0});
253+ HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:rounding", SConfigValue{.intValue = 3});
254+ HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:render_text", SConfigValue{.intValue = 1});
255+ HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:text_font", SConfigValue{.strValue = "Sans"});
256+ HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:text_height", SConfigValue{.intValue = 8});
257+ HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:text_padding", SConfigValue{.intValue = 3});
258 HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:col.active", SConfigValue{.intValue = 0xff32b4ff});
259 HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:col.urgent", SConfigValue{.intValue = 0xffff4f4f});
260 HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:col.inactive", SConfigValue{.intValue = 0x80808080});
261- HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:from_top", SConfigValue{.intValue = 0});
262- HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:rounding", SConfigValue{.intValue = 3});
263+ HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:col.text.active", SConfigValue{.intValue = 0xff000000});
264+ HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:col.text.urgent", SConfigValue{.intValue = 0xff000000});
265+ HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:col.text.inactive", SConfigValue{.intValue = 0xff000000});
266
267 g_Hy3Layout = std::make_unique<Hy3Layout>();
268 HyprlandAPI::addLayout(PHANDLE, "hy3", g_Hy3Layout.get());