10 #include "render/render.h"
14 Action
*action_new(void (*func
)(union ActionData
*data
))
16 Action
*a
= g_new0(Action
, 1);
19 /* deal with pointers */
20 if (func
== action_execute
)
21 a
->data
.execute
.path
= NULL
;
26 void action_free(Action
*a
)
28 if (a
== NULL
) return;
30 /* deal with pointers */
31 if (a
->func
== action_execute
|| a
->func
== action_restart
)
32 g_free(a
->data
.execute
.path
);
37 Action
*action_from_string(char *name
)
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
;
186 void action_execute(union ActionData
*data
)
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
);
196 void action_focus(union ActionData
*data
)
199 client_focus(data
->client
.c
);
202 void action_unfocus (union ActionData
*data
)
205 client_unfocus(data
->client
.c
);
208 void action_iconify(union ActionData
*data
)
211 client_iconify(data
->client
.c
, TRUE
, TRUE
);
214 void action_focusraise(union ActionData
*data
)
216 if (data
->client
.c
) {
217 client_focus(data
->client
.c
);
218 stacking_raise(data
->client
.c
);
222 void action_raise(union ActionData
*data
)
225 stacking_raise(data
->client
.c
);
228 void action_unshaderaise(union ActionData
*data
)
230 if (data
->client
.c
) {
231 if (data
->client
.c
->shaded
)
232 client_shade(data
->client
.c
, FALSE
);
234 stacking_raise(data
->client
.c
);
238 void action_shadelower(union ActionData
*data
)
240 if (data
->client
.c
) {
241 if (data
->client
.c
->shaded
)
242 stacking_lower(data
->client
.c
);
244 client_shade(data
->client
.c
, TRUE
);
248 void action_lower(union ActionData
*data
)
251 stacking_lower(data
->client
.c
);
254 void action_close(union ActionData
*data
)
257 client_close(data
->client
.c
);
260 void action_kill(union ActionData
*data
)
263 client_kill(data
->client
.c
);
266 void action_shade(union ActionData
*data
)
269 client_shade(data
->client
.c
, TRUE
);
272 void action_unshade(union ActionData
*data
)
275 client_shade(data
->client
.c
, FALSE
);
278 void action_toggle_shade(union ActionData
*data
)
281 client_shade(data
->client
.c
, !data
->client
.c
->shaded
);
284 void action_toggle_omnipresent(union ActionData
*data
)
287 client_set_desktop(data
->client
.c
,
288 data
->client
.c
->desktop
== DESKTOP_ALL
?
289 screen_desktop
: DESKTOP_ALL
, FALSE
);
292 void action_move_relative_horz(union ActionData
*data
)
294 Client
*c
= data
->relative
.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
);
301 void action_move_relative_vert(union ActionData
*data
)
303 Client
*c
= data
->relative
.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
);
310 void action_resize_relative_horz(union ActionData
*data
)
312 Client
*c
= data
->relative
.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
);
319 void action_resize_relative_vert(union ActionData
*data
)
321 Client
*c
= data
->relative
.c
;
323 client_configure(c
, Corner_TopLeft
, c
->area
.x
, c
->area
.y
,
324 c
->area
.width
, c
->area
.height
+ data
->relative
.delta
,
328 void action_maximize_full(union ActionData
*data
)
331 client_maximize(data
->client
.c
, TRUE
, 0, TRUE
);
334 void action_unmaximize_full(union ActionData
*data
)
337 client_maximize(data
->client
.c
, FALSE
, 0, TRUE
);
340 void action_toggle_maximize_full(union ActionData
*data
)
343 client_maximize(data
->client
.c
,
344 !(data
->client
.c
->max_horz
||
345 data
->client
.c
->max_vert
),
349 void action_maximize_horz(union ActionData
*data
)
352 client_maximize(data
->client
.c
, TRUE
, 1, TRUE
);
355 void action_unmaximize_horz(union ActionData
*data
)
358 client_maximize(data
->client
.c
, FALSE
, 1, TRUE
);
361 void action_toggle_maximize_horz(union ActionData
*data
)
364 client_maximize(data
->client
.c
, !data
->client
.c
->max_horz
, 1, TRUE
);
367 void action_maximize_vert(union ActionData
*data
)
370 client_maximize(data
->client
.c
, TRUE
, 2, TRUE
);
373 void action_unmaximize_vert(union ActionData
*data
)
376 client_maximize(data
->client
.c
, FALSE
, 2, TRUE
);
379 void action_toggle_maximize_vert(union ActionData
*data
)
382 client_maximize(data
->client
.c
, !data
->client
.c
->max_vert
, 2, TRUE
);
385 void action_send_to_desktop(union ActionData
*data
)
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
);
397 void action_send_to_next_desktop(union ActionData
*data
)
401 if (!data
->sendtonextprev
.c
) return;
403 d
= screen_desktop
+ 1;
404 if (d
>= screen_num_desktops
) {
405 if (!data
->sendtonextprev
.wrap
) return;
408 client_set_desktop(data
->sendtonextprev
.c
, d
, data
->sendtonextprev
.follow
);
409 if (data
->sendtonextprev
.follow
) screen_set_desktop(d
);
412 void action_send_to_previous_desktop(union ActionData
*data
)
416 if (!data
->sendtonextprev
.c
) return;
418 d
= screen_desktop
- 1;
419 if (d
>= screen_num_desktops
) {
420 if (!data
->sendtonextprev
.wrap
) return;
421 d
= screen_num_desktops
- 1;
423 client_set_desktop(data
->sendtonextprev
.c
, d
, data
->sendtonextprev
.follow
);
424 if (data
->sendtonextprev
.follow
) screen_set_desktop(d
);
427 void action_desktop(union ActionData
*data
)
429 if (data
->desktop
.desk
< screen_num_desktops
||
430 data
->desktop
.desk
== DESKTOP_ALL
)
431 screen_set_desktop(data
->desktop
.desk
);
434 void action_next_desktop(union ActionData
*data
)
438 d
= screen_desktop
+ 1;
439 if (d
>= screen_num_desktops
) {
440 if (!data
->nextprevdesktop
.wrap
) return;
443 screen_set_desktop(d
);
446 void action_previous_desktop(union ActionData
*data
)
450 d
= screen_desktop
- 1;
451 if (d
>= screen_num_desktops
) {
452 if (!data
->nextprevdesktop
.wrap
) return;
453 d
= screen_num_desktops
- 1;
455 screen_set_desktop(d
);
458 static void cur_row_col(guint
*r
, guint
*c
)
460 switch (screen_desktop_layout
.orientation
) {
461 case Orientation_Horz
:
462 switch (screen_desktop_layout
.start_corner
) {
464 *r
= screen_desktop
/ screen_desktop_layout
.columns
;
465 *c
= screen_desktop
% screen_desktop_layout
.columns
;
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
;
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
;
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
;
485 case Orientation_Vert
:
486 switch (screen_desktop_layout
.start_corner
) {
488 *r
= screen_desktop
% screen_desktop_layout
.rows
;
489 *c
= screen_desktop
/ screen_desktop_layout
.rows
;
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
;
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
;
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
;
512 static guint
translate_row_col(guint r
, guint c
)
514 switch (screen_desktop_layout
.orientation
) {
515 case Orientation_Horz
:
516 switch (screen_desktop_layout
.start_corner
) {
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
);
530 case Orientation_Vert
:
531 switch (screen_desktop_layout
.start_corner
) {
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
);
546 g_assert_not_reached();
550 void action_next_desktop_column(union ActionData
*data
)
556 d
= translate_row_col(r
, c
);
557 if (d
>= screen_num_desktops
) {
558 if (!data
->nextprevdesktop
.wrap
) return;
561 if (d
>= screen_num_desktops
)
563 d
= translate_row_col(r
, c
);
564 if (d
< screen_num_desktops
)
565 screen_set_desktop(d
);
568 void action_previous_desktop_column(union ActionData
*data
)
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;
579 if (d
>= screen_num_desktops
)
581 d
= translate_row_col(r
, c
);
582 if (d
< screen_num_desktops
)
583 screen_set_desktop(d
);
586 void action_next_desktop_row(union ActionData
*data
)
592 d
= translate_row_col(r
, c
);
593 if (d
>= screen_num_desktops
) {
594 if (!data
->nextprevdesktop
.wrap
) return;
597 if (d
>= screen_num_desktops
)
599 d
= translate_row_col(r
, c
);
600 if (d
< screen_num_desktops
)
601 screen_set_desktop(d
);
604 void action_previous_desktop_row(union ActionData
*data
)
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;
615 if (d
>= screen_num_desktops
)
617 d
= translate_row_col(r
, c
);
618 if (d
< screen_num_desktops
)
619 screen_set_desktop(d
);
622 void action_toggle_decorations(union ActionData
*data
)
624 Client
*c
= data
->client
.c
;;
628 c
->disabled_decorations
= c
->disabled_decorations
? 0 : ~0;
629 client_setup_decor_and_functions(c
);
632 static void popup_coords(char *format
, int a
, int b
, gboolean hide
)
634 XSetWindowAttributes attrib
;
635 static Window coords
= None
;
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
);
646 XUnmapWindow(ob_display
, coords
);
651 text
= g_strdup_printf(format
, a
, b
);
652 engine_size_label(text
, TRUE
, TRUE
, &s
);
653 XMoveResizeWindow(ob_display
, coords
,
654 10, 10, s
.width
, s
.height
);
655 engine_render_label(coords
, &s
, text
, TRUE
, TRUE
);
658 XMapWindow(ob_display
, coords
);
662 void action_move(union ActionData
*data
)
664 Client
*c
= data
->move
.c
;
665 int x
= data
->move
.x
;
666 int y
= data
->move
.y
;
668 if (!c
|| !client_normal(c
)) return;
670 dispatch_move(c
, &x
, &y
);
672 popup_coords("X: %d Y: %d", x
, y
, data
->move
.final
);
674 frame_frame_gravity(c
->frame
, &x
, &y
); /* get where the client should be */
675 client_configure(c
, Corner_TopLeft
, x
, y
, c
->area
.width
, c
->area
.height
,
676 TRUE
, data
->move
.final
);
679 void action_resize(union ActionData
*data
)
681 Client
*c
= data
->resize
.c
;
682 int w
= data
->resize
.x
;
683 int h
= data
->resize
.y
;
685 if (!c
|| c
->shaded
|| !client_normal(c
)) return;
687 dispatch_resize(c
, &w
, &h
, data
->resize
.corner
);
689 w
-= c
->frame
->size
.left
+ c
->frame
->size
.right
;
690 h
-= c
->frame
->size
.top
+ c
->frame
->size
.bottom
;
692 client_configure(c
, data
->resize
.corner
, c
->area
.x
, c
->area
.y
, w
, h
,
693 TRUE
, data
->resize
.final
);
695 popup_coords("W: %d H: %d", c
->logical_size
.width
,
696 c
->logical_size
.height
, data
->move
.final
);
699 void action_restart(union ActionData
*data
)
701 ob_restart_path
= data
->execute
.path
;
702 ob_shutdown
= ob_restart
= TRUE
;
705 void action_exit(union ActionData
*data
)
710 void action_showmenu(union ActionData
*data
)
712 g_message(__FUNCTION__
);
715 static void popup_cycle(Client
*c
, gboolean hide
)
717 XSetWindowAttributes attrib
;
718 static Window coords
= None
;
720 if (coords
== None
) {
721 attrib
.override_redirect
= TRUE
;
722 coords
= XCreateWindow(ob_display
, ob_root
,
723 0, 0, 1, 1, 0, render_depth
, InputOutput
,
724 render_visual
, CWOverrideRedirect
, &attrib
);
725 g_assert(coords
!= None
);
729 XUnmapWindow(ob_display
, coords
);
734 a
= screen_area(c
->desktop
);
736 engine_size_label(c
->title
, TRUE
, TRUE
, &s
);
737 XMoveResizeWindow(ob_display
, coords
,
738 a
->x
+ (a
->width
- s
.width
) / 2,
739 a
->y
+ (a
->height
- s
.height
) / 2,
741 engine_render_label(coords
, &s
, c
->title
, TRUE
, TRUE
);
743 XMapWindow(ob_display
, coords
);
747 void action_cycle_windows(union ActionData
*data
)
751 c
= focus_cycle(data
->cycle
.forward
, data
->cycle
.linear
, data
->cycle
.final
,
753 popup_cycle(c
, !c
|| data
->cycle
.final
|| data
->cycle
.cancel
);