10 Action *action_new(void (*func)(union ActionData *data))
12 Action *a = g_new(Action, 1);
15 /* deal with pointers */
16 if (func == action_execute)
17 a->data.execute.path = NULL;
22 void action_free(Action *a)
24 /* deal with pointers */
25 if (a->func == action_execute)
26 g_free(a->data.execute.path);
31 void action_execute(union ActionData *data)
34 if (!g_spawn_command_line_async(data->execute.path, &e)) {
35 g_warning("failed to execute '%s': %s",
36 data->execute.path, e->message);
40 void action_focus(union ActionData *data)
42 client_focus(data->client.c);
45 void action_unfocus (union ActionData *data)
47 client_unfocus(data->client.c);
50 void action_iconify(union ActionData *data)
52 client_iconify(data->client.c, TRUE, TRUE);
55 void action_focusraise(union ActionData *data)
57 client_focus(data->client.c);
58 stacking_raise(data->client.c);
61 void action_raise(union ActionData *data)
63 stacking_raise(data->client.c);
66 void action_lower(union ActionData *data)
68 stacking_lower(data->client.c);
71 void action_close(union ActionData *data)
73 client_close(data->client.c);
76 void action_kill(union ActionData *data)
78 client_kill(data->client.c);
81 void action_shade(union ActionData *data)
83 client_shade(data->client.c, TRUE);
86 void action_unshade(union ActionData *data)
88 client_shade(data->client.c, FALSE);
91 void action_toggle_shade(union ActionData *data)
93 client_shade(data->client.c, !data->client.c->shaded);
96 void action_toggle_omnipresent(union ActionData *data)
98 client_set_desktop(data->client.c, data->client.c->desktop == DESKTOP_ALL ?
99 screen_desktop : DESKTOP_ALL);
102 void action_move_relative(union ActionData *data)
104 Client *c = data->relative.c;
105 client_configure(c, Corner_TopLeft,
106 c->area.x + data->relative.dx,
107 c->area.y + data->relative.dy,
108 c->area.width, c->area.height, TRUE, TRUE);
111 void action_resize_relative(union ActionData *data)
113 Client *c = data->relative.c;
114 client_configure(c, Corner_TopLeft, c->area.x, c->area.y,
115 c->area.width + data->relative.dx,
116 c->area.height + data->relative.dy, TRUE, TRUE);
119 void action_maximize_full(union ActionData *data)
121 client_maximize(data->client.c, TRUE, 0, TRUE);
124 void action_unmaximize_full(union ActionData *data)
126 client_maximize(data->client.c, FALSE, 0, TRUE);
129 void action_toggle_maximize_full(union ActionData *data)
131 client_maximize(data->client.c,
132 !(data->client.c->max_horz || data->client.c->max_vert),
136 void action_maximize_horz(union ActionData *data)
138 client_maximize(data->client.c, TRUE, 1, TRUE);
141 void action_unmaximize_horz(union ActionData *data)
143 client_maximize(data->client.c, FALSE, 1, TRUE);
146 void action_toggle_maximize_horz(union ActionData *data)
148 client_maximize(data->client.c, !data->client.c->max_horz, 1, TRUE);
151 void action_maximize_vert(union ActionData *data)
153 client_maximize(data->client.c, TRUE, 2, TRUE);
156 void action_unmaximize_vert(union ActionData *data)
158 client_maximize(data->client.c, FALSE, 2, TRUE);
161 void action_toggle_maximize_vert(union ActionData *data)
163 client_maximize(data->client.c, !data->client.c->max_vert, 2, TRUE);
166 void action_send_to_desktop(union ActionData *data)
168 if (data->sendto.desktop < screen_num_desktops ||
169 data->sendto.desktop == DESKTOP_ALL)
170 client_set_desktop(data->sendto.c, data->sendto.desktop);
173 void action_send_to_next_desktop(union ActionData *data)
177 d = screen_desktop + 1;
178 if (d >= screen_num_desktops) {
179 if (!data->sendtonextprev.wrap) return;
182 client_set_desktop(data->sendtonextprev.c, d);
183 if (data->sendtonextprev.follow) screen_set_desktop(d);
186 void action_send_to_previous_desktop(union ActionData *data)
190 d = screen_desktop - 1;
191 if (d >= screen_num_desktops) {
192 if (!data->sendtonextprev.wrap) return;
193 d = screen_num_desktops - 1;
195 client_set_desktop(data->sendtonextprev.c, d);
196 if (data->sendtonextprev.follow) screen_set_desktop(d);
199 void action_desktop(union ActionData *data)
201 if (data->desktop.desk < screen_num_desktops ||
202 data->desktop.desk == DESKTOP_ALL)
203 screen_set_desktop(data->desktop.desk);
206 void action_next_desktop(union ActionData *data)
210 d = screen_desktop + 1;
211 if (d >= screen_num_desktops) {
212 if (!data->nextprevdesktop.wrap) return;
215 screen_set_desktop(d);
218 void action_previous_desktop(union ActionData *data)
222 d = screen_desktop - 1;
223 if (d >= screen_num_desktops) {
224 if (!data->nextprevdesktop.wrap) return;
225 d = screen_num_desktops - 1;
227 screen_set_desktop(d);
230 static void cur_row_col(guint *r, guint *c)
232 switch (screen_desktop_layout.orientation) {
233 case Orientation_Horz:
234 switch (screen_desktop_layout.start_corner) {
236 *r = screen_desktop / screen_desktop_layout.columns;
237 *c = screen_desktop % screen_desktop_layout.columns;
239 case Corner_BottomLeft:
240 *r = screen_desktop_layout.rows - 1 -
241 screen_desktop / screen_desktop_layout.columns;
242 *c = screen_desktop % screen_desktop_layout.columns;
245 case Corner_TopRight:
246 *r = screen_desktop / screen_desktop_layout.columns;
247 *c = screen_desktop_layout.columns - 1 -
248 screen_desktop % screen_desktop_layout.columns;
250 case Corner_BottomRight:
251 *r = screen_desktop_layout.rows - 1 -
252 screen_desktop / screen_desktop_layout.columns;
253 *c = screen_desktop_layout.columns - 1 -
254 screen_desktop % screen_desktop_layout.columns;
258 case Orientation_Vert:
259 switch (screen_desktop_layout.start_corner) {
261 *r = screen_desktop % screen_desktop_layout.rows;
262 *c = screen_desktop / screen_desktop_layout.rows;
264 case Corner_BottomLeft:
265 *r = screen_desktop_layout.rows - 1 -
266 screen_desktop % screen_desktop_layout.rows;
267 *c = screen_desktop / screen_desktop_layout.rows;
270 case Corner_TopRight:
271 *r = screen_desktop % screen_desktop_layout.rows;
272 *c = screen_desktop_layout.columns - 1 -
273 screen_desktop / screen_desktop_layout.rows;
275 case Corner_BottomRight:
276 *r = screen_desktop_layout.rows - 1 -
277 screen_desktop % screen_desktop_layout.rows;
278 *c = screen_desktop_layout.columns - 1 -
279 screen_desktop / screen_desktop_layout.rows;
287 static guint translate_row_col(guint r, guint c)
289 switch (screen_desktop_layout.orientation) {
290 case Orientation_Horz:
291 switch (screen_desktop_layout.start_corner) {
293 return r * screen_desktop_layout.columns + c;
294 case Corner_BottomLeft:
295 return (screen_desktop_layout.rows - 1 - r) *
296 screen_desktop_layout.columns + c;
297 case Corner_TopRight:
298 return r * screen_desktop_layout.columns +
299 (screen_desktop_layout.columns - 1 - c);
300 case Corner_BottomRight:
301 return (screen_desktop_layout.rows - 1 - r) *
302 screen_desktop_layout.columns +
303 (screen_desktop_layout.columns - 1 - c);
305 case Orientation_Vert:
306 switch (screen_desktop_layout.start_corner) {
308 return c * screen_desktop_layout.rows + r;
309 case Corner_BottomLeft:
310 return c * screen_desktop_layout.rows +
311 (screen_desktop_layout.rows - 1 - r);
312 case Corner_TopRight:
313 return (screen_desktop_layout.columns - 1 - c) *
314 screen_desktop_layout.rows + r;
315 case Corner_BottomRight:
316 return (screen_desktop_layout.columns - 1 - c) *
317 screen_desktop_layout.rows +
318 (screen_desktop_layout.rows - 1 - r);
321 g_assert_not_reached();
325 void action_next_desktop_column(union ActionData *data)
331 d = translate_row_col(r, c);
332 if (d >= screen_num_desktops) {
333 if (!data->nextprevdesktop.wrap) return;
336 if (d >= screen_num_desktops)
338 d = translate_row_col(r, c);
339 if (d < screen_num_desktops)
340 screen_set_desktop(d);
343 void action_previous_desktop_column(union ActionData *data)
349 d = translate_row_col(r, c);
350 if (d >= screen_num_desktops) {
351 if (!data->nextprevdesktop.wrap) return;
352 c = screen_desktop_layout.columns - 1;
354 if (d >= screen_num_desktops)
356 d = translate_row_col(r, c);
357 if (d < screen_num_desktops)
358 screen_set_desktop(d);
361 void action_next_desktop_row(union ActionData *data)
367 d = translate_row_col(r, c);
368 if (d >= screen_num_desktops) {
369 if (!data->nextprevdesktop.wrap) return;
372 if (d >= screen_num_desktops)
374 d = translate_row_col(r, c);
375 if (d < screen_num_desktops)
376 screen_set_desktop(d);
379 void action_previous_desktop_row(union ActionData *data)
385 d = translate_row_col(r, c);
386 if (d >= screen_num_desktops) {
387 if (!data->nextprevdesktop.wrap) return;
388 c = screen_desktop_layout.rows - 1;
390 if (d >= screen_num_desktops)
392 d = translate_row_col(r, c);
393 if (d < screen_num_desktops)
394 screen_set_desktop(d);
397 void action_toggle_decorations(union ActionData *data)
399 Client *c = data->client.c;
400 c->disabled_decorations = c->disabled_decorations ? 0 : ~0;
401 client_setup_decor_and_functions(c);
404 void action_move(union ActionData *data)
406 Client *c = data->move.c;
407 int x = data->move.x;
408 int y = data->move.y;
410 dispatch_move(c, &x, &y);
412 frame_frame_gravity(c->frame, &x, &y); /* get where the client should be */
413 client_configure(c, Corner_TopLeft, x, y, c->area.width, c->area.height,
414 TRUE, data->move.final);
417 void action_resize(union ActionData *data)
419 Client *c = data->resize.c;
420 int w = data->resize.x - c->frame->size.left - c->frame->size.right;
421 int h = data->resize.y - c->frame->size.top - c->frame->size.bottom;
423 /* XXX window snapping/struts */
425 client_configure(c, data->resize.corner, c->area.x, c->area.y, w, h,
426 TRUE, data->resize.final);