11 Action *action_new(void (*func)(union ActionData *data))
13 Action *a = g_new(Action, 1);
16 /* deal with pointers */
17 if (func == action_execute)
18 a->data.execute.path = NULL;
23 void action_free(Action *a)
25 /* deal with pointers */
26 if (a->func == action_execute || a->func == action_restart)
27 g_free(a->data.execute.path);
32 void action_execute(union ActionData *data)
35 if (!g_spawn_command_line_async(data->execute.path, &e)) {
36 g_warning("failed to execute '%s': %s",
37 data->execute.path, e->message);
41 void action_focus(union ActionData *data)
44 client_focus(data->client.c);
47 void action_unfocus (union ActionData *data)
50 client_unfocus(data->client.c);
53 void action_iconify(union ActionData *data)
56 client_iconify(data->client.c, TRUE, TRUE);
59 void action_focusraise(union ActionData *data)
62 client_focus(data->client.c);
63 stacking_raise(data->client.c);
67 void action_raise(union ActionData *data)
70 stacking_raise(data->client.c);
73 void action_lower(union ActionData *data)
76 stacking_lower(data->client.c);
79 void action_close(union ActionData *data)
82 client_close(data->client.c);
85 void action_kill(union ActionData *data)
88 client_kill(data->client.c);
91 void action_shade(union ActionData *data)
94 client_shade(data->client.c, TRUE);
97 void action_unshade(union ActionData *data)
100 client_shade(data->client.c, FALSE);
103 void action_toggle_shade(union ActionData *data)
106 client_shade(data->client.c, !data->client.c->shaded);
109 void action_toggle_omnipresent(union ActionData *data)
112 client_set_desktop(data->client.c,
113 data->client.c->desktop == DESKTOP_ALL ?
114 screen_desktop : DESKTOP_ALL);
117 void action_move_relative(union ActionData *data)
119 Client *c = data->relative.c;
121 client_configure(c, Corner_TopLeft,
122 c->area.x + data->relative.dx,
123 c->area.y + data->relative.dy,
124 c->area.width, c->area.height, TRUE, TRUE);
127 void action_resize_relative(union ActionData *data)
129 Client *c = data->relative.c;
131 client_configure(c, Corner_TopLeft, c->area.x, c->area.y,
132 c->area.width + data->relative.dx,
133 c->area.height + data->relative.dy, TRUE, TRUE);
136 void action_maximize_full(union ActionData *data)
139 client_maximize(data->client.c, TRUE, 0, TRUE);
142 void action_unmaximize_full(union ActionData *data)
145 client_maximize(data->client.c, FALSE, 0, TRUE);
148 void action_toggle_maximize_full(union ActionData *data)
151 client_maximize(data->client.c,
152 !(data->client.c->max_horz ||
153 data->client.c->max_vert),
157 void action_maximize_horz(union ActionData *data)
160 client_maximize(data->client.c, TRUE, 1, TRUE);
163 void action_unmaximize_horz(union ActionData *data)
166 client_maximize(data->client.c, FALSE, 1, TRUE);
169 void action_toggle_maximize_horz(union ActionData *data)
172 client_maximize(data->client.c, !data->client.c->max_horz, 1, TRUE);
175 void action_maximize_vert(union ActionData *data)
178 client_maximize(data->client.c, TRUE, 2, TRUE);
181 void action_unmaximize_vert(union ActionData *data)
184 client_maximize(data->client.c, FALSE, 2, TRUE);
187 void action_toggle_maximize_vert(union ActionData *data)
190 client_maximize(data->client.c, !data->client.c->max_vert, 2, TRUE);
193 void action_send_to_desktop(union ActionData *data)
196 if (data->sendto.desktop < screen_num_desktops ||
197 data->sendto.desktop == DESKTOP_ALL)
198 client_set_desktop(data->sendto.c, data->sendto.desktop);
201 void action_send_to_next_desktop(union ActionData *data)
205 if (!data->sendto.c) return;
207 d = screen_desktop + 1;
208 if (d >= screen_num_desktops) {
209 if (!data->sendtonextprev.wrap) return;
212 client_set_desktop(data->sendtonextprev.c, d);
213 if (data->sendtonextprev.follow) screen_set_desktop(d);
216 void action_send_to_previous_desktop(union ActionData *data)
220 if (!data->sendto.c) return;
222 d = screen_desktop - 1;
223 if (d >= screen_num_desktops) {
224 if (!data->sendtonextprev.wrap) return;
225 d = screen_num_desktops - 1;
227 client_set_desktop(data->sendtonextprev.c, d);
228 if (data->sendtonextprev.follow) screen_set_desktop(d);
231 void action_desktop(union ActionData *data)
233 if (data->desktop.desk < screen_num_desktops ||
234 data->desktop.desk == DESKTOP_ALL)
235 screen_set_desktop(data->desktop.desk);
238 void action_next_desktop(union ActionData *data)
242 d = screen_desktop + 1;
243 if (d >= screen_num_desktops) {
244 if (!data->nextprevdesktop.wrap) return;
247 screen_set_desktop(d);
250 void action_previous_desktop(union ActionData *data)
254 d = screen_desktop - 1;
255 if (d >= screen_num_desktops) {
256 if (!data->nextprevdesktop.wrap) return;
257 d = screen_num_desktops - 1;
259 screen_set_desktop(d);
262 static void cur_row_col(guint *r, guint *c)
264 switch (screen_desktop_layout.orientation) {
265 case Orientation_Horz:
266 switch (screen_desktop_layout.start_corner) {
268 *r = screen_desktop / screen_desktop_layout.columns;
269 *c = screen_desktop % screen_desktop_layout.columns;
271 case Corner_BottomLeft:
272 *r = screen_desktop_layout.rows - 1 -
273 screen_desktop / screen_desktop_layout.columns;
274 *c = screen_desktop % screen_desktop_layout.columns;
277 case Corner_TopRight:
278 *r = screen_desktop / screen_desktop_layout.columns;
279 *c = screen_desktop_layout.columns - 1 -
280 screen_desktop % screen_desktop_layout.columns;
282 case Corner_BottomRight:
283 *r = screen_desktop_layout.rows - 1 -
284 screen_desktop / screen_desktop_layout.columns;
285 *c = screen_desktop_layout.columns - 1 -
286 screen_desktop % screen_desktop_layout.columns;
290 case Orientation_Vert:
291 switch (screen_desktop_layout.start_corner) {
293 *r = screen_desktop % screen_desktop_layout.rows;
294 *c = screen_desktop / screen_desktop_layout.rows;
296 case Corner_BottomLeft:
297 *r = screen_desktop_layout.rows - 1 -
298 screen_desktop % screen_desktop_layout.rows;
299 *c = screen_desktop / screen_desktop_layout.rows;
302 case Corner_TopRight:
303 *r = screen_desktop % screen_desktop_layout.rows;
304 *c = screen_desktop_layout.columns - 1 -
305 screen_desktop / screen_desktop_layout.rows;
307 case Corner_BottomRight:
308 *r = screen_desktop_layout.rows - 1 -
309 screen_desktop % screen_desktop_layout.rows;
310 *c = screen_desktop_layout.columns - 1 -
311 screen_desktop / screen_desktop_layout.rows;
319 static guint translate_row_col(guint r, guint c)
321 switch (screen_desktop_layout.orientation) {
322 case Orientation_Horz:
323 switch (screen_desktop_layout.start_corner) {
325 return r * screen_desktop_layout.columns + c;
326 case Corner_BottomLeft:
327 return (screen_desktop_layout.rows - 1 - r) *
328 screen_desktop_layout.columns + c;
329 case Corner_TopRight:
330 return r * screen_desktop_layout.columns +
331 (screen_desktop_layout.columns - 1 - c);
332 case Corner_BottomRight:
333 return (screen_desktop_layout.rows - 1 - r) *
334 screen_desktop_layout.columns +
335 (screen_desktop_layout.columns - 1 - c);
337 case Orientation_Vert:
338 switch (screen_desktop_layout.start_corner) {
340 return c * screen_desktop_layout.rows + r;
341 case Corner_BottomLeft:
342 return c * screen_desktop_layout.rows +
343 (screen_desktop_layout.rows - 1 - r);
344 case Corner_TopRight:
345 return (screen_desktop_layout.columns - 1 - c) *
346 screen_desktop_layout.rows + r;
347 case Corner_BottomRight:
348 return (screen_desktop_layout.columns - 1 - c) *
349 screen_desktop_layout.rows +
350 (screen_desktop_layout.rows - 1 - r);
353 g_assert_not_reached();
357 void action_next_desktop_column(union ActionData *data)
363 d = translate_row_col(r, c);
364 if (d >= screen_num_desktops) {
365 if (!data->nextprevdesktop.wrap) return;
368 if (d >= screen_num_desktops)
370 d = translate_row_col(r, c);
371 if (d < screen_num_desktops)
372 screen_set_desktop(d);
375 void action_previous_desktop_column(union ActionData *data)
381 d = translate_row_col(r, c);
382 if (d >= screen_num_desktops) {
383 if (!data->nextprevdesktop.wrap) return;
384 c = screen_desktop_layout.columns - 1;
386 if (d >= screen_num_desktops)
388 d = translate_row_col(r, c);
389 if (d < screen_num_desktops)
390 screen_set_desktop(d);
393 void action_next_desktop_row(union ActionData *data)
399 d = translate_row_col(r, c);
400 if (d >= screen_num_desktops) {
401 if (!data->nextprevdesktop.wrap) return;
404 if (d >= screen_num_desktops)
406 d = translate_row_col(r, c);
407 if (d < screen_num_desktops)
408 screen_set_desktop(d);
411 void action_previous_desktop_row(union ActionData *data)
417 d = translate_row_col(r, c);
418 if (d >= screen_num_desktops) {
419 if (!data->nextprevdesktop.wrap) return;
420 c = screen_desktop_layout.rows - 1;
422 if (d >= screen_num_desktops)
424 d = translate_row_col(r, c);
425 if (d < screen_num_desktops)
426 screen_set_desktop(d);
429 void action_toggle_decorations(union ActionData *data)
431 Client *c = data->client.c;
432 c->disabled_decorations = c->disabled_decorations ? 0 : ~0;
433 client_setup_decor_and_functions(c);
436 void action_move(union ActionData *data)
438 Client *c = data->move.c;
439 int x = data->move.x;
440 int y = data->move.y;
442 if (!c || !client_normal(c)) return;
444 dispatch_move(c, &x, &y);
446 frame_frame_gravity(c->frame, &x, &y); /* get where the client should be */
447 client_configure(c, Corner_TopLeft, x, y, c->area.width, c->area.height,
448 TRUE, data->move.final);
451 void action_resize(union ActionData *data)
453 Client *c = data->resize.c;
454 int w = data->resize.x - c->frame->size.left - c->frame->size.right;
455 int h = data->resize.y - c->frame->size.top - c->frame->size.bottom;
457 if (!c || !client_normal(c)) return;
459 /* XXX window snapping/struts */
461 client_configure(c, data->resize.corner, c->area.x, c->area.y, w, h,
462 TRUE, data->resize.final);
465 void action_restart(union ActionData *data)
467 ob_restart_path = data->execute.path;
468 ob_shutdown = ob_restart = TRUE;
471 void action_exit(union ActionData *data)