]> git.lizzy.rs Git - bspwm.git/blob - messages.c
f1838af4ef16b64f793d6f915d934390fb16c4b4
[bspwm.git] / messages.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include "settings.h"
5 #include "messages.h"
6 #include "common.h"
7 #include "types.h"
8 #include "bspwm.h"
9 #include "ewmh.h"
10 #include "helpers.h"
11 #include "window.h"
12 #include "tree.h"
13
14 void process_message(char *msg, char *rsp)
15 {
16     char *cmd = strtok(msg, TOKEN_SEP);
17
18     if (cmd == NULL)
19         return;
20
21     if (strcmp(cmd, "get") == 0) {
22         char *name = strtok(NULL, TOKEN_SEP);
23         get_setting(name, rsp);
24         return;
25     } else if (strcmp(cmd, "set") == 0) {
26         char *name = strtok(NULL, TOKEN_SEP);
27         char *value = strtok(NULL, TOKEN_SEP);
28         set_setting(name, value, rsp);
29         return;
30     } else if (strcmp(cmd, "dump") == 0) {
31         dump_tree(desk, desk->root, rsp, 0);
32         return;
33     } else if (strcmp(cmd, "list") == 0) {
34         list_desktops(rsp);
35         return;
36     } else if (strcmp(cmd, "windows") == 0) {
37         list_windows(rsp);
38         return;
39     } else if (strcmp(cmd, "close") == 0) {
40         window_close(desk->focus);
41         return;
42     } else if (strcmp(cmd, "kill") == 0) {
43         window_kill(desk, desk->focus);
44     } else if (strcmp(cmd, "magnetise") == 0) {
45         char *cor = strtok(NULL, TOKEN_SEP);
46         if (cor != NULL) {
47             corner_t c;
48             if (parse_corner(cor, &c)) {
49                 magnetise_tree(desk->root, c);
50             }
51         }
52     } else if (strcmp(cmd, "rotate") == 0) {
53         char *deg = strtok(NULL, TOKEN_SEP);
54         if (deg != NULL) {
55             rotate_t r;
56             if (parse_rotate(deg, &r)) {
57                 rotate_tree(desk->root, r);
58             }
59         }
60     } else if (strcmp(cmd, "layout") == 0) {
61         char *lyt = strtok(NULL, TOKEN_SEP);
62         if (lyt != NULL) {
63             layout_t l;
64             if (parse_layout(lyt, &l)) {
65                 desk->layout = l;
66             }
67         }
68     } else if (strcmp(cmd, "cycle_layout") == 0) {
69         if (desk->layout == LAYOUT_MONOCLE)
70             desk->layout = LAYOUT_TILED;
71         else
72             desk->layout = LAYOUT_MONOCLE;
73     } else if (strcmp(cmd, "shift") == 0) {
74         char *dir = strtok(NULL, TOKEN_SEP);
75         if (dir != NULL) {
76             direction_t d;
77             if (parse_direction(dir, &d)) {
78                 swap_nodes(desk->focus, find_neighbor(desk->focus, d));
79             }
80         }
81     } else if (strcmp(cmd, "toggle_fullscreen") == 0) {
82         if (desk->focus != NULL)
83             toggle_fullscreen(desk->focus->client);
84     } else if (strcmp(cmd, "toggle_floating") == 0) {
85         split_mode = MODE_AUTOMATIC;
86         toggle_floating(desk->focus);
87     } else if (strcmp(cmd, "toggle_locked") == 0) {
88         if (desk->focus != NULL)
89             toggle_locked(desk->focus->client);
90     } else if (strcmp(cmd, "ratio") == 0) {
91         char *value = strtok(NULL, TOKEN_SEP);
92         if (value != NULL && desk->focus != NULL)
93             sscanf(value, "%lf", &desk->focus->split_ratio);
94     } else if (strcmp(cmd, "cancel") == 0) {
95         split_mode = MODE_AUTOMATIC;
96         window_draw_border(desk->focus, true);
97         return;
98     } else if (strcmp(cmd, "presel") == 0) {
99         if (desk->focus == NULL || !is_tiled(desk->focus->client) || desk->layout != LAYOUT_TILED)
100             return;
101         char *dir = strtok(NULL, TOKEN_SEP);
102         if (dir != NULL) {
103             direction_t d;
104             if (parse_direction(dir, &d)) {
105                 split_mode = MODE_MANUAL;
106                 split_dir = d;
107                 window_draw_border(desk->focus, true);
108             }
109         }
110         return;
111     } else if (strcmp(cmd, "push") == 0 || strcmp(cmd, "pull") == 0) {
112         char *dir = strtok(NULL, TOKEN_SEP);
113         if (dir != NULL) {
114             fence_move_t m;
115             direction_t d;
116             if (parse_fence_move(cmd, &m) && parse_direction(dir, &d)) {
117                 move_fence(desk->focus, d, m);
118             }
119         }
120     } else if (strcmp(cmd, "send_to") == 0) {
121         char *name = strtok(NULL, TOKEN_SEP);
122         if (name != NULL) {
123             desktop_t *d = find_desktop(name);
124             transfer_node(desk, d, desk->focus);
125         }
126     } else if (strcmp(cmd, "rename") == 0) {
127         char *cur_name = strtok(NULL, TOKEN_SEP);
128         if (cur_name != NULL) {
129             desktop_t *d = find_desktop(cur_name);
130             if (d != NULL) {
131                 char *new_name = strtok(NULL, TOKEN_SEP);
132                 if (new_name != NULL) {
133                     strncpy(d->name, new_name, sizeof(d->name));
134                     ewmh_update_desktop_names();
135                 }
136             }
137         }
138     } else if (strcmp(cmd, "use") == 0) {
139         char *name = strtok(NULL, TOKEN_SEP);
140         if (name != NULL) {
141             desktop_t *d = find_desktop(name);
142             select_desktop(d);
143         }
144     } else if (strcmp(cmd, "cycle_desktop") == 0) {
145         char *dir = strtok(NULL, TOKEN_SEP);
146         if (dir != NULL) {
147             cycle_dir_t d;
148             if (parse_cycle_direction(dir, &d)) {
149                 cycle_desktop(d);
150             }
151         }
152     } else if (strcmp(cmd, "nearest") == 0) {
153         if (desk->focus != NULL && desk->focus->client->fullscreen)
154             return;
155         char *arg = strtok(NULL, TOKEN_SEP);
156         if (arg != NULL) {
157             nearest_arg_t a;
158             if (parse_nearest_argument(arg, &a)) {
159                 skip_client_t k;
160                 char *skip = strtok(NULL, TOKEN_SEP);
161                 if (parse_skip_client(skip, &k))
162                     nearest_leaf(desk, desk->focus, a, k);
163             }
164         }
165         return;
166     } else if (strcmp(cmd, "cycle") == 0) {
167         if (desk->focus != NULL && desk->focus->client->fullscreen)
168             return;
169         char *dir = strtok(NULL, TOKEN_SEP);
170         if (dir != NULL) {
171             cycle_dir_t d;
172             if (parse_cycle_direction(dir, &d)) {
173                 skip_client_t k;
174                 char *skip = strtok(NULL, TOKEN_SEP);
175                 if (parse_skip_client(skip, &k))
176                     cycle_leaf(desk, desk->focus, d, k);
177             }
178         }
179         return;
180     } else if (strcmp(cmd, "rule") == 0) {
181         char *name = strtok(NULL, TOKEN_SEP);
182         if (name != NULL) {
183             rule_t *rule = make_rule();
184             strncpy(rule->cause.name, name, sizeof(rule->cause.name));
185             char *arg = strtok(NULL, TOKEN_SEP);
186             while (arg != NULL) {
187                 if (strcmp(arg, "floating") == 0)
188                     rule->effect.floating = true;
189                 arg = strtok(NULL, TOKEN_SEP);
190             }
191             rule->next = rule_head;
192             rule_head = rule;
193         }
194         return;
195     } else if (strcmp(cmd, "alternate_focus") == 0) {
196         focus_node(desk, desk->last_focus, true);
197     } else if (strcmp(cmd, "alternate") == 0) {
198         select_desktop(last_desk);
199     } else if (strcmp(cmd, "add") == 0) {
200         char *name = strtok(NULL, TOKEN_SEP);
201         if (name != NULL) {
202             add_desktop(name);
203         }
204         return;
205     } else if (strcmp(cmd, "focus") == 0) {
206         if (desk->focus != NULL && desk->focus->client->fullscreen)
207             return;
208         char *dir = strtok(NULL, TOKEN_SEP);
209         if (dir != NULL) {
210             direction_t d;
211             if (parse_direction(dir, &d)) {
212                 node_t *n = find_neighbor(desk->focus, d);
213                 focus_node(desk, n, true);
214             }
215         }
216         return;
217     } else if (strcmp(cmd, "reload") == 0) {
218         load_settings();
219         run_autostart();
220     } else if (strcmp(cmd, "reload_autostart") == 0) {
221         run_autostart();
222     } else if (strcmp(cmd, "reload_settings") == 0) {
223         load_settings();
224     } else if (strcmp(cmd, "quit") == 0) {
225         quit();
226         return;
227     } else {
228         snprintf(rsp, BUFSIZ, "unknown command: %s", cmd);
229         return;
230     }
231
232     apply_layout(desk, desk->root, root_rect);
233 }
234
235 void set_setting(char *name, char *value, char *rsp)
236 {
237     if (name == NULL || value == NULL)
238         return;
239
240     if (strcmp(name, "inner_border_width") == 0) {
241         sscanf(value, "%u", &inner_border_width);
242         border_width = inner_border_width + main_border_width + outer_border_width;
243     } else if (strcmp(name, "main_border_width") == 0) {
244         sscanf(value, "%u", &main_border_width);
245         border_width = inner_border_width + main_border_width + outer_border_width;
246     } else if (strcmp(name, "outer_border_width") == 0) {
247         sscanf(value, "%u", &outer_border_width);
248         border_width = inner_border_width + main_border_width + outer_border_width;
249     } else if (strcmp(name, "window_gap") == 0) {
250         sscanf(value, "%i", &window_gap);
251         update_root_dimensions();
252     } else if (strcmp(name, "left_padding") == 0) {
253         sscanf(value, "%i", &left_padding);
254         update_root_dimensions();
255     } else if (strcmp(name, "right_padding") == 0) {
256         sscanf(value, "%i", &right_padding);
257         update_root_dimensions();
258     } else if (strcmp(name, "top_padding") == 0) {
259         sscanf(value, "%i", &top_padding);
260         update_root_dimensions();
261     } else if (strcmp(name, "bottom_padding") == 0) {
262         sscanf(value, "%i", &bottom_padding);
263         update_root_dimensions();
264     } else if (strcmp(name, "active_border_color") == 0) {
265         strncpy(active_border_color, value, sizeof(active_border_color));
266         active_border_color_pxl = get_color(active_border_color);
267     } else if (strcmp(name, "normal_border_color") == 0) {
268         strncpy(normal_border_color, value, sizeof(normal_border_color));
269         normal_border_color_pxl = get_color(normal_border_color);
270     } else if (strcmp(name, "inner_border_color") == 0) {
271         strncpy(inner_border_color, value, sizeof(inner_border_color));
272         inner_border_color_pxl = get_color(inner_border_color);
273     } else if (strcmp(name, "outer_border_color") == 0) {
274         strncpy(outer_border_color, value, sizeof(outer_border_color));
275         outer_border_color_pxl = get_color(outer_border_color);
276     } else if (strcmp(name, "presel_border_color") == 0) {
277         strncpy(presel_border_color, value, sizeof(presel_border_color));
278         presel_border_color_pxl = get_color(presel_border_color);
279     } else if (strcmp(name, "active_locked_border_color") == 0) {
280         strncpy(active_locked_border_color, value, sizeof(active_locked_border_color));
281         active_locked_border_color_pxl = get_color(active_locked_border_color);
282     } else if (strcmp(name, "normal_locked_border_color") == 0) {
283         strncpy(normal_locked_border_color, value, sizeof(normal_locked_border_color));
284         normal_locked_border_color_pxl = get_color(normal_locked_border_color);
285     } else if (strcmp(name, "urgent_border_color") == 0) {
286         strncpy(urgent_border_color, value, sizeof(urgent_border_color));
287         urgent_border_color_pxl = get_color(urgent_border_color);
288     } else if (strcmp(name, "borderless_monocle") == 0) {
289         bool b;
290         if (parse_bool(value, &b))
291             borderless_monocle = b;
292     } else if (strcmp(name, "focus_follows_mouse") == 0) {
293         bool b;
294         if (parse_bool(value, &b))
295             focus_follows_mouse = b;
296     } else if (strcmp(name, "wm_name") == 0) {
297         strncpy(wm_name, value, sizeof(wm_name));
298         ewmh_update_wm_name();
299         return;
300     } else {
301         snprintf(rsp, BUFSIZ, "unknown setting: %s", name);
302         return;
303     }
304
305     apply_layout(desk, desk->root, root_rect);
306 }
307
308 void get_setting(char *name, char* rsp)
309 {
310     if (name == NULL)
311         return;
312
313     if (strcmp(name, "inner_border_width") == 0)
314         snprintf(rsp, BUFSIZ, "%u", inner_border_width);
315     else if (strcmp(name, "main_border_width") == 0)
316         snprintf(rsp, BUFSIZ, "%u", main_border_width);
317     else if (strcmp(name, "outer_border_width") == 0)
318         snprintf(rsp, BUFSIZ, "%u", outer_border_width);
319     else if (strcmp(name, "border_width") == 0)
320         snprintf(rsp, BUFSIZ, "%u", border_width);
321     else if (strcmp(name, "window_gap") == 0)
322         snprintf(rsp, BUFSIZ, "%i", window_gap);
323     else if (strcmp(name, "left_padding") == 0)
324         snprintf(rsp, BUFSIZ, "%i", left_padding);
325     else if (strcmp(name, "right_padding") == 0)
326         snprintf(rsp, BUFSIZ, "%i", right_padding);
327     else if (strcmp(name, "top_padding") == 0)
328         snprintf(rsp, BUFSIZ, "%i", top_padding);
329     else if (strcmp(name, "bottom_padding") == 0)
330         snprintf(rsp, BUFSIZ, "%i", bottom_padding);
331     else if (strcmp(name, "active_border_color") == 0)
332         snprintf(rsp, BUFSIZ, "%s (%06X)", active_border_color, active_border_color_pxl);
333     else if (strcmp(name, "normal_border_color") == 0)
334         snprintf(rsp, BUFSIZ, "%s (%06X)", normal_border_color, normal_border_color_pxl);
335     else if (strcmp(name, "inner_border_color") == 0)
336         snprintf(rsp, BUFSIZ, "%s (%06X)", inner_border_color, inner_border_color_pxl);
337     else if (strcmp(name, "outer_border_color") == 0)
338         snprintf(rsp, BUFSIZ, "%s (%06X)", outer_border_color, outer_border_color_pxl);
339     else if (strcmp(name, "presel_border_color") == 0)
340         snprintf(rsp, BUFSIZ, "%s (%06X)", presel_border_color, presel_border_color_pxl);
341     else if (strcmp(name, "active_locked_border_color") == 0)
342         snprintf(rsp, BUFSIZ, "%s (%06X)", active_locked_border_color, active_locked_border_color_pxl);
343     else if (strcmp(name, "normal_locked_border_color") == 0)
344         snprintf(rsp, BUFSIZ, "%s (%06X)", normal_locked_border_color, normal_locked_border_color_pxl);
345     else if (strcmp(name, "urgent_border_color") == 0)
346         snprintf(rsp, BUFSIZ, "%s (%06X)", urgent_border_color, urgent_border_color_pxl);
347     else if (strcmp(name, "borderless_monocle") == 0)
348         snprintf(rsp, BUFSIZ, "%s", BOOLSTR(borderless_monocle));
349     else if (strcmp(name, "focus_follows_mouse") == 0)
350         snprintf(rsp, BUFSIZ, "%s", BOOLSTR(focus_follows_mouse));
351     else if (strcmp(name, "wm_name") == 0)
352         snprintf(rsp, BUFSIZ, "%s", wm_name);
353     else
354         snprintf(rsp, BUFSIZ, "unknown setting: %s", name);
355 }
356
357
358 bool parse_bool(char *value, bool *b)
359 {
360     if (strcmp(value, "true") == 0) {
361         *b = true;
362         return true;
363     } else if (strcmp(value, "false") == 0) {
364         *b = false;
365         return true;
366     }
367     return false;
368 }
369
370 bool parse_layout(char *s, layout_t *l)
371 {
372     if (strcmp(s, "monocle") == 0) {
373         *l = LAYOUT_MONOCLE;
374         return true;
375     } else if (strcmp(s, "tiled") == 0) {
376         *l = LAYOUT_TILED;
377         return true;
378     }
379     return false;
380 }
381
382 bool parse_direction(char *s, direction_t *d)
383 {
384     if (strcmp(s, "up") == 0) {
385         *d = DIR_UP;
386         return true;
387     } else if (strcmp(s, "down") == 0) {
388         *d = DIR_DOWN;
389         return true;
390     } else if (strcmp(s, "left") == 0) {
391         *d = DIR_LEFT;
392         return true;
393     } else if (strcmp(s, "right") == 0) {
394         *d = DIR_RIGHT;
395         return true;
396     }
397     return false;
398 }
399
400 bool parse_nearest_argument(char *s, nearest_arg_t *a)
401 {
402     if (strcmp(s, "older") == 0) {
403         *a = NEAREST_OLDER;
404         return true;
405     } else if (strcmp(s, "newer") == 0) {
406         *a = NEAREST_NEWER;
407         return true;
408     }
409     return false;
410 }
411
412 bool parse_cycle_direction(char *s, cycle_dir_t *d)
413 {
414     if (strcmp(s, "prev") == 0) {
415         *d = CYCLE_PREV;
416         return true;
417     } else if (strcmp(s, "next") == 0) {
418         *d = CYCLE_NEXT;
419         return true;
420     }
421     return false;
422 }
423
424 bool parse_skip_client(char *s, skip_client_t *k)
425 {
426     if (s == NULL || strcmp(s, "--skip-none") == 0) {
427         *k = SKIP_NONE;
428         return true;
429     } else if (strcmp(s, "--skip-floating") == 0) {
430         *k = SKIP_FLOATING;
431         return true;
432     } else if (strcmp(s, "--skip-tiled") == 0) {
433         *k = SKIP_TILED;
434         return true;
435     } else if (strcmp(s, "--skip-class-equal") == 0) {
436         *k = SKIP_CLASS_EQUAL;
437         return true;
438     } else if (strcmp(s, "--skip-class-differ") == 0) {
439         *k = SKIP_CLASS_DIFFER;
440         return true;
441     }
442     return false;
443 }
444
445 bool parse_corner(char *s, corner_t *c)
446 {
447     if (strcmp(s, "top_left") == 0) {
448         *c = TOP_LEFT;
449         return true;
450     } else if (strcmp(s, "top_right") == 0) {
451         *c = TOP_RIGHT;
452         return true;
453     } else if (strcmp(s, "bottom_left") == 0) {
454         *c = BOTTOM_LEFT;
455         return true;
456     } else if (strcmp(s, "bottom_right") == 0) {
457         *c = BOTTOM_RIGHT;
458         return true;
459     }
460     return false;
461 }
462
463 bool parse_rotate(char *s, rotate_t *r)
464 {
465     if (strcmp(s, "clockwise") == 0) {
466         *r = ROTATE_CLOCKWISE;
467         return true;
468     } else if (strcmp(s, "counter_clockwise") == 0) {
469         *r = ROTATE_COUNTER_CLOCKWISE;
470         return true;
471     } else if (strcmp(s, "full_cycle") == 0) {
472         *r = ROTATE_FULL_CYCLE;
473         return true;
474     }
475     return false;
476 }
477
478 bool parse_fence_move(char *s, fence_move_t *m)
479 {
480     if (strcmp(s, "push") == 0) {
481         *m = MOVE_PUSH;
482         return true;
483     } else if (strcmp(s, "pull") == 0) {
484         *m = MOVE_PULL;
485         return true;
486     }
487     return false;
488 }
489