Merge branch 'backport' into work
[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 } Options;
8
9 static gpointer setup_func_top(xmlNodePtr node);
10 static gpointer setup_func_bottom(xmlNodePtr node);
11 static gpointer setup_func_send(xmlNodePtr node);
12 static gboolean run_func(ObActionsData *data, gpointer options);
13 /* 3.4-compatibility */
14 static gpointer setup_sendtop_func(xmlNodePtr node);
15 static gpointer setup_sendbottom_func(xmlNodePtr node);
16 static gpointer setup_sendnormal_func(xmlNodePtr node);
17
18 void action_layer_startup(void)
19 {
20     actions_register("ToggleAlwaysOnTop", setup_func_top, g_free,
21                      run_func, NULL, NULL);
22     actions_register("ToggleAlwaysOnBottom", setup_func_bottom, g_free,
23                      run_func, NULL, NULL);
24     actions_register("SendToLayer", setup_func_send, g_free,
25                      run_func, NULL, NULL);
26     /* 3.4-compatibility */
27     actions_register("SendToTopLayer", setup_sendtop_func, g_free,
28                      run_func, NULL, NULL);
29     actions_register("SendToBottomLayer", setup_sendbottom_func, g_free,
30                      run_func, NULL, NULL);
31     actions_register("SendToNormalLayer", setup_sendnormal_func, g_free,
32                      run_func, NULL, NULL);
33 }
34
35 static gpointer setup_func_top(xmlNodePtr node)
36 {
37     Options *o = g_new0(Options, 1);
38     o->layer = 1;
39     o->toggle = TRUE;
40     return o;
41 }
42
43 static gpointer setup_func_bottom(xmlNodePtr node)
44 {
45     Options *o = g_new0(Options, 1);
46     o->layer = -1;
47     o->toggle = TRUE;
48     return o;
49 }
50
51 static gpointer setup_func_send(xmlNodePtr node)
52 {
53     xmlNodePtr n;
54     Options *o;
55
56     o = g_new0(Options, 1);
57
58     if ((n = obt_parse_find_node(node, "layer"))) {
59         gchar *s = obt_parse_node_string(n);
60         if (!g_ascii_strcasecmp(s, "above") ||
61             !g_ascii_strcasecmp(s, "top"))
62             o->layer = 1;
63         else if (!g_ascii_strcasecmp(s, "below") ||
64                  !g_ascii_strcasecmp(s, "bottom"))
65             o->layer = -1;
66         else if (!g_ascii_strcasecmp(s, "normal") ||
67                  !g_ascii_strcasecmp(s, "middle"))
68             o->layer = 0;
69         g_free(s);
70     }
71
72     return o;
73 }
74
75 /* Always return FALSE because its not interactive */
76 static gboolean run_func(ObActionsData *data, gpointer options)
77 {
78     Options *o = options;
79
80     if (data->client) {
81         ObClient *c = data->client;
82
83         actions_client_move(data, TRUE);
84
85         if (o->layer < 0) {
86             if (o->toggle || !c->below)
87                 client_set_layer(c, c->below ? 0 : -1);
88         }
89         else if (o->layer > 0) {
90             if (o->toggle || !c->above)
91                 client_set_layer(c, c->above ? 0 : 1);
92         }
93         else if (c->above || c->below)
94             client_set_layer(c, 0);
95
96         actions_client_move(data, FALSE);
97     }
98
99     return FALSE;
100 }
101
102 /* 3.4-compatibility */
103 static gpointer setup_sendtop_func(xmlNodePtr node)
104 {
105     Options *o = g_new0(Options, 1);
106     o->layer = 1;
107     o->toggle = FALSE;
108     return o;
109 }
110
111 static gpointer setup_sendbottom_func(xmlNodePtr node)
112 {
113     Options *o = g_new0(Options, 1);
114     o->layer = -1;
115     o->toggle = FALSE;
116     return o;
117 }
118
119 static gpointer setup_sendnormal_func(xmlNodePtr node)
120 {
121     Options *o = g_new0(Options, 1);
122     o->layer = 0;
123     o->toggle = FALSE;
124     return o;
125 }
126