Change "plain" to "exact" for If's <title>
[openbox.git] / openbox / actions / if.c
blob3f4c4d64f72c15d5f1df8fcb9baa10045d772ab5
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>
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 guint client_monitor;
33 GPatternSpec *matchtitle;
34 GRegex *regextitle;
35 gchar *exacttitle;
36 GSList *thenacts;
37 GSList *elseacts;
38 } Options;
40 static gpointer setup_func(xmlNodePtr node);
41 static void free_func(gpointer options);
42 static gboolean run_func(ObActionsData *data, gpointer options);
44 void action_if_startup(void)
46 actions_register("If", setup_func, free_func, run_func);
49 static inline set_bool(xmlNodePtr node,
50 const char *name,
51 gboolean *on,
52 gboolean *off)
54 xmlNodePtr n;
56 if ((n = obt_xml_find_node(node, name))) {
57 if (obt_xml_node_bool(n))
58 *on = TRUE;
59 else
60 *off = TRUE;
64 static gpointer setup_func(xmlNodePtr node)
66 xmlNodePtr n;
67 Options *o;
69 o = g_slice_new0(Options);
71 set_bool(node, "shaded", &o->shaded_on, &o->shaded_off);
72 set_bool(node, "maximized", &o->maxfull_on, &o->maxfull_off);
73 set_bool(node, "maximizedhorizontal", &o->maxhorz_on, &o->maxhorz_off);
74 set_bool(node, "maximizedvertical", &o->maxvert_on, &o->maxvert_off);
75 set_bool(node, "iconified", &o->iconic_on, &o->iconic_off);
76 set_bool(node, "focused", &o->focused, &o->unfocused);
77 set_bool(node, "urgent", &o->urgent_on, &o->urgent_off);
78 set_bool(node, "undecorated", &o->decor_off, &o->decor_on);
79 set_bool(node, "omnipresent", &o->omnipresent_on, &o->omnipresent_off);
81 if ((n = obt_xml_find_node(node, "desktop"))) {
82 gchar *s;
83 if ((s = obt_xml_node_string(n))) {
84 if (!g_ascii_strcasecmp(s, "current"))
85 o->desktop_current = TRUE;
86 if (!g_ascii_strcasecmp(s, "other"))
87 o->desktop_other = TRUE;
88 else
89 o->desktop_number = atoi(s);
90 g_free(s);
93 if ((n = obt_xml_find_node(node, "activedesktop"))) {
94 o->screendesktop_number = obt_xml_node_int(n);
96 if ((n = obt_xml_find_node(node, "title"))) {
97 gchar *s, *type = NULL;
98 if ((s = obt_xml_node_string(n))) {
99 if (!obt_xml_attr_string(n, "type", &type) ||
100 !g_ascii_strcasecmp(type, "pattern"))
102 o->matchtitle = g_pattern_spec_new(s);
103 } else if (type && !g_ascii_strcasecmp(type, "regex")) {
104 o->regextitle = g_regex_new(s, 0, 0, NULL);
105 } else if (type && !g_ascii_strcasecmp(type, "exact")) {
106 o->exacttitle = g_strdup(s);
108 g_free(s);
111 if ((n = obt_xml_find_node(node, "monitor"))) {
112 o->client_monitor = obt_xml_node_int(n);
115 if ((n = obt_xml_find_node(node, "then"))) {
116 xmlNodePtr m;
118 m = obt_xml_find_node(n->children, "action");
119 while (m) {
120 ObActionsAct *action = actions_parse(m);
121 if (action) o->thenacts = g_slist_append(o->thenacts, action);
122 m = obt_xml_find_node(m->next, "action");
125 if ((n = obt_xml_find_node(node, "else"))) {
126 xmlNodePtr m;
128 m = obt_xml_find_node(n->children, "action");
129 while (m) {
130 ObActionsAct *action = actions_parse(m);
131 if (action) o->elseacts = g_slist_append(o->elseacts, action);
132 m = obt_xml_find_node(m->next, "action");
136 return o;
139 static void free_func(gpointer options)
141 Options *o = options;
143 while (o->thenacts) {
144 actions_act_unref(o->thenacts->data);
145 o->thenacts = g_slist_delete_link(o->thenacts, o->thenacts);
147 while (o->elseacts) {
148 actions_act_unref(o->elseacts->data);
149 o->elseacts = g_slist_delete_link(o->elseacts, o->elseacts);
151 if (o->matchtitle)
152 g_pattern_spec_free(o->matchtitle);
153 if (o->regextitle)
154 g_regex_unref(o->regextitle);
155 if (o->exacttitle)
156 g_free(o->exacttitle);
158 g_slice_free(Options, o);
161 /* Always return FALSE because its not interactive */
162 static gboolean run_func(ObActionsData *data, gpointer options)
164 Options *o = options;
165 GSList *acts;
166 ObClient *c = data->client;
168 if (c &&
169 (!o->shaded_on || c->shaded) &&
170 (!o->shaded_off || !c->shaded) &&
171 (!o->iconic_on || c->iconic) &&
172 (!o->iconic_off || !c->iconic) &&
173 (!o->maxhorz_on || c->max_horz) &&
174 (!o->maxhorz_off || !c->max_horz) &&
175 (!o->maxvert_on || c->max_vert) &&
176 (!o->maxvert_off || !c->max_vert) &&
177 (!o->maxfull_on || (c->max_vert && c->max_horz)) &&
178 (!o->maxfull_off || !(c->max_vert && c->max_horz)) &&
179 (!o->focused || (c == focus_client)) &&
180 (!o->unfocused || !(c == focus_client)) &&
181 (!o->urgent_on || (c->urgent || c->demands_attention)) &&
182 (!o->urgent_off || !(c->urgent || c->demands_attention)) &&
183 (!o->decor_off || (c->undecorated || !(c->decorations & OB_FRAME_DECOR_TITLEBAR))) &&
184 (!o->decor_on || (!c->undecorated && (c->decorations & OB_FRAME_DECOR_TITLEBAR))) &&
185 (!o->omnipresent_on || (c->desktop == DESKTOP_ALL)) &&
186 (!o->omnipresent_off || (c->desktop != DESKTOP_ALL)) &&
187 (!o->desktop_current || ((c->desktop == screen_desktop) ||
188 (c->desktop == DESKTOP_ALL))) &&
189 (!o->desktop_other || ((c->desktop != screen_desktop) &&
190 (c->desktop != DESKTOP_ALL))) &&
191 (!o->desktop_number || ((c->desktop == o->desktop_number - 1) ||
192 (c->desktop == DESKTOP_ALL))) &&
193 (!o->screendesktop_number || screen_desktop == o->screendesktop_number - 1) &&
194 (!o->matchtitle ||
195 (g_pattern_match_string(o->matchtitle, c->original_title))) &&
196 (!o->regextitle ||
197 (g_regex_match(o->regextitle, c->original_title, 0, NULL))) &&
198 (!o->exacttitle ||
199 (!strcmp(o->exacttitle, c->original_title))) &&
200 (!o->client_monitor ||
201 (o->client_monitor == client_monitor(c) + 1)))
203 acts = o->thenacts;
205 else
206 acts = o->elseacts;
208 actions_run_acts(acts, data->uact, data->state,
209 data->x, data->y, data->button,
210 data->context, data->client);
212 return FALSE;