]> git.lizzy.rs Git - bspwm.git/blob - rule.c
Externalize rules
[bspwm.git] / rule.c
1 /* * Copyright (c) 2012-2013 Bastien Dejean
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  *  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation and/or
11  * other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
17  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include "bspwm.h"
29 #include "ewmh.h"
30 #include "window.h"
31 #include "messages.h"
32 #include "settings.h"
33 #include "query.h"
34 #include "rule.h"
35
36 rule_consequence_t *make_rule_conquence(void)
37 {
38     rule_consequence_t *r = calloc(1, sizeof(rule_consequence_t));
39     r->manage = r->focus = true;
40     return r;
41 }
42
43 void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, rule_consequence_t *csq)
44 {
45     xcb_size_hints_t size_hints;
46     if (xcb_icccm_get_wm_normal_hints_reply(dpy, xcb_icccm_get_wm_normal_hints(dpy, win), &size_hints, NULL) == 1) {
47         if (size_hints.min_width > 0 && size_hints.min_height > 0
48                 && size_hints.min_width == size_hints.max_width
49                 && size_hints.min_height == size_hints.max_height)
50             csq->floating = true;
51     }
52     xcb_window_t transient_for = XCB_NONE;
53     xcb_icccm_get_wm_transient_for_reply(dpy, xcb_icccm_get_wm_transient_for(dpy, win), &transient_for, NULL);
54     if (transient_for != XCB_NONE)
55         csq->transient = csq->floating = true;
56     char cmd[MAXLEN];
57     snprintf(cmd, sizeof(cmd), rule_command, win);
58     FILE *results = popen(cmd, "r");
59     if (results == NULL) {
60         warn("Failed to run rule command: '%s'.", cmd);
61         return;
62     }
63     char line[MAXLEN];
64     bool v;
65     while (fgets(line, sizeof(line), results) != NULL) {
66         size_t i = strlen(line) - 1;
67         while (i > 0 && isspace(line[i])) {
68             line[i] = '\0';
69             i--;
70         }
71         char *key = strtok(line, CSQ_BLK);
72         char *value = strtok(NULL, CSQ_BLK);
73         while (key != NULL && value != NULL) {
74             PRINTF("%s = %s\n", key, value);
75             if (streq("desktop", key)) {
76                 coordinates_t ref = {mon, mon->desk, NULL};
77                 coordinates_t trg = {NULL, NULL, NULL};
78                 if (desktop_from_desc(value, &ref, &trg)) {
79                     *m = trg.monitor;
80                     *d = trg.desktop;
81                 }
82             } else if (streq("monitor", key)) {
83                 coordinates_t ref = {mon, NULL, NULL};
84                 coordinates_t trg = {NULL, NULL, NULL};
85                 if (monitor_from_desc(value, &ref, &trg)) {
86                     *m = trg.monitor;
87                     *d = trg.monitor->desk;
88                 }
89             } else if (parse_bool(value, &v)) {
90                 if (streq("floating", key))
91                     csq->floating = v;
92 #define SETCSQ(name) \
93                 else if (streq(#name, key)) \
94                     csq->name = v;
95                 SETCSQ(fullscreen)
96                 SETCSQ(locked)
97                 SETCSQ(sticky)
98                 SETCSQ(private)
99                 SETCSQ(frame)
100                 SETCSQ(center)
101                 SETCSQ(lower)
102                 SETCSQ(follow)
103                 SETCSQ(manage)
104                 SETCSQ(focus)
105 #undef SETCSQ
106
107             }
108             key = strtok(NULL, CSQ_BLK);
109             value = strtok(NULL, CSQ_BLK);
110         }
111     }
112     if (csq->sticky) {
113         *m = mon;
114         *d = mon->desk;
115     }
116 }