e3bb15bc13d1d1cb74ac5240cd7826aaddb7a99b
- 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/TabGroup.cpp b/src/TabGroup.cpp
2index 979444a39e9001b8633c70538fabb983350fa560..b04ce91cc38adebfa069ee8d9328b5f0ad5aafe6 100644
3--- a/src/TabGroup.cpp
4+++ b/src/TabGroup.cpp
5@@ -21,8 +21,8 @@ bool Hy3TabBarEntry::operator==(const Hy3Node& node) const {
6 }
7
8 Hy3TabBar::Hy3TabBar() {
9- this->vertical_pos.create(AVARTYPE_FLOAT, 20.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
10- this->fade_opacity.create(AVARTYPE_FLOAT, 0.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
11+ this->vertical_pos.create(AVARTYPE_FLOAT, 1.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
12+ this->fade_opacity.create(AVARTYPE_FLOAT, 1.0f, g_pConfigManager->getAnimationPropertyConfig("windowsMove"), nullptr, AVARDAMAGE_NONE);
13 this->focus_start.create(AVARTYPE_FLOAT, 0.0f, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), nullptr, AVARDAMAGE_NONE);
14 this->focus_end.create(AVARTYPE_FLOAT, 1.0f, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), nullptr, AVARDAMAGE_NONE);
15 this->vertical_pos.registerVar();
16@@ -221,16 +221,22 @@ void Hy3TabGroup::updateWithGroup(Hy3Node& node) {
17 if (this->size.goalv() != tsize) this->size = tsize;
18
19 this->bar.updateNodeList(node.data.as_group.children);
20+
21+ if (node.data.as_group.lastFocusedChild != nullptr) {
22+ this->updateStencilWindows(*node.data.as_group.lastFocusedChild);
23+ }
24 }
25
26 void Hy3TabGroup::renderTabBar() {
27+ static auto* const window_rounding = &HyprlandAPI::getConfigValue(PHANDLE, "decoration:rounding")->intValue;
28+ static auto* const enter_from_top = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hy3:tabs:from_top")->intValue;
29
30 auto* monitor = g_pHyprOpenGL->m_RenderData.pMonitor;
31 auto scale = monitor->scale;
32
33 auto pos = this->pos.vec();
34- pos.y += this->bar.vertical_pos.fl();
35 auto size = this->size.vec();
36+ pos.y += (this->bar.vertical_pos.fl() * size.y) * (*enter_from_top ? -1 : 1);
37
38 auto scaled_pos = Vector2D(std::round(pos.x * scale), std::round(pos.y * scale));
39 auto scaled_size = Vector2D(std::round(size.x * scale), std::round(size.y * scale));
40@@ -238,7 +244,76 @@ void Hy3TabGroup::renderTabBar() {
41
42 this->bar.setSize(scaled_size);
43
44+ {
45+ glClearStencil(0);
46+ glClear(GL_STENCIL_BUFFER_BIT);
47+ glEnable(GL_STENCIL_TEST);
48+ glStencilMask(0xff);
49+ glStencilFunc(GL_ALWAYS, 1, 0xff);
50+ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
51+
52+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
53+
54+ for (auto* window: this->stencil_windows) {
55+ if (!g_pCompositor->windowExists(window)) continue;
56+
57+ auto wpos = window->m_vRealPosition.vec();
58+ auto wsize = window->m_vRealPosition.vec();
59+
60+ wlr_box window_box = { wpos.x, wpos.y, wsize.x, wsize.y };
61+ g_pHyprOpenGL->renderRect(&window_box, CColor(0, 0, 0, 0), *window_rounding);
62+ }
63+
64+
65+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
66+
67+ glStencilMask(0x00);
68+ glStencilFunc(GL_NOTEQUAL, 1, 0xff);
69+ }
70+
71 this->bar.prepareMask();
72 g_pHyprOpenGL->renderTexture(this->bar.mask_texture, &box, this->bar.fade_opacity.fl());
73+
74+ {
75+ glClearStencil(0);
76+ glClear(GL_STENCIL_BUFFER_BIT);
77+ glDisable(GL_STENCIL_TEST);
78+ glStencilMask(0xff);
79+ glStencilFunc(GL_ALWAYS, 1, 0xff);
80+ }
81+
82 g_pHyprRenderer->damageBox(&box);
83 }
84+
85+void findOverlappingWindows(Hy3Node& node, float height, std::vector<CWindow*>& windows) {
86+ switch (node.data.type) {
87+ case Hy3NodeData::Window:
88+ windows.push_back(node.data.as_window);
89+ break;
90+ case Hy3NodeData::Group:
91+ auto& group = node.data.as_group;
92+
93+ switch (group.layout) {
94+ case Hy3GroupLayout::SplitH:
95+ for (auto* node: group.children) {
96+ findOverlappingWindows(*node, height, windows);
97+ }
98+ break;
99+ case Hy3GroupLayout::SplitV:
100+ for (auto* node: group.children) {
101+ findOverlappingWindows(*node, height, windows);
102+ height -= node->size.y;
103+ if (height <= 0) break;
104+ }
105diff --git a/src/TabGroup.hpp b/src/TabGroup.hpp
106index eb373c4f6d6d0bca500a7828a021b8e79e3e1cd0..399e2156e21364806a8444db75cd34bd27642735 100644
107--- a/src/TabGroup.hpp
108+++ b/src/TabGroup.hpp
109@@ -3,6 +3,7 @@
110 #include <hyprland/src/helpers/AnimatedVariable.hpp>
111 #include <hyprland/src/helpers/Vector2D.hpp>
112 #include <list>
113+#include <vector>
114
115 class Hy3TabGroup;
116 class Hy3TabBar;
117@@ -66,6 +67,11 @@ public:
118 void renderTabBar();
119
120 private:
121+ std::vector<CWindow*> stencil_windows;
122+
123 // moving a Hy3TabGroup will unregister any active animations
124 Hy3TabGroup(Hy3TabGroup&&) = delete;
125+
126+ // UB if node is not a group.
127+ void updateStencilWindows(Hy3Node&);
128 };
129diff --git a/src/main.cpp b/src/main.cpp
130index 309303b838f6221f7bdccb287417e507dc2df6ca..3ffa2dcf281ee31425d2cdf86a38be1af5f23594 100644
131--- a/src/main.cpp
132+++ b/src/main.cpp
133@@ -107,6 +107,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
134
135 HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:no_gaps_when_only", SConfigValue{.intValue = 0});
136 HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:bar_height", SConfigValue{.intValue = 15});
137+ HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:from_top", SConfigValue{.intValue = 0});
138 HyprlandAPI::addConfigValue(PHANDLE, "plugin:hy3:tabs:rounding", SConfigValue{.intValue = 3});
139
140 g_Hy3Layout = std::make_unique<Hy3Layout>();