]> git.lizzy.rs Git - bspwm.git/blob - messages.c
Add index selector for desktops and monitors
[bspwm.git] / messages.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include "settings.h"
6 #include "messages.h"
7 #include "query.h"
8 #include "restore.h"
9 #include "common.h"
10 #include "types.h"
11 #include "bspwm.h"
12 #include "ewmh.h"
13 #include "helpers.h"
14 #include "window.h"
15 #include "events.h"
16 #include "tree.h"
17 #include "rules.h"
18
19 bool cmd_window(char **args, int num)
20 {
21     if (num < 1)
22         return false;
23
24     coordinates_t ref = {mon, mon->desk, mon->desk->focus};
25     coordinates_t trg = ref;
26
27     if (*args[0] != OPT_CHR) {
28         if (node_from_desc(*args, &ref, &trg))
29             num--, args++;
30         else
31             return false;
32     }
33
34     if (trg.node == NULL)
35         return false;
36
37     bool dirty = false;
38
39     while (num > 0) {
40         if (streq("-f", *args) || streq("--focus", *args)) {
41             coordinates_t dst = trg;
42             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
43                 num--, args++;
44                 if (!node_from_desc(*args, &trg, &dst))
45                     return false;
46             }
47             focus_node(dst.monitor, dst.desktop, dst.node);
48         } else if (streq("-d", *args) || streq("--to-desktop", *args)) {
49             num--, args++;
50             coordinates_t dst;
51             if (desktop_from_desc(*args, &trg, &dst)) {
52                 transfer_node(trg.monitor, trg.desktop, dst.monitor, dst.desktop, trg.node);
53                 trg.monitor = dst.monitor;
54                 trg.desktop = dst.desktop;
55             } else {
56                 return false;
57             }
58         } else if (streq("-m", *args) || streq("--to-monitor", *args)) {
59             num--, args++;
60             if (num < 1)
61                 return false;
62             coordinates_t dst;
63             if (monitor_from_desc(*args, &trg, &dst)) {
64                 transfer_node(trg.monitor, trg.desktop, dst.monitor, dst.monitor->desk, trg.node);
65                 trg.monitor = dst.monitor;
66                 trg.desktop = dst.monitor->desk;
67             } else {
68                 return false;
69             }
70         } else if (streq("-w", *args) || streq("--to-window", *args)) {
71             num--, args++;
72             if (num < 1)
73                 return false;
74             coordinates_t dst;
75             if (node_from_desc(*args, &trg, &dst))
76                 transplant_node(trg.monitor, trg.desktop, trg.node, dst.node);
77             else
78                 return false;
79             dirty = true;
80         } else if (streq("-s", *args) || streq("--swap", *args)) {
81             num--, args++;
82             if (num < 1)
83                 return false;
84             coordinates_t dst;
85             if (node_from_desc(*args, &trg, &dst))
86                 swap_nodes(trg.node, dst.node);
87             else
88                 return false;
89             dirty = true;
90         } else if (streq("-t", *args) || streq("--toggle", *args)) {
91             num--, args++;
92             if (num < 1)
93                 return false;
94             char *key = strtok(*args, EQL_TOK);
95             char *val = strtok(NULL, EQL_TOK);
96             state_alter_t a = ALTER_NONE;
97             bool b;
98             if (val == NULL) {
99                 a = ALTER_TOGGLE;
100             } else {
101                 if (parse_bool(val, &b))
102                     a = ALTER_SET;
103                 else
104                     return false;
105             }
106             if (streq("fullscreen", key)) {
107                 set_fullscreen(trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->fullscreen));
108                 dirty = true;
109             } else if (streq("floating", key)) {
110                 set_floating(trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->floating));
111                 dirty = true;
112             } else if (streq("locked", key)) {
113                 set_locked(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->locked));
114             }
115         } else if (streq("-p", *args) || streq("--presel", *args)) {
116             num--, args++;
117             if (num < 1 || !is_tiled(trg.node->client)
118                     || trg.desktop->layout != LAYOUT_TILED)
119                 return false;
120             if (streq("cancel", *args)) {
121                 reset_mode(&trg);
122             } else {
123                 direction_t dir;
124                 if (parse_direction(*args, &dir)) {
125                     double rat = trg.node->split_ratio;
126                     if (num > 1 && *(args + 1)[0] != OPT_CHR) {
127                         num--, args++;
128                         if (sscanf(*args, "%lf", &rat) != 1 || rat <= 0 || rat >= 1)
129                             return false;
130                     }
131                     if (auto_cancel && trg.node->split_mode == MODE_MANUAL
132                             && dir == trg.node->split_dir
133                             && rat == trg.node->split_ratio) {
134                         reset_mode(&trg);
135                     } else {
136                         trg.node->split_mode = MODE_MANUAL;
137                         trg.node->split_dir = dir;
138                         trg.node->split_ratio = rat;
139                     }
140                     window_draw_border(trg.node, trg.desktop->focus == trg.node, mon == trg.monitor);
141                 } else {
142                     return false;
143                 }
144             }
145         } else if (streq("-e", *args) || streq("--edge", *args)) {
146             num--, args++;
147             if (num < 2)
148                 return false;
149             direction_t dir;
150             if (!parse_direction(*args, &dir))
151                 return false;
152             node_t *n = find_fence(trg.node, dir);
153             if (n == NULL)
154                 return false;
155             num--, args++;
156             fence_move_t fmo;
157             if (parse_fence_move(*args, &fmo)) {
158                 move_fence(n, dir, fmo);
159             } else {
160                 double rat;
161                 if (sscanf(*args, "%lf", &rat) == 1 && rat > 0 && rat < 1)
162                     n->split_ratio = rat;
163                 else
164                     return false;
165             }
166             dirty = true;
167         } else if (streq("-r", *args) || streq("--ratio", *args)) {
168             num--, args++;
169             if (num < 1)
170                 return false;
171             double rat;
172             if (sscanf(*args, "%lf", &rat) == 1 && rat > 0 && rat < 1) {
173                 trg.node->split_ratio = rat;
174                 window_draw_border(trg.node, trg.desktop->focus == trg.node, mon == trg.monitor);
175             } else {
176                 return false;
177             }
178         } else if (streq("-R", *args) || streq("--rotate", *args)) {
179             num--, args++;
180             if (num < 2)
181                 return false;
182             direction_t dir;
183             if (!parse_direction(*args, &dir))
184                 return false;
185             node_t *n = find_fence(trg.node, dir);
186             if (n == NULL)
187                 return false;
188             num--, args++;
189             int deg;
190             if (parse_degree(*args, &deg)) {
191                 rotate_tree(n, deg);
192                 dirty = true;
193             } else {
194                 return false;
195             }
196         } else if (streq("-c", *args) || streq("--close", *args)) {
197             if (num > 1)
198                 return false;
199             window_close(trg.node);
200         } else if (streq("-k", *args) || streq("--kill", *args)) {
201             if (num > 1)
202                 return false;
203             window_kill(trg.desktop, trg.node);
204             dirty = true;
205         } else {
206             return false;
207         }
208         num--, args++;
209     }
210
211     if (dirty)
212         arrange(trg.monitor, trg.desktop);
213
214     return true;
215 }
216
217 bool cmd_desktop(char **args, int num)
218 {
219     if (num < 1)
220         return false;
221
222     coordinates_t ref = {mon, mon->desk, NULL};
223     coordinates_t trg = ref;
224
225     if (*args[0] != OPT_CHR) {
226         if (desktop_from_desc(*args, &ref, &trg))
227             num--, args++;
228         else
229             return false;
230     }
231
232     bool dirty = false;
233
234     while (num > 0) {
235         if (streq("-f", *args) || streq("--focus", *args)) {
236             coordinates_t dst = trg;
237             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
238                 num--, args++;
239                 if (!desktop_from_desc(*args, &trg, &dst))
240                     return false;
241             }
242             if (auto_alternate && dst.desktop == dst.monitor->desk && dst.monitor->last_desk != NULL)
243                 dst.desktop = dst.monitor->last_desk;
244             focus_node(dst.monitor, dst.desktop, dst.desktop->focus);
245         } else if (streq("-m", *args) || streq("--to-monitor", *args)) {
246             num--, args++;
247             if (num < 1 || trg.monitor->desk_head == trg.monitor->desk_tail)
248                 return false;
249             coordinates_t dst;
250             if (monitor_from_desc(*args, &trg, &dst)) {
251                 transfer_desktop(trg.monitor, dst.monitor, trg.desktop);
252                 trg.monitor = dst.monitor;
253                 update_current();
254             } else {
255                 return false;
256             }
257         } else if (streq("-l", *args) || streq("--layout", *args)) {
258             num--, args++;
259             if (num < 1)
260                 return false;
261             layout_t lyt;
262             cycle_dir_t cyc;
263             if (parse_cycle_direction(*args, &cyc))
264                 change_layout(trg.monitor, trg.desktop, (trg.desktop->layout + 1) % 2);
265             else if (parse_layout(*args, &lyt))
266                 change_layout(trg.monitor, trg.desktop, lyt);
267             else
268                 return false;
269         } else if (streq("-n", *args) || streq("--rename", *args)) {
270             num--, args++;
271             if (num < 1)
272                 return false;
273             strncpy(trg.desktop->name, *args, sizeof(trg.desktop->name));
274             ewmh_update_desktop_names();
275             put_status();
276         } else if (streq("-r", *args) || streq("--rm", *args)) {
277             if (trg.desktop->root == NULL
278                     && trg.monitor->desk_head != trg.monitor->desk_tail) {
279                 remove_desktop(trg.monitor, trg.desktop);
280                 desktop_show(trg.monitor->desk);
281                 update_current();
282                 return true;
283             } else {
284                 return false;
285             }
286         } else if (streq("-c", *args) || streq("--cancel-presel", *args)) {
287             reset_mode(&trg);
288         } else if (streq("-F", *args) || streq("--flip", *args)) {
289             num--, args++;
290             if (num < 1)
291                 return false;
292             flip_t flp;
293             if (parse_flip(*args, &flp)) {
294                 flip_tree(trg.desktop->root, flp);
295                 dirty = true;
296             } else {
297                 return false;
298             }
299         } else if (streq("-R", *args) || streq("--rotate", *args)) {
300             num--, args++;
301             if (num < 1)
302                 return false;
303             int deg;
304             if (parse_degree(*args, &deg)) {
305                 rotate_tree(trg.desktop->root, deg);
306                 dirty = true;
307             } else {
308                 return false;
309             }
310         } else if (streq("-B", *args) || streq("--balance", *args)) {
311             balance_tree(trg.desktop->root);
312             dirty = true;
313         } else if (streq("-C", *args) || streq("--circulate", *args)) {
314             num--, args++;
315             if (num < 1)
316                 return false;
317             circulate_dir_t cir;
318             if (parse_circulate_direction(*args, &cir)) {
319                 circulate_leaves(trg.monitor, trg.desktop, cir);
320                 dirty = true;
321             } else {
322                 return false;
323             }
324         } else {
325             return false;
326         }
327         num--, args++;
328     }
329
330     if (dirty)
331         arrange(trg.monitor, trg.desktop);
332
333     return true;
334 }
335
336 bool cmd_monitor(char **args, int num)
337 {
338     if (num < 1)
339         return false;
340
341     coordinates_t ref = {mon, NULL, NULL};
342     coordinates_t trg = ref;
343
344     if (*args[0] != OPT_CHR) {
345         if (monitor_from_desc(*args, &ref, &trg))
346             num--, args++;
347         else
348             return false;
349     }
350
351     while (num > 0) {
352         if (streq("-f", *args) || streq("--focus", *args)) {
353             coordinates_t dst = trg;
354             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
355                 num--, args++;
356                 if (!monitor_from_desc(*args, &trg, &dst))
357                     return false;
358             }
359             if (auto_alternate && dst.monitor == mon && last_mon != NULL)
360                 dst.monitor = last_mon;
361             focus_node(dst.monitor, dst.monitor->desk, dst.monitor->desk->focus);
362         } else if (streq("-a", *args) || streq("--add-desktops", *args)) {
363             num--, args++;
364             if (num < 1)
365                 return false;
366             while (num > 0) {
367                 add_desktop(trg.monitor, make_desktop(*args));
368                 num--, args++;
369             }
370         } else if (streq("-r", *args) || streq("--remove-desktops", *args)) {
371             num--, args++;
372             if (num < 1)
373                 return false;
374             while (num > 0) {
375                 coordinates_t dst;
376                 if (locate_desktop(*args, &dst) && dst.monitor->desk_head != dst.monitor->desk_tail && dst.desktop->root == NULL) {
377                     remove_desktop(dst.monitor, dst.desktop);
378                     desktop_show(dst.monitor->desk);
379                 }
380                 num--, args++;
381             }
382         } else if (streq("-p", *args) || streq("--pad", *args)) {
383             num--, args++;
384             if (num < 4)
385                 return false;
386             char values[MAXLEN];
387             snprintf(values, sizeof(values), "%s %s %s %s", args[0], args[1], args[2], args[3]);
388             num -= 3;
389             args += 3;
390             if (sscanf(values, "%i %i %i %i", &trg.monitor->top_padding, &trg.monitor->right_padding, &trg.monitor->bottom_padding, &trg.monitor->left_padding) == 4)
391                 for (desktop_t *d = trg.monitor->desk_head; d != NULL; d = d->next)
392                     arrange(trg.monitor, d);
393             else
394                 return false;
395         } else if (streq("-n", *args) || streq("--rename", *args)) {
396             num--, args++;
397             if (num < 1)
398                 return false;
399             strncpy(trg.monitor->name, *args, sizeof(trg.monitor->name));
400             put_status();
401         } else {
402             return false;
403         }
404         num--, args++;
405     }
406
407     return true;
408 }
409
410 bool cmd_query(char **args, int num, char *rsp) {
411     coordinates_t ref = {mon, mon->desk, mon->desk->focus};
412     coordinates_t trg = {NULL, NULL, NULL};
413     domain_t dom = DOMAIN_TREE;
414     int d = 0, t = 0;
415
416     while (num > 0) {
417         if (streq("-T", *args) || streq("--tree", *args)) {
418             dom = DOMAIN_TREE, d++;
419         } else if (streq("-M", *args) || streq("--monitors", *args)) {
420             dom = DOMAIN_MONITOR, d++;
421         } else if (streq("-D", *args) || streq("--desktops", *args)) {
422             dom = DOMAIN_DESKTOP, d++;
423         } else if (streq("-W", *args) || streq("--windows", *args)) {
424             dom = DOMAIN_WINDOW, d++;
425         } else if (streq("-H", *args) || streq("--history", *args)) {
426             dom = DOMAIN_HISTORY, d++;
427         } else if (streq("-m", *args) || streq("--monitor", *args)) {
428             trg.monitor = ref.monitor;
429             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
430                 num--, args++;
431                 if (!monitor_from_desc(*args, &ref, &trg))
432                     return false;
433             }
434             t++;
435         } else if (streq("-d", *args) || streq("--desktop", *args)) {
436             trg.monitor = ref.monitor;
437             trg.desktop = ref.desktop;
438             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
439                 num--, args++;
440                 if (!desktop_from_desc(*args, &ref, &trg))
441                     return false;
442             }
443             t++;
444         } else if (streq("-w", *args) || streq("--window", *args)) {
445             trg = ref;
446             if (num > 1 && *(args + 1)[0] != OPT_CHR) {
447                 num--, args++;
448                 if (!node_from_desc(*args, &ref, &trg))
449                     return false;
450             }
451             t++;
452         } else {
453             return false;
454         }
455         num--, args++;
456     }
457
458     if (d != 1 || t > 1)
459         return false;
460
461     if (dom == DOMAIN_HISTORY)
462         query_history(trg, rsp);
463     else if (dom == DOMAIN_WINDOW)
464         query_windows(trg, rsp);
465     else
466         query_monitors(trg, dom, rsp);
467
468     return true;
469 }
470
471 bool cmd_rule(char **args, int num, char *rsp) {
472     if (num < 1)
473         return false;
474     while (num > 0) {
475         if (streq("-a", *args) || streq("--add", *args)) {
476             num--, args++;
477             if (num < 2)
478                 return false;
479             rule_t *rule = make_rule();
480             strncpy(rule->cause.name, *args, sizeof(rule->cause.name));
481             num--, args++;
482             while (num > 0) {
483                 if (streq("--floating", *args)) {
484                     rule->effect.floating = true;
485                 } else if (streq("--follow", *args)) {
486                     rule->effect.follow = true;
487                 } else if (streq("--focus", *args)) {
488                     rule->effect.focus = true;
489                 } else if (streq("-d", *args) || streq("--desktop", *args)) {
490                     num--, args++;
491                     if (num < 1) {
492                         free(rule);
493                         rule_uid--;
494                         return false;
495                     }
496                     strncpy(rule->effect.desc, *args, sizeof(rule->effect.desc));
497                 } else {
498                     free(rule);
499                     rule_uid--;
500                     return false;
501                 }
502                 num--, args++;
503             }
504             add_rule(rule);
505         } else if (streq("-r", *args) || streq("--rm", *args)) {
506             num--, args++;
507             if (num < 1)
508                 return false;
509             unsigned int uid;
510             while (num > 0) {
511                 if (sscanf(*args, "%X", &uid) == 1)
512                     remove_rule_by_uid(uid);
513                 else
514                     return false;
515                 num--, args++;
516             }
517         } else if (streq("-l", *args) || streq("--list", *args)) {
518             num--, args++;
519             list_rules(num > 0 ? *args : NULL, rsp);
520         } else {
521             return false;
522         }
523         num--, args++;
524     }
525
526     return true;
527 }
528
529 bool cmd_pointer(char **args, int num) {
530     if (num < 1)
531         return false;
532     while (num > 0) {
533         if (streq("-t", *args) || streq("--track", *args)) {
534             num--, args++;
535             if (num < 2)
536                 return false;
537             int x, y;
538             if (sscanf(*args, "%i", &x) == 1 && sscanf(*(args + 1), "%i", &y) == 1)
539                 track_pointer(x, y);
540             else
541                 return false;
542         } else if (streq("-g", *args) || streq("--grab", *args)) {
543             num--, args++;
544             if (num < 1)
545                 return false;
546             pointer_action_t pac;
547             if (parse_pointer_action(*args, &pac))
548                 grab_pointer(pac);
549             else
550                 return false;
551         } else {
552             return false;
553         }
554         num--, args++;
555     }
556
557     return true;
558 }
559
560 bool cmd_restore(char **args, int num) {
561     if (num < 1)
562         return false;
563     while (num > 0) {
564         if (streq("-T", *args) || streq("--tree", *args)) {
565             num--, args++;
566             if (num < 1)
567                 return false;
568             restore_tree(*args);
569         } else if (streq("-H", *args) || streq("--history", *args)) {
570             num--, args++;
571             if (num < 1)
572                 return false;
573             restore_history(*args);
574         } else {
575             return false;
576         }
577         num--, args++;
578     }
579
580     return true;
581 }
582
583 bool cmd_control(char **args, int num) {
584     if (num < 1)
585         return false;
586     while (num > 0) {
587         if (streq("--adopt-orphans", *args)) {
588             adopt_orphans();
589         } else if (streq("--put-status", *args)) {
590             put_status();
591         } else if (streq("--toggle-visibility", *args)) {
592             toggle_visibility();
593         } else {
594             return false;
595         }
596         num--, args++;
597     }
598
599     return true;
600 }
601
602 bool cmd_config(char **args, int num, char *rsp) {
603     if (num == 2)
604         return set_setting(*args, *(args + 1));
605     else if (num == 1)
606         return get_setting(*args, rsp);
607     else
608         return false;
609 }
610
611 bool cmd_quit(char **args, int num) {
612     if (num > 0 && sscanf(*args, "%i", &exit_status) != 1)
613         return false;
614     quit();
615     return true;
616 }
617
618 bool handle_message(char *msg, int msg_len, char *rsp)
619 {
620     int cap = INIT_CAP;
621     int num = 0;
622     char **args = malloc(cap * sizeof(char *));
623     if (args == NULL)
624         return false;
625
626     for (int i = 0, j = 0; i < msg_len; i++) {
627         if (msg[i] == 0) {
628             args[num++] = msg + j;
629             j = i + 1;
630         }
631         if (num >= cap) {
632             cap *= 2;
633             char **new = realloc(args, cap * sizeof(char *));
634             if (new == NULL) {
635                 free(args);
636                 return false;
637             } else {
638                 args = new;
639             }
640         }
641     }
642
643     if (num < 1) {
644         free(args);
645         return false;
646     }
647
648     char **args_orig = args;
649     bool ret = process_message(args, num, rsp);
650     free(args_orig);
651     return ret;
652 }
653
654 bool process_message(char **args, int num, char *rsp)
655 {
656     if (streq("window", *args)) {
657         return cmd_window(++args, --num);
658     } else if (streq("desktop", *args)) {
659         return cmd_desktop(++args, --num);
660     } else if (streq("monitor", *args)) {
661         return cmd_monitor(++args, --num);
662     } else if (streq("query", *args)) {
663         return cmd_query(++args, --num, rsp);
664     } else if (streq("restore", *args)) {
665         return cmd_restore(++args, --num);
666     } else if (streq("control", *args)) {
667         return cmd_control(++args, --num);
668     } else if (streq("rule", *args)) {
669         return cmd_rule(++args, --num, rsp);
670     } else if (streq("pointer", *args)) {
671         return cmd_pointer(++args, --num);
672     } else if (streq("config", *args)) {
673         return cmd_config(++args, --num, rsp);
674     } else if (streq("quit", *args)) {
675         return cmd_quit(++args, --num);
676     }
677
678     return false;
679 }
680
681 bool set_setting(char *name, char *value)
682 {
683     if (streq("border_width", name)) {
684         if (sscanf(value, "%u", &border_width) != 1)
685             return false;
686     } else if (streq("window_gap", name)) {
687         if (sscanf(value, "%i", &window_gap) != 1)
688             return false;
689     } else if (streq("split_ratio", name)) {
690         double rat;
691         if (sscanf(value, "%lf", &rat) == 1 && rat > 0 && rat < 1)
692             split_ratio = rat;
693         else
694             return false;
695 #define SETCOLOR(s) \
696     } else if (streq(#s, name)) { \
697         if (get_color(value, &s ## _pxl)) \
698             strncpy(s, value, sizeof(s)); \
699         else \
700             return false;
701     SETCOLOR(focused_border_color)
702     SETCOLOR(active_border_color)
703     SETCOLOR(normal_border_color)
704     SETCOLOR(presel_border_color)
705     SETCOLOR(focused_locked_border_color)
706     SETCOLOR(active_locked_border_color)
707     SETCOLOR(normal_locked_border_color)
708     SETCOLOR(urgent_border_color)
709 #undef SETCOLOR
710     } else if (streq("focus_follows_pointer", name)) {
711         bool b;
712         if (parse_bool(value, &b) && b != focus_follows_pointer) {
713             uint32_t values[] = {(focus_follows_pointer ? CLIENT_EVENT_MASK : CLIENT_EVENT_MASK_FFP)};
714             for (monitor_t *m = mon_head; m != NULL; m = m->next)
715                 for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
716                     for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
717                         xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
718             if (focus_follows_pointer)
719                 disable_motion_recorder();
720             else
721                 enable_motion_recorder();
722             focus_follows_pointer = b;
723             return true;
724         } else {
725             return false;
726         }
727 #define SETBOOL(s) \
728     } else if (streq(#s, name)) { \
729         if (!parse_bool(value, &s)) \
730             return false;
731         SETBOOL(borderless_monocle)
732         SETBOOL(gapless_monocle)
733         SETBOOL(pointer_follows_monitor)
734         SETBOOL(adaptative_raise)
735         SETBOOL(apply_shadow_property)
736         SETBOOL(auto_alternate)
737         SETBOOL(auto_cancel)
738         SETBOOL(history_aware_focus)
739 #undef SETBOOL
740     } else if (streq("wm_name", name)) {
741         strncpy(wm_name, value, sizeof(wm_name));
742         ewmh_update_wm_name();
743         return true;
744     } else {
745         return false;
746     }
747
748     for (monitor_t *m = mon_head; m != NULL; m = m->next)
749         for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
750             arrange(m, d);
751
752     return true;
753 }
754
755 bool get_setting(char *name, char* rsp)
756 {
757     if (streq("border_width", name))
758         snprintf(rsp, BUFSIZ, "%u", border_width);
759     else if (streq("split_ratio", name))
760         snprintf(rsp, BUFSIZ, "%lf", split_ratio);
761     else if (streq("window_gap", name))
762         snprintf(rsp, BUFSIZ, "%i", window_gap);
763 #define GETCOLOR(s) \
764     else if (streq(#s, name)) \
765         snprintf(rsp, BUFSIZ, "%s (%06X)", s, s##_pxl);
766     GETCOLOR(focused_border_color)
767     GETCOLOR(active_border_color)
768     GETCOLOR(normal_border_color)
769     GETCOLOR(presel_border_color)
770     GETCOLOR(focused_locked_border_color)
771     GETCOLOR(active_locked_border_color)
772     GETCOLOR(normal_locked_border_color)
773     GETCOLOR(urgent_border_color)
774 #undef GETCOLOR
775 #define GETBOOL(s) \
776     else if (streq(#s, name)) \
777         snprintf(rsp, BUFSIZ, "%s", BOOLSTR(s));
778     GETBOOL(borderless_monocle)
779     GETBOOL(gapless_monocle)
780     GETBOOL(focus_follows_pointer)
781     GETBOOL(pointer_follows_monitor)
782     GETBOOL(adaptative_raise)
783     GETBOOL(apply_shadow_property)
784     GETBOOL(auto_alternate)
785     GETBOOL(auto_cancel)
786     GETBOOL(history_aware_focus)
787 #undef GETBOOL
788     else if (streq("wm_name", name))
789         snprintf(rsp, BUFSIZ, "%s", wm_name);
790     else
791         return false;
792     return true;
793 }
794
795 bool parse_bool(char *value, bool *b)
796 {
797     if (streq("true", value) || streq("on", value)) {
798         *b = true;
799         return true;
800     } else if (streq("false", value) || streq("off", value)) {
801         *b = false;
802         return true;
803     }
804     return false;
805 }
806
807 bool parse_layout(char *s, layout_t *l)
808 {
809     if (streq("monocle", s)) {
810         *l = LAYOUT_MONOCLE;
811         return true;
812     } else if (streq("tiled", s)) {
813         *l = LAYOUT_TILED;
814         return true;
815     }
816     return false;
817 }
818
819 bool parse_direction(char *s, direction_t *d)
820 {
821     if (streq("right", s)) {
822         *d = DIR_RIGHT;
823         return true;
824     } else if (streq("down", s)) {
825         *d = DIR_DOWN;
826         return true;
827     } else if (streq("left", s)) {
828         *d = DIR_LEFT;
829         return true;
830     } else if (streq("up", s)) {
831         *d = DIR_UP;
832         return true;
833     }
834     return false;
835 }
836
837 bool parse_cycle_direction(char *s, cycle_dir_t *d)
838 {
839     if (streq("next", s)) {
840         *d = CYCLE_NEXT;
841         return true;
842     } else if (streq("prev", s)) {
843         *d = CYCLE_PREV;
844         return true;
845     }
846     return false;
847 }
848
849 bool parse_circulate_direction(char *s, circulate_dir_t *d)
850 {
851     if (streq("forward", s)) {
852         *d = CIRCULATE_FORWARD;
853         return true;
854     } else if (streq("backward", s)) {
855         *d = CIRCULATE_BACKWARD;
856         return true;
857     }
858     return false;
859 }
860
861 bool parse_flip(char *s, flip_t *f)
862 {
863     if (streq("horizontal", s)) {
864         *f = FLIP_HORIZONTAL;
865         return true;
866     } else if (streq("vertical", s)) {
867         *f = FLIP_VERTICAL;
868         return true;
869     }
870     return false;
871 }
872
873 bool parse_fence_move(char *s, fence_move_t *m)
874 {
875     if (streq("push", s)) {
876         *m = MOVE_PUSH;
877         return true;
878     } else if (streq("pull", s)) {
879         *m = MOVE_PULL;
880         return true;
881     }
882     return false;
883 }
884
885 bool parse_pointer_action(char *s, pointer_action_t *a)
886 {
887     if (streq("move", s)) {
888         *a = ACTION_MOVE;
889         return true;
890     } else if (streq("resize_corner", s)) {
891         *a = ACTION_RESIZE_CORNER;
892         return true;
893     } else if (streq("resize_side", s)) {
894         *a = ACTION_RESIZE_SIDE;
895         return true;
896     } else if (streq("focus", s)) {
897         *a = ACTION_FOCUS;
898         return true;
899     }
900     return false;
901 }
902
903 bool parse_degree(char *s, int *d)
904 {
905     int i = atoi(s);
906     while (i < 0)
907         i += 360;
908     while (i > 359)
909         i -= 360;
910     if ((i % 90) != 0) {
911         return false;
912     } else {
913         *d = i;
914         return true;
915     }
916 }
917
918 bool parse_window_id(char *s, long int *i)
919 {
920     char *end;
921     errno = 0;
922     long int ret = strtol(s, &end, 0);
923     if (errno != 0 || *end != '\0')
924         return false;
925     else
926         *i = ret;
927     return true;
928 }
929
930 bool parse_index(char *s, int *i)
931 {
932     return sscanf(s, "^%i", i) == 1;
933 }