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