1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 focus.c for the Openbox window manager
4 Copyright (c) 2003 Ben Jansens
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 See the COPYING file for a copy of the GNU General Public License.
23 #include "framerender.h"
33 #include "render/render.h"
39 ObClient
*focus_client
, *focus_hilite
;
40 GList
**focus_order
; /* these lists are created when screen_startup
41 sets the number of desktops */
42 ObClient
*focus_cycle_target
;
48 InternalWindow bottom
;
51 RrAppearance
*a_focus_indicator
;
54 static ObIconPopup
*focus_cycle_popup
;
56 static void focus_cycle_destructor(ObClient
*client
, gpointer data
)
58 /* end cycling if the target disappears */
59 if (focus_cycle_target
== client
)
60 focus_cycle(TRUE
, TRUE
, TRUE
, TRUE
, TRUE
);
63 static Window
createWindow(Window parent
, unsigned long mask
,
64 XSetWindowAttributes
*attrib
)
66 return XCreateWindow(ob_display
, parent
, 0, 0, 1, 1, 0,
67 RrDepth(ob_rr_inst
), InputOutput
,
68 RrVisual(ob_rr_inst
), mask
, attrib
);
72 void focus_startup(gboolean reconfig
)
74 focus_cycle_popup
= icon_popup_new(TRUE
);
77 XSetWindowAttributes attr
;
79 client_add_destructor(focus_cycle_destructor
, NULL
);
81 /* start with nothing focused */
82 focus_set_client(NULL
);
84 focus_indicator
.top
.obwin
.type
= Window_Internal
;
85 focus_indicator
.left
.obwin
.type
= Window_Internal
;
86 focus_indicator
.right
.obwin
.type
= Window_Internal
;
87 focus_indicator
.bottom
.obwin
.type
= Window_Internal
;
89 attr
.save_under
= True
;
90 attr
.override_redirect
= True
;
91 attr
.background_pixel
= BlackPixel(ob_display
, ob_screen
);
92 focus_indicator
.top
.win
=
93 createWindow(RootWindow(ob_display
, ob_screen
),
94 CWOverrideRedirect
| CWBackPixel
| CWSaveUnder
,
96 focus_indicator
.left
.win
=
97 createWindow(RootWindow(ob_display
, ob_screen
),
98 CWOverrideRedirect
| CWBackPixel
| CWSaveUnder
,
100 focus_indicator
.right
.win
=
101 createWindow(RootWindow(ob_display
, ob_screen
),
102 CWOverrideRedirect
| CWBackPixel
| CWSaveUnder
,
104 focus_indicator
.bottom
.win
=
105 createWindow(RootWindow(ob_display
, ob_screen
),
106 CWOverrideRedirect
| CWBackPixel
| CWSaveUnder
,
109 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.top
));
110 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.left
));
111 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.right
));
112 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.bottom
));
114 color_white
= RrColorNew(ob_rr_inst
, 0xff, 0xff, 0xff);
116 a_focus_indicator
= RrAppearanceNew(ob_rr_inst
, 4);
117 a_focus_indicator
->surface
.grad
= RR_SURFACE_SOLID
;
118 a_focus_indicator
->surface
.relief
= RR_RELIEF_FLAT
;
119 a_focus_indicator
->surface
.primary
= RrColorNew(ob_rr_inst
,
121 a_focus_indicator
->texture
[0].type
= RR_TEXTURE_LINE_ART
;
122 a_focus_indicator
->texture
[0].data
.lineart
.color
= color_white
;
123 a_focus_indicator
->texture
[1].type
= RR_TEXTURE_LINE_ART
;
124 a_focus_indicator
->texture
[1].data
.lineart
.color
= color_white
;
125 a_focus_indicator
->texture
[2].type
= RR_TEXTURE_LINE_ART
;
126 a_focus_indicator
->texture
[2].data
.lineart
.color
= color_white
;
127 a_focus_indicator
->texture
[3].type
= RR_TEXTURE_LINE_ART
;
128 a_focus_indicator
->texture
[3].data
.lineart
.color
= color_white
;
132 void focus_shutdown(gboolean reconfig
)
136 icon_popup_free(focus_cycle_popup
);
139 client_remove_destructor(focus_cycle_destructor
);
141 for (i
= 0; i
< screen_num_desktops
; ++i
)
142 g_list_free(focus_order
[i
]);
145 /* reset focus to root */
146 XSetInputFocus(ob_display
, PointerRoot
, RevertToNone
, event_lasttime
);
148 RrColorFree(color_white
);
150 RrAppearanceFree(a_focus_indicator
);
152 XDestroyWindow(ob_display
, focus_indicator
.top
.win
);
153 XDestroyWindow(ob_display
, focus_indicator
.left
.win
);
154 XDestroyWindow(ob_display
, focus_indicator
.right
.win
);
155 XDestroyWindow(ob_display
, focus_indicator
.bottom
.win
);
159 static void push_to_top(ObClient
*client
)
163 desktop
= client
->desktop
;
164 if (desktop
== DESKTOP_ALL
) desktop
= screen_desktop
;
165 focus_order
[desktop
] = g_list_remove(focus_order
[desktop
], client
);
166 focus_order
[desktop
] = g_list_prepend(focus_order
[desktop
], client
);
169 void focus_set_client(ObClient
*client
)
175 ob_debug("focus_set_client 0x%lx\n", client
? client
->window
: 0);
178 /* uninstall the old colormap, and install the new one */
179 screen_install_colormap(focus_client
, FALSE
);
180 screen_install_colormap(client
, TRUE
);
182 if (client
== NULL
) {
184 ob_debug("actively focusing NONWINDOW\n");
186 /* when nothing will be focused, send focus to the backup target */
187 XSetInputFocus(ob_display
, screen_support_win
, RevertToNone
,
189 XSync(ob_display
, FALSE
);
192 /* in the middle of cycling..? kill it. */
193 if (focus_cycle_target
)
194 focus_cycle(TRUE
, TRUE
, TRUE
, TRUE
, TRUE
);
197 focus_client
= client
;
199 /* move to the top of the list */
203 /* set the NET_ACTIVE_WINDOW hint, but preserve it on shutdown */
204 if (ob_state() != OB_STATE_EXITING
) {
205 active
= client
? client
->window
: None
;
206 PROP_SET32(RootWindow(ob_display
, ob_screen
),
207 net_active_window
, window
, active
);
211 /* finds the first transient that isn't 'skip' and ensure's that client_normal
213 static ObClient
*find_transient_recursive(ObClient
*c
, ObClient
*top
, ObClient
*skip
)
218 for (it
= c
->transients
; it
; it
= it
->next
) {
219 if (it
->data
== top
) return NULL
;
220 ret
= find_transient_recursive(it
->data
, top
, skip
);
221 if (ret
&& ret
!= skip
&& client_normal(ret
)) return ret
;
222 if (it
->data
!= skip
&& client_normal(it
->data
)) return it
->data
;
227 static ObClient
* focus_fallback_transient(ObClient
*top
, ObClient
*old
)
229 ObClient
*target
= find_transient_recursive(top
, top
, old
);
231 /* make sure client_normal is true always */
232 if (!client_normal(top
))
234 target
= top
; /* no transient, keep the top */
236 if (client_can_focus(target
))
242 ObClient
* focus_fallback_target(ObFocusFallbackType type
)
245 ObClient
*old
= NULL
;
246 ObClient
*target
= NULL
;
250 if (type
== OB_FOCUS_FALLBACK_UNFOCUSING
&& old
) {
251 if (old
->transient_for
) {
252 gboolean trans
= FALSE
;
254 if (!config_focus_follow
)
257 if ((target
= client_under_pointer()) &&
258 client_search_transient
259 (client_search_top_transient(target
), old
))
265 /* try for transient relations */
267 if (old
->transient_for
== OB_TRAN_GROUP
) {
268 for (it
= focus_order
[screen_desktop
]; it
; it
= it
->next
) {
271 for (sit
= old
->group
->members
; sit
; sit
= sit
->next
)
272 if (sit
->data
== it
->data
)
274 focus_fallback_transient(sit
->data
, old
)))
279 focus_fallback_transient(old
->transient_for
, old
)))
286 if (config_focus_follow
) {
287 if ((target
= client_under_pointer()))
288 if (client_normal(target
) && client_can_focus(target
))
293 /* try for group relations */
297 for (it
= focus_order
[screen_desktop
]; it
!= NULL
; it
= it
->next
)
298 for (sit
= old
->group
->members
; sit
; sit
= sit
->next
)
299 if (sit
->data
== it
->data
)
300 if (sit
->data
!= old
&& client_normal(sit
->data
))
301 if (client_can_focus(sit
->data
))
306 for (it
= focus_order
[screen_desktop
]; it
!= NULL
; it
= it
->next
)
307 if (type
!= OB_FOCUS_FALLBACK_UNFOCUSING
|| it
->data
!= old
)
308 if (client_normal(it
->data
) && client_can_focus(it
->data
))
314 void focus_fallback(ObFocusFallbackType type
)
318 /* unfocus any focused clients.. they can be focused by Pointer events
319 and such, and then when I try focus them, I won't get a FocusIn event
322 focus_set_client(NULL
);
324 if ((new = focus_fallback_target(type
)))
328 static void popup_cycle(ObClient
*c
, gboolean show
)
331 icon_popup_hide(focus_cycle_popup
);
337 a
= screen_physical_area_monitor(0);
338 icon_popup_position(focus_cycle_popup
, CenterGravity
,
339 a
->x
+ a
->width
/ 2, a
->y
+ a
->height
/ 2);
340 /* icon_popup_size(focus_cycle_popup, a->height/2, a->height/16);
341 icon_popup_show(focus_cycle_popup, c->title,
342 client_icon(c, a->height/16, a->height/16));
344 /* XXX the size and the font extents need to be related on some level
346 icon_popup_size(focus_cycle_popup
, POPUP_WIDTH
, POPUP_HEIGHT
);
348 /* use the transient's parent's title/icon */
349 while (p
->transient_for
&& p
->transient_for
!= OB_TRAN_GROUP
)
350 p
= p
->transient_for
;
355 title
= g_strconcat((c
->iconic
? c
->icon_title
: c
->title
),
357 (p
->iconic
? p
->icon_title
: p
->title
),
360 icon_popup_show(focus_cycle_popup
,
362 (c
->iconic
? c
->icon_title
: c
->title
)),
363 client_icon(p
, 48, 48));
368 void focus_cycle_draw_indicator()
370 if (!focus_cycle_target
) {
371 XUnmapWindow(ob_display
, focus_indicator
.top
.win
);
372 XUnmapWindow(ob_display
, focus_indicator
.left
.win
);
373 XUnmapWindow(ob_display
, focus_indicator
.right
.win
);
374 XUnmapWindow(ob_display
, focus_indicator
.bottom
.win
);
377 if (focus_cycle_target)
378 frame_adjust_focus(focus_cycle_target->frame, FALSE);
379 frame_adjust_focus(focus_cycle_target->frame, TRUE);
384 wt
= wl
= wr
= wb
= MAX(3,
385 ob_rr_theme
->handle_height
+
386 ob_rr_theme
->bwidth
* 2);
388 x
= focus_cycle_target
->frame
->area
.x
;
389 y
= focus_cycle_target
->frame
->area
.y
;
390 w
= focus_cycle_target
->frame
->area
.width
;
393 XMoveResizeWindow(ob_display
, focus_indicator
.top
.win
,
395 a_focus_indicator
->texture
[0].data
.lineart
.x1
= 0;
396 a_focus_indicator
->texture
[0].data
.lineart
.y1
= h
-1;
397 a_focus_indicator
->texture
[0].data
.lineart
.x2
= 0;
398 a_focus_indicator
->texture
[0].data
.lineart
.y2
= 0;
399 a_focus_indicator
->texture
[1].data
.lineart
.x1
= 0;
400 a_focus_indicator
->texture
[1].data
.lineart
.y1
= 0;
401 a_focus_indicator
->texture
[1].data
.lineart
.x2
= w
-1;
402 a_focus_indicator
->texture
[1].data
.lineart
.y2
= 0;
403 a_focus_indicator
->texture
[2].data
.lineart
.x1
= w
-1;
404 a_focus_indicator
->texture
[2].data
.lineart
.y1
= 0;
405 a_focus_indicator
->texture
[2].data
.lineart
.x2
= w
-1;
406 a_focus_indicator
->texture
[2].data
.lineart
.y2
= h
-1;
407 a_focus_indicator
->texture
[3].data
.lineart
.x1
= (wl
-1);
408 a_focus_indicator
->texture
[3].data
.lineart
.y1
= h
-1;
409 a_focus_indicator
->texture
[3].data
.lineart
.x2
= w
- wr
;
410 a_focus_indicator
->texture
[3].data
.lineart
.y2
= h
-1;
411 RrPaint(a_focus_indicator
, focus_indicator
.top
.win
,
414 x
= focus_cycle_target
->frame
->area
.x
;
415 y
= focus_cycle_target
->frame
->area
.y
;
417 h
= focus_cycle_target
->frame
->area
.height
;
419 XMoveResizeWindow(ob_display
, focus_indicator
.left
.win
,
421 a_focus_indicator
->texture
[0].data
.lineart
.x1
= w
-1;
422 a_focus_indicator
->texture
[0].data
.lineart
.y1
= 0;
423 a_focus_indicator
->texture
[0].data
.lineart
.x2
= 0;
424 a_focus_indicator
->texture
[0].data
.lineart
.y2
= 0;
425 a_focus_indicator
->texture
[1].data
.lineart
.x1
= 0;
426 a_focus_indicator
->texture
[1].data
.lineart
.y1
= 0;
427 a_focus_indicator
->texture
[1].data
.lineart
.x2
= 0;
428 a_focus_indicator
->texture
[1].data
.lineart
.y2
= h
-1;
429 a_focus_indicator
->texture
[2].data
.lineart
.x1
= 0;
430 a_focus_indicator
->texture
[2].data
.lineart
.y1
= h
-1;
431 a_focus_indicator
->texture
[2].data
.lineart
.x2
= w
-1;
432 a_focus_indicator
->texture
[2].data
.lineart
.y2
= h
-1;
433 a_focus_indicator
->texture
[3].data
.lineart
.x1
= w
-1;
434 a_focus_indicator
->texture
[3].data
.lineart
.y1
= wt
-1;
435 a_focus_indicator
->texture
[3].data
.lineart
.x2
= w
-1;
436 a_focus_indicator
->texture
[3].data
.lineart
.y2
= h
- wb
;
437 RrPaint(a_focus_indicator
, focus_indicator
.left
.win
,
440 x
= focus_cycle_target
->frame
->area
.x
+
441 focus_cycle_target
->frame
->area
.width
- wr
;
442 y
= focus_cycle_target
->frame
->area
.y
;
444 h
= focus_cycle_target
->frame
->area
.height
;
446 XMoveResizeWindow(ob_display
, focus_indicator
.right
.win
,
448 a_focus_indicator
->texture
[0].data
.lineart
.x1
= 0;
449 a_focus_indicator
->texture
[0].data
.lineart
.y1
= 0;
450 a_focus_indicator
->texture
[0].data
.lineart
.x2
= w
-1;
451 a_focus_indicator
->texture
[0].data
.lineart
.y2
= 0;
452 a_focus_indicator
->texture
[1].data
.lineart
.x1
= w
-1;
453 a_focus_indicator
->texture
[1].data
.lineart
.y1
= 0;
454 a_focus_indicator
->texture
[1].data
.lineart
.x2
= w
-1;
455 a_focus_indicator
->texture
[1].data
.lineart
.y2
= h
-1;
456 a_focus_indicator
->texture
[2].data
.lineart
.x1
= w
-1;
457 a_focus_indicator
->texture
[2].data
.lineart
.y1
= h
-1;
458 a_focus_indicator
->texture
[2].data
.lineart
.x2
= 0;
459 a_focus_indicator
->texture
[2].data
.lineart
.y2
= h
-1;
460 a_focus_indicator
->texture
[3].data
.lineart
.x1
= 0;
461 a_focus_indicator
->texture
[3].data
.lineart
.y1
= wt
-1;
462 a_focus_indicator
->texture
[3].data
.lineart
.x2
= 0;
463 a_focus_indicator
->texture
[3].data
.lineart
.y2
= h
- wb
;
464 RrPaint(a_focus_indicator
, focus_indicator
.right
.win
,
467 x
= focus_cycle_target
->frame
->area
.x
;
468 y
= focus_cycle_target
->frame
->area
.y
+
469 focus_cycle_target
->frame
->area
.height
- wb
;
470 w
= focus_cycle_target
->frame
->area
.width
;
473 XMoveResizeWindow(ob_display
, focus_indicator
.bottom
.win
,
475 a_focus_indicator
->texture
[0].data
.lineart
.x1
= 0;
476 a_focus_indicator
->texture
[0].data
.lineart
.y1
= 0;
477 a_focus_indicator
->texture
[0].data
.lineart
.x2
= 0;
478 a_focus_indicator
->texture
[0].data
.lineart
.y2
= h
-1;
479 a_focus_indicator
->texture
[1].data
.lineart
.x1
= 0;
480 a_focus_indicator
->texture
[1].data
.lineart
.y1
= h
-1;
481 a_focus_indicator
->texture
[1].data
.lineart
.x2
= w
-1;
482 a_focus_indicator
->texture
[1].data
.lineart
.y2
= h
-1;
483 a_focus_indicator
->texture
[2].data
.lineart
.x1
= w
-1;
484 a_focus_indicator
->texture
[2].data
.lineart
.y1
= h
-1;
485 a_focus_indicator
->texture
[2].data
.lineart
.x2
= w
-1;
486 a_focus_indicator
->texture
[2].data
.lineart
.y2
= 0;
487 a_focus_indicator
->texture
[3].data
.lineart
.x1
= wl
-1;
488 a_focus_indicator
->texture
[3].data
.lineart
.y1
= 0;
489 a_focus_indicator
->texture
[3].data
.lineart
.x2
= w
- wr
;
490 a_focus_indicator
->texture
[3].data
.lineart
.y2
= 0;
491 RrPaint(a_focus_indicator
, focus_indicator
.bottom
.win
,
494 XMapWindow(ob_display
, focus_indicator
.top
.win
);
495 XMapWindow(ob_display
, focus_indicator
.left
.win
);
496 XMapWindow(ob_display
, focus_indicator
.right
.win
);
497 XMapWindow(ob_display
, focus_indicator
.bottom
.win
);
501 static gboolean
valid_focus_target(ObClient
*ft
)
503 /* we don't use client_can_focus here, because that doesn't let you
504 focus an iconic window, but we want to be able to, so we just check
505 if the focus flags on the window allow it, and its on the current
507 return ((ft
->type
== OB_CLIENT_TYPE_NORMAL
||
508 ft
->type
== OB_CLIENT_TYPE_DIALOG
||
509 (!client_has_group_siblings(ft
) &&
510 (ft
->type
== OB_CLIENT_TYPE_TOOLBAR
||
511 ft
->type
== OB_CLIENT_TYPE_MENU
||
512 ft
->type
== OB_CLIENT_TYPE_UTILITY
))) &&
514 ((ft
->can_focus
|| ft
->focus_notify
) &&
516 (ft
->desktop
== screen_desktop
|| ft
->desktop
== DESKTOP_ALL
)));
519 void focus_cycle(gboolean forward
, gboolean linear
,
520 gboolean dialog
, gboolean done
, gboolean cancel
)
522 static ObClient
*first
= NULL
;
523 static ObClient
*t
= NULL
;
524 static GList
*order
= NULL
;
525 GList
*it
, *start
, *list
;
529 focus_cycle_target
= NULL
;
534 if (!focus_order
[screen_desktop
])
537 if (!first
) first
= focus_client
;
538 if (!focus_cycle_target
) focus_cycle_target
= focus_client
;
540 if (linear
) list
= client_list
;
541 else list
= focus_order
[screen_desktop
];
543 start
= it
= g_list_find(list
, focus_cycle_target
);
544 if (!start
) /* switched desktops or something? */
545 start
= it
= forward
? g_list_last(list
) : g_list_first(list
);
546 if (!start
) goto done_cycle
;
551 if (it
== NULL
) it
= g_list_first(list
);
554 if (it
== NULL
) it
= g_list_last(list
);
557 if (valid_focus_target(ft
)) {
558 if (ft
!= focus_cycle_target
) { /* prevents flicker */
559 focus_cycle_target
= ft
;
560 focus_cycle_draw_indicator();
562 popup_cycle(ft
, dialog
);
565 } while (it
!= start
);
568 if (done
&& focus_cycle_target
)
569 client_activate(focus_cycle_target
, FALSE
);
573 focus_cycle_target
= NULL
;
577 focus_cycle_draw_indicator();
578 popup_cycle(ft
, FALSE
);
583 void focus_directional_cycle(ObDirection dir
,
584 gboolean dialog
, gboolean done
, gboolean cancel
)
586 static ObClient
*first
= NULL
;
590 focus_cycle_target
= NULL
;
595 if (!focus_order
[screen_desktop
])
598 if (!first
) first
= focus_client
;
599 if (!focus_cycle_target
) focus_cycle_target
= focus_client
;
601 if (focus_cycle_target
)
602 ft
= client_find_directional(focus_cycle_target
, dir
);
606 for (it
= focus_order
[screen_desktop
]; it
; it
= g_list_next(it
))
607 if (valid_focus_target(it
->data
))
612 if (ft
!= focus_cycle_target
) {/* prevents flicker */
613 focus_cycle_target
= ft
;
614 focus_cycle_draw_indicator();
617 if (focus_cycle_target
) {
618 popup_cycle(focus_cycle_target
, dialog
);
625 if (done
&& focus_cycle_target
)
626 client_activate(focus_cycle_target
, FALSE
);
629 focus_cycle_target
= NULL
;
631 focus_cycle_draw_indicator();
632 popup_cycle(ft
, FALSE
);
637 void focus_order_add_new(ObClient
*c
)
642 focus_order_to_top(c
);
645 if (d
== DESKTOP_ALL
) {
646 for (i
= 0; i
< screen_num_desktops
; ++i
) {
647 if (focus_order
[i
] && ((ObClient
*)focus_order
[i
]->data
)->iconic
)
648 focus_order
[i
] = g_list_insert(focus_order
[i
], c
, 0);
650 focus_order
[i
] = g_list_insert(focus_order
[i
], c
, 1);
653 if (focus_order
[d
] && ((ObClient
*)focus_order
[d
]->data
)->iconic
)
654 focus_order
[d
] = g_list_insert(focus_order
[d
], c
, 0);
656 focus_order
[d
] = g_list_insert(focus_order
[d
], c
, 1);
660 void focus_order_remove(ObClient
*c
)
665 if (d
== DESKTOP_ALL
) {
666 for (i
= 0; i
< screen_num_desktops
; ++i
)
667 focus_order
[i
] = g_list_remove(focus_order
[i
], c
);
669 focus_order
[d
] = g_list_remove(focus_order
[d
], c
);
672 static void to_top(ObClient
*c
, guint d
)
674 focus_order
[d
] = g_list_remove(focus_order
[d
], c
);
676 focus_order
[d
] = g_list_prepend(focus_order
[d
], c
);
680 /* insert before first iconic window */
681 for (it
= focus_order
[d
];
682 it
&& !((ObClient
*)it
->data
)->iconic
; it
= it
->next
);
683 focus_order
[d
] = g_list_insert_before(focus_order
[d
], it
, c
);
687 void focus_order_to_top(ObClient
*c
)
692 if (d
== DESKTOP_ALL
) {
693 for (i
= 0; i
< screen_num_desktops
; ++i
)
699 static void to_bottom(ObClient
*c
, guint d
)
701 focus_order
[d
] = g_list_remove(focus_order
[d
], c
);
703 focus_order
[d
] = g_list_append(focus_order
[d
], c
);
707 /* insert before first iconic window */
708 for (it
= focus_order
[d
];
709 it
&& !((ObClient
*)it
->data
)->iconic
; it
= it
->next
);
710 g_list_insert_before(focus_order
[d
], it
, c
);
714 void focus_order_to_bottom(ObClient
*c
)
719 if (d
== DESKTOP_ALL
) {
720 for (i
= 0; i
< screen_num_desktops
; ++i
)