Make it possible for an action name to choose whether it is interactive or not based...
[dana/openbox.git] / 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     GSList *thenacts;
23     GSList *elseacts;
24 } Options;
25
26 static gpointer setup_func(xmlNodePtr node);
27 static void     free_func(gpointer options);
28 static gboolean run_func(ObActionsData *data, gpointer options);
29
30 void action_if_startup(void)
31 {
32     actions_register("If", setup_func, free_func, run_func);
33 }
34
35 static gpointer setup_func(xmlNodePtr node)
36 {
37     xmlNodePtr n;
38     Options *o;
39
40     o = g_new0(Options, 1);
41
42     if ((n = obt_parse_find_node(node, "shaded"))) {
43         if (obt_parse_node_bool(n))
44             o->shaded_on = TRUE;
45         else
46             o->shaded_off = TRUE;
47     }
48     if ((n = obt_parse_find_node(node, "maximized"))) {
49         if (obt_parse_node_bool(n))
50             o->maxfull_on = TRUE;
51         else
52             o->maxfull_off = TRUE;
53     }
54     if ((n = obt_parse_find_node(node, "maximizedhorizontal"))) {
55         if (obt_parse_node_bool(n))
56             o->maxhorz_on = TRUE;
57         else
58             o->maxhorz_off = TRUE;
59     }
60     if ((n = obt_parse_find_node(node, "maximizedvertical"))) {
61         if (obt_parse_node_bool(n))
62             o->maxvert_on = TRUE;
63         else
64             o->maxvert_off = TRUE;
65     }
66     if ((n = obt_parse_find_node(node, "iconified"))) {
67         if (obt_parse_node_bool(n))
68             o->iconic_on = TRUE;
69         else
70             o->iconic_off = TRUE;
71     }
72     if ((n = obt_parse_find_node(node, "focused"))) {
73         if (obt_parse_node_bool(n))
74             o->focused = TRUE;
75         else
76             o->unfocused = TRUE;
77     }
78
79     if ((n = obt_parse_find_node(node, "then"))) {
80         xmlNodePtr m;
81
82         m = obt_parse_find_node(n->children, "action");
83         while (m) {
84             ObActionsAct *action = actions_parse(m);
85             if (action) o->thenacts = g_slist_append(o->thenacts, action);
86             m = obt_parse_find_node(m->next, "action");
87         }
88     }
89     if ((n = obt_parse_find_node(node, "else"))) {
90         xmlNodePtr m;
91
92         m = obt_parse_find_node(n->children, "action");
93         while (m) {
94             ObActionsAct *action = actions_parse(m);
95             if (action) o->elseacts = g_slist_append(o->elseacts, action);
96             m = obt_parse_find_node(m->next, "action");
97         }
98     }
99
100     return o;
101 }
102
103 static void free_func(gpointer options)
104 {
105     Options *o = options;
106
107     while (o->thenacts) {
108         actions_act_unref(o->thenacts->data);
109         o->thenacts = g_slist_delete_link(o->thenacts, o->thenacts);
110     }
111     while (o->elseacts) {
112         actions_act_unref(o->elseacts->data);
113         o->elseacts = g_slist_delete_link(o->elseacts, o->elseacts);
114     }
115
116     g_free(o);
117 }
118
119 /* Always return FALSE because its not interactive */
120 static gboolean run_func(ObActionsData *data, gpointer options)
121 {
122     Options *o = options;
123     GSList *acts;
124     ObClient *c = data->client;
125
126     if ((!o->shaded_on || (c && c->shaded)) &&
127         (!o->shaded_off || (c && !c->shaded)) &&
128         (!o->iconic_on || (c && c->iconic)) &&
129         (!o->iconic_off || (c && !c->iconic)) &&
130         (!o->maxhorz_on || (c && c->max_horz)) &&
131         (!o->maxhorz_off || (c && !c->max_horz)) &&
132         (!o->maxvert_on || (c && c->max_vert)) &&
133         (!o->maxvert_off || (c && !c->max_vert)) &&
134         (!o->maxfull_on || (c && c->max_vert && c->max_horz)) &&
135         (!o->maxfull_off || (c && !(c->max_vert && c->max_horz))) &&
136         (!o->focused || (c && (c == focus_client))) &&
137         (!o->unfocused || (c && !(c == focus_client))))
138     {
139         acts = o->thenacts;
140     }
141     else
142         acts = o->elseacts;
143
144     actions_run_acts(acts, data->uact, data->state,
145                      data->x, data->y, data->button,
146                      data->context, data->client);
147
148     return FALSE;
149 }