]> icculus.org git repositories - mikachu/openbox.git/blob - openbox/actions/layer.c
add the layer action
[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 void     free_func(gpointer options);
12 static gboolean run_func(ObActionsData *data, gpointer options);
13
14 void action_layer_startup()
15 {
16     actions_register("Layer",
17                      setup_func,
18                      free_func,
19                      run_func,
20                      NULL, NULL);
21 }
22
23 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
24 {
25     xmlNodePtr n;
26     Options *o;
27
28     o = g_new0(Options, 1);
29     o->toggle = TRUE;
30
31     if ((n = parse_find_node("layer", node))) {
32         gchar *s = parse_string(doc, n);
33         if (!g_ascii_strcasecmp(s, "above") ||
34             !g_ascii_strcasecmp(s, "top"))
35             o->layer = 1;
36         else if (!g_ascii_strcasecmp(s, "below") ||
37                  !g_ascii_strcasecmp(s, "bottom"))
38             o->layer = -1;
39         else if (!g_ascii_strcasecmp(s, "normal") ||
40                  !g_ascii_strcasecmp(s, "middle"))
41             o->layer = 0;
42         g_free(s);
43     }
44     if ((n = parse_find_node("state", node))) {
45         gchar *s = parse_string(doc, n);
46         if (g_ascii_strcasecmp(s, "toggle")) {
47             o->toggle = FALSE;
48             o->on = parse_bool(doc, n);
49         }
50         g_free(s);
51     }
52
53     return o;
54 }
55
56 static void free_func(gpointer options)
57 {
58     Options *o = options;
59
60     g_free(o);
61 }
62
63 /* Always return FALSE because its not interactive */
64 static gboolean run_func(ObActionsData *data, gpointer options)
65 {
66     Options *o = options;
67
68     if (data->client) {
69         ObClient *c = data->client;
70
71         actions_client_move(data, TRUE);
72
73         if (o->layer < 0) {
74             if (o->toggle || c->below != o->on)
75                 client_set_layer(c, c->below ? 0 : -1);
76         }
77         else if (o->layer > 0) {
78             if (o->toggle || c->above != o->on)
79                 client_set_layer(c, c->above ? 0 : 1);
80         }
81         else {
82             if ((o->toggle || o->on) && (c->above || c->below))
83                 client_set_layer(c, 0);
84         }
85
86         actions_client_move(data, FALSE);
87     }
88
89     return FALSE;
90 }