commit 61baa02
wf
·
2026-05-07 18:48:47 +0000 UTC
parent 67d143b
Add optional IPC command arguments
4 files changed,
+105,
-104
+1,
-1
1@@ -11,7 +11,7 @@ TODO
2 ----
3
4 * Sort window list output by window stack order
5- * Add optional window ID flags to `get_*` commands
6+ * Improve code quality; remove some hacky stuff
7
8 REQUIREMENTS
9 ------------
+1,
-1
1@@ -147,7 +147,7 @@ main(int argc, char **argv) {
2
3 for (int i = 0; i < (int)(sizeof commands / sizeof commands[0]); i++) {
4 if (strcmp(commands[i].name, argv[1]) == 0) {
5- if (commands[i].argc != argc - 2) {
6+ if (argc - 2 < commands[i].argc) {
7 fprintf(stderr, "Wrong number of arguments for %s (need %d)\n", commands[i].name, commands[i].argc);
8 return 1;
9 }
+3,
-4
1@@ -506,12 +506,11 @@ ws_go_to(uint8_t ws) {
2 }
3
4 void
5-ws_move_to(uint8_t ws) {
6- struct client *c, *next;
7+ws_move_to(uint8_t ws, struct client *c) {
8+ struct client *next;
9
10- if (!wm.cur || ws < 1 || ws > 9)
11+ if (!c || ws < 1 || ws > 9)
12 return;
13- c = wm.cur;
14 if (c->ws == ws)
15 return;
16
+100,
-98
1@@ -11,6 +11,15 @@
2 #include "types.h"
3 #include "ipc.h"
4
5+/* ugly mess but better than nothing */
6+#define ARG_CLIENT(x) \
7+ uint32_t id = wm.cur->id; \
8+ if (x) id = fn_uint(x); \
9+ struct client *tmp, *c = wm.cur; \
10+ wl_list_for_each(tmp, &wm.clients, link) \
11+ if (tmp->id == id) c = tmp; \
12+ if (!c) return (status){ false, "" }
13+
14 extern struct wm wm;
15 extern struct config config;
16
17@@ -71,7 +80,7 @@ extern void bind_handler(void *, uint32_t, uint32_t, uint32_t);
18 extern void decorate(struct client *, bool);
19 extern bool load_decor(char *);
20 extern void ws_go_to(int8_t);
21-extern void ws_move_to(int8_t);
22+extern void ws_move_to(int8_t, struct client *);
23 extern void focus_prev(void);
24 extern void focus_next(void);
25 extern void cleanup(void);
26@@ -80,56 +89,64 @@ extern void cleanup(void);
27
28 status
29 ipc_move(char **arg) {
30- if (arg[1] == NULL || arg[2] == NULL || !wm.cur)
31+ if (arg[1] == NULL || arg[2] == NULL)
32 return (status){ false, "" };
33
34+ ARG_CLIENT(arg[3]);
35+
36 struct swc_rectangle geom;
37- if (swc_window_get_geometry(wm.cur->win, &geom)) {
38- wm.cur->x = geom.x;
39- wm.cur->y = geom.y;
40- wm.cur->width = geom.width;
41- wm.cur->height = geom.height;
42+ if (swc_window_get_geometry(c->win, &geom)) {
43+ c->x = geom.x;
44+ c->y = geom.y;
45+ c->width = geom.width;
46+ c->height = geom.height;
47 }
48
49- swc_window_set_position(wm.cur->win, wm.cur->x + fn_int(arg[1]), wm.cur->y + fn_int(arg[2]));
50+ swc_window_set_position(c->win, c->x + fn_int(arg[1]), c->y + fn_int(arg[2]));
51
52 return (status){ true, "" };
53 }
54
55 status
56 ipc_move_absolute(char **arg) {
57- if (arg[1] == NULL || arg[2] == NULL || !wm.cur)
58+ if (arg[1] == NULL || arg[2] == NULL)
59 return (status){ false, "" };
60
61- swc_window_set_position(wm.cur->win, fn_int(arg[1]), fn_int(arg[2]));
62+ ARG_CLIENT(arg[3]);
63+
64+ swc_window_set_position(c->win, fn_int(arg[1]), fn_int(arg[2]));
65
66 return (status){ true, "" };
67 }
68
69 status
70 ipc_resize(char **arg) {
71- if (arg[1] == NULL || arg[2] == NULL || !wm.cur)
72+ if (arg[1] == NULL || arg[2] == NULL)
73 return (status){ false, "" };
74
75+ ARG_CLIENT(arg[3]);
76+
77 struct swc_rectangle geom;
78- if (swc_window_get_geometry(wm.cur->win, &geom)) {
79- wm.cur->x = geom.x;
80- wm.cur->y = geom.y;
81- wm.cur->width = geom.width;
82- wm.cur->height = geom.height;
83+ if (swc_window_get_geometry(c->win, &geom)) {
84+ c->x = geom.x;
85+ c->y = geom.y;
86+ c->width = geom.width;
87+ c->height = geom.height;
88 }
89
90- swc_window_set_size(wm.cur->win, wm.cur->width + fn_uint(arg[1]), wm.cur->height + fn_uint(arg[2]));
91+ swc_window_set_size(c->win, c->width + fn_uint(arg[1]), c->height + fn_uint(arg[2]));
92
93 return (status){ true, "" };
94 }
95
96 status
97 ipc_resize_absolute(char **arg) {
98- if (arg[1] == NULL || arg[2] == NULL || !wm.cur)
99+ if (arg[1] == NULL || arg[2] == NULL)
100 return (status){ false, "" };
101
102- swc_window_set_size(wm.cur->win, fn_uint(arg[1]), fn_uint(arg[2]));
103+ ARG_CLIENT(arg[3]);
104+
105+ swc_window_set_size(c->win, fn_uint(arg[1]), fn_uint(arg[2]));
106
107 return (status){ true, "" };
108 }
109@@ -137,9 +154,11 @@ ipc_resize_absolute(char **arg) {
110 status
111 ipc_teleport(char **arg) {
112 if (arg[1] == NULL || arg[2] == NULL ||
113- arg[3] == NULL || arg[4] == NULL || !wm.cur)
114+ arg[3] == NULL || arg[4] == NULL)
115 return (status){ false, "" };
116
117+ ARG_CLIENT(arg[5]);
118+
119 struct swc_rectangle rect = {
120 .x = fn_int(arg[1]),
121 .y = fn_int(arg[2]),
122@@ -147,29 +166,27 @@ ipc_teleport(char **arg) {
123 .height = fn_uint(arg[4])
124 };
125
126- swc_window_set_geometry(wm.cur->win, &rect);
127+ swc_window_set_geometry(c->win, &rect);
128
129 return (status){ true, "" };
130 }
131
132 status
133 ipc_center(char **arg) {
134- UNUSED(arg);
135- if (!wm.cur)
136- return (status){ false, "" };
137+ ARG_CLIENT(arg[1]);
138
139 struct swc_rectangle geom;
140- if (swc_window_get_geometry(wm.cur->win, &geom)) {
141- wm.cur->x = geom.x;
142- wm.cur->y = geom.y;
143- wm.cur->width = geom.width;
144- wm.cur->height = geom.height;
145+ if (swc_window_get_geometry(c->win, &geom)) {
146+ c->x = geom.x;
147+ c->y = geom.y;
148+ c->width = geom.width;
149+ c->height = geom.height;
150 }
151
152 swc_window_set_position(
153- wm.cur->win,
154- wm.scr->width / 2 - wm.cur->width / 2,
155- wm.scr->height / 2 - wm.cur->height / 2
156+ c->win,
157+ wm.scr->width / 2 - c->width / 2,
158+ wm.scr->height / 2 - c->height / 2
159 );
160
161 return (status){ true, "" };
162@@ -177,83 +194,73 @@ ipc_center(char **arg) {
163
164 status
165 ipc_fullscreen(char **arg) {
166- UNUSED(arg);
167- if (!wm.cur)
168- return (status){ false, "" };
169+ ARG_CLIENT(arg[1]);
170
171 struct swc_rectangle geom;
172
173 if (wm.cur->fullscreen) {
174- wm.cur->fullscreen = false;
175- swc_window_set_stacked(wm.cur->win);
176-
177- if (wm.cur->width > 0 && wm.cur->height > 0) {
178- geom.x = wm.cur->x;
179- geom.y = wm.cur->y;
180- geom.width = wm.cur->width;
181- geom.height = wm.cur->height;
182- swc_window_set_geometry(wm.cur->win, &geom);
183+ c->fullscreen = false;
184+ swc_window_set_stacked(c->win);
185+
186+ if (c->width > 0 & c->height > 0) {
187+ geom.x = c->x;
188+ geom.y = c->y;
189+ geom.width = c->width;
190+ geom.height = c->height;
191+ swc_window_set_geometry(c->win, &geom);
192 }
193 return (status){ true, "" };
194 }
195
196- if (!wm.cur->scr || !wm.cur->scr->scr)
197+ if (!c->scr || !c->scr->scr)
198 return (status){ false, "" };
199
200- if (swc_window_get_geometry(wm.cur->win, &geom)) {
201- wm.cur->x = geom.x;
202- wm.cur->y = geom.y;
203- wm.cur->width = geom.width;
204- wm.cur->height = geom.height;
205+ if (swc_window_get_geometry(c->win, &geom)) {
206+ c->x = geom.x;
207+ c->y = geom.y;
208+ c->width = geom.width;
209+ c->height = geom.height;
210 }
211
212- wm.cur->fullscreen = true;
213- swc_window_set_fullscreen(wm.cur->win, wm.scr->scr);
214+ c->fullscreen = true;
215+ swc_window_set_fullscreen(c->win, wm.scr->scr);
216
217 return (status){ true, "" };
218 }
219
220 status
221 ipc_hide(char **arg) {
222- UNUSED(arg);
223- if (!wm.cur)
224- return (status){ false, "" };
225+ ARG_CLIENT(arg[1]);
226
227- swc_window_hide(wm.cur->win);
228+ swc_window_hide(c->win);
229
230 return (status){ true, "" };
231 }
232
233 status
234 ipc_show(char **arg) {
235- UNUSED(arg);
236- if (!wm.cur)
237- return (status){ false, "" };
238+ ARG_CLIENT(arg[1]);
239
240- swc_window_show(wm.cur->win);
241+ swc_window_show(c->win);
242
243 return (status){ true, "" };
244 }
245
246-/* I really doubt anyone even has 99 clients opened at the same time */
247+/* TODO: this doesn't work until someone adds lower/raise upstream */
248 status
249 ipc_lower(char **arg) {
250- UNUSED(arg);
251- if (!wm.cur)
252- return (status){ false, "" };
253+ ARG_CLIENT(arg[1]);
254
255- swc_window_stack(wm.cur->win, 99);
256+ swc_window_stack(c->win, 99);
257
258 return (status){ true, "" };
259 }
260
261 status
262 ipc_raise(char **arg) {
263- UNUSED(arg);
264- if (!wm.cur)
265- return (status){ false, "" };
266+ ARG_CLIENT(arg[1]);
267
268- swc_window_stack(wm.cur->win, -99);
269+ swc_window_stack(c->win, -99);
270
271 return (status){ true, "" };
272 }
273@@ -278,11 +285,9 @@ ipc_focus_next(char **arg) {
274
275 status
276 ipc_close(char **arg) {
277- UNUSED(arg);
278- if (!wm.cur)
279- return (status){ false, "" };
280+ ARG_CLIENT(arg[1]);
281
282- swc_window_close(wm.cur->win);
283+ swc_window_close(c->win);
284
285 return (status){ true, "" };
286 }
287@@ -299,10 +304,12 @@ ipc_workspace(char **arg) {
288
289 status
290 ipc_send_workspace(char **arg) {
291- if (arg[1] == NULL || !wm.cur)
292+ if (arg[1] == NULL)
293 return (status){ false, "" };
294
295- ws_move_to(fn_int(arg[1]));
296+ ARG_CLIENT(arg[2]);
297+
298+ ws_move_to(fn_int(arg[1]), c);
299
300 return (status){ true, "" };
301 }
302@@ -313,12 +320,10 @@ status
303 ipc_get_geometry(char **arg) {
304 status s = {0};
305
306- UNUSED(arg);
307- if (!wm.cur)
308- return (status){ false, "" };
309+ ARG_CLIENT(arg[1]);
310
311 struct swc_rectangle geom;
312- if (swc_window_get_geometry(wm.cur->win, &geom)) {
313+ if (swc_window_get_geometry(c->win, &geom)) {
314 snprintf(s.msg, MAXSIZE * sizeof(char), "%d %d %" PRIu32 " %" PRIu32 "\n", geom.x, geom.y, geom.width, geom.height);
315 }
316
317@@ -330,11 +335,9 @@ status
318 ipc_get_pid(char **arg) {
319 status s = {0};
320
321- UNUSED(arg);
322- if (!wm.cur)
323- return (status){ false, "" };
324+ ARG_CLIENT(arg[1]);
325
326- pid_t pid = swc_window_get_pid(wm.cur->win);
327+ pid_t pid = swc_window_get_pid(c->win);
328 snprintf(s.msg, MAXSIZE * sizeof(char), "%d\n", pid);
329
330 s.ok = true;
331@@ -345,11 +348,9 @@ status
332 ipc_get_title(char **arg) {
333 status s = {0};
334
335- UNUSED(arg);
336- if (!wm.cur)
337- return (status){ false, "" };
338+ ARG_CLIENT(arg[1]);
339
340- snprintf(s.msg, MAXSIZE * sizeof(char), "%s\n", wm.cur->win->title);
341+ snprintf(s.msg, MAXSIZE * sizeof(char), "%s\n", c->win->title);
342
343 s.ok = true;
344 return s;
345@@ -359,11 +360,9 @@ status
346 ipc_get_app_id(char **arg) {
347 status s = {0};
348
349- UNUSED(arg);
350- if (!wm.cur)
351- return (status){ false, "" };
352+ ARG_CLIENT(arg[1]);
353
354- snprintf(s.msg, MAXSIZE * sizeof(char), "%s\n", wm.cur->win->app_id);
355+ snprintf(s.msg, MAXSIZE * sizeof(char), "%s\n", c->win->app_id);
356
357 s.ok = true;
358 return s;
359@@ -371,11 +370,9 @@ ipc_get_app_id(char **arg) {
360
361 status
362 ipc_get_focus(char **arg) {
363- status s = {0};
364-
365 UNUSED(arg);
366- if (!wm.cur)
367- return (status){ false, "" };
368+
369+ status s = {0};
370
371 snprintf(s.msg, MAXSIZE * sizeof(char), "%" PRIu32 "\n", wm.cur->id);
372
373@@ -385,9 +382,10 @@ ipc_get_focus(char **arg) {
374
375 status
376 ipc_get_workspace(char **arg) {
377+ UNUSED(arg);
378+
379 status s = {0};
380
381- UNUSED(arg);
382 snprintf(s.msg, MAXSIZE * sizeof(char), "%d\n", wm.ws);
383
384 s.ok = true;
385@@ -396,9 +394,10 @@ ipc_get_workspace(char **arg) {
386
387 status
388 ipc_list_windows(char **arg) {
389+ UNUSED(arg);
390+
391 status s = {0};
392
393- UNUSED(arg);
394 if (!wl_list_empty(&wm.clients)) {
395 size_t o = 0;
396 struct client *c;
397@@ -412,9 +411,10 @@ ipc_list_windows(char **arg) {
398
399 status
400 ipc_get_screen_geometry(char **arg) {
401+ UNUSED(arg);
402+
403 status s = {0};
404
405- UNUSED(arg);
406 if (!wm.scr)
407 return (status){ false, "" };
408
409@@ -521,7 +521,9 @@ ipc_config(char **arg) {
410 status
411 ipc_quit(char **arg) {
412 UNUSED(arg);
413+
414 wm.running = false;
415 wl_display_terminate(wm.dpy);
416+
417 return (status){ true, "" }; /* NOTREACHED */
418 }