]> Dogcows Code - chaz/openbox/blob - openbox/actions/desktop.c
142fec513108f6a64abb3a6360ee39300436af4e
[chaz/openbox] / 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 enum {
7 LAST,
8 RELATIVE,
9 ABSOLUTE
10 } SwitchType;
11
12 typedef struct {
13 SwitchType type;
14 union {
15 struct {
16 guint desktop;
17 } abs;
18
19 struct {
20 gboolean linear;
21 gboolean wrap;
22 ObDirection dir;
23 } rel;
24 };
25 gboolean send;
26 gboolean follow;
27 } Options;
28
29 static gpointer setup_go_func(ObParseInst *i, xmlDocPtr doc,
30 xmlNodePtr node);
31 static gpointer setup_send_func(ObParseInst *i, xmlDocPtr doc,
32 xmlNodePtr node);
33 static gboolean run_func(ObActionsData *data, gpointer options);
34
35 void action_desktop_startup(void)
36 {
37 actions_register("GoToDesktop", setup_go_func, g_free, run_func,
38 NULL, NULL);
39 actions_register("SendToDesktop", setup_send_func, g_free, run_func,
40 NULL, NULL);
41 }
42
43 static gpointer setup_go_func(ObParseInst *i, xmlDocPtr doc,
44 xmlNodePtr node)
45 {
46 xmlNodePtr n;
47 Options *o;
48
49 o = g_new0(Options, 1);
50 /* don't go anywhere if theres no options given */
51 o->type = ABSOLUTE;
52 o->abs.desktop = screen_desktop;
53 /* wrap by default - it's handy! */
54 o->rel.wrap = TRUE;
55
56 if ((n = parse_find_node("to", node))) {
57 gchar *s = parse_string(doc, n);
58 if (!g_ascii_strcasecmp(s, "last"))
59 o->type = LAST;
60 else if (!g_ascii_strcasecmp(s, "next")) {
61 o->type = RELATIVE;
62 o->rel.linear = TRUE;
63 o->rel.dir = OB_DIRECTION_EAST;
64 }
65 else if (!g_ascii_strcasecmp(s, "previous")) {
66 o->type = RELATIVE;
67 o->rel.linear = TRUE;
68 o->rel.dir = OB_DIRECTION_WEST;
69 }
70 else if (!g_ascii_strcasecmp(s, "north") ||
71 !g_ascii_strcasecmp(s, "up")) {
72 o->type = RELATIVE;
73 o->rel.dir = OB_DIRECTION_NORTH;
74 }
75 else if (!g_ascii_strcasecmp(s, "south") ||
76 !g_ascii_strcasecmp(s, "down")) {
77 o->type = RELATIVE;
78 o->rel.dir = OB_DIRECTION_SOUTH;
79 }
80 else if (!g_ascii_strcasecmp(s, "west") ||
81 !g_ascii_strcasecmp(s, "left")) {
82 o->type = RELATIVE;
83 o->rel.dir = OB_DIRECTION_WEST;
84 }
85 else if (!g_ascii_strcasecmp(s, "east") ||
86 !g_ascii_strcasecmp(s, "right")) {
87 o->type = RELATIVE;
88 o->rel.dir = OB_DIRECTION_EAST;
89 }
90 else {
91 o->type = ABSOLUTE;
92 o->abs.desktop = atoi(s) - 1;
93 }
94 g_free(s);
95 }
96
97 if ((n = parse_find_node("wrap", node)))
98 o->rel.wrap = parse_bool(doc, n);
99
100 return o;
101 }
102
103 static gpointer setup_send_func(ObParseInst *i, xmlDocPtr doc,
104 xmlNodePtr node)
105 {
106 xmlNodePtr n;
107 Options *o;
108
109 o = setup_go_func(i, doc, node);
110 o->send = TRUE;
111 o->follow = TRUE;
112
113 if ((n = parse_find_node("follow", node)))
114 o->follow = parse_bool(doc, n);
115
116 return o;
117 }
118
119 /* Always return FALSE because its not interactive */
120 static gboolean run_func(ObActionsData *data, gpointer options)
121 {
122 Options *o = options;
123 guint d;
124
125
126
127 switch (o->type) {
128 case LAST:
129 d = screen_last_desktop;
130 break;
131 case ABSOLUTE:
132 d = o->abs.desktop;
133 break;
134 case RELATIVE:
135 d = screen_find_desktop(screen_desktop,
136 o->rel.dir, o->rel.wrap, o->rel.linear);
137 break;
138 }
139
140 if (d < screen_num_desktops && d != screen_desktop) {
141 gboolean go = TRUE;
142
143 actions_client_move(data, TRUE);
144 if (o->send && data->client && client_normal(data->client)) {
145 client_set_desktop(data->client, d, o->follow, FALSE);
146 go = o->follow;
147 }
148
149 if (go) screen_set_desktop(d, TRUE);
150 actions_client_move(data, FALSE);
151 }
152 return FALSE;
153 }
This page took 0.03686 seconds and 3 git commands to generate.