]> icculus.org git repositories - mikachu/openbox.git/blob - openbox/action.c
comment what funcs is
[mikachu/openbox.git] / openbox / action.c
1 #include "client.h"
2 #include "stacking.h"
3 #include "frame.h"
4 #include "screen.h"
5 #include "action.h"
6
7 #include <glib.h>
8
9 Action *action_new(void (*func)(union ActionData *data))
10 {
11     Action *a = g_new(Action, 1);
12     a->func = func;
13
14     /* deal with pointers */
15     if (func == action_execute)
16         a->data.execute.path = NULL;
17
18     return a;
19 }
20
21 void action_free(Action *a)
22 {
23     /* deal with pointers */
24     if (a->func == action_execute)
25         g_free(a->data.execute.path);
26
27     g_free(a);
28 }
29
30 void action_execute(union ActionData *data)
31 {
32     GError *e;
33     if (!g_spawn_command_line_async(data->execute.path, &e)) {
34         g_warning("failed to execute '%s': %s",
35                   data->execute.path, e->message);
36     }
37 }
38
39 void action_focus(union ActionData *data)
40 {
41     client_focus(data->client.c);
42 }
43
44 void action_unfocus (union ActionData *data)
45 {
46     client_unfocus(data->client.c);
47 }
48
49 void action_iconify(union ActionData *data)
50 {
51     client_iconify(data->client.c, TRUE, TRUE);
52 }
53
54 void action_raise(union ActionData *data)
55 {
56     stacking_raise(data->client.c);
57 }
58
59 void action_lower(union ActionData *data)
60 {
61     stacking_lower(data->client.c);
62 }
63
64 void action_close(union ActionData *data)
65 {
66     client_close(data->client.c);
67 }
68
69 void action_shade(union ActionData *data)
70 {
71     client_shade(data->client.c, TRUE);
72 }
73
74 void action_unshade(union ActionData *data)
75 {
76     client_shade(data->client.c, FALSE);
77 }
78
79 void action_toggle_shade(union ActionData *data)
80 {
81     client_shade(data->client.c, !data->client.c->shaded);
82 }
83
84 void action_toggle_omnipresent(union ActionData *data)
85 {
86     client_set_desktop(data->client.c, data->client.c->desktop == DESKTOP_ALL ?
87                        screen_desktop : DESKTOP_ALL);
88 }
89
90 void action_move_relative(union ActionData *data)
91 {
92     Client *c = data->relative.c;
93     client_configure(c, Corner_TopLeft,
94                      c->area.x + data->relative.dx,
95                      c->area.y + data->relative.dy,
96                      c->area.width, c->area.height, TRUE, TRUE);
97 }
98
99 void action_resize_relative(union ActionData *data)
100 {
101     Client *c = data->relative.c;
102     client_configure(c, Corner_TopLeft, c->area.x, c->area.y,
103                      c->area.width + data->relative.dx,
104                      c->area.height + data->relative.dy, TRUE, TRUE);
105 }
106
107 void action_maximize_full(union ActionData *data)
108 {
109     client_maximize(data->client.c, TRUE, 0, TRUE);
110 }
111
112 void action_unmaximize_full(union ActionData *data)
113 {
114     client_maximize(data->client.c, FALSE, 0, TRUE);
115 }
116
117 void action_toggle_maximize_full(union ActionData *data)
118 {
119     client_maximize(data->client.c,
120                     !(data->client.c->max_horz || data->client.c->max_vert),
121                     0, TRUE);
122 }
123
124 void action_maximize_horz(union ActionData *data)
125 {
126     client_maximize(data->client.c, TRUE, 1, TRUE);
127 }
128
129 void action_unmaximize_horz(union ActionData *data)
130 {
131     client_maximize(data->client.c, FALSE, 1, TRUE);
132 }
133
134 void action_toggle_maximize_horz(union ActionData *data)
135 {
136     client_maximize(data->client.c, !data->client.c->max_horz, 1, TRUE);
137 }
138
139 void action_maximize_vert(union ActionData *data)
140 {
141     client_maximize(data->client.c, TRUE, 2, TRUE);
142 }
143
144 void action_unmaximize_vert(union ActionData *data)
145 {
146     client_maximize(data->client.c, FALSE, 2, TRUE);
147 }
148
149 void action_toggle_maximize_vert(union ActionData *data)
150 {
151     client_maximize(data->client.c, !data->client.c->max_vert, 2, TRUE);
152 }
153
154 void action_send_to_desktop(union ActionData *data)
155 {
156     if (data->sendto.desktop < screen_num_desktops ||
157         data->sendto.desktop == DESKTOP_ALL)
158         client_set_desktop(data->sendto.c, data->sendto.desktop);
159 }
160
161 void action_send_to_next_desktop(union ActionData *data)
162 {
163     guint d;
164
165     d = screen_desktop + 1;
166     if (d >= screen_num_desktops) {
167         if (!data->sendtonextprev.wrap) return;
168         d = 0;
169     }
170     client_set_desktop(data->sendtonextprev.c, d);
171     if (data->sendtonextprev.follow) screen_set_desktop(d);
172 }
173
174 void action_send_to_previous_desktop(union ActionData *data)
175 {
176     guint d;
177
178     d = screen_desktop - 1;
179     if (d >= screen_num_desktops) {
180         if (!data->sendtonextprev.wrap) return;
181         d = screen_num_desktops - 1;
182     }
183     client_set_desktop(data->sendtonextprev.c, d);
184     if (data->sendtonextprev.follow) screen_set_desktop(d);
185 }
186
187 void action_desktop(union ActionData *data)
188 {
189     if (data->desktop.desk < screen_num_desktops ||
190         data->desktop.desk == DESKTOP_ALL)
191         screen_set_desktop(data->desktop.desk);
192 }
193
194 void action_next_desktop(union ActionData *data)
195 {
196     guint d;
197
198     d = screen_desktop + 1;
199     if (d >= screen_num_desktops) {
200         if (!data->nextprevdesktop.wrap) return;
201         d = 0;
202     }
203     screen_set_desktop(d);
204 }
205
206 void action_previous_desktop(union ActionData *data)
207 {
208     guint d;
209
210     d = screen_desktop - 1;
211     if (d >= screen_num_desktops) {
212         if (!data->nextprevdesktop.wrap) return;
213         d = screen_num_desktops - 1;
214     }
215     screen_set_desktop(d);
216 }
217
218 static void cur_row_col(guint *r, guint *c)
219 {
220     switch (screen_desktop_layout.orientation) {
221     case Orientation_Horz:
222         switch (screen_desktop_layout.start_corner) {
223         case Corner_TopLeft:
224             *r = screen_desktop / screen_desktop_layout.columns;
225             *c = screen_desktop % screen_desktop_layout.columns;
226             break;
227         case Corner_BottomLeft:
228             *r = screen_desktop_layout.rows - 1 -
229                 screen_desktop / screen_desktop_layout.columns;
230             *c = screen_desktop % screen_desktop_layout.columns;
231             break;
232         break;
233         case Corner_TopRight:
234             *r = screen_desktop / screen_desktop_layout.columns;
235             *c = screen_desktop_layout.columns - 1 -
236                 screen_desktop % screen_desktop_layout.columns;
237             break;
238         case Corner_BottomRight:
239             *r = screen_desktop_layout.rows - 1 -
240                 screen_desktop / screen_desktop_layout.columns;
241             *c = screen_desktop_layout.columns - 1 -
242                 screen_desktop % screen_desktop_layout.columns;
243             break;
244         break;
245         }
246     case Orientation_Vert:
247         switch (screen_desktop_layout.start_corner) {
248         case Corner_TopLeft:
249             *r = screen_desktop % screen_desktop_layout.rows;
250             *c = screen_desktop / screen_desktop_layout.rows;
251             break;
252         case Corner_BottomLeft:
253             *r = screen_desktop_layout.rows - 1 -
254                 screen_desktop % screen_desktop_layout.rows;
255             *c = screen_desktop / screen_desktop_layout.rows;
256             break;
257         break;
258         case Corner_TopRight:
259             *r = screen_desktop % screen_desktop_layout.rows;
260             *c = screen_desktop_layout.columns - 1 -
261                 screen_desktop / screen_desktop_layout.rows;
262             break;
263         case Corner_BottomRight:
264             *r = screen_desktop_layout.rows - 1 -
265                 screen_desktop % screen_desktop_layout.rows;
266             *c = screen_desktop_layout.columns - 1 -
267                 screen_desktop / screen_desktop_layout.rows;
268             break;
269         break;
270         }
271         break;
272     }
273 }
274
275 static guint translate_row_col(guint r, guint c)
276 {
277     switch (screen_desktop_layout.orientation) {
278     case Orientation_Horz:
279         switch (screen_desktop_layout.start_corner) {
280         case Corner_TopLeft:
281             return r * screen_desktop_layout.columns + c;
282         case Corner_BottomLeft:
283             return (screen_desktop_layout.rows - 1 - r) *
284                 screen_desktop_layout.columns + c;
285         case Corner_TopRight:
286             return r * screen_desktop_layout.columns +
287                 (screen_desktop_layout.columns - 1 - c);
288         case Corner_BottomRight:
289             return (screen_desktop_layout.rows - 1 - r) *
290                 screen_desktop_layout.columns +
291                 (screen_desktop_layout.columns - 1 - c);
292         }
293     case Orientation_Vert:
294         switch (screen_desktop_layout.start_corner) {
295         case Corner_TopLeft:
296             return c * screen_desktop_layout.rows + r;
297         case Corner_BottomLeft:
298             return c * screen_desktop_layout.rows +
299                 (screen_desktop_layout.rows - 1 - r);
300         case Corner_TopRight:
301             return (screen_desktop_layout.columns - 1 - c) *
302                 screen_desktop_layout.rows + r;
303         case Corner_BottomRight:
304             return (screen_desktop_layout.columns - 1 - c) *
305                 screen_desktop_layout.rows +
306                 (screen_desktop_layout.rows - 1 - r);
307         }
308     }
309     g_assert_not_reached();
310     return 0;
311 }
312
313 void action_next_desktop_column(union ActionData *data)
314 {
315     guint r, c, d;
316
317     cur_row_col(&r, &c);
318     ++c;
319     d = translate_row_col(r, c);
320     if (d >= screen_num_desktops) {
321         if (!data->nextprevdesktop.wrap) return;
322         c = 0;
323     }
324     if (d >= screen_num_desktops)
325         ++c;
326     d = translate_row_col(r, c);
327     if (d < screen_num_desktops)
328         screen_set_desktop(d);
329 }
330
331 void action_previous_desktop_column(union ActionData *data)
332 {
333     guint r, c, d;
334
335     cur_row_col(&r, &c);
336     --c;
337     d = translate_row_col(r, c);
338     if (d >= screen_num_desktops) {
339         if (!data->nextprevdesktop.wrap) return;
340         c = screen_desktop_layout.columns - 1;
341     }
342     if (d >= screen_num_desktops)
343         --c;
344     d = translate_row_col(r, c);
345     if (d < screen_num_desktops)
346         screen_set_desktop(d);
347 }
348
349 void action_next_desktop_row(union ActionData *data)
350 {
351     guint r, c, d;
352
353     cur_row_col(&r, &c);
354     ++r;
355     d = translate_row_col(r, c);
356     if (d >= screen_num_desktops) {
357         if (!data->nextprevdesktop.wrap) return;
358         r = 0;
359     }
360     if (d >= screen_num_desktops)
361         ++r;
362     d = translate_row_col(r, c);
363     if (d < screen_num_desktops)
364         screen_set_desktop(d);
365 }
366
367 void action_previous_desktop_row(union ActionData *data)
368 {
369     guint r, c, d;
370
371     cur_row_col(&r, &c);
372     --r;
373     d = translate_row_col(r, c);
374     if (d >= screen_num_desktops) {
375         if (!data->nextprevdesktop.wrap) return;
376         c = screen_desktop_layout.rows - 1;
377     }
378     if (d >= screen_num_desktops)
379         --r;
380     d = translate_row_col(r, c);
381     if (d < screen_num_desktops)
382         screen_set_desktop(d);
383 }
384
385 void action_toggle_decorations(union ActionData *data)
386 {
387     Client *c = data->client.c;
388     c->disabled_decorations = c->disabled_decorations ? 0 : ~0;
389     client_setup_decor_and_functions(c);
390 }
391
392 void action_move(union ActionData *data)
393 {
394     Client *c = data->move.c;
395     int x = data->move.x;
396     int y = data->move.y;
397
398     client_configure(c, Corner_TopLeft, x, y, c->area.width, c->area.height,
399                      TRUE, data->move.final);
400 }
401
402 void action_resize(union ActionData *data)
403 {
404     Client *c = data->resize.c;
405     int w = data->resize.x - c->frame->size.left - c->frame->size.right;
406     int h = data->resize.y - c->frame->size.top - c->frame->size.bottom;
407
408     client_configure(c, data->resize.corner, c->area.x, c->area.y, w, h,
409                      TRUE, data->resize.final);
410 }