]> Dogcows Code - chaz/openbox/blob - openbox/actions/if.c
Let the If action match window titles with GRegex
[chaz/openbox] / openbox / actions / if.c
1 #include "openbox/actions.h"
2 #include "openbox/misc.h"
3 #include "openbox/client.h"
4 #include "openbox/frame.h"
5 #include "openbox/screen.h"
6 #include "openbox/focus.h"
7 #include <glib.h>
8
9 typedef struct {
10 gboolean shaded_on;
11 gboolean shaded_off;
12 gboolean maxvert_on;
13 gboolean maxvert_off;
14 gboolean maxhorz_on;
15 gboolean maxhorz_off;
16 gboolean maxfull_on;
17 gboolean maxfull_off;
18 gboolean iconic_on;
19 gboolean iconic_off;
20 gboolean focused;
21 gboolean unfocused;
22 gboolean urgent_on;
23 gboolean urgent_off;
24 gboolean decor_off;
25 gboolean decor_on;
26 gboolean omnipresent_on;
27 gboolean omnipresent_off;
28 gboolean desktop_current;
29 gboolean desktop_other;
30 guint desktop_number;
31 guint screendesktop_number;
32 GPatternSpec *matchtitle;
33 GRegex *regextitle;
34 gchar *plaintitle;
35 GSList *thenacts;
36 GSList *elseacts;
37 } Options;
38
39 static gpointer setup_func(xmlNodePtr node);
40 static void free_func(gpointer options);
41 static gboolean run_func(ObActionsData *data, gpointer options);
42
43 void action_if_startup(void)
44 {
45 actions_register("If", setup_func, free_func, run_func);
46 }
47
48 static inline set_bool(xmlNodePtr node,
49 const char *name,
50 gboolean *on,
51 gboolean *off)
52 {
53 xmlNodePtr n;
54
55 if ((n = obt_xml_find_node(node, name))) {
56 if (obt_xml_node_bool(n))
57 *on = TRUE;
58 else
59 *off = TRUE;
60 }
61 }
62
63 static gpointer setup_func(xmlNodePtr node)
64 {
65 xmlNodePtr n;
66 Options *o;
67
68 o = g_slice_new0(Options);
69
70 set_bool(node, "shaded", &o->shaded_on, &o->shaded_off);
71 set_bool(node, "maximized", &o->maxfull_on, &o->maxfull_off);
72 set_bool(node, "maximizedhorizontal", &o->maxhorz_on, &o->maxhorz_off);
73 set_bool(node, "maximizedvertical", &o->maxvert_on, &o->maxvert_off);
74 set_bool(node, "iconified", &o->iconic_on, &o->iconic_off);
75 set_bool(node, "focused", &o->focused, &o->unfocused);
76 set_bool(node, "urgent", &o->urgent_on, &o->urgent_off);
77 set_bool(node, "undecorated", &o->decor_off, &o->decor_on);
78 set_bool(node, "omnipresent", &o->omnipresent_on, &o->omnipresent_off);
79
80 if ((n = obt_xml_find_node(node, "desktop"))) {
81 gchar *s;
82 if ((s = obt_xml_node_string(n))) {
83 if (!g_ascii_strcasecmp(s, "current"))
84 o->desktop_current = TRUE;
85 if (!g_ascii_strcasecmp(s, "other"))
86 o->desktop_other = TRUE;
87 else
88 o->desktop_number = atoi(s);
89 g_free(s);
90 }
91 }
92 if ((n = obt_xml_find_node(node, "activedesktop"))) {
93 o->screendesktop_number = obt_xml_node_int(n);
94 }
95 if ((n = obt_xml_find_node(node, "title"))) {
96 gchar *s, *type = NULL;
97 if ((s = obt_xml_node_string(n))) {
98 if (!obt_xml_attr_string(n, "type", &type) ||
99 !g_ascii_strcasecmp(type, "pattern"))
100 {
101 o->matchtitle = g_pattern_spec_new(s);
102 } else if (type && !g_ascii_strcasecmp(type, "regex")) {
103 o->regextitle = g_regex_new(s, 0, 0, NULL);
104 } else if (type && !g_ascii_strcasecmp(type, "plain")) {
105 o->plaintitle = g_strdup(s);
106 }
107 g_free(s);
108 }
109 }
110
111 if ((n = obt_xml_find_node(node, "then"))) {
112 xmlNodePtr m;
113
114 m = obt_xml_find_node(n->children, "action");
115 while (m) {
116 ObActionsAct *action = actions_parse(m);
117 if (action) o->thenacts = g_slist_append(o->thenacts, action);
118 m = obt_xml_find_node(m->next, "action");
119 }
120 }
121 if ((n = obt_xml_find_node(node, "else"))) {
122 xmlNodePtr m;
123
124 m = obt_xml_find_node(n->children, "action");
125 while (m) {
126 ObActionsAct *action = actions_parse(m);
127 if (action) o->elseacts = g_slist_append(o->elseacts, action);
128 m = obt_xml_find_node(m->next, "action");
129 }
130 }
131
132 return o;
133 }
134
135 static void free_func(gpointer options)
136 {
137 Options *o = options;
138
139 while (o->thenacts) {
140 actions_act_unref(o->thenacts->data);
141 o->thenacts = g_slist_delete_link(o->thenacts, o->thenacts);
142 }
143 while (o->elseacts) {
144 actions_act_unref(o->elseacts->data);
145 o->elseacts = g_slist_delete_link(o->elseacts, o->elseacts);
146 }
147 if (o->matchtitle)
148 g_pattern_spec_free(o->matchtitle);
149 if (o->regextitle)
150 g_regex_unref(o->regextitle);
151 if (o->plaintitle)
152 g_free(o->plaintitle);
153
154 g_slice_free(Options, o);
155 }
156
157 /* Always return FALSE because its not interactive */
158 static gboolean run_func(ObActionsData *data, gpointer options)
159 {
160 Options *o = options;
161 GSList *acts;
162 ObClient *c = data->client;
163
164 if (c &&
165 (!o->shaded_on || c->shaded) &&
166 (!o->shaded_off || !c->shaded) &&
167 (!o->iconic_on || c->iconic) &&
168 (!o->iconic_off || !c->iconic) &&
169 (!o->maxhorz_on || c->max_horz) &&
170 (!o->maxhorz_off || !c->max_horz) &&
171 (!o->maxvert_on || c->max_vert) &&
172 (!o->maxvert_off || !c->max_vert) &&
173 (!o->maxfull_on || (c->max_vert && c->max_horz)) &&
174 (!o->maxfull_off || !(c->max_vert && c->max_horz)) &&
175 (!o->focused || (c == focus_client)) &&
176 (!o->unfocused || !(c == focus_client)) &&
177 (!o->urgent_on || (c->urgent || c->demands_attention)) &&
178 (!o->urgent_off || !(c->urgent || c->demands_attention)) &&
179 (!o->decor_off || (c->undecorated || !(c->decorations & OB_FRAME_DECOR_TITLEBAR))) &&
180 (!o->decor_on || (!c->undecorated && (c->decorations & OB_FRAME_DECOR_TITLEBAR))) &&
181 (!o->omnipresent_on || (c->desktop == DESKTOP_ALL)) &&
182 (!o->omnipresent_off || (c->desktop != DESKTOP_ALL)) &&
183 (!o->desktop_current || ((c->desktop == screen_desktop) ||
184 (c->desktop == DESKTOP_ALL))) &&
185 (!o->desktop_other || ((c->desktop != screen_desktop) &&
186 (c->desktop != DESKTOP_ALL))) &&
187 (!o->desktop_number || ((c->desktop == o->desktop_number - 1) ||
188 (c->desktop == DESKTOP_ALL))) &&
189 (!o->screendesktop_number || screen_desktop == o->screendesktop_number - 1) &&
190 (!o->matchtitle ||
191 (g_pattern_match_string(o->matchtitle, c->original_title))) &&
192 (!o->regextitle ||
193 (g_regex_match(o->regextitle, c->original_title, 0, NULL))) &&
194 (!o->plaintitle ||
195 (!strcmp(o->plaintitle, c->original_title))))
196 {
197 acts = o->thenacts;
198 }
199 else
200 acts = o->elseacts;
201
202 actions_run_acts(acts, data->uact, data->state,
203 data->x, data->y, data->button,
204 data->context, data->client);
205
206 return FALSE;
207 }
This page took 0.037781 seconds and 4 git commands to generate.