]> icculus.org git repositories - dana/openbox.git/blob - openbox/actions/layer.c
Use ObConfigValue to parse gravity coords, remove parse special functions from config...
[dana/openbox.git] / openbox / actions / layer.c
1 #include "openbox/action.h"
2 #include "openbox/action_list_run.h"
3 #include "openbox/config_value.h"
4 #include "openbox/client.h"
5 #include "openbox/client_set.h"
6
7 typedef struct {
8     gint layer; /*!< -1 for below, 0 for normal, and 1 for above */
9     gboolean toggle;
10 } Options;
11
12 static gpointer setup_func_top(GHashTable *config);
13 static gpointer setup_func_bottom(GHashTable *config);
14 static gpointer setup_func_send(GHashTable *config);
15 static void free_func(gpointer o);
16 static gboolean run_func(const ObClientSet *set,
17                          const ObActionListRun *data, gpointer options);
18
19 void action_layer_startup(void)
20 {
21     action_register("ToggleAlwaysOnTop", OB_ACTION_DEFAULT_FILTER_SINGLE,
22                     setup_func_top, free_func, run_func);
23     action_register("ToggleAlwaysOnBottom", OB_ACTION_DEFAULT_FILTER_SINGLE,
24                     setup_func_bottom, free_func, run_func);
25     action_register("SendToLayer", OB_ACTION_DEFAULT_FILTER_SINGLE,
26                     setup_func_send, free_func, run_func);
27 }
28
29 static gpointer setup_func_top(GHashTable *config)
30 {
31     Options *o = g_slice_new0(Options);
32     o->layer = 1;
33     o->toggle = TRUE;
34     return o;
35 }
36
37 static gpointer setup_func_bottom(GHashTable *config)
38 {
39     Options *o = g_slice_new0(Options);
40     o->layer = -1;
41     o->toggle = TRUE;
42     return o;
43 }
44
45 static gpointer setup_func_send(GHashTable *config)
46 {
47     ObConfigValue *v;
48     Options *o;
49
50     o = g_slice_new0(Options);
51
52     v = g_hash_table_lookup(config, "layer");
53     if (v && config_value_is_string(v)) {
54         const gchar *s = config_value_string(v);
55         if (!g_ascii_strcasecmp(s, "above") ||
56             !g_ascii_strcasecmp(s, "top"))
57             o->layer = 1;
58         else if (!g_ascii_strcasecmp(s, "below") ||
59                  !g_ascii_strcasecmp(s, "bottom"))
60             o->layer = -1;
61         else if (!g_ascii_strcasecmp(s, "normal") ||
62                  !g_ascii_strcasecmp(s, "middle"))
63             o->layer = 0;
64     }
65
66     return o;
67 }
68
69 static void free_func(gpointer o)
70 {
71     g_slice_free(Options, o);
72 }
73
74 static gboolean each_run(ObClient *c, const ObActionListRun *data,
75                          gpointer options)
76 {
77     Options *o = options;
78
79     if (o->layer < 0) {
80         if (o->toggle || !c->below)
81             client_set_layer(c, c->below ? 0 : -1);
82     }
83     else if (o->layer > 0) {
84         if (o->toggle || !c->above)
85             client_set_layer(c, c->above ? 0 : 1);
86     }
87     else if (c->above || c->below)
88         client_set_layer(c, 0);
89     return TRUE;
90 }
91
92 /* Always return FALSE because its not interactive */
93 static gboolean run_func(const ObClientSet *set,
94                          const ObActionListRun *data, gpointer options)
95 {
96     if (!client_set_is_empty(set)) {
97         action_client_move(data, TRUE);
98         client_set_run(set, data, each_run, options);
99         action_client_move(data, FALSE);
100     }
101     return FALSE;
102 }