9 Action *action_new(void (*func)(union ActionData *data))
11 Action *a = g_new(Action, 1);
14 /* deal with pointers */
15 if (func == action_execute)
16 a->data.execute.path = NULL;
21 void action_free(Action *a)
23 /* deal with pointers */
24 if (a->func == action_execute)
25 g_free(a->data.execute.path);
30 void action_execute(union ActionData *data)
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);
39 void action_focus(union ActionData *data)
41 client_focus(data->client.c);
44 void action_unfocus (union ActionData *data)
46 client_unfocus(data->client.c);
49 void action_iconify(union ActionData *data)
51 client_iconify(data->client.c, TRUE, TRUE);
54 void action_focusraise(union ActionData *data)
56 client_focus(data->client.c);
57 stacking_raise(data->client.c);
60 void action_raise(union ActionData *data)
62 stacking_raise(data->client.c);
65 void action_lower(union ActionData *data)
67 stacking_lower(data->client.c);
70 void action_close(union ActionData *data)
72 client_close(data->client.c);
75 void action_shade(union ActionData *data)
77 client_shade(data->client.c, TRUE);
80 void action_unshade(union ActionData *data)
82 client_shade(data->client.c, FALSE);
85 void action_toggle_shade(union ActionData *data)
87 client_shade(data->client.c, !data->client.c->shaded);
90 void action_toggle_omnipresent(union ActionData *data)
92 client_set_desktop(data->client.c, data->client.c->desktop == DESKTOP_ALL ?
93 screen_desktop : DESKTOP_ALL);
96 void action_move_relative(union ActionData *data)
98 Client *c = data->relative.c;
99 client_configure(c, Corner_TopLeft,
100 c->area.x + data->relative.dx,
101 c->area.y + data->relative.dy,
102 c->area.width, c->area.height, TRUE, TRUE);
105 void action_resize_relative(union ActionData *data)
107 Client *c = data->relative.c;
108 client_configure(c, Corner_TopLeft, c->area.x, c->area.y,
109 c->area.width + data->relative.dx,
110 c->area.height + data->relative.dy, TRUE, TRUE);
113 void action_maximize_full(union ActionData *data)
115 client_maximize(data->client.c, TRUE, 0, TRUE);
118 void action_unmaximize_full(union ActionData *data)
120 client_maximize(data->client.c, FALSE, 0, TRUE);
123 void action_toggle_maximize_full(union ActionData *data)
125 client_maximize(data->client.c,
126 !(data->client.c->max_horz || data->client.c->max_vert),
130 void action_maximize_horz(union ActionData *data)
132 client_maximize(data->client.c, TRUE, 1, TRUE);
135 void action_unmaximize_horz(union ActionData *data)
137 client_maximize(data->client.c, FALSE, 1, TRUE);
140 void action_toggle_maximize_horz(union ActionData *data)
142 client_maximize(data->client.c, !data->client.c->max_horz, 1, TRUE);
145 void action_maximize_vert(union ActionData *data)
147 client_maximize(data->client.c, TRUE, 2, TRUE);
150 void action_unmaximize_vert(union ActionData *data)
152 client_maximize(data->client.c, FALSE, 2, TRUE);
155 void action_toggle_maximize_vert(union ActionData *data)
157 client_maximize(data->client.c, !data->client.c->max_vert, 2, TRUE);
160 void action_send_to_desktop(union ActionData *data)
162 if (data->sendto.desktop < screen_num_desktops ||
163 data->sendto.desktop == DESKTOP_ALL)
164 client_set_desktop(data->sendto.c, data->sendto.desktop);
167 void action_send_to_next_desktop(union ActionData *data)
171 d = screen_desktop + 1;
172 if (d >= screen_num_desktops) {
173 if (!data->sendtonextprev.wrap) return;
176 client_set_desktop(data->sendtonextprev.c, d);
177 if (data->sendtonextprev.follow) screen_set_desktop(d);
180 void action_send_to_previous_desktop(union ActionData *data)
184 d = screen_desktop - 1;
185 if (d >= screen_num_desktops) {
186 if (!data->sendtonextprev.wrap) return;
187 d = screen_num_desktops - 1;
189 client_set_desktop(data->sendtonextprev.c, d);
190 if (data->sendtonextprev.follow) screen_set_desktop(d);
193 void action_desktop(union ActionData *data)
195 if (data->desktop.desk < screen_num_desktops ||
196 data->desktop.desk == DESKTOP_ALL)
197 screen_set_desktop(data->desktop.desk);
200 void action_next_desktop(union ActionData *data)
204 d = screen_desktop + 1;
205 if (d >= screen_num_desktops) {
206 if (!data->nextprevdesktop.wrap) return;
209 screen_set_desktop(d);
212 void action_previous_desktop(union ActionData *data)
216 d = screen_desktop - 1;
217 if (d >= screen_num_desktops) {
218 if (!data->nextprevdesktop.wrap) return;
219 d = screen_num_desktops - 1;
221 screen_set_desktop(d);
224 static void cur_row_col(guint *r, guint *c)
226 switch (screen_desktop_layout.orientation) {
227 case Orientation_Horz:
228 switch (screen_desktop_layout.start_corner) {
230 *r = screen_desktop / screen_desktop_layout.columns;
231 *c = screen_desktop % screen_desktop_layout.columns;
233 case Corner_BottomLeft:
234 *r = screen_desktop_layout.rows - 1 -
235 screen_desktop / screen_desktop_layout.columns;
236 *c = screen_desktop % screen_desktop_layout.columns;
239 case Corner_TopRight:
240 *r = screen_desktop / screen_desktop_layout.columns;
241 *c = screen_desktop_layout.columns - 1 -
242 screen_desktop % screen_desktop_layout.columns;
244 case Corner_BottomRight:
245 *r = screen_desktop_layout.rows - 1 -
246 screen_desktop / screen_desktop_layout.columns;
247 *c = screen_desktop_layout.columns - 1 -
248 screen_desktop % screen_desktop_layout.columns;
252 case Orientation_Vert:
253 switch (screen_desktop_layout.start_corner) {
255 *r = screen_desktop % screen_desktop_layout.rows;
256 *c = screen_desktop / screen_desktop_layout.rows;
258 case Corner_BottomLeft:
259 *r = screen_desktop_layout.rows - 1 -
260 screen_desktop % screen_desktop_layout.rows;
261 *c = screen_desktop / screen_desktop_layout.rows;
264 case Corner_TopRight:
265 *r = screen_desktop % screen_desktop_layout.rows;
266 *c = screen_desktop_layout.columns - 1 -
267 screen_desktop / screen_desktop_layout.rows;
269 case Corner_BottomRight:
270 *r = screen_desktop_layout.rows - 1 -
271 screen_desktop % screen_desktop_layout.rows;
272 *c = screen_desktop_layout.columns - 1 -
273 screen_desktop / screen_desktop_layout.rows;
281 static guint translate_row_col(guint r, guint c)
283 switch (screen_desktop_layout.orientation) {
284 case Orientation_Horz:
285 switch (screen_desktop_layout.start_corner) {
287 return r * screen_desktop_layout.columns + c;
288 case Corner_BottomLeft:
289 return (screen_desktop_layout.rows - 1 - r) *
290 screen_desktop_layout.columns + c;
291 case Corner_TopRight:
292 return r * screen_desktop_layout.columns +
293 (screen_desktop_layout.columns - 1 - c);
294 case Corner_BottomRight:
295 return (screen_desktop_layout.rows - 1 - r) *
296 screen_desktop_layout.columns +
297 (screen_desktop_layout.columns - 1 - c);
299 case Orientation_Vert:
300 switch (screen_desktop_layout.start_corner) {
302 return c * screen_desktop_layout.rows + r;
303 case Corner_BottomLeft:
304 return c * screen_desktop_layout.rows +
305 (screen_desktop_layout.rows - 1 - r);
306 case Corner_TopRight:
307 return (screen_desktop_layout.columns - 1 - c) *
308 screen_desktop_layout.rows + r;
309 case Corner_BottomRight:
310 return (screen_desktop_layout.columns - 1 - c) *
311 screen_desktop_layout.rows +
312 (screen_desktop_layout.rows - 1 - r);
315 g_assert_not_reached();
319 void action_next_desktop_column(union ActionData *data)
325 d = translate_row_col(r, c);
326 if (d >= screen_num_desktops) {
327 if (!data->nextprevdesktop.wrap) return;
330 if (d >= screen_num_desktops)
332 d = translate_row_col(r, c);
333 if (d < screen_num_desktops)
334 screen_set_desktop(d);
337 void action_previous_desktop_column(union ActionData *data)
343 d = translate_row_col(r, c);
344 if (d >= screen_num_desktops) {
345 if (!data->nextprevdesktop.wrap) return;
346 c = screen_desktop_layout.columns - 1;
348 if (d >= screen_num_desktops)
350 d = translate_row_col(r, c);
351 if (d < screen_num_desktops)
352 screen_set_desktop(d);
355 void action_next_desktop_row(union ActionData *data)
361 d = translate_row_col(r, c);
362 if (d >= screen_num_desktops) {
363 if (!data->nextprevdesktop.wrap) return;
366 if (d >= screen_num_desktops)
368 d = translate_row_col(r, c);
369 if (d < screen_num_desktops)
370 screen_set_desktop(d);
373 void action_previous_desktop_row(union ActionData *data)
379 d = translate_row_col(r, c);
380 if (d >= screen_num_desktops) {
381 if (!data->nextprevdesktop.wrap) return;
382 c = screen_desktop_layout.rows - 1;
384 if (d >= screen_num_desktops)
386 d = translate_row_col(r, c);
387 if (d < screen_num_desktops)
388 screen_set_desktop(d);
391 void action_toggle_decorations(union ActionData *data)
393 Client *c = data->client.c;
394 c->disabled_decorations = c->disabled_decorations ? 0 : ~0;
395 client_setup_decor_and_functions(c);
398 void action_move(union ActionData *data)
400 Client *c = data->move.c;
401 int x = data->move.x;
402 int y = data->move.y;
404 /* XXX window snapping/struts */
406 client_configure(c, Corner_TopLeft, x, y, c->area.width, c->area.height,
407 TRUE, data->move.final);
410 void action_resize(union ActionData *data)
412 Client *c = data->resize.c;
413 int w = data->resize.x - c->frame->size.left - c->frame->size.right;
414 int h = data->resize.y - c->frame->size.top - c->frame->size.bottom;
416 /* XXX window snapping/struts */
418 client_configure(c, data->resize.corner, c->area.x, c->area.y, w, h,
419 TRUE, data->resize.final);