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