let you send windows with the desktop and directionaldesktop actions
[mikachu/openbox.git] / openbox / actions / desktop.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 last;
8     guint desktop;
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_desktop_startup()
18 {
19     actions_register("Desktop",
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->follow = TRUE;
33
34     if ((n = parse_find_node("desktop", node))) {
35         gchar *s = parse_string(doc, n);
36         if (!g_ascii_strcasecmp(s, "last"))
37             o->last = TRUE;
38         else
39             o->desktop = parse_int(doc, n) - 1;
40         g_free(s);
41     }
42     if ((n = parse_find_node("send", node)))
43         o->send = parse_bool(doc, n);
44     if ((n = parse_find_node("follow", node)))
45         o->follow = parse_bool(doc, n);
46
47     return o;
48 }
49
50 static void free_func(gpointer options)
51 {
52     Options *o = options;
53
54     g_free(o);
55 }
56
57 /* Always return FALSE because its not interactive */
58 static gboolean run_func(ObActionsData *data, gpointer options)
59 {
60     Options *o = options;
61     guint d;
62
63     if (o->last)
64         d = screen_last_desktop;
65     else
66         d = o->desktop;
67
68     if (d < screen_num_desktops && d != screen_desktop) {
69         gboolean go = !o->send;
70         if (o->send) {
71             if (data->client && client_normal(data->client)) {
72                 client_set_desktop(data->client, d, o->follow, FALSE);
73                 go = TRUE;
74             }
75         }
76         if (go)
77             screen_set_desktop(d, TRUE);
78     }
79     return FALSE;
80 }