]> Dogcows Code - chaz/openbox/blob - openbox/action.c
add a menuOverlap property to themes, and use it in the submenu placement
[chaz/openbox] / openbox / action.c
1 #include "client.h"
2 #include "focus.h"
3 #include "moveresize.h"
4 #include "menu.h"
5 #include "prop.h"
6 #include "stacking.h"
7 #include "frame.h"
8 #include "screen.h"
9 #include "action.h"
10 #include "dispatch.h"
11 #include "openbox.h"
12
13 #include <glib.h>
14
15 typedef struct ActionString {
16 char *name;
17 void (*func)(union ActionData *);
18 void (*setup)(Action *);
19 } ActionString;
20
21 Action *action_new(void (*func)(union ActionData *data))
22 {
23 Action *a = g_new0(Action, 1);
24 a->func = func;
25
26 return a;
27 }
28
29 void action_free(Action *a)
30 {
31 if (a == NULL) return;
32
33 /* deal with pointers */
34 if (a->func == action_execute || a->func == action_restart)
35 g_free(a->data.execute.path);
36 else if (a->func == action_showmenu)
37 g_free(a->data.showmenu.name);
38
39 g_free(a);
40 }
41
42 void setup_action_directional_focus_north(Action *a)
43 {
44 a->data.diraction.direction = OB_DIRECTION_NORTH;
45 }
46
47 void setup_action_directional_focus_east(Action *a)
48 {
49 a->data.diraction.direction = OB_DIRECTION_EAST;
50 }
51
52 void setup_action_directional_focus_south(Action *a)
53 {
54 a->data.diraction.direction = OB_DIRECTION_SOUTH;
55 }
56
57 void setup_action_directional_focus_west(Action *a)
58 {
59 a->data.diraction.direction = OB_DIRECTION_WEST;
60 }
61
62 void setup_action_directional_focus_northeast(Action *a)
63 {
64 a->data.diraction.direction = OB_DIRECTION_NORTHEAST;
65 }
66
67 void setup_action_directional_focus_southeast(Action *a)
68 {
69 a->data.diraction.direction = OB_DIRECTION_SOUTHEAST;
70 }
71
72 void setup_action_directional_focus_southwest(Action *a)
73 {
74 a->data.diraction.direction = OB_DIRECTION_SOUTHWEST;
75 }
76
77 void setup_action_directional_focus_northwest(Action *a)
78 {
79 a->data.diraction.direction = OB_DIRECTION_NORTHWEST;
80 }
81
82 void setup_action_send_to_desktop(Action *a)
83 {
84 a->data.sendto.follow = TRUE;
85 }
86
87 void setup_action_send_to_desktop_direction(Action *a)
88 {
89 a->data.sendtodir.wrap = TRUE;
90 a->data.sendtodir.follow = TRUE;
91 }
92
93 void setup_action_desktop_direction(Action *a)
94 {
95 a->data.desktopdir.wrap = TRUE;
96 }
97
98 void setup_action_move_keyboard(Action *a)
99 {
100 a->data.moveresize.corner = prop_atoms.net_wm_moveresize_move_keyboard;
101 }
102
103 void setup_action_move(Action *a)
104 {
105 a->data.moveresize.corner = prop_atoms.net_wm_moveresize_move;
106 }
107
108 void setup_action_resize(Action *a)
109 {
110 a->data.moveresize.corner = prop_atoms.net_wm_moveresize_size_topleft;
111 }
112
113 void setup_action_resize_keyboard(Action *a)
114 {
115 a->data.moveresize.corner = prop_atoms.net_wm_moveresize_size_keyboard;
116 }
117
118 void setup_action_cycle_windows_linear_next(Action *a)
119 {
120 a->data.cycle.linear = TRUE;
121 a->data.cycle.forward = TRUE;
122 }
123
124 void setup_action_cycle_windows_linear_previous(Action *a)
125 {
126 a->data.cycle.linear = TRUE;
127 a->data.cycle.forward = FALSE;
128 }
129
130 void setup_action_cycle_windows_next(Action *a)
131 {
132 a->data.cycle.linear = FALSE;
133 a->data.cycle.forward = TRUE;
134 }
135
136 void setup_action_cycle_windows_previous(Action *a)
137 {
138 a->data.cycle.linear = FALSE;
139 a->data.cycle.forward = FALSE;
140 }
141
142 void setup_action_movetoedge_north(Action *a)
143 {
144 a->data.diraction.direction = OB_DIRECTION_NORTH;
145 }
146
147 void setup_action_movetoedge_south(Action *a)
148 {
149 a->data.diraction.direction = OB_DIRECTION_SOUTH;
150 }
151
152 void setup_action_movetoedge_east(Action *a)
153 {
154 a->data.diraction.direction = OB_DIRECTION_EAST;
155 }
156
157 void setup_action_movetoedge_west(Action *a)
158 {
159 a->data.diraction.direction = OB_DIRECTION_WEST;
160 }
161
162 void setup_action_top_layer(Action *a)
163 {
164 a->data.layer.layer = 1;
165 }
166
167 void setup_action_normal_layer(Action *a)
168 {
169 a->data.layer.layer = 0;
170 }
171
172 void setup_action_bottom_layer(Action *a)
173 {
174 a->data.layer.layer = -1;
175 }
176
177 ActionString actionstrings[] =
178 {
179 {
180 "execute",
181 action_execute,
182 NULL
183 },
184 {
185 "directionalfocusnorth",
186 action_directional_focus,
187 setup_action_directional_focus_north
188 },
189 {
190 "directionalfocuseast",
191 action_directional_focus,
192 setup_action_directional_focus_east
193 },
194 {
195 "directionalfocussouth",
196 action_directional_focus,
197 setup_action_directional_focus_south
198 },
199 {
200 "directionalfocuswest",
201 action_directional_focus,
202 setup_action_directional_focus_west
203 },
204 {
205 "directionalfocusnortheast",
206 action_directional_focus,
207 setup_action_directional_focus_northeast
208 },
209 {
210 "directionalfocussoutheast",
211 action_directional_focus,
212 setup_action_directional_focus_southeast
213 },
214 {
215 "directionalfocussouthwest",
216 action_directional_focus,
217 setup_action_directional_focus_southwest
218 },
219 {
220 "directionalfocusnorthwest",
221 action_directional_focus,
222 setup_action_directional_focus_northwest
223 },
224 {
225 "focus",
226 action_focus,
227 NULL,
228 },
229 {
230 "unfocus",
231 action_unfocus,
232 NULL
233 },
234 {
235 "iconify",
236 action_iconify,
237 NULL
238 },
239 {
240 "raise",
241 action_raise,
242 NULL
243 },
244 {
245 "lower",
246 action_lower,
247 NULL
248 },
249 {
250 "close",
251 action_close,
252 NULL
253 },
254 {
255 "kill",
256 action_kill,
257 NULL
258 },
259 {
260 "shadelower",
261 action_shadelower,
262 NULL
263 },
264 {
265 "unshaderaise",
266 action_unshaderaise,
267 NULL
268 },
269 {
270 "shade",
271 action_shade,
272 NULL
273 },
274 {
275 "unshade",
276 action_unshade,
277 NULL
278 },
279 {
280 "toggleshade",
281 action_toggle_shade,
282 NULL
283 },
284 {
285 "toggleomnipresent",
286 action_toggle_omnipresent,
287 NULL
288 },
289 {
290 "moverelativehorz",
291 action_move_relative_horz,
292 NULL
293 },
294 {
295 "moverelativevert",
296 action_move_relative_vert,
297 NULL
298 },
299 {
300 "resizerelativehorz",
301 action_resize_relative_horz,
302 NULL
303 },
304 {
305 "resizerelativevert",
306 action_resize_relative_vert,
307 NULL
308 },
309 {
310 "maximizefull",
311 action_maximize_full,
312 NULL
313 },
314 {
315 "unmaximizefull",
316 action_unmaximize_full,
317 NULL
318 },
319 {
320 "togglemaximizefull",
321 action_toggle_maximize_full,
322 NULL
323 },
324 {
325 "maximizehorz",
326 action_maximize_horz,
327 NULL
328 },
329 {
330 "unmaximizehorz",
331 action_unmaximize_horz,
332 NULL
333 },
334 {
335 "togglemaximizehorz",
336 action_toggle_maximize_horz,
337 NULL
338 },
339 {
340 "maximizevert",
341 action_maximize_vert,
342 NULL
343 },
344 {
345 "unmaximizevert",
346 action_unmaximize_vert,
347 NULL
348 },
349 {
350 "togglemaximizevert",
351 action_toggle_maximize_vert,
352 NULL
353 },
354 {
355 "sendtodesktop",
356 action_send_to_desktop,
357 setup_action_send_to_desktop
358 },
359 {
360 "sendtodesktopright",
361 action_send_to_desktop_right,
362 setup_action_send_to_desktop_direction
363 },
364 {
365 "sendtodesktopleft",
366 action_send_to_desktop_left,
367 setup_action_send_to_desktop_direction
368 },
369 {
370 "sendtodesktopup",
371 action_send_to_desktop_up,
372 setup_action_send_to_desktop_direction
373 },
374 {
375 "sendtodesktopdown",
376 action_send_to_desktop_down,
377 setup_action_send_to_desktop_direction
378 },
379 {
380 "desktop",
381 action_desktop,
382 NULL
383 },
384 {
385 "desktopright",
386 action_desktop_right,
387 setup_action_desktop_direction
388 },
389 {
390 "desktopleft",
391 action_desktop_left,
392 setup_action_desktop_direction
393 },
394 {
395 "desktopup",
396 action_desktop_up,
397 setup_action_desktop_direction
398 },
399 {
400 "desktopdown",
401 action_desktop_down,
402 setup_action_desktop_direction
403 },
404 {
405 "toggledecorations",
406 action_toggle_decorations,
407 NULL
408 },
409 {
410 "keyboardmove",
411 action_moveresize,
412 setup_action_move_keyboard
413 },
414 {
415 "move",
416 action_moveresize,
417 setup_action_move
418 },
419 {
420 "resize",
421 action_moveresize,
422 setup_action_resize
423 },
424 {
425 "keyboardresize",
426 action_moveresize,
427 setup_action_resize_keyboard
428 },
429 {
430 "toggleshowdesktop",
431 action_toggle_show_desktop,
432 NULL
433 },
434 {
435 "showdesktop",
436 action_show_desktop,
437 NULL
438 },
439 {
440 "unshowdesktop",
441 action_unshow_desktop,
442 NULL
443 },
444 {
445 "restart",
446 action_restart,
447 NULL
448 },
449 {
450 "exit",
451 action_exit,
452 NULL
453 },
454 {
455 "showmenu",
456 action_showmenu,
457 NULL
458 },
459 {
460 "sendtotoplayer",
461 action_send_to_layer,
462 setup_action_top_layer
463 },
464 {
465 "togglealwaysontop",
466 action_toggle_layer,
467 setup_action_top_layer
468 },
469 {
470 "sendtonormallayer",
471 action_send_to_layer,
472 setup_action_normal_layer
473 },
474 {
475 "sendtobottomlayer",
476 action_send_to_layer,
477 setup_action_bottom_layer
478 },
479 {
480 "togglealwaysonbottom",
481 action_toggle_layer,
482 setup_action_bottom_layer
483 },
484 {
485 "nextwindowlinear",
486 action_cycle_windows,
487 setup_action_cycle_windows_linear_next
488 },
489 {
490 "previouswindowlinear",
491 action_cycle_windows,
492 setup_action_cycle_windows_linear_previous
493 },
494 {
495 "nextwindow",
496 action_cycle_windows,
497 setup_action_cycle_windows_next
498 },
499 {
500 "previouswindow",
501 action_cycle_windows,
502 setup_action_cycle_windows_previous
503 },
504 {
505 "movetoedgenorth",
506 action_movetoedge,
507 setup_action_movetoedge_north
508 },
509 {
510 "movetoedgesouth",
511 action_movetoedge,
512 setup_action_movetoedge_south
513 },
514 {
515 "movetoedgewest",
516 action_movetoedge,
517 setup_action_movetoedge_west
518 },
519 {
520 "movetoedgeeast",
521 action_movetoedge,
522 setup_action_movetoedge_east
523 },
524 {
525 NULL,
526 NULL,
527 NULL
528 }
529 };
530
531 Action *action_from_string(char *name)
532 {
533 Action *a = NULL;
534 int i;
535
536 for (i = 0; actionstrings[i].name; i++)
537 if (!g_ascii_strcasecmp(name, actionstrings[i].name)) {
538 a = action_new(actionstrings[i].func);
539 if (actionstrings[i].setup)
540 actionstrings[i].setup(a);
541 break;
542 }
543 return a;
544 }
545
546 Action *action_parse(xmlDocPtr doc, xmlNodePtr node)
547 {
548 char *actname;
549 Action *act = NULL;
550 xmlNodePtr n;
551
552 if (parse_attr_string("name", node, &actname)) {
553 if ((act = action_from_string(actname))) {
554 if (act->func == action_execute || act->func == action_restart) {
555 if ((n = parse_find_node("execute", node->xmlChildrenNode)))
556 act->data.execute.path = parse_string(doc, n);
557 } else if (act->func == action_showmenu) {
558 if ((n = parse_find_node("menu", node->xmlChildrenNode)))
559 act->data.showmenu.name = parse_string(doc, n);
560 } else if (act->func == action_desktop) {
561 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
562 act->data.desktop.desk = parse_int(doc, n);
563 if (act->data.desktop.desk > 0) act->data.desktop.desk--;
564 } else if (act->func == action_send_to_desktop) {
565 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
566 act->data.sendto.desk = parse_int(doc, n);
567 if (act->data.sendto.desk > 0) act->data.sendto.desk--;
568 } else if (act->func == action_move_relative_horz ||
569 act->func == action_move_relative_vert ||
570 act->func == action_resize_relative_horz ||
571 act->func == action_resize_relative_vert) {
572 if ((n = parse_find_node("delta", node->xmlChildrenNode)))
573 act->data.relative.delta = parse_int(doc, n);
574 } else if (act->func == action_desktop_right ||
575 act->func == action_desktop_left ||
576 act->func == action_desktop_up ||
577 act->func == action_desktop_down) {
578 if ((n = parse_find_node("wrap", node->xmlChildrenNode))) {
579 g_message("WRAP %d", parse_bool(doc, n));
580 act->data.desktopdir.wrap = parse_bool(doc, n);
581 }
582 } else if (act->func == action_send_to_desktop_right ||
583 act->func == action_send_to_desktop_left ||
584 act->func == action_send_to_desktop_up ||
585 act->func == action_send_to_desktop_down) {
586 if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
587 act->data.sendtodir.wrap = parse_bool(doc, n);
588 if ((n = parse_find_node("follow", node->xmlChildrenNode)))
589 act->data.sendtodir.follow = parse_bool(doc, n);
590 }
591 }
592 g_free(actname);
593 }
594 return act;
595 }
596
597 void action_execute(union ActionData *data)
598 {
599 GError *e = NULL;
600 char *cmd;
601 if (data->execute.path) {
602 cmd = g_filename_from_utf8(data->execute.path, -1, NULL, NULL, NULL);
603 if (cmd) {
604 if (!g_spawn_command_line_async(cmd, &e)) {
605 g_warning("failed to execute '%s': %s",
606 cmd, e->message);
607 }
608 } else {
609 g_warning("failed to convert '%s' from utf8", data->execute.path);
610 }
611 }
612 }
613
614 void action_focus(union ActionData *data)
615 {
616 if (data->client.c)
617 client_focus(data->client.c);
618 }
619
620 void action_unfocus (union ActionData *data)
621 {
622 if (data->client.c)
623 client_unfocus(data->client.c);
624 }
625
626 void action_iconify(union ActionData *data)
627 {
628 if (data->client.c)
629 client_iconify(data->client.c, TRUE, TRUE);
630 }
631
632 void action_raise(union ActionData *data)
633 {
634 if (data->client.c)
635 stacking_raise(CLIENT_AS_WINDOW(data->client.c));
636 }
637
638 void action_unshaderaise(union ActionData *data)
639 {
640 if (data->client.c) {
641 if (data->client.c->shaded)
642 client_shade(data->client.c, FALSE);
643 else
644 stacking_raise(CLIENT_AS_WINDOW(data->client.c));
645 }
646 }
647
648 void action_shadelower(union ActionData *data)
649 {
650 if (data->client.c) {
651 if (data->client.c->shaded)
652 stacking_lower(CLIENT_AS_WINDOW(data->client.c));
653 else
654 client_shade(data->client.c, TRUE);
655 }
656 }
657
658 void action_lower(union ActionData *data)
659 {
660 if (data->client.c)
661 stacking_lower(CLIENT_AS_WINDOW(data->client.c));
662 }
663
664 void action_close(union ActionData *data)
665 {
666 if (data->client.c)
667 client_close(data->client.c);
668 }
669
670 void action_kill(union ActionData *data)
671 {
672 if (data->client.c)
673 client_kill(data->client.c);
674 }
675
676 void action_shade(union ActionData *data)
677 {
678 if (data->client.c)
679 client_shade(data->client.c, TRUE);
680 }
681
682 void action_unshade(union ActionData *data)
683 {
684 if (data->client.c)
685 client_shade(data->client.c, FALSE);
686 }
687
688 void action_toggle_shade(union ActionData *data)
689 {
690 if (data->client.c)
691 client_shade(data->client.c, !data->client.c->shaded);
692 }
693
694 void action_toggle_omnipresent(union ActionData *data)
695 {
696 if (data->client.c)
697 client_set_desktop(data->client.c,
698 data->client.c->desktop == DESKTOP_ALL ?
699 screen_desktop : DESKTOP_ALL, FALSE);
700 }
701
702 void action_move_relative_horz(union ActionData *data)
703 {
704 ObClient *c = data->relative.c;
705 if (c)
706 client_configure(c, OB_CORNER_TOPLEFT,
707 c->area.x + data->relative.delta, c->area.y,
708 c->area.width, c->area.height, TRUE, TRUE);
709 }
710
711 void action_move_relative_vert(union ActionData *data)
712 {
713 ObClient *c = data->relative.c;
714 if (c)
715 client_configure(c, OB_CORNER_TOPLEFT,
716 c->area.x, c->area.y + data->relative.delta,
717 c->area.width, c->area.height, TRUE, TRUE);
718 }
719
720 void action_resize_relative_horz(union ActionData *data)
721 {
722 ObClient *c = data->relative.c;
723 if (c)
724 client_configure(c, OB_CORNER_TOPLEFT, c->area.x, c->area.y,
725 c->area.width +
726 data->relative.delta * c->size_inc.width,
727 c->area.height, TRUE, TRUE);
728 }
729
730 void action_resize_relative_vert(union ActionData *data)
731 {
732 ObClient *c = data->relative.c;
733 if (c && !c->shaded)
734 client_configure(c, OB_CORNER_TOPLEFT, c->area.x, c->area.y,
735 c->area.width, c->area.height +
736 data->relative.delta * c->size_inc.height,
737 TRUE, TRUE);
738 }
739
740 void action_maximize_full(union ActionData *data)
741 {
742 if (data->client.c)
743 client_maximize(data->client.c, TRUE, 0, TRUE);
744 }
745
746 void action_unmaximize_full(union ActionData *data)
747 {
748 if (data->client.c)
749 client_maximize(data->client.c, FALSE, 0, TRUE);
750 }
751
752 void action_toggle_maximize_full(union ActionData *data)
753 {
754 if (data->client.c)
755 client_maximize(data->client.c,
756 !(data->client.c->max_horz ||
757 data->client.c->max_vert),
758 0, TRUE);
759 }
760
761 void action_maximize_horz(union ActionData *data)
762 {
763 if (data->client.c)
764 client_maximize(data->client.c, TRUE, 1, TRUE);
765 }
766
767 void action_unmaximize_horz(union ActionData *data)
768 {
769 if (data->client.c)
770 client_maximize(data->client.c, FALSE, 1, TRUE);
771 }
772
773 void action_toggle_maximize_horz(union ActionData *data)
774 {
775 if (data->client.c)
776 client_maximize(data->client.c, !data->client.c->max_horz, 1, TRUE);
777 }
778
779 void action_maximize_vert(union ActionData *data)
780 {
781 if (data->client.c)
782 client_maximize(data->client.c, TRUE, 2, TRUE);
783 }
784
785 void action_unmaximize_vert(union ActionData *data)
786 {
787 if (data->client.c)
788 client_maximize(data->client.c, FALSE, 2, TRUE);
789 }
790
791 void action_toggle_maximize_vert(union ActionData *data)
792 {
793 if (data->client.c)
794 client_maximize(data->client.c, !data->client.c->max_vert, 2, TRUE);
795 }
796
797 void action_send_to_desktop(union ActionData *data)
798 {
799 ObClient *c = data->sendto.c;
800
801 if (!c || !client_normal(c)) return;
802
803 if (data->sendto.desk < screen_num_desktops ||
804 data->sendto.desk == DESKTOP_ALL) {
805 client_set_desktop(c, data->sendto.desk, data->sendto.follow);
806 if (data->sendto.follow) screen_set_desktop(data->sendto.desk);
807 }
808 }
809
810 void action_desktop(union ActionData *data)
811 {
812 if (data->desktop.desk < screen_num_desktops ||
813 data->desktop.desk == DESKTOP_ALL)
814 screen_set_desktop(data->desktop.desk);
815 }
816
817 static void cur_row_col(guint *r, guint *c)
818 {
819 switch (screen_desktop_layout.orientation) {
820 case OB_ORIENTATION_HORZ:
821 switch (screen_desktop_layout.start_corner) {
822 case OB_CORNER_TOPLEFT:
823 *r = screen_desktop / screen_desktop_layout.columns;
824 *c = screen_desktop % screen_desktop_layout.columns;
825 break;
826 case OB_CORNER_BOTTOMLEFT:
827 *r = screen_desktop_layout.rows - 1 -
828 screen_desktop / screen_desktop_layout.columns;
829 *c = screen_desktop % screen_desktop_layout.columns;
830 break;
831 case OB_CORNER_TOPRIGHT:
832 *r = screen_desktop / screen_desktop_layout.columns;
833 *c = screen_desktop_layout.columns - 1 -
834 screen_desktop % screen_desktop_layout.columns;
835 break;
836 case OB_CORNER_BOTTOMRIGHT:
837 *r = screen_desktop_layout.rows - 1 -
838 screen_desktop / screen_desktop_layout.columns;
839 *c = screen_desktop_layout.columns - 1 -
840 screen_desktop % screen_desktop_layout.columns;
841 break;
842 }
843 break;
844 case OB_ORIENTATION_VERT:
845 switch (screen_desktop_layout.start_corner) {
846 case OB_CORNER_TOPLEFT:
847 *r = screen_desktop % screen_desktop_layout.rows;
848 *c = screen_desktop / screen_desktop_layout.rows;
849 break;
850 case OB_CORNER_BOTTOMLEFT:
851 *r = screen_desktop_layout.rows - 1 -
852 screen_desktop % screen_desktop_layout.rows;
853 *c = screen_desktop / screen_desktop_layout.rows;
854 break;
855 case OB_CORNER_TOPRIGHT:
856 *r = screen_desktop % screen_desktop_layout.rows;
857 *c = screen_desktop_layout.columns - 1 -
858 screen_desktop / screen_desktop_layout.rows;
859 break;
860 case OB_CORNER_BOTTOMRIGHT:
861 *r = screen_desktop_layout.rows - 1 -
862 screen_desktop % screen_desktop_layout.rows;
863 *c = screen_desktop_layout.columns - 1 -
864 screen_desktop / screen_desktop_layout.rows;
865 break;
866 }
867 break;
868 }
869 }
870
871 static guint translate_row_col(guint r, guint c)
872 {
873 switch (screen_desktop_layout.orientation) {
874 case OB_ORIENTATION_HORZ:
875 switch (screen_desktop_layout.start_corner) {
876 case OB_CORNER_TOPLEFT:
877 return r % screen_desktop_layout.rows *
878 screen_desktop_layout.columns +
879 c % screen_desktop_layout.columns;
880 case OB_CORNER_BOTTOMLEFT:
881 return (screen_desktop_layout.rows - 1 -
882 r % screen_desktop_layout.rows) *
883 screen_desktop_layout.columns +
884 c % screen_desktop_layout.columns;
885 case OB_CORNER_TOPRIGHT:
886 return r % screen_desktop_layout.rows *
887 screen_desktop_layout.columns +
888 (screen_desktop_layout.columns - 1 -
889 c % screen_desktop_layout.columns);
890 case OB_CORNER_BOTTOMRIGHT:
891 return (screen_desktop_layout.rows - 1 -
892 r % screen_desktop_layout.rows) *
893 screen_desktop_layout.columns +
894 (screen_desktop_layout.columns - 1 -
895 c % screen_desktop_layout.columns);
896 }
897 case OB_ORIENTATION_VERT:
898 switch (screen_desktop_layout.start_corner) {
899 case OB_CORNER_TOPLEFT:
900 return c % screen_desktop_layout.columns *
901 screen_desktop_layout.rows +
902 r % screen_desktop_layout.rows;
903 case OB_CORNER_BOTTOMLEFT:
904 return c % screen_desktop_layout.columns *
905 screen_desktop_layout.rows +
906 (screen_desktop_layout.rows - 1 -
907 r % screen_desktop_layout.rows);
908 case OB_CORNER_TOPRIGHT:
909 return (screen_desktop_layout.columns - 1 -
910 c % screen_desktop_layout.columns) *
911 screen_desktop_layout.rows +
912 r % screen_desktop_layout.rows;
913 case OB_CORNER_BOTTOMRIGHT:
914 return (screen_desktop_layout.columns - 1 -
915 c % screen_desktop_layout.columns) *
916 screen_desktop_layout.rows +
917 (screen_desktop_layout.rows - 1 -
918 r % screen_desktop_layout.rows);
919 }
920 }
921 g_assert_not_reached();
922 return 0;
923 }
924
925 void action_desktop_right(union ActionData *data)
926 {
927 guint r, c, d;
928
929 cur_row_col(&r, &c);
930 ++c;
931 if (c >= screen_desktop_layout.columns) {
932 if (!data->desktopdir.wrap) return;
933 c = 0;
934 }
935 d = translate_row_col(r, c);
936 if (d >= screen_num_desktops) {
937 if (!data->desktopdir.wrap) return;
938 ++c;
939 }
940 d = translate_row_col(r, c);
941 if (d < screen_num_desktops)
942 screen_set_desktop(d);
943 }
944
945 void action_send_to_desktop_right(union ActionData *data)
946 {
947 ObClient *cl = data->sendto.c;
948 guint r, c, d;
949
950 if (!cl || !client_normal(cl)) return;
951
952 cur_row_col(&r, &c);
953 ++c;
954 if (c >= screen_desktop_layout.columns) {
955 if (!data->sendtodir.wrap) return;
956 c = 0;
957 }
958 d = translate_row_col(r, c);
959 if (d >= screen_num_desktops) {
960 if (!data->sendtodir.wrap) return;
961 ++c;
962 }
963 d = translate_row_col(r, c);
964 if (d < screen_num_desktops) {
965 client_set_desktop(cl, d, data->sendtodir.follow);
966 if (data->sendtodir.follow) screen_set_desktop(d);
967 }
968 }
969
970 void action_desktop_left(union ActionData *data)
971 {
972 guint r, c, d;
973
974 cur_row_col(&r, &c);
975 --c;
976 if (c >= screen_desktop_layout.columns) {
977 if (!data->desktopdir.wrap) return;
978 c = screen_desktop_layout.columns - 1;
979 }
980 d = translate_row_col(r, c);
981 if (d >= screen_num_desktops) {
982 if (!data->desktopdir.wrap) return;
983 --c;
984 }
985 d = translate_row_col(r, c);
986 if (d < screen_num_desktops)
987 screen_set_desktop(d);
988 }
989
990 void action_send_to_desktop_left(union ActionData *data)
991 {
992 ObClient *cl = data->sendto.c;
993 guint r, c, d;
994
995 if (!cl || !client_normal(cl)) return;
996
997 cur_row_col(&r, &c);
998 --c;
999 if (c >= screen_desktop_layout.columns) {
1000 if (!data->sendtodir.wrap) return;
1001 c = screen_desktop_layout.columns - 1;
1002 }
1003 d = translate_row_col(r, c);
1004 if (d >= screen_num_desktops) {
1005 if (!data->sendtodir.wrap) return;
1006 --c;
1007 }
1008 d = translate_row_col(r, c);
1009 if (d < screen_num_desktops) {
1010 client_set_desktop(cl, d, data->sendtodir.follow);
1011 if (data->sendtodir.follow) screen_set_desktop(d);
1012 }
1013 }
1014
1015 void action_desktop_down(union ActionData *data)
1016 {
1017 guint r, c, d;
1018
1019 cur_row_col(&r, &c);
1020 ++r;
1021 if (r >= screen_desktop_layout.rows) {
1022 if (!data->desktopdir.wrap) return;
1023 r = 0;
1024 }
1025 d = translate_row_col(r, c);
1026 if (d >= screen_num_desktops) {
1027 if (!data->desktopdir.wrap) return;
1028 ++r;
1029 }
1030 d = translate_row_col(r, c);
1031 if (d < screen_num_desktops)
1032 screen_set_desktop(d);
1033 }
1034
1035 void action_send_to_desktop_down(union ActionData *data)
1036 {
1037 guint r, c, d;
1038
1039 if (data->sendtodir.c) {
1040 cur_row_col(&r, &c);
1041 ++r;
1042 if (r >= screen_desktop_layout.rows) {
1043 if (!data->sendtodir.wrap) return;
1044 r = 0;
1045 }
1046 d = translate_row_col(r, c);
1047 if (d >= screen_num_desktops) {
1048 if (!data->sendtodir.wrap) return;
1049 ++r;
1050 }
1051 d = translate_row_col(r, c);
1052 if (d < screen_num_desktops) {
1053 client_set_desktop(data->sendtodir.c, d, data->sendtodir.follow);
1054 if (data->sendtodir.follow) screen_set_desktop(d);
1055 }
1056 }
1057 }
1058
1059 void action_desktop_up(union ActionData *data)
1060 {
1061 guint r, c, d;
1062
1063 cur_row_col(&r, &c);
1064 --r;
1065 if (r >= screen_desktop_layout.rows) {
1066 if (!data->desktopdir.wrap) return;
1067 r = screen_desktop_layout.rows - 1;
1068 }
1069 d = translate_row_col(r, c);
1070 if (d >= screen_num_desktops) {
1071 if (!data->desktopdir.wrap) return;
1072 --r;
1073 }
1074 d = translate_row_col(r, c);
1075 if (d < screen_num_desktops)
1076 screen_set_desktop(d);
1077 }
1078
1079 void action_send_to_desktop_up(union ActionData *data)
1080 {
1081 guint r, c, d;
1082
1083 if (data->sendtodir.c) {
1084 cur_row_col(&r, &c);
1085 --r;
1086 if (r >= screen_desktop_layout.rows) {
1087 if (!data->sendtodir.wrap) return;
1088 r = screen_desktop_layout.rows - 1;
1089 }
1090 d = translate_row_col(r, c);
1091 if (d >= screen_num_desktops) {
1092 if (!data->sendtodir.wrap) return;
1093 --r;
1094 }
1095 d = translate_row_col(r, c);
1096 if (d < screen_num_desktops) {
1097 client_set_desktop(data->sendtodir.c, d, data->sendtodir.follow);
1098 if (data->sendtodir.follow) screen_set_desktop(d);
1099 }
1100 }
1101 }
1102
1103 void action_toggle_decorations(union ActionData *data)
1104 {
1105 ObClient *c = data->client.c;;
1106
1107 if (!c) return;
1108
1109 c->decorate = !c->decorate;
1110 client_setup_decor_and_functions(c);
1111 }
1112
1113 void action_moveresize(union ActionData *data)
1114 {
1115 ObClient *c = data->moveresize.c;
1116
1117 if (!c || !client_normal(c)) return;
1118
1119 moveresize_start(c, data->moveresize.x, data->moveresize.y,
1120 data->moveresize.button, data->moveresize.corner);
1121 }
1122
1123 void action_restart(union ActionData *data)
1124 {
1125 ob_restart_other(data->execute.path);
1126 }
1127
1128 void action_exit(union ActionData *data)
1129 {
1130 ob_exit();
1131 }
1132
1133 void action_showmenu(union ActionData *data)
1134 {
1135 if (data->showmenu.name) {
1136 menu_show(data->showmenu.name, data->showmenu.x, data->showmenu.y,
1137 data->showmenu.c);
1138 }
1139 }
1140
1141 void action_cycle_windows(union ActionData *data)
1142 {
1143 ObClient *c;
1144
1145 c = focus_cycle(data->cycle.forward, data->cycle.linear, data->cycle.final,
1146 data->cycle.cancel);
1147 }
1148
1149 void action_directional_focus(union ActionData *data)
1150 {
1151 ObClient *nf;
1152
1153 if (!data->diraction.c)
1154 return;
1155 if ((nf = client_find_directional(data->diraction.c,
1156 data->diraction.direction)))
1157 client_activate(nf);
1158 }
1159
1160 void action_movetoedge(union ActionData *data)
1161 {
1162 int x, y, h, w;
1163 ObClient *c = data->diraction.c;
1164
1165 if (!c)
1166 return;
1167 x = c->frame->area.x;
1168 y = c->frame->area.y;
1169
1170 h = screen_area(c->desktop)->height;
1171 w = screen_area(c->desktop)->width;
1172 switch(data->diraction.direction) {
1173 case OB_DIRECTION_NORTH:
1174 y = 0;
1175 break;
1176 case OB_DIRECTION_WEST:
1177 x = 0;
1178 break;
1179 case OB_DIRECTION_SOUTH:
1180 y = h - c->frame->area.height;
1181 break;
1182 case OB_DIRECTION_EAST:
1183 x = w - c->frame->area.width;
1184 break;
1185 default:
1186 g_assert_not_reached();
1187 }
1188 frame_frame_gravity(c->frame, &x, &y);
1189 client_configure(c, OB_CORNER_TOPLEFT,
1190 x, y, c->area.width, c->area.height, TRUE, TRUE);
1191
1192 }
1193
1194 void action_send_to_layer(union ActionData *data)
1195 {
1196 if (data->layer.c)
1197 client_set_layer(data->layer.c, data->layer.layer);
1198 }
1199
1200 void action_toggle_layer(union ActionData *data)
1201 {
1202 ObClient *c = data->layer.c;
1203
1204 if (c) {
1205 if (data->layer.layer < 0)
1206 client_set_layer(c, c->below ? 0 : -1);
1207 else if (data->layer.layer > 0)
1208 client_set_layer(c, c->above ? 0 : 1);
1209 }
1210 }
1211
1212 void action_toggle_show_desktop(union ActionData *data)
1213 {
1214 screen_show_desktop(!screen_showing_desktop);
1215 }
1216
1217 void action_show_desktop(union ActionData *data)
1218 {
1219 screen_show_desktop(TRUE);
1220 }
1221
1222 void action_unshow_desktop(union ActionData *data)
1223 {
1224 screen_show_desktop(FALSE);
1225 }
This page took 0.099395 seconds and 4 git commands to generate.