Diff
1diff --git a/flake.lock b/flake.lock
2index 5fc180c9f6dacc7ccc51a6c87f87120f50e32425..0abb1d4802853ab6161b0fe0d421e9895f797693 100644
3--- a/flake.lock
4+++ b/flake.lock
5@@ -10,11 +10,11 @@
6 "xdph": "xdph"
7 },
8 "locked": {
9- "lastModified": 1708272248,
10- "narHash": "sha256-EMGPzNg9422NEoFJUfidRHPokX2+UWErX9qSghpfS/g=",
11+ "lastModified": 1708650152,
12+ "narHash": "sha256-OZUS5FED7KKAPpNaJYQr4BPGXQzGrDFgkKVg9U2aZh8=",
13 "owner": "hyprwm",
14 "repo": "Hyprland",
15- "rev": "301b48b74087cc59753ffa144b215540e6f82831",
16+ "rev": "8c3613632a6ccebf9fb797ec756ecfce99514eec",
17 "type": "github"
18 },
19 "original": {
20@@ -131,18 +131,18 @@
21 "flake": false,
22 "locked": {
23 "host": "gitlab.freedesktop.org",
24- "lastModified": 1706359063,
25- "narHash": "sha256-5HUTG0p+nCJv3cn73AmFHRZdfRV5AD5N43g8xAePSKM=",
26+ "lastModified": 1708558866,
27+ "narHash": "sha256-Mz6hCtommq7RQfcPnxLINigO4RYSNt23HeJHC6mVmWI=",
28 "owner": "wlroots",
29 "repo": "wlroots",
30- "rev": "00b869c1a96f300a8f25da95d624524895e0ddf2",
31+ "rev": "0cb091f1a2d345f37d2ee445f4ffd04f7f4ec9e5",
32 "type": "gitlab"
33 },
34 "original": {
35 "host": "gitlab.freedesktop.org",
36 "owner": "wlroots",
37 "repo": "wlroots",
38- "rev": "00b869c1a96f300a8f25da95d624524895e0ddf2",
39+ "rev": "0cb091f1a2d345f37d2ee445f4ffd04f7f4ec9e5",
40 "type": "gitlab"
41 }
42 },
43diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
44index dde4c3147bbd37abc298a050d7982d45cd9d4783..14b3c9be9fad2e7f9a1cdd026f00fd500b819432 100644
45--- a/src/Hy3Layout.cpp
46+++ b/src/Hy3Layout.cpp
47@@ -543,13 +543,21 @@ void Hy3Layout::fullscreenRequestForWindow(
48 // Copy of vaxry's massive hack
49
50 // clang-format off
51- static const auto gaps_in = ConfigValue<Hyprlang::INT>("general:gaps_in");
52- static const auto gaps_out = ConfigValue<Hyprlang::INT>("general:gaps_out");
53+ static const auto gaps_in = ConfigValue<Hyprlang::CUSTOMTYPE, CCssGapData>("general:gaps_in");
54+ static const auto gaps_out = ConfigValue<Hyprlang::CUSTOMTYPE, CCssGapData>("general:gaps_out");
55 // clang-format on
56
57- int outer_gaps = -(*gaps_in - *gaps_out);
58- auto gap_pos_offset = Vector2D(outer_gaps, outer_gaps);
59- auto gap_size_offset = Vector2D(outer_gaps * 2, outer_gaps * 2);
60+ // clang-format off
61+ auto gap_pos_offset = Vector2D(
62+ -(gaps_in->left - gaps_out->left),
63+ -(gaps_in->top - gaps_out->top)
64+ );
65+ // clang-format on
66+
67+ auto gap_size_offset = Vector2D(
68+ -(gaps_in->left - gaps_out->left) + -(gaps_in->right - gaps_out->right),
69+ -(gaps_in->top - gaps_out->top) + -(gaps_in->bottom - gaps_out->bottom)
70+ );
71
72 Hy3Node fakeNode = {
73 .data = window,
74@@ -1049,8 +1057,8 @@ bottom:
75
76 Hy3Node* findTabBarAt(Hy3Node& node, Vector2D pos, Hy3Node** focused_node) {
77 // clang-format off
78- static const auto gaps_in = ConfigValue<Hyprlang::INT>("general:gaps_in");
79- static const auto gaps_out = ConfigValue<Hyprlang::INT>("general:gaps_out");
80+ static const auto gaps_in = ConfigValue<Hyprlang::CUSTOMTYPE, CCssGapData>("general:gaps_in");
81+ static const auto gaps_out = ConfigValue<Hyprlang::CUSTOMTYPE, CCssGapData>("general:gaps_out");
82 static const auto tab_bar_height = ConfigValue<Hyprlang::INT>("plugin:hy3:tabs:height");
83 static const auto tab_bar_padding = ConfigValue<Hyprlang::INT>("plugin:hy3:tabs:padding");
84 // clang-format on
85@@ -1058,9 +1066,9 @@ Hy3Node* findTabBarAt(Hy3Node& node, Vector2D pos, Hy3Node** focused_node) {
86 auto inset = *tab_bar_height + *tab_bar_padding;
87
88 if (node.parent == nullptr) {
89- inset += *gaps_out;
90+ inset += gaps_out->left;
91 } else {
92- inset += *gaps_in;
93+ inset += gaps_in->left;
94 }
95
96 if (node.data.type == Hy3NodeType::Group) {
97@@ -1468,7 +1476,7 @@ void Hy3Layout::applyNodeDataToWindow(Hy3Node* node, bool no_animation) {
98 }
99
100 // clang-format off
101- static const auto gaps_in = ConfigValue<Hyprlang::INT>("general:gaps_in");
102+ static const auto gaps_in = ConfigValue<Hyprlang::CUSTOMTYPE, CCssGapData>("general:gaps_in");
103 static const auto single_window_no_gaps = ConfigValue<Hyprlang::INT>("plugin:hy3:no_gaps_when_only");
104 // clang-format on
105
106@@ -1517,9 +1525,10 @@ void Hy3Layout::applyNodeDataToWindow(Hy3Node* node, bool no_animation) {
107 auto calcPos = window->m_vPosition;
108 auto calcSize = window->m_vSize;
109
110- auto gaps_offset_topleft = Vector2D(*gaps_in, *gaps_in) + node->gap_topleft_offset;
111- auto gaps_offset_bottomright = Vector2D(*gaps_in * 2, *gaps_in * 2)
112- + node->gap_bottomright_offset + node->gap_topleft_offset;
113+ auto gaps_offset_topleft = Vector2D(gaps_in->left, gaps_in->top) + node->gap_topleft_offset;
114+ auto gaps_offset_bottomright =
115+ Vector2D(gaps_in->left + gaps_in->right, gaps_in->top + gaps_in->bottom)
116+ + node->gap_bottomright_offset + node->gap_topleft_offset;
117
118 calcPos = calcPos + gaps_offset_topleft;
119 calcSize = calcSize - gaps_offset_bottomright;
120diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp
121index 59264f27ce60cb333ebba325f76b4c2ca5e11087..5eed0fcffdb8883c48e8b33dc32d39e11ee9be5b 100644
122--- a/src/Hy3Node.cpp
123+++ b/src/Hy3Node.cpp
124@@ -270,13 +270,25 @@ Hy3Node& Hy3Node::getExpandActor() {
125
126 void Hy3Node::recalcSizePosRecursive(bool no_animation) {
127 // clang-format off
128- static const auto gaps_in = ConfigValue<Hyprlang::INT>("general:gaps_in");
129- static const auto gaps_out = ConfigValue<Hyprlang::INT>("general:gaps_out");
130+ static const auto gaps_in = ConfigValue<Hyprlang::CUSTOMTYPE, CCssGapData>("general:gaps_in");
131+ static const auto gaps_out = ConfigValue<Hyprlang::CUSTOMTYPE, CCssGapData>("general:gaps_out");
132 static const auto group_inset = ConfigValue<Hyprlang::INT>("plugin:hy3:group_inset");
133 static const auto tab_bar_height = ConfigValue<Hyprlang::INT>("plugin:hy3:tabs:height");
134 static const auto tab_bar_padding = ConfigValue<Hyprlang::INT>("plugin:hy3:tabs:padding");
135 // clang-format on
136
137+ // clang-format off
138+ auto gap_topleft_offset = Vector2D(
139+ -(gaps_in->left - gaps_out->left),
140+ -(gaps_in->top - gaps_out->top)
141+ );
142+
143+ auto gap_bottomright_offset = Vector2D(
144+ -(gaps_in->right - gaps_out->right),
145+ -(gaps_in->bottom - gaps_out->bottom)
146+ );
147+ // clang-format on
148+
149 if (this->data.type == Hy3NodeType::Window && this->data.as_window->m_bIsFullscreen) {
150 auto* workspace = g_pCompositor->getWorkspaceByID(this->workspace_id);
151 auto* monitor = g_pCompositor->getMonitorFromID(workspace->m_iMonitorID);
152@@ -287,11 +299,6 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
153 return;
154 }
155
156- int outer_gaps = -(*gaps_in - *gaps_out);
157-
158- auto gap_topleft_offset = Vector2D(outer_gaps, outer_gaps);
159- auto gap_bottomright_offset = Vector2D(outer_gaps, outer_gaps);
160-
161 Hy3Node fake_node = {
162 .data = this->data.as_window,
163 .position = monitor->vecPosition + monitor->vecReservedTopLeft,
164@@ -305,15 +312,7 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
165 return;
166 }
167
168- int outer_gaps = 0;
169- Vector2D gap_topleft_offset;
170- Vector2D gap_bottomright_offset;
171- if (this->parent == nullptr) {
172- outer_gaps = -(*gaps_in - *gaps_out);
173-
174- gap_topleft_offset = Vector2D(outer_gaps, outer_gaps);
175- gap_bottomright_offset = Vector2D(outer_gaps, outer_gaps);
176- } else {
177+ if (this->parent != nullptr) {
178 gap_topleft_offset = this->gap_topleft_offset;
179 gap_bottomright_offset = this->gap_bottomright_offset;
180 }
181diff --git a/src/TabGroup.cpp b/src/TabGroup.cpp
182index b48a7848281c996e19ff8122dc445ee805182ed3..e7049fb932a4fc7343308a94137a52c37548e279 100644
183--- a/src/TabGroup.cpp
184+++ b/src/TabGroup.cpp
185@@ -452,16 +452,19 @@ Hy3TabGroup::Hy3TabGroup(Hy3Node& node) {
186 }
187
188 void Hy3TabGroup::updateWithGroup(Hy3Node& node, bool warp) {
189- static const auto gaps_in = ConfigValue<Hyprlang::INT>("general:gaps_in");
190- static const auto gaps_out = ConfigValue<Hyprlang::INT>("general:gaps_out");
191+ static const auto gaps_in = ConfigValue<Hyprlang::CUSTOMTYPE, CCssGapData>("general:gaps_in");
192+ static const auto gaps_out = ConfigValue<Hyprlang::CUSTOMTYPE, CCssGapData>("general:gaps_out");
193 static const auto bar_height = ConfigValue<Hyprlang::INT>("plugin:hy3:tabs:height");
194
195- auto gaps = node.parent == nullptr ? *gaps_out : *gaps_in;
196- auto tpos = node.position + Vector2D(gaps, gaps) + node.gap_topleft_offset;
197+ auto& gaps = node.parent == nullptr ? gaps_out : gaps_in;
198+ auto tpos = node.position + Vector2D(gaps->left, gaps->top) + node.gap_topleft_offset;
199+
200+ // clang-format off
201 auto tsize = Vector2D(
202- node.size.x - node.gap_bottomright_offset.x - node.gap_topleft_offset.x - gaps * 2,
203- *bar_height
204+ node.size.x - node.gap_bottomright_offset.x - node.gap_topleft_offset.x - (gaps->left + gaps->right),
205+ *bar_height
206 );
207+ // clang-format on
208
209 this->hidden = node.hidden;
210 if (this->pos.goalv() != tpos) {
211diff --git a/src/globals.hpp b/src/globals.hpp
212index fbaabe506bb56386e9fab48b65d9a97d86da9e2b..48839ca34b5ca87ab3721242200c680df7fc176d 100644
213--- a/src/globals.hpp
214+++ b/src/globals.hpp
215@@ -1,5 +1,7 @@
216 #pragma once
217
218+#include <type_traits>
219+
220 #include <hyprland/src/plugins/PluginAPI.hpp>
221 #include <hyprlang.hpp>
222
223@@ -21,23 +23,43 @@ inline void errorNotif() {
224 );
225 }
226
227-template <typename T>
228+class HyprlangUnspecifiedCustomType {};
229+
230+// abandon hope all ye who enter here
231+template <typename T, typename V = HyprlangUnspecifiedCustomType>
232 class ConfigValue {
233 public:
234 ConfigValue(const std::string& option) {
235 this->static_data_ptr = HyprlandAPI::getConfigValue(PHANDLE, option)->getDataStaticPtr();
236 }
237
238- const T& get() const { return *(T*) *this->static_data_ptr; }
239+ template <typename U = T>
240+ typename std::enable_if<std::is_same<U, Hyprlang::CUSTOMTYPE>::value, const V&>::type
241+ operator*() const {
242+ return *(V*) ((Hyprlang::CUSTOMTYPE*) *this->static_data_ptr)->getData();
243+ }
244+
245+ template <typename U = T>
246+ typename std::enable_if<std::is_same<U, Hyprlang::CUSTOMTYPE>::value, const V*>::type
247+ operator->() const {
248+ return &**this;
249+ }
250+
251+ // Bullshit microptimization case for strings
252+ template <typename U = T>
253+ typename std::enable_if<std::is_same<U, Hyprlang::STRING>::value, const char*>::type
254+ operator*() const {
255+ return *(const char**) this->static_data_ptr;
256+ }
257
258- const T& operator*() const { return this->get(); }
259+ template <typename U = T>
260+ typename std::enable_if<
261+ !std::is_same<U, Hyprlang::CUSTOMTYPE>::value && !std::is_same<U, Hyprlang::STRING>::value,
262+ const T&>::type
263+ operator*() const {
264+ return *(T*) *this->static_data_ptr;
265+ }
266
267 private:
268 void* const* static_data_ptr;
269 };
270-
271-// Bullshit undocumented microptimization case for strings
272-template <>
273-inline const Hyprlang::STRING& ConfigValue<Hyprlang::STRING>::get() const {
274- return *(char* const*) this->static_data_ptr;
275-}