]> icculus.org git repositories - mikachu/openbox.git/blob - openbox/actions/layer.c
changes for the 3.4 branch from master (svn trunk)
[mikachu/openbox.git] / openbox / actions / layer.c
1 #include "openbox/actions.h"
2 #include "openbox/client.h"
3
4 typedef struct {
5     gint layer; /*!< -1 for below, 0 for normal, and 1 for above */
6     gboolean toggle;
7     gboolean on;
8 } Options;
9
10 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
11 static gpointer setup_toggletop_func(ObParseInst *i,
12                                      xmlDocPtr doc, xmlNodePtr node);
13 static gpointer setup_togglebottom_func(ObParseInst *i,
14                                         xmlDocPtr doc, xmlNodePtr node);
15 static gpointer setup_sendtop_func(ObParseInst *i,
16                                      xmlDocPtr doc, xmlNodePtr node);
17 static gpointer setup_sendbottom_func(ObParseInst *i,
18                                         xmlDocPtr doc, xmlNodePtr node);
19 static gpointer setup_sendnormal_func(ObParseInst *i,
20                                       xmlDocPtr doc, xmlNodePtr node);
21 static void     free_func(gpointer options);
22 static gboolean run_func(ObActionsData *data, gpointer options);
23
24 void action_layer_startup()
25 {
26     actions_register("Layer",
27                      setup_func,
28                      free_func,
29                      run_func,
30                      NULL, NULL);
31     actions_register("ToggleAlwaysOnTop",
32                      setup_toggletop_func,
33                      free_func,
34                      run_func,
35                      NULL, NULL);
36     actions_register("ToggleAlwaysOnBottom",
37                      setup_togglebottom_func,
38                      free_func,
39                      run_func,
40                      NULL, NULL);
41     actions_register("SendToTopLayer",
42                      setup_sendtop_func,
43                      free_func,
44                      run_func,
45                      NULL, NULL);
46     actions_register("SendToBottomLayer",
47                      setup_sendbottom_func,
48                      free_func,
49                      run_func,
50                      NULL, NULL);
51     actions_register("SendToNormalLayer",
52                      setup_sendnormal_func,
53                      free_func,
54                      run_func,
55                      NULL, NULL);
56 }
57
58 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
59 {
60     xmlNodePtr n;
61     Options *o;
62
63     o = g_new0(Options, 1);
64     o->toggle = TRUE;
65
66     if ((n = parse_find_node("layer", node))) {
67         gchar *s = parse_string(doc, n);
68         if (!g_ascii_strcasecmp(s, "above") ||
69             !g_ascii_strcasecmp(s, "top"))
70             o->layer = 1;
71         else if (!g_ascii_strcasecmp(s, "below") ||
72                  !g_ascii_strcasecmp(s, "bottom"))
73             o->layer = -1;
74         else if (!g_ascii_strcasecmp(s, "normal") ||
75                  !g_ascii_strcasecmp(s, "middle"))
76             o->layer = 0;
77         g_free(s);
78     }
79     if ((n = parse_find_node("state", node))) {
80         gchar *s = parse_string(doc, n);
81         if (g_ascii_strcasecmp(s, "toggle")) {
82             o->toggle = FALSE;
83             o->on = parse_bool(doc, n);
84         }
85         g_free(s);
86     }
87
88     return o;
89 }
90
91 static gpointer setup_toggletop_func(ObParseInst *i,
92                                      xmlDocPtr doc, xmlNodePtr node)
93 {
94     Options *o = g_new0(Options, 1);
95     o->toggle = TRUE;
96     o->layer = 1;
97     return o;
98 }
99
100 static gpointer setup_togglebottom_func(ObParseInst *i,
101                                         xmlDocPtr doc, xmlNodePtr node)
102 {
103     Options *o = g_new0(Options, 1);
104     o->toggle = TRUE;
105     o->layer = -1;
106     return o;
107 }
108
109 static gpointer setup_sendtop_func(ObParseInst *i,
110                                      xmlDocPtr doc, xmlNodePtr node)
111 {
112     Options *o = g_new0(Options, 1);
113     o->on = TRUE;
114     o->layer = 1;
115     return o;
116 }
117
118 static gpointer setup_sendbottom_func(ObParseInst *i,
119                                         xmlDocPtr doc, xmlNodePtr node)
120 {
121     Options *o = g_new0(Options, 1);
122     o->on = TRUE;
123     o->layer = -1;
124     return o;
125 }
126
127 static gpointer setup_sendnormal_func(ObParseInst *i,
128                                       xmlDocPtr doc, xmlNodePtr node)
129 {
130     Options *o = g_new0(Options, 1);
131     o->on = TRUE;
132     o->layer = 0;
133     return o;
134 }
135
136 static void free_func(gpointer options)
137 {
138     Options *o = options;
139
140     g_free(o);
141 }
142
143 /* Always return FALSE because its not interactive */
144 static gboolean run_func(ObActionsData *data, gpointer options)
145 {
146     Options *o = options;
147
148     if (data->client) {
149         ObClient *c = data->client;
150
151         actions_client_move(data, TRUE);
152
153         if (o->layer < 0) {
154             if (o->toggle || c->below != o->on)
155                 client_set_layer(c, c->below ? 0 : -1);
156         }
157         else if (o->layer > 0) {
158             if (o->toggle || c->above != o->on)
159                 client_set_layer(c, c->above ? 0 : 1);
160         }
161         else {
162             if ((o->toggle || o->on) && (c->above || c->below))
163                 client_set_layer(c, 0);
164         }
165
166         actions_client_move(data, FALSE);
167     }
168
169     return FALSE;
170 }