summaryrefslogtreecommitdiff
path: root/patches/directional-gaps-pbadeer.patch
blob: 289893ab7974dc2835c7b3c890ce11ad02538d34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
Author: pbadeer
Date: 2025-07-20
Description: Add directional gap support with runtime adjustment
Commit Version: 539a8ff (fix bottom bar struts taking half screen && windows killed on exit)

This patch extends the existing gap system to support individual gaps for each side:
gap_top, gap_bottom, gap_left, and gap_right. The original 'gaps' config option
is preserved for backward compatibility and sets all four directional gaps when used.

Key features:
- Individual gap configuration per side (gap_top, gap_bottom, gap_left, gap_right)
- Runtime adjustment functions for each gap direction
- Parser commands: increase_gap_[side], decrease_gap_[side]
- Backward compatibility with existing 'gaps' option
- Fixed stack window positioning to avoid internal gaps
- Transparent border fix for picom compatibility
- Added linux-headers dependency for Alpine Linux builds

This allows users to configure asymmetric gaps for specific layouts while
maintaining the simplicity of the original gap system for basic use cases.

---

diff --git a/README.md b/README.md
index 11c0314..262b6de 100644
--- a/README.md
+++ b/README.md
@@ -259,7 +259,7 @@ sudo zypper install libX11-devel libXinerama-devel gcc make</code></pre>
 <details>
 <summary>Alpine Linux</summary>
 <pre><code>doas apk update
-doas apk add libx11-dev libxinerama-dev gcc make musl-dev</code></pre>
+doas apk add libx11-dev libxinerama-dev gcc make musl-dev linux-headers</code></pre>
 </details>
 
 <details>
diff --git a/src/defs.h b/src/defs.h
index 1652fbe..496dc61 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -89,6 +89,10 @@ typedef struct Client {
 typedef struct {
 	int modkey;
 	int gaps;
+	int gap_top;
+	int gap_bottom;
+	int gap_left;
+	int gap_right;
 	int border_width;
 	long border_foc_col;
 	long border_ufoc_col;
@@ -131,6 +135,14 @@ typedef struct {
 extern void centre_window();
 extern void close_focused(void);
 extern void dec_gaps(void);
+extern void inc_gap_top(void);
+extern void dec_gap_top(void);
+extern void inc_gap_bottom(void);
+extern void dec_gap_bottom(void);
+extern void inc_gap_left(void);
+extern void dec_gap_left(void);
+extern void inc_gap_right(void);
+extern void dec_gap_right(void);
 extern void focus_next(void);
 extern void focus_prev(void);
 extern void focus_next_mon(void);
diff --git a/src/parser.c b/src/parser.c
index 9e82c08..f347762 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -21,6 +21,14 @@ static const CommandEntry call_table[] = {{"close_window", close_focused},
                                           {"focus_next_mon", focus_next_mon},
                                           {"focus_prev_mon", focus_prev_mon},
                                           {"increase_gaps", inc_gaps},
+                                          {"increase_gap_top", inc_gap_top},
+                                          {"decrease_gap_top", dec_gap_top},
+                                          {"increase_gap_bottom", inc_gap_bottom},
+                                          {"decrease_gap_bottom", dec_gap_bottom},
+                                          {"increase_gap_left", inc_gap_left},
+                                          {"decrease_gap_left", dec_gap_left},
+                                          {"increase_gap_right", inc_gap_right},
+                                          {"decrease_gap_right", dec_gap_right},
                                           {"master_next", move_master_next},
                                           {"master_previous", move_master_prev},
                                           {"move_next_mon", move_next_mon},
@@ -225,7 +233,24 @@ found:
 			}
 		}
 		else if (!strcmp(key, "gaps")) {
-			cfg->gaps = atoi(rest);
+			int gap_val = atoi(rest);
+			cfg->gaps = gap_val;
+			cfg->gap_top = gap_val;
+			cfg->gap_bottom = gap_val;
+			cfg->gap_left = gap_val;
+			cfg->gap_right = gap_val;
+		}
+		else if (!strcmp(key, "gap_top")) {
+			cfg->gap_top = atoi(rest);
+		}
+		else if (!strcmp(key, "gap_bottom")) {
+			cfg->gap_bottom = atoi(rest);
+		}
+		else if (!strcmp(key, "gap_left")) {
+			cfg->gap_left = atoi(rest);
+		}
+		else if (!strcmp(key, "gap_right")) {
+			cfg->gap_right = atoi(rest);
 		}
 		else if (!strcmp(key, "border_width")) {
 			cfg->border_width = atoi(rest);
diff --git a/src/sxwm.c b/src/sxwm.c
index 90ef09d..c6598fb 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -112,7 +112,6 @@ Atom atom_net_active_window;
 Atom atom_net_current_desktop;
 Atom atom_net_supported;
 Atom atom_net_wm_state;
-Atom atom_net_wm_state_fullscreen;
 Atom atom_wm_window_type;
 Atom atom_net_wm_window_type_dock;
 Atom atom_net_workarea;
@@ -367,6 +366,19 @@ void dec_gaps(void)
 {
 	if (user_config.gaps > 0) {
 		user_config.gaps--;
+		user_config.gap_top--;
+		user_config.gap_bottom--;
+		user_config.gap_left--;
+		user_config.gap_right--;
+		tile();
+		update_borders();
+	}
+}
+
+void dec_gap_top(void)
+{
+	if (user_config.gap_top > 0) {
+		user_config.gap_top--;
 		tile();
 		update_borders();
 	}
@@ -854,19 +866,6 @@ void hdl_client_msg(XEvent *xev)
 		change_workspace(ws);
 		return;
 	}
-	if (xev->xclient.message_type == atom_net_wm_state) {
-		long action = xev->xclient.data.l[0];
-		Atom target = xev->xclient.data.l[1];
-		if (target == atom_net_wm_state_fullscreen) {
-			if (action == 1 || action == 2) {
-				toggle_fullscreen();
-			}
-			else if (action == 0 && focused && focused->fullscreen) {
-				toggle_fullscreen();
-			}
-		}
-		return;
-	}
 }
 
 void hdl_config_ntf(XEvent *xev)
@@ -1519,14 +1518,77 @@ void update_workarea(void)
 void inc_gaps(void)
 {
 	user_config.gaps++;
+	user_config.gap_top++;
+	user_config.gap_bottom++;
+	user_config.gap_left++;
+	user_config.gap_right++;
 	tile();
 	update_borders();
 }
 
+void inc_gap_top(void)
+{
+	user_config.gap_top++;
+	tile();
+	update_borders();
+}
+
+void inc_gap_bottom(void)
+{
+	user_config.gap_bottom++;
+	tile();
+	update_borders();
+}
+
+void dec_gap_bottom(void)
+{
+	if (user_config.gap_bottom > 0) {
+		user_config.gap_bottom--;
+		tile();
+		update_borders();
+	}
+}
+
+void inc_gap_left(void)
+{
+	user_config.gap_left++;
+	tile();
+	update_borders();
+}
+
+void dec_gap_left(void)
+{
+	if (user_config.gap_left > 0) {
+		user_config.gap_left--;
+		tile();
+		update_borders();
+	}
+}
+
+void inc_gap_right(void)
+{
+	user_config.gap_right++;
+	tile();
+	update_borders();
+}
+
+void dec_gap_right(void)
+{
+	if (user_config.gap_right > 0) {
+		user_config.gap_right--;
+		tile();
+		update_borders();
+	}
+}
+
 void init_defaults(void)
 {
 	default_config.modkey = Mod4Mask;
 	default_config.gaps = 10;
+	default_config.gap_top = 10;
+	default_config.gap_bottom = 10;
+	default_config.gap_left = 10;
+	default_config.gap_right = 10;
 	default_config.border_width = 1;
 	default_config.border_foc_col = parse_col("#c0cbff");
 	default_config.border_ufoc_col = parse_col("#555555");
@@ -1730,9 +1792,8 @@ long parse_col(const char *hex)
 		return WhitePixel(dpy, DefaultScreen(dpy));
 	}
 
-	/* return col.pixel |= 0xff << 24; */
-	/* This is a fix for picom making the borders transparent. DANGEROUS */
-	return col.pixel;
+	/* possibly unsafe BUT i dont think it can cause any problems */
+	return col.pixel |= 0xff << 24;
 }
 
 void quit(void)
@@ -2062,9 +2123,7 @@ void setup_atoms(void)
 	atom_net_wm_window_type_dock = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
 	atom_net_workarea = XInternAtom(dpy, "_NET_WORKAREA", False);
 	atom_net_wm_state = XInternAtom(dpy, "_NET_WM_STATE", False);
-	atom_net_wm_state_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
 	atom_net_wm_state = XInternAtom(dpy, "_NET_WM_STATE", False);
-	atom_net_wm_state_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
 	atom_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
 	atom_net_supporting_wm_check = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
 	atom_net_wm_name = XInternAtom(dpy, "_NET_WM_NAME", False);
@@ -2078,7 +2137,6 @@ void setup_atoms(void)
 	    atom_net_active_window,
 	    atom_net_supported,
 	    atom_net_wm_state,
-	    atom_net_wm_state_fullscreen,
 	    atom_wm_window_type,
 	    atom_net_wm_window_type_dock,
 	    atom_net_workarea,
@@ -2305,13 +2363,14 @@ void tile(void)
 			continue;
 		}
 
-		int gx = user_config.gaps, gy = user_config.gaps;
-		int tile_x = mon_x + gx, tile_y = mon_y + gy;
-		int tile_w = MAX(1, mon_w - 2 * gx);
-		int tile_h = MAX(1, mon_h - 2 * gy);
+		int gap_left = user_config.gap_left, gap_right = user_config.gap_right;
+		int gap_top = user_config.gap_top, gap_bottom = user_config.gap_bottom;
+		int tile_x = mon_x + gap_left, tile_y = mon_y + gap_top;
+		int tile_w = MAX(1, mon_w - gap_left - gap_right);
+		int tile_h = MAX(1, mon_h - gap_top - gap_bottom);
 		float mf = CLAMP(user_config.master_width[m], MF_MIN, MF_MAX);
 		int master_w = (N > 1) ? (int)(tile_w * mf) : tile_w;
-		int stack_w = (N > 1) ? (tile_w - master_w - gx) : 0;
+		int stack_w = (N > 1) ? (tile_w - master_w) : 0;
 
 		{
 			Client *c = stackers[0];
@@ -2338,7 +2397,6 @@ void tile(void)
 		}
 
 		int bw2 = 2 * user_config.border_width;
-		int num_stack = N - 1;
 		int min_raw = bw2 + 1;
 		int total_fixed_heights = 0, auto_count = 0;
 		int heights_final[MAXCLIENTS] = {0};
@@ -2354,7 +2412,7 @@ void tile(void)
 			}
 		}
 
-		int total_vgaps = (num_stack - 1) * gy;
+		int total_vgaps = 0;
 		int remaining = tile_h - total_fixed_heights - total_vgaps;
 
 		if (auto_count > 0 && remaining >= auto_count * min_raw) {
@@ -2408,7 +2466,7 @@ void tile(void)
 		int sy = tile_y;
 		for (int i = 1; i < N; i++) {
 			Client *c = stackers[i];
-			XWindowChanges wc = {.x = tile_x + master_w + gx,
+			XWindowChanges wc = {.x = tile_x + master_w,
 			                     .y = sy,
 			                     .width = MAX(1, stack_w - (2 * user_config.border_width)),
 			                     .height = MAX(1, heights_final[i] - (2 * user_config.border_width)),
@@ -2423,7 +2481,7 @@ void tile(void)
 			c->w = wc.width;
 			c->h = wc.height;
 
-			sy += heights_final[i] + gy;
+			sy += heights_final[i];
 		}
 
 		update_borders();