]> Dogcows Code - chaz/openbox/blob - openbox/action.c
cc934206ce58935654a6c77a09868b716070d310
[chaz/openbox] / openbox / action.c
1 #include "client.h"
2 #include "focus.h"
3 #include "stacking.h"
4 #include "frame.h"
5 #include "screen.h"
6 #include "action.h"
7 #include "dispatch.h"
8 #include "openbox.h"
9 #include "engine.h"
10 #include "render/render.h"
11
12 #include <glib.h>
13
14 Action *action_new(void (*func)(union ActionData *data))
15 {
16 Action *a = g_new0(Action, 1);
17 a->func = func;
18
19 /* deal with pointers */
20 if (func == action_execute)
21 a->data.execute.path = NULL;
22
23 return a;
24 }
25
26 void action_free(Action *a)
27 {
28 if (a == NULL) return;
29
30 /* deal with pointers */
31 if (a->func == action_execute || a->func == action_restart)
32 g_free(a->data.execute.path);
33
34 g_free(a);
35 }
36
37 Action *action_from_string(char *name)
38 {
39 Action *a = NULL;
40 if (!g_ascii_strcasecmp(name, "execute")) {
41 a = action_new(action_execute);
42 } else if (!g_ascii_strcasecmp(name, "focus")) {
43 a = action_new(action_focus);
44 } else if (!g_ascii_strcasecmp(name, "unfocus")) {
45 a = action_new(action_unfocus);
46 } else if (!g_ascii_strcasecmp(name, "iconify")) {
47 a = action_new(action_iconify);
48 } else if (!g_ascii_strcasecmp(name, "raise")) {
49 a = action_new(action_raise);
50 } else if (!g_ascii_strcasecmp(name, "lower")) {
51 a = action_new(action_lower);
52 } else if (!g_ascii_strcasecmp(name, "focusraise")) {
53 a = action_new(action_focusraise);
54 } else if (!g_ascii_strcasecmp(name, "close")) {
55 a = action_new(action_close);
56 } else if (!g_ascii_strcasecmp(name, "kill")) {
57 a = action_new(action_kill);
58 } else if (!g_ascii_strcasecmp(name, "shadelower")) {
59 a = action_new(action_shadelower);
60 } else if (!g_ascii_strcasecmp(name, "unshaderaise")) {
61 a = action_new(action_unshaderaise);
62 } else if (!g_ascii_strcasecmp(name, "shade")) {
63 a = action_new(action_shade);
64 } else if (!g_ascii_strcasecmp(name, "unshade")) {
65 a = action_new(action_unshade);
66 } else if (!g_ascii_strcasecmp(name, "toggleshade")) {
67 a = action_new(action_toggle_shade);
68 } else if (!g_ascii_strcasecmp(name, "toggleomnipresent")) {
69 a = action_new(action_toggle_omnipresent);
70 } else if (!g_ascii_strcasecmp(name, "moverelativehorz")) {
71 a = action_new(action_move_relative_horz);
72 } else if (!g_ascii_strcasecmp(name, "moverelativevert")) {
73 a = action_new(action_move_relative_vert);
74 } else if (!g_ascii_strcasecmp(name, "resizerelativehorz")) {
75 a = action_new(action_resize_relative_horz);
76 } else if (!g_ascii_strcasecmp(name, "resizerelativevert")) {
77 a = action_new(action_resize_relative_vert);
78 } else if (!g_ascii_strcasecmp(name, "maximizefull")) {
79 a = action_new(action_maximize_full);
80 } else if (!g_ascii_strcasecmp(name, "unmaximizefull")) {
81 a = action_new(action_unmaximize_full);
82 } else if (!g_ascii_strcasecmp(name, "togglemaximizefull")) {
83 a = action_new(action_toggle_maximize_full);
84 } else if (!g_ascii_strcasecmp(name, "maximizehorz")) {
85 a = action_new(action_maximize_horz);
86 } else if (!g_ascii_strcasecmp(name, "unmaximizehorz")) {
87 a = action_new(action_unmaximize_horz);
88 } else if (!g_ascii_strcasecmp(name, "togglemaximizehorz")) {
89 a = action_new(action_toggle_maximize_horz);
90 } else if (!g_ascii_strcasecmp(name, "maximizevert")) {
91 a = action_new(action_maximize_vert);
92 } else if (!g_ascii_strcasecmp(name, "unmaximizevert")) {
93 a = action_new(action_unmaximize_vert);
94 } else if (!g_ascii_strcasecmp(name, "togglemaximizevert")) {
95 a = action_new(action_toggle_maximize_vert);
96 } else if (!g_ascii_strcasecmp(name, "sendtodesktop")) {
97 a = action_new(action_send_to_desktop);
98 a->data.sendto.follow = TRUE;
99 } else if (!g_ascii_strcasecmp(name, "sendtonextdesktop")) {
100 a = action_new(action_send_to_next_desktop);
101 a->data.sendtonextprev.wrap = FALSE;
102 a->data.sendtonextprev.follow = TRUE;
103 } else if (!g_ascii_strcasecmp(name, "sendtonextdesktopwrap")) {
104 a = action_new(action_send_to_next_desktop);
105 a->data.sendtonextprev.wrap = TRUE;
106 a->data.sendtonextprev.follow = TRUE;
107 } else if (!g_ascii_strcasecmp(name, "sendtopreviousdesktop")) {
108 a = action_new(action_send_to_previous_desktop);
109 a->data.sendtonextprev.wrap = FALSE;
110 a->data.sendtonextprev.follow = TRUE;
111 } else if (!g_ascii_strcasecmp(name, "sendtopreviousdesktopwrap")) {
112 a = action_new(action_send_to_previous_desktop);
113 a->data.sendtonextprev.wrap = TRUE;
114 a->data.sendtonextprev.follow = TRUE;
115 } else if (!g_ascii_strcasecmp(name, "desktop")) {
116 a = action_new(action_desktop);
117 } else if (!g_ascii_strcasecmp(name, "nextdesktop")) {
118 a = action_new(action_next_desktop);
119 a->data.nextprevdesktop.wrap = FALSE;
120 } else if (!g_ascii_strcasecmp(name, "nextdesktopwrap")) {
121 a = action_new(action_next_desktop);
122 a->data.nextprevdesktop.wrap = TRUE;
123 } else if (!g_ascii_strcasecmp(name, "previousdesktop")) {
124 a = action_new(action_previous_desktop);
125 a->data.nextprevdesktop.wrap = FALSE;
126 } else if (!g_ascii_strcasecmp(name, "previousdesktopwrap")) {
127 a = action_new(action_previous_desktop);
128 a->data.nextprevdesktop.wrap = TRUE;
129 } else if (!g_ascii_strcasecmp(name, "nextdesktopcolumn")) {
130 a = action_new(action_next_desktop_column);
131 a->data.nextprevdesktop.wrap = FALSE;
132 } else if (!g_ascii_strcasecmp(name, "nextdesktopcolumnwrap")) {
133 a = action_new(action_next_desktop_column);
134 a->data.nextprevdesktop.wrap = TRUE;
135 } else if (!g_ascii_strcasecmp(name, "previousdesktopcolumn")) {
136 a = action_new(action_previous_desktop_column);
137 a->data.nextprevdesktop.wrap = FALSE;
138 } else if (!g_ascii_strcasecmp(name, "previousdesktopcolumnwrap")) {
139 a = action_new(action_previous_desktop_column);
140 a->data.nextprevdesktop.wrap = TRUE;
141 } else if (!g_ascii_strcasecmp(name, "nextdesktoprow")) {
142 a = action_new(action_next_desktop_row);
143 a->data.nextprevdesktop.wrap = FALSE;
144 } else if (!g_ascii_strcasecmp(name, "nextdesktoprowwrap")) {
145 a = action_new(action_next_desktop_row);
146 a->data.nextprevdesktop.wrap = TRUE;
147 } else if (!g_ascii_strcasecmp(name, "previousdesktoprow")) {
148 a = action_new(action_previous_desktop_row);
149 a->data.nextprevdesktop.wrap = FALSE;
150 } else if (!g_ascii_strcasecmp(name, "previousdesktoprowwrap")) {
151 a = action_new(action_previous_desktop_row);
152 a->data.nextprevdesktop.wrap = TRUE;
153 } else if (!g_ascii_strcasecmp(name, "toggledecorations")) {
154 a = action_new(action_toggle_decorations);
155 } else if (!g_ascii_strcasecmp(name, "move")) {
156 a = action_new(action_move);
157 } else if (!g_ascii_strcasecmp(name, "resize")) {
158 a = action_new(action_resize);
159 } else if (!g_ascii_strcasecmp(name, "restart")) {
160 a = action_new(action_restart);
161 } else if (!g_ascii_strcasecmp(name, "exit")) {
162 a = action_new(action_exit);
163 } else if (!g_ascii_strcasecmp(name, "showmenu")) {
164 a = action_new(action_showmenu);
165 } else if (!g_ascii_strcasecmp(name, "nextwindowlinear")) {
166 a = action_new(action_cycle_windows);
167 a->data.cycle.linear = TRUE;
168 a->data.cycle.forward = TRUE;
169 } else if (!g_ascii_strcasecmp(name, "previouswindowlinear")) {
170 a = action_new(action_cycle_windows);
171 a->data.cycle.linear = TRUE;
172 a->data.cycle.forward = FALSE;
173 } else if (!g_ascii_strcasecmp(name, "nextwindow")) {
174 a = action_new(action_cycle_windows);
175 a->data.cycle.linear = FALSE;
176 a->data.cycle.forward = TRUE;
177 } else if (!g_ascii_strcasecmp(name, "previouswindow")) {
178 a = action_new(action_cycle_windows);
179 a->data.cycle.linear = FALSE;
180 a->data.cycle.forward = FALSE;
181 }
182
183 return a;
184 }
185
186 void action_execute(union ActionData *data)
187 {
188 GError *e = NULL;
189 if (data->execute.path)
190 if (!g_spawn_command_line_async(data->execute.path, &e)) {
191 g_warning("failed to execute '%s': %s",
192 data->execute.path, e->message);
193 }
194 }
195
196 void action_focus(union ActionData *data)
197 {
198 if (data->client.c)
199 client_focus(data->client.c);
200 }
201
202 void action_unfocus (union ActionData *data)
203 {
204 if (data->client.c)
205 client_unfocus(data->client.c);
206 }
207
208 void action_iconify(union ActionData *data)
209 {
210 if (data->client.c)
211 client_iconify(data->client.c, TRUE, TRUE);
212 }
213
214 void action_focusraise(union ActionData *data)
215 {
216 if (data->client.c) {
217 client_focus(data->client.c);
218 stacking_raise(data->client.c);
219 }
220 }
221
222 void action_raise(union ActionData *data)
223 {
224 if (data->client.c)
225 stacking_raise(data->client.c);
226 }
227
228 void action_unshaderaise(union ActionData *data)
229 {
230 if (data->client.c) {
231 if (data->client.c->shaded)
232 client_shade(data->client.c, FALSE);
233 else
234 stacking_raise(data->client.c);
235 }
236 }
237
238 void action_shadelower(union ActionData *data)
239 {
240 if (data->client.c) {
241 if (data->client.c->shaded)
242 stacking_lower(data->client.c);
243 else
244 client_shade(data->client.c, TRUE);
245 }
246 }
247
248 void action_lower(union ActionData *data)
249 {
250 if (data->client.c)
251 stacking_lower(data->client.c);
252 }
253
254 void action_close(union ActionData *data)
255 {
256 if (data->client.c)
257 client_close(data->client.c);
258 }
259
260 void action_kill(union ActionData *data)
261 {
262 if (data->client.c)
263 client_kill(data->client.c);
264 }
265
266 void action_shade(union ActionData *data)
267 {
268 if (data->client.c)
269 client_shade(data->client.c, TRUE);
270 }
271
272 void action_unshade(union ActionData *data)
273 {
274 if (data->client.c)
275 client_shade(data->client.c, FALSE);
276 }
277
278 void action_toggle_shade(union ActionData *data)
279 {
280 if (data->client.c)
281 client_shade(data->client.c, !data->client.c->shaded);
282 }
283
284 void action_toggle_omnipresent(union ActionData *data)
285 {
286 if (data->client.c)
287 client_set_desktop(data->client.c,
288 data->client.c->desktop == DESKTOP_ALL ?
289 screen_desktop : DESKTOP_ALL, FALSE);
290 }
291
292 void action_move_relative_horz(union ActionData *data)
293 {
294 Client *c = data->relative.c;
295 if (c)
296 client_configure(c, Corner_TopLeft,
297 c->area.x + data->relative.delta, c->area.y,
298 c->area.width, c->area.height, TRUE, TRUE);
299 }
300
301 void action_move_relative_vert(union ActionData *data)
302 {
303 Client *c = data->relative.c;
304 if (c)
305 client_configure(c, Corner_TopLeft,
306 c->area.x, c->area.y + data->relative.delta,
307 c->area.width, c->area.height, TRUE, TRUE);
308 }
309
310 void action_resize_relative_horz(union ActionData *data)
311 {
312 Client *c = data->relative.c;
313 if (c)
314 client_configure(c, Corner_TopLeft, c->area.x, c->area.y,
315 c->area.width + data->relative.delta,
316 c->area.height, TRUE, TRUE);
317 }
318
319 void action_resize_relative_vert(union ActionData *data)
320 {
321 Client *c = data->relative.c;
322 if (c && !c->shaded)
323 client_configure(c, Corner_TopLeft, c->area.x, c->area.y,
324 c->area.width, c->area.height + data->relative.delta,
325 TRUE, TRUE);
326 }
327
328 void action_maximize_full(union ActionData *data)
329 {
330 if (data->client.c)
331 client_maximize(data->client.c, TRUE, 0, TRUE);
332 }
333
334 void action_unmaximize_full(union ActionData *data)
335 {
336 if (data->client.c)
337 client_maximize(data->client.c, FALSE, 0, TRUE);
338 }
339
340 void action_toggle_maximize_full(union ActionData *data)
341 {
342 if (data->client.c)
343 client_maximize(data->client.c,
344 !(data->client.c->max_horz ||
345 data->client.c->max_vert),
346 0, TRUE);
347 }
348
349 void action_maximize_horz(union ActionData *data)
350 {
351 if (data->client.c)
352 client_maximize(data->client.c, TRUE, 1, TRUE);
353 }
354
355 void action_unmaximize_horz(union ActionData *data)
356 {
357 if (data->client.c)
358 client_maximize(data->client.c, FALSE, 1, TRUE);
359 }
360
361 void action_toggle_maximize_horz(union ActionData *data)
362 {
363 if (data->client.c)
364 client_maximize(data->client.c, !data->client.c->max_horz, 1, TRUE);
365 }
366
367 void action_maximize_vert(union ActionData *data)
368 {
369 if (data->client.c)
370 client_maximize(data->client.c, TRUE, 2, TRUE);
371 }
372
373 void action_unmaximize_vert(union ActionData *data)
374 {
375 if (data->client.c)
376 client_maximize(data->client.c, FALSE, 2, TRUE);
377 }
378
379 void action_toggle_maximize_vert(union ActionData *data)
380 {
381 if (data->client.c)
382 client_maximize(data->client.c, !data->client.c->max_vert, 2, TRUE);
383 }
384
385 void action_send_to_desktop(union ActionData *data)
386 {
387 if (data->sendto.c) {
388 if (data->sendto.desk < screen_num_desktops ||
389 data->sendto.desk == DESKTOP_ALL) {
390 client_set_desktop(data->desktop.c,
391 data->sendto.desk, data->sendto.follow);
392 if (data->sendto.follow) screen_set_desktop(data->sendto.desk);
393 }
394 }
395 }
396
397 void action_send_to_next_desktop(union ActionData *data)
398 {
399 guint d;
400
401 if (!data->sendtonextprev.c) return;
402
403 d = screen_desktop + 1;
404 if (d >= screen_num_desktops) {
405 if (!data->sendtonextprev.wrap) return;
406 d = 0;
407 }
408 client_set_desktop(data->sendtonextprev.c, d, data->sendtonextprev.follow);
409 if (data->sendtonextprev.follow) screen_set_desktop(d);
410 }
411
412 void action_send_to_previous_desktop(union ActionData *data)
413 {
414 guint d;
415
416 if (!data->sendtonextprev.c) return;
417
418 d = screen_desktop - 1;
419 if (d >= screen_num_desktops) {
420 if (!data->sendtonextprev.wrap) return;
421 d = screen_num_desktops - 1;
422 }
423 client_set_desktop(data->sendtonextprev.c, d, data->sendtonextprev.follow);
424 if (data->sendtonextprev.follow) screen_set_desktop(d);
425 }
426
427 void action_desktop(union ActionData *data)
428 {
429 if (data->desktop.desk < screen_num_desktops ||
430 data->desktop.desk == DESKTOP_ALL)
431 screen_set_desktop(data->desktop.desk);
432 }
433
434 void action_next_desktop(union ActionData *data)
435 {
436 guint d;
437
438 d = screen_desktop + 1;
439 if (d >= screen_num_desktops) {
440 if (!data->nextprevdesktop.wrap) return;
441 d = 0;
442 }
443 screen_set_desktop(d);
444 }
445
446 void action_previous_desktop(union ActionData *data)
447 {
448 guint d;
449
450 d = screen_desktop - 1;
451 if (d >= screen_num_desktops) {
452 if (!data->nextprevdesktop.wrap) return;
453 d = screen_num_desktops - 1;
454 }
455 screen_set_desktop(d);
456 }
457
458 static void cur_row_col(guint *r, guint *c)
459 {
460 switch (screen_desktop_layout.orientation) {
461 case Orientation_Horz:
462 switch (screen_desktop_layout.start_corner) {
463 case Corner_TopLeft:
464 *r = screen_desktop / screen_desktop_layout.columns;
465 *c = screen_desktop % screen_desktop_layout.columns;
466 break;
467 case Corner_BottomLeft:
468 *r = screen_desktop_layout.rows - 1 -
469 screen_desktop / screen_desktop_layout.columns;
470 *c = screen_desktop % screen_desktop_layout.columns;
471 break;
472 case Corner_TopRight:
473 *r = screen_desktop / screen_desktop_layout.columns;
474 *c = screen_desktop_layout.columns - 1 -
475 screen_desktop % screen_desktop_layout.columns;
476 break;
477 case Corner_BottomRight:
478 *r = screen_desktop_layout.rows - 1 -
479 screen_desktop / screen_desktop_layout.columns;
480 *c = screen_desktop_layout.columns - 1 -
481 screen_desktop % screen_desktop_layout.columns;
482 break;
483 }
484 break;
485 case Orientation_Vert:
486 switch (screen_desktop_layout.start_corner) {
487 case Corner_TopLeft:
488 *r = screen_desktop % screen_desktop_layout.rows;
489 *c = screen_desktop / screen_desktop_layout.rows;
490 break;
491 case Corner_BottomLeft:
492 *r = screen_desktop_layout.rows - 1 -
493 screen_desktop % screen_desktop_layout.rows;
494 *c = screen_desktop / screen_desktop_layout.rows;
495 break;
496 case Corner_TopRight:
497 *r = screen_desktop % screen_desktop_layout.rows;
498 *c = screen_desktop_layout.columns - 1 -
499 screen_desktop / screen_desktop_layout.rows;
500 break;
501 case Corner_BottomRight:
502 *r = screen_desktop_layout.rows - 1 -
503 screen_desktop % screen_desktop_layout.rows;
504 *c = screen_desktop_layout.columns - 1 -
505 screen_desktop / screen_desktop_layout.rows;
506 break;
507 }
508 break;
509 }
510 }
511
512 static guint translate_row_col(guint r, guint c)
513 {
514 switch (screen_desktop_layout.orientation) {
515 case Orientation_Horz:
516 switch (screen_desktop_layout.start_corner) {
517 case Corner_TopLeft:
518 return r * screen_desktop_layout.columns + c;
519 case Corner_BottomLeft:
520 return (screen_desktop_layout.rows - 1 - r) *
521 screen_desktop_layout.columns + c;
522 case Corner_TopRight:
523 return r * screen_desktop_layout.columns +
524 (screen_desktop_layout.columns - 1 - c);
525 case Corner_BottomRight:
526 return (screen_desktop_layout.rows - 1 - r) *
527 screen_desktop_layout.columns +
528 (screen_desktop_layout.columns - 1 - c);
529 }
530 case Orientation_Vert:
531 switch (screen_desktop_layout.start_corner) {
532 case Corner_TopLeft:
533 return c * screen_desktop_layout.rows + r;
534 case Corner_BottomLeft:
535 return c * screen_desktop_layout.rows +
536 (screen_desktop_layout.rows - 1 - r);
537 case Corner_TopRight:
538 return (screen_desktop_layout.columns - 1 - c) *
539 screen_desktop_layout.rows + r;
540 case Corner_BottomRight:
541 return (screen_desktop_layout.columns - 1 - c) *
542 screen_desktop_layout.rows +
543 (screen_desktop_layout.rows - 1 - r);
544 }
545 }
546 g_assert_not_reached();
547 return 0;
548 }
549
550 void action_next_desktop_column(union ActionData *data)
551 {
552 guint r, c, d;
553
554 cur_row_col(&r, &c);
555 ++c;
556 d = translate_row_col(r, c);
557 if (d >= screen_num_desktops) {
558 if (!data->nextprevdesktop.wrap) return;
559 c = 0;
560 }
561 if (d >= screen_num_desktops)
562 ++c;
563 d = translate_row_col(r, c);
564 if (d < screen_num_desktops)
565 screen_set_desktop(d);
566 }
567
568 void action_previous_desktop_column(union ActionData *data)
569 {
570 guint r, c, d;
571
572 cur_row_col(&r, &c);
573 --c;
574 d = translate_row_col(r, c);
575 if (d >= screen_num_desktops) {
576 if (!data->nextprevdesktop.wrap) return;
577 c = screen_desktop_layout.columns - 1;
578 }
579 if (d >= screen_num_desktops)
580 --c;
581 d = translate_row_col(r, c);
582 if (d < screen_num_desktops)
583 screen_set_desktop(d);
584 }
585
586 void action_next_desktop_row(union ActionData *data)
587 {
588 guint r, c, d;
589
590 cur_row_col(&r, &c);
591 ++r;
592 d = translate_row_col(r, c);
593 if (d >= screen_num_desktops) {
594 if (!data->nextprevdesktop.wrap) return;
595 r = 0;
596 }
597 if (d >= screen_num_desktops)
598 ++r;
599 d = translate_row_col(r, c);
600 if (d < screen_num_desktops)
601 screen_set_desktop(d);
602 }
603
604 void action_previous_desktop_row(union ActionData *data)
605 {
606 guint r, c, d;
607
608 cur_row_col(&r, &c);
609 --r;
610 d = translate_row_col(r, c);
611 if (d >= screen_num_desktops) {
612 if (!data->nextprevdesktop.wrap) return;
613 c = screen_desktop_layout.rows - 1;
614 }
615 if (d >= screen_num_desktops)
616 --r;
617 d = translate_row_col(r, c);
618 if (d < screen_num_desktops)
619 screen_set_desktop(d);
620 }
621
622 void action_toggle_decorations(union ActionData *data)
623 {
624 Client *c = data->client.c;;
625
626 if (!c) return;
627
628 c->disabled_decorations = c->disabled_decorations ? 0 : ~0;
629 client_setup_decor_and_functions(c);
630 }
631
632 static void popup_coords(char *format, int a, int b, gboolean hide)
633 {
634 XSetWindowAttributes attrib;
635 static Window coords = None;
636
637 if (coords == None) {
638 attrib.override_redirect = TRUE;
639 coords = XCreateWindow(ob_display, ob_root,
640 0, 0, 1, 1, 0, render_depth, InputOutput,
641 render_visual, CWOverrideRedirect, &attrib);
642 g_assert(coords != None);
643 }
644
645 if (hide)
646 XUnmapWindow(ob_display, coords);
647 else {
648 Rect area = { 10, 10, 1, 1 };
649 Size s;
650 char *text;
651
652 text = g_strdup_printf(format, a, b);
653 engine_size_label(text, TRUE, TRUE, &s);
654 area.width = s.width; area.height = s.height;
655 XMoveResizeWindow(ob_display, coords,
656 area.x, area.y, area.width, area.height);
657 engine_render_label(coords, &area, text, TRUE, TRUE);
658 g_free(text);
659
660 XMapWindow(ob_display, coords);
661 }
662 }
663
664 void action_move(union ActionData *data)
665 {
666 Client *c = data->move.c;
667 int x = data->move.x;
668 int y = data->move.y;
669
670 if (!c || !client_normal(c)) return;
671
672 dispatch_move(c, &x, &y);
673
674 popup_coords("X: %d Y: %d", x, y, data->move.final);
675
676 frame_frame_gravity(c->frame, &x, &y); /* get where the client should be */
677 client_configure(c, Corner_TopLeft, x, y, c->area.width, c->area.height,
678 TRUE, data->move.final);
679 }
680
681 void action_resize(union ActionData *data)
682 {
683 Client *c = data->resize.c;
684 int w = data->resize.x;
685 int h = data->resize.y;
686
687 if (!c || c->shaded || !client_normal(c)) return;
688
689 dispatch_resize(c, &w, &h, data->resize.corner);
690
691 w -= c->frame->size.left + c->frame->size.right;
692 h -= c->frame->size.top + c->frame->size.bottom;
693
694 client_configure(c, data->resize.corner, c->area.x, c->area.y, w, h,
695 TRUE, data->resize.final);
696
697 popup_coords("W: %d H: %d", c->logical_size.width,
698 c->logical_size.height, data->move.final);
699 }
700
701 void action_restart(union ActionData *data)
702 {
703 ob_restart_path = data->execute.path;
704 ob_shutdown = ob_restart = TRUE;
705 }
706
707 void action_exit(union ActionData *data)
708 {
709 ob_shutdown = TRUE;
710 }
711
712 void action_showmenu(union ActionData *data)
713 {
714 g_message(__FUNCTION__);
715 }
716
717 void action_cycle_windows(union ActionData *data)
718 {
719 static Client *first = NULL;
720 static Client *t = NULL;
721 static GList *order = NULL;
722 GList *it, *start, *list;
723
724 if (data->cycle.cancel) {
725 if (first) client_focus(first);
726 goto done_cycle;
727 }
728 if (!first) first = focus_client;
729
730 if (data->cycle.linear)
731 list = client_list;
732 else {
733 if (!order) order = g_list_copy(focus_order[screen_desktop]);
734 list = order;
735 }
736 start = it = g_list_find(list, data->cycle.c);
737 if (!start) goto done_cycle;
738
739 if (!data->cycle.final) {
740 t = NULL;
741 if (!start) /* switched desktops or something? */
742 goto done_cycle;
743
744 do {
745 if (data->cycle.forward) {
746 it = it->next;
747 if (it == NULL) it = list;
748 } else {
749 it = it->prev;
750 if (it == NULL) it = g_list_last(list);
751 }
752 if (client_focus(it->data)) {
753 t = it->data;
754 focus_ignore_in++;
755 break;
756 }
757 } while (it != start);
758 } else {
759 if (t) stacking_raise(t);
760 goto done_cycle;
761 }
762 return;
763
764 done_cycle:
765 first = NULL;
766 g_list_free(order);
767 order = NULL;
768 }
769
This page took 0.070709 seconds and 3 git commands to generate.