5 #include "framerender.h"
13 Action
*action_new(void (*func
)(union ActionData
*data
))
15 Action
*a
= g_new0(Action
, 1);
18 /* deal with pointers */
19 if (func
== action_execute
)
20 a
->data
.execute
.path
= NULL
;
25 void action_free(Action
*a
)
27 if (a
== NULL
) return;
29 /* deal with pointers */
30 if (a
->func
== action_execute
|| a
->func
== action_restart
)
31 g_free(a
->data
.execute
.path
);
36 Action
*action_from_string(char *name
)
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
;
185 void action_execute(union ActionData
*data
)
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
);
195 void action_focus(union ActionData
*data
)
198 client_focus(data
->client
.c
);
201 void action_unfocus (union ActionData
*data
)
204 client_unfocus(data
->client
.c
);
207 void action_iconify(union ActionData
*data
)
210 client_iconify(data
->client
.c
, TRUE
, TRUE
);
213 void action_focusraise(union ActionData
*data
)
215 if (data
->client
.c
) {
216 client_focus(data
->client
.c
);
217 stacking_raise(data
->client
.c
);
221 void action_raise(union ActionData
*data
)
224 stacking_raise(data
->client
.c
);
227 void action_unshaderaise(union ActionData
*data
)
229 if (data
->client
.c
) {
230 if (data
->client
.c
->shaded
)
231 client_shade(data
->client
.c
, FALSE
);
233 stacking_raise(data
->client
.c
);
237 void action_shadelower(union ActionData
*data
)
239 if (data
->client
.c
) {
240 if (data
->client
.c
->shaded
)
241 stacking_lower(data
->client
.c
);
243 client_shade(data
->client
.c
, TRUE
);
247 void action_lower(union ActionData
*data
)
250 stacking_lower(data
->client
.c
);
253 void action_close(union ActionData
*data
)
256 client_close(data
->client
.c
);
259 void action_kill(union ActionData
*data
)
262 client_kill(data
->client
.c
);
265 void action_shade(union ActionData
*data
)
268 client_shade(data
->client
.c
, TRUE
);
271 void action_unshade(union ActionData
*data
)
274 client_shade(data
->client
.c
, FALSE
);
277 void action_toggle_shade(union ActionData
*data
)
280 client_shade(data
->client
.c
, !data
->client
.c
->shaded
);
283 void action_toggle_omnipresent(union ActionData
*data
)
286 client_set_desktop(data
->client
.c
,
287 data
->client
.c
->desktop
== DESKTOP_ALL
?
288 screen_desktop
: DESKTOP_ALL
, FALSE
);
291 void action_move_relative_horz(union ActionData
*data
)
293 Client
*c
= data
->relative
.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
);
300 void action_move_relative_vert(union ActionData
*data
)
302 Client
*c
= data
->relative
.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
);
309 void action_resize_relative_horz(union ActionData
*data
)
311 Client
*c
= data
->relative
.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
);
318 void action_resize_relative_vert(union ActionData
*data
)
320 Client
*c
= data
->relative
.c
;
322 client_configure(c
, Corner_TopLeft
, c
->area
.x
, c
->area
.y
,
323 c
->area
.width
, c
->area
.height
+ data
->relative
.delta
,
327 void action_maximize_full(union ActionData
*data
)
330 client_maximize(data
->client
.c
, TRUE
, 0, TRUE
);
333 void action_unmaximize_full(union ActionData
*data
)
336 client_maximize(data
->client
.c
, FALSE
, 0, TRUE
);
339 void action_toggle_maximize_full(union ActionData
*data
)
342 client_maximize(data
->client
.c
,
343 !(data
->client
.c
->max_horz
||
344 data
->client
.c
->max_vert
),
348 void action_maximize_horz(union ActionData
*data
)
351 client_maximize(data
->client
.c
, TRUE
, 1, TRUE
);
354 void action_unmaximize_horz(union ActionData
*data
)
357 client_maximize(data
->client
.c
, FALSE
, 1, TRUE
);
360 void action_toggle_maximize_horz(union ActionData
*data
)
363 client_maximize(data
->client
.c
, !data
->client
.c
->max_horz
, 1, TRUE
);
366 void action_maximize_vert(union ActionData
*data
)
369 client_maximize(data
->client
.c
, TRUE
, 2, TRUE
);
372 void action_unmaximize_vert(union ActionData
*data
)
375 client_maximize(data
->client
.c
, FALSE
, 2, TRUE
);
378 void action_toggle_maximize_vert(union ActionData
*data
)
381 client_maximize(data
->client
.c
, !data
->client
.c
->max_vert
, 2, TRUE
);
384 void action_send_to_desktop(union ActionData
*data
)
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
);
396 void action_send_to_next_desktop(union ActionData
*data
)
400 if (!data
->sendtonextprev
.c
) return;
402 d
= screen_desktop
+ 1;
403 if (d
>= screen_num_desktops
) {
404 if (!data
->sendtonextprev
.wrap
) return;
407 client_set_desktop(data
->sendtonextprev
.c
, d
, data
->sendtonextprev
.follow
);
408 if (data
->sendtonextprev
.follow
) screen_set_desktop(d
);
411 void action_send_to_previous_desktop(union ActionData
*data
)
415 if (!data
->sendtonextprev
.c
) return;
417 d
= screen_desktop
- 1;
418 if (d
>= screen_num_desktops
) {
419 if (!data
->sendtonextprev
.wrap
) return;
420 d
= screen_num_desktops
- 1;
422 client_set_desktop(data
->sendtonextprev
.c
, d
, data
->sendtonextprev
.follow
);
423 if (data
->sendtonextprev
.follow
) screen_set_desktop(d
);
426 void action_desktop(union ActionData
*data
)
428 if (data
->desktop
.desk
< screen_num_desktops
||
429 data
->desktop
.desk
== DESKTOP_ALL
)
430 screen_set_desktop(data
->desktop
.desk
);
433 void action_next_desktop(union ActionData
*data
)
437 d
= screen_desktop
+ 1;
438 if (d
>= screen_num_desktops
) {
439 if (!data
->nextprevdesktop
.wrap
) return;
442 screen_set_desktop(d
);
445 void action_previous_desktop(union ActionData
*data
)
449 d
= screen_desktop
- 1;
450 if (d
>= screen_num_desktops
) {
451 if (!data
->nextprevdesktop
.wrap
) return;
452 d
= screen_num_desktops
- 1;
454 screen_set_desktop(d
);
457 static void cur_row_col(guint
*r
, guint
*c
)
459 switch (screen_desktop_layout
.orientation
) {
460 case Orientation_Horz
:
461 switch (screen_desktop_layout
.start_corner
) {
463 *r
= screen_desktop
/ screen_desktop_layout
.columns
;
464 *c
= screen_desktop
% screen_desktop_layout
.columns
;
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
;
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
;
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
;
484 case Orientation_Vert
:
485 switch (screen_desktop_layout
.start_corner
) {
487 *r
= screen_desktop
% screen_desktop_layout
.rows
;
488 *c
= screen_desktop
/ screen_desktop_layout
.rows
;
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
;
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
;
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
;
511 static guint
translate_row_col(guint r
, guint c
)
513 switch (screen_desktop_layout
.orientation
) {
514 case Orientation_Horz
:
515 switch (screen_desktop_layout
.start_corner
) {
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
);
529 case Orientation_Vert
:
530 switch (screen_desktop_layout
.start_corner
) {
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
);
545 g_assert_not_reached();
549 void action_next_desktop_column(union ActionData
*data
)
555 d
= translate_row_col(r
, c
);
556 if (d
>= screen_num_desktops
) {
557 if (!data
->nextprevdesktop
.wrap
) return;
560 if (d
>= screen_num_desktops
)
562 d
= translate_row_col(r
, c
);
563 if (d
< screen_num_desktops
)
564 screen_set_desktop(d
);
567 void action_previous_desktop_column(union ActionData
*data
)
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;
578 if (d
>= screen_num_desktops
)
580 d
= translate_row_col(r
, c
);
581 if (d
< screen_num_desktops
)
582 screen_set_desktop(d
);
585 void action_next_desktop_row(union ActionData
*data
)
591 d
= translate_row_col(r
, c
);
592 if (d
>= screen_num_desktops
) {
593 if (!data
->nextprevdesktop
.wrap
) return;
596 if (d
>= screen_num_desktops
)
598 d
= translate_row_col(r
, c
);
599 if (d
< screen_num_desktops
)
600 screen_set_desktop(d
);
603 void action_previous_desktop_row(union ActionData
*data
)
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;
614 if (d
>= screen_num_desktops
)
616 d
= translate_row_col(r
, c
);
617 if (d
< screen_num_desktops
)
618 screen_set_desktop(d
);
621 void action_toggle_decorations(union ActionData
*data
)
623 Client
*c
= data
->client
.c
;;
627 c
->disabled_decorations
= c
->disabled_decorations
? 0 : ~0;
628 client_setup_decor_and_functions(c
);
631 static void popup_coords(char *format
, int a
, int b
, gboolean hide
)
633 XSetWindowAttributes attrib
;
634 static Window coords
= None
;
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
);
645 XUnmapWindow(ob_display
, coords
);
650 text
= g_strdup_printf(format
, a
, b
);
651 framerender_size_popup_label(text
, &s
);
652 XMoveResizeWindow(ob_display
, coords
,
653 10, 10, s
.width
, s
.height
);
654 framerender_popup_label(coords
, &s
, text
);
657 XMapWindow(ob_display
, coords
);
661 void action_move(union ActionData
*data
)
663 Client
*c
= data
->move
.c
;
664 int x
= data
->move
.x
;
665 int y
= data
->move
.y
;
667 if (!c
|| !client_normal(c
)) return;
669 dispatch_move(c
, &x
, &y
);
671 popup_coords("X: %d Y: %d", x
, y
, data
->move
.final
);
673 frame_frame_gravity(c
->frame
, &x
, &y
); /* get where the client should be */
674 client_configure(c
, Corner_TopLeft
, x
, y
, c
->area
.width
, c
->area
.height
,
675 TRUE
, data
->move
.final
);
678 void action_resize(union ActionData
*data
)
680 Client
*c
= data
->resize
.c
;
681 int w
= data
->resize
.x
;
682 int h
= data
->resize
.y
;
684 if (!c
|| c
->shaded
|| !client_normal(c
)) return;
686 dispatch_resize(c
, &w
, &h
, data
->resize
.corner
);
688 w
-= c
->frame
->size
.left
+ c
->frame
->size
.right
;
689 h
-= c
->frame
->size
.top
+ c
->frame
->size
.bottom
;
691 client_configure(c
, data
->resize
.corner
, c
->area
.x
, c
->area
.y
, w
, h
,
692 TRUE
, data
->resize
.final
);
694 popup_coords("W: %d H: %d", c
->logical_size
.width
,
695 c
->logical_size
.height
, data
->move
.final
);
698 void action_restart(union ActionData
*data
)
700 ob_restart_path
= data
->execute
.path
;
701 ob_shutdown
= ob_restart
= TRUE
;
704 void action_exit(union ActionData
*data
)
709 void action_showmenu(union ActionData
*data
)
711 g_message(__FUNCTION__
);
714 static void popup_cycle(Client
*c
, gboolean hide
)
716 XSetWindowAttributes attrib
;
717 static Window coords
= None
;
719 if (coords
== None
) {
720 attrib
.override_redirect
= TRUE
;
721 coords
= XCreateWindow(ob_display
, ob_root
,
722 0, 0, 1, 1, 0, render_depth
, InputOutput
,
723 render_visual
, CWOverrideRedirect
, &attrib
);
724 g_assert(coords
!= None
);
728 XUnmapWindow(ob_display
, coords
);
733 a
= screen_area(c
->desktop
);
735 framerender_size_popup_label(c
->title
, &s
);
736 XMoveResizeWindow(ob_display
, coords
,
737 a
->x
+ (a
->width
- s
.width
) / 2,
738 a
->y
+ (a
->height
- s
.height
) / 2,
740 framerender_popup_label(coords
, &s
, c
->title
);
742 XMapWindow(ob_display
, coords
);
746 void action_cycle_windows(union ActionData
*data
)
750 c
= focus_cycle(data
->cycle
.forward
, data
->cycle
.linear
, data
->cycle
.final
,
752 popup_cycle(c
, !c
|| data
->cycle
.final
|| data
->cycle
.cancel
);