update hardcoded bindings to previous changes
[mikachu/openbox.git] / openbox / actions / directionaldesktop.c
1 #include "openbox/actions.h"
2 #include "openbox/screen.h"
3 #include "openbox/client.h"
4 #include <glib.h>
5
6 typedef struct {
7     gboolean linear;
8     gboolean wrap;
9     ObDirection dir;
10     gboolean send;
11     gboolean follow;
12 } Options;
13
14 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
15 static void     free_func(gpointer options);
16 static gboolean run_func(ObActionsData *data, gpointer options);
17
18 void action_directionaldesktop_startup()
19 {
20     actions_register("DirectionalDesktop",
21                      setup_func,
22                      free_func,
23                      run_func,
24                      NULL, NULL);
25 }
26
27 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
28 {
29     xmlNodePtr n;
30     Options *o;
31
32     o = g_new0(Options, 1);
33     o->wrap = TRUE;
34     o->dir = OB_DIRECTION_EAST;
35     o->follow = TRUE;
36
37     if ((n = parse_find_node("wrap", node)))
38         o->wrap = parse_bool(doc, n);
39     if ((n = parse_find_node("direction", node))) {
40         gchar *s = parse_string(doc, n);
41         if (!g_ascii_strcasecmp(s, "next")) {
42             o->linear = TRUE;
43             o->dir = OB_DIRECTION_EAST;
44         }
45         else if (!g_ascii_strcasecmp(s, "previous")) {
46             o->linear = TRUE;
47             o->dir = OB_DIRECTION_WEST;
48         }
49         else if (!g_ascii_strcasecmp(s, "north") ||
50                  !g_ascii_strcasecmp(s, "up"))
51             o->dir = OB_DIRECTION_NORTH;
52         else if (!g_ascii_strcasecmp(s, "south") ||
53                  !g_ascii_strcasecmp(s, "down"))
54             o->dir = OB_DIRECTION_SOUTH;
55         else if (!g_ascii_strcasecmp(s, "west") ||
56                  !g_ascii_strcasecmp(s, "left"))
57             o->dir = OB_DIRECTION_WEST;
58         else if (!g_ascii_strcasecmp(s, "east") ||
59                  !g_ascii_strcasecmp(s, "right"))
60             o->dir = OB_DIRECTION_EAST;
61         g_free(s);
62     }
63     if ((n = parse_find_node("send", node)))
64         o->send = parse_bool(doc, n);
65     if ((n = parse_find_node("follow", node)))
66         o->follow = parse_bool(doc, n);
67
68     return o;
69 }
70
71 static void free_func(gpointer options)
72 {
73     Options *o = options;
74
75     g_free(o);
76 }
77
78 /* Always return FALSE because its not interactive */
79 static gboolean run_func(ObActionsData *data, gpointer options)
80 {
81     Options *o = options;
82     guint d;
83
84     d = screen_cycle_desktop(o->dir,
85                              o->wrap,
86                              o->linear,
87                              FALSE, TRUE, FALSE);
88     if (d < screen_num_desktops && d != screen_desktop) {
89         gboolean go = !o->send;
90         if (o->send) {
91             if (data->client && client_normal(data->client)) {
92                 client_set_desktop(data->client, d, o->follow, FALSE);
93                 go = TRUE;
94             }
95         }
96         if (go)
97             screen_set_desktop(d, TRUE);
98     }
99
100     return FALSE;
101 }