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
;
55 static ObIconPopup
*focus_cycle_popup
;
57 static void focus_cycle_destructor(ObClient
*client
, gpointer data
)
59 /* end cycling if the target disappears */
60 if (focus_cycle_target
== client
)
61 focus_cycle(TRUE
, TRUE
, TRUE
, TRUE
, TRUE
);
64 static Window
createWindow(Window parent
, unsigned long mask
,
65 XSetWindowAttributes
*attrib
)
67 return XCreateWindow(ob_display
, parent
, 0, 0, 1, 1, 0,
68 RrDepth(ob_rr_inst
), InputOutput
,
69 RrVisual(ob_rr_inst
), mask
, attrib
);
73 void focus_startup(gboolean reconfig
)
75 focus_cycle_popup
= icon_popup_new(TRUE
);
78 XSetWindowAttributes attr
;
80 client_add_destructor(focus_cycle_destructor
, NULL
);
82 /* start with nothing focused */
83 focus_set_client(NULL
);
85 focus_indicator
.top
.obwin
.type
= Window_Internal
;
86 focus_indicator
.left
.obwin
.type
= Window_Internal
;
87 focus_indicator
.right
.obwin
.type
= Window_Internal
;
88 focus_indicator
.bottom
.obwin
.type
= Window_Internal
;
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
, &attr
);
95 focus_indicator
.left
.win
=
96 createWindow(RootWindow(ob_display
, ob_screen
),
97 CWOverrideRedirect
| CWBackPixel
, &attr
);
98 focus_indicator
.right
.win
=
99 createWindow(RootWindow(ob_display
, ob_screen
),
100 CWOverrideRedirect
| CWBackPixel
, &attr
);
101 focus_indicator
.bottom
.win
=
102 createWindow(RootWindow(ob_display
, ob_screen
),
103 CWOverrideRedirect
| CWBackPixel
, &attr
);
105 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.top
));
106 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.left
));
107 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.right
));
108 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.bottom
));
110 color_black
= RrColorNew(ob_rr_inst
, 0, 0, 0);
111 color_white
= RrColorNew(ob_rr_inst
, 0xff, 0xff, 0xff);
113 a_focus_indicator
= RrAppearanceNew(ob_rr_inst
, 4);
114 a_focus_indicator
->surface
.grad
= RR_SURFACE_SOLID
;
115 a_focus_indicator
->surface
.relief
= RR_RELIEF_FLAT
;
116 a_focus_indicator
->surface
.primary
= RrColorNew(ob_rr_inst
,
118 a_focus_indicator
->texture
[0].type
= RR_TEXTURE_LINE_ART
;
119 a_focus_indicator
->texture
[0].data
.lineart
.color
= color_white
;
120 a_focus_indicator
->texture
[1].type
= RR_TEXTURE_LINE_ART
;
121 a_focus_indicator
->texture
[1].data
.lineart
.color
= color_white
;
122 a_focus_indicator
->texture
[2].type
= RR_TEXTURE_LINE_ART
;
123 a_focus_indicator
->texture
[2].data
.lineart
.color
= color_white
;
124 a_focus_indicator
->texture
[3].type
= RR_TEXTURE_LINE_ART
;
125 a_focus_indicator
->texture
[3].data
.lineart
.color
= color_white
;
129 void focus_shutdown(gboolean reconfig
)
133 icon_popup_free(focus_cycle_popup
);
136 client_remove_destructor(focus_cycle_destructor
);
138 for (i
= 0; i
< screen_num_desktops
; ++i
)
139 g_list_free(focus_order
[i
]);
142 /* reset focus to root */
143 XSetInputFocus(ob_display
, PointerRoot
, RevertToNone
, event_lasttime
);
145 RrColorFree(color_black
);
146 RrColorFree(color_white
);
148 RrAppearanceFree(a_focus_indicator
);
150 XDestroyWindow(ob_display
, focus_indicator
.top
.win
);
151 XDestroyWindow(ob_display
, focus_indicator
.left
.win
);
152 XDestroyWindow(ob_display
, focus_indicator
.right
.win
);
153 XDestroyWindow(ob_display
, focus_indicator
.bottom
.win
);
157 static void push_to_top(ObClient
*client
)
161 desktop
= client
->desktop
;
162 if (desktop
== DESKTOP_ALL
) desktop
= screen_desktop
;
163 focus_order
[desktop
] = g_list_remove(focus_order
[desktop
], client
);
164 focus_order
[desktop
] = g_list_prepend(focus_order
[desktop
], client
);
167 void focus_set_client(ObClient
*client
)
173 ob_debug("focus_set_client 0x%lx\n", client
? client
->window
: 0);
176 /* uninstall the old colormap, and install the new one */
177 screen_install_colormap(focus_client
, FALSE
);
178 screen_install_colormap(client
, TRUE
);
180 if (client
== NULL
) {
182 ob_debug("actively focusing NONWINDOW\n");
184 /* when nothing will be focused, send focus to the backup target */
185 XSetInputFocus(ob_display
, screen_support_win
, RevertToNone
,
187 XSync(ob_display
, FALSE
);
190 /* in the middle of cycling..? kill it. */
191 if (focus_cycle_target
)
192 focus_cycle(TRUE
, TRUE
, TRUE
, TRUE
, TRUE
);
195 focus_client
= client
;
197 /* move to the top of the list */
201 /* set the NET_ACTIVE_WINDOW hint, but preserve it on shutdown */
202 if (ob_state() != OB_STATE_EXITING
) {
203 active
= client
? client
->window
: None
;
204 PROP_SET32(RootWindow(ob_display
, ob_screen
),
205 net_active_window
, window
, active
);
209 /* finds the first transient that isn't 'skip' and ensure's that client_normal
211 static ObClient
*find_transient_recursive(ObClient
*c
, ObClient
*top
, ObClient
*skip
)
216 for (it
= c
->transients
; it
; it
= it
->next
) {
217 if (it
->data
== top
) return NULL
;
218 ret
= find_transient_recursive(it
->data
, top
, skip
);
219 if (ret
&& ret
!= skip
&& client_normal(ret
)) return ret
;
220 if (it
->data
!= skip
&& client_normal(it
->data
)) return it
->data
;
225 static ObClient
* focus_fallback_transient(ObClient
*top
, ObClient
*old
)
227 ObClient
*target
= find_transient_recursive(top
, top
, old
);
229 /* make sure client_normal is true always */
230 if (!client_normal(top
))
232 target
= top
; /* no transient, keep the top */
234 if (client_can_focus(target
))
240 ObClient
* focus_fallback_target(ObFocusFallbackType type
)
243 ObClient
*old
= NULL
;
244 ObClient
*target
= NULL
;
248 if (type
== OB_FOCUS_FALLBACK_UNFOCUSING
&& old
) {
249 if (old
->transient_for
) {
250 gboolean trans
= FALSE
;
252 if (!config_focus_follow
)
255 if ((target
= client_under_pointer()) &&
256 client_search_transient
257 (client_search_top_transient(target
), old
))
263 /* try for transient relations */
265 if (old
->transient_for
== OB_TRAN_GROUP
) {
266 for (it
= focus_order
[screen_desktop
]; it
; it
= it
->next
) {
269 for (sit
= old
->group
->members
; sit
; sit
= sit
->next
)
270 if (sit
->data
== it
->data
)
272 focus_fallback_transient(sit
->data
, old
)))
277 focus_fallback_transient(old
->transient_for
, old
)))
284 if (config_focus_follow
) {
285 if ((target
= client_under_pointer()))
286 if (client_normal(target
) && client_can_focus(target
))
291 /* try for group relations */
295 for (it
= focus_order
[screen_desktop
]; it
!= NULL
; it
= it
->next
)
296 for (sit
= old
->group
->members
; sit
; sit
= sit
->next
)
297 if (sit
->data
== it
->data
)
298 if (sit
->data
!= old
&& client_normal(sit
->data
))
299 if (client_can_focus(sit
->data
))
304 for (it
= focus_order
[screen_desktop
]; it
!= NULL
; it
= it
->next
)
305 if (type
!= OB_FOCUS_FALLBACK_UNFOCUSING
|| it
->data
!= old
)
306 if (client_normal(it
->data
) && client_can_focus(it
->data
))
312 void focus_fallback(ObFocusFallbackType type
)
316 /* unfocus any focused clients.. they can be focused by Pointer events
317 and such, and then when I try focus them, I won't get a FocusIn event
320 focus_set_client(NULL
);
322 if ((new = focus_fallback_target(type
)))
326 static void popup_cycle(ObClient
*c
, gboolean show
)
329 icon_popup_hide(focus_cycle_popup
);
335 a
= screen_physical_area_monitor(0);
336 icon_popup_position(focus_cycle_popup
, CenterGravity
,
337 a
->x
+ a
->width
/ 2, a
->y
+ a
->height
/ 2);
338 /* icon_popup_size(focus_cycle_popup, a->height/2, a->height/16);
339 icon_popup_show(focus_cycle_popup, c->title,
340 client_icon(c, a->height/16, a->height/16));
342 /* XXX the size and the font extents need to be related on some level
344 icon_popup_size(focus_cycle_popup
, POPUP_WIDTH
, POPUP_HEIGHT
);
346 /* use the transient's parent's title/icon */
347 while (p
->transient_for
&& p
->transient_for
!= OB_TRAN_GROUP
)
348 p
= p
->transient_for
;
353 title
= g_strconcat((c
->iconic
? c
->icon_title
: c
->title
),
355 (p
->iconic
? p
->icon_title
: p
->title
),
358 icon_popup_show(focus_cycle_popup
,
360 (c
->iconic
? c
->icon_title
: c
->title
)),
361 client_icon(p
, 48, 48));
366 void focus_cycle_draw_indicator()
368 if (!focus_cycle_target
) {
369 XUnmapWindow(ob_display
, focus_indicator
.top
.win
);
370 XUnmapWindow(ob_display
, focus_indicator
.left
.win
);
371 XUnmapWindow(ob_display
, focus_indicator
.right
.win
);
372 XUnmapWindow(ob_display
, focus_indicator
.bottom
.win
);
375 if (focus_cycle_target)
376 frame_adjust_focus(focus_cycle_target->frame, FALSE);
377 frame_adjust_focus(focus_cycle_target->frame, TRUE);
382 wt
= wl
= wr
= wb
= MAX(3,
383 ob_rr_theme
->handle_height
+
384 ob_rr_theme
->bwidth
* 2);
386 x
= focus_cycle_target
->frame
->area
.x
;
387 y
= focus_cycle_target
->frame
->area
.y
;
388 w
= focus_cycle_target
->frame
->area
.width
;
391 XMoveResizeWindow(ob_display
, focus_indicator
.top
.win
,
393 a_focus_indicator
->texture
[0].data
.lineart
.x1
= 0;
394 a_focus_indicator
->texture
[0].data
.lineart
.y1
= h
-1;
395 a_focus_indicator
->texture
[0].data
.lineart
.x2
= 0;
396 a_focus_indicator
->texture
[0].data
.lineart
.y2
= 0;
397 a_focus_indicator
->texture
[1].data
.lineart
.x1
= 0;
398 a_focus_indicator
->texture
[1].data
.lineart
.y1
= 0;
399 a_focus_indicator
->texture
[1].data
.lineart
.x2
= w
-1;
400 a_focus_indicator
->texture
[1].data
.lineart
.y2
= 0;
401 a_focus_indicator
->texture
[2].data
.lineart
.x1
= w
-1;
402 a_focus_indicator
->texture
[2].data
.lineart
.y1
= 0;
403 a_focus_indicator
->texture
[2].data
.lineart
.x2
= w
-1;
404 a_focus_indicator
->texture
[2].data
.lineart
.y2
= h
-1;
405 a_focus_indicator
->texture
[3].data
.lineart
.x1
= (wl
-1);
406 a_focus_indicator
->texture
[3].data
.lineart
.y1
= h
-1;
407 a_focus_indicator
->texture
[3].data
.lineart
.x2
= w
- wr
;
408 a_focus_indicator
->texture
[3].data
.lineart
.y2
= h
-1;
409 RrPaint(a_focus_indicator
, focus_indicator
.top
.win
,
412 x
= focus_cycle_target
->frame
->area
.x
;
413 y
= focus_cycle_target
->frame
->area
.y
;
415 h
= focus_cycle_target
->frame
->area
.height
;
417 XMoveResizeWindow(ob_display
, focus_indicator
.left
.win
,
419 a_focus_indicator
->texture
[0].data
.lineart
.x1
= w
-1;
420 a_focus_indicator
->texture
[0].data
.lineart
.y1
= 0;
421 a_focus_indicator
->texture
[0].data
.lineart
.x2
= 0;
422 a_focus_indicator
->texture
[0].data
.lineart
.y2
= 0;
423 a_focus_indicator
->texture
[1].data
.lineart
.x1
= 0;
424 a_focus_indicator
->texture
[1].data
.lineart
.y1
= 0;
425 a_focus_indicator
->texture
[1].data
.lineart
.x2
= 0;
426 a_focus_indicator
->texture
[1].data
.lineart
.y2
= h
-1;
427 a_focus_indicator
->texture
[2].data
.lineart
.x1
= 0;
428 a_focus_indicator
->texture
[2].data
.lineart
.y1
= h
-1;
429 a_focus_indicator
->texture
[2].data
.lineart
.x2
= w
-1;
430 a_focus_indicator
->texture
[2].data
.lineart
.y2
= h
-1;
431 a_focus_indicator
->texture
[3].data
.lineart
.x1
= w
-1;
432 a_focus_indicator
->texture
[3].data
.lineart
.y1
= wt
-1;
433 a_focus_indicator
->texture
[3].data
.lineart
.x2
= w
-1;
434 a_focus_indicator
->texture
[3].data
.lineart
.y2
= h
- wb
;
435 RrPaint(a_focus_indicator
, focus_indicator
.left
.win
,
438 x
= focus_cycle_target
->frame
->area
.x
+
439 focus_cycle_target
->frame
->area
.width
- wr
;
440 y
= focus_cycle_target
->frame
->area
.y
;
442 h
= focus_cycle_target
->frame
->area
.height
;
444 XMoveResizeWindow(ob_display
, focus_indicator
.right
.win
,
446 a_focus_indicator
->texture
[0].data
.lineart
.x1
= 0;
447 a_focus_indicator
->texture
[0].data
.lineart
.y1
= 0;
448 a_focus_indicator
->texture
[0].data
.lineart
.x2
= w
-1;
449 a_focus_indicator
->texture
[0].data
.lineart
.y2
= 0;
450 a_focus_indicator
->texture
[1].data
.lineart
.x1
= w
-1;
451 a_focus_indicator
->texture
[1].data
.lineart
.y1
= 0;
452 a_focus_indicator
->texture
[1].data
.lineart
.x2
= w
-1;
453 a_focus_indicator
->texture
[1].data
.lineart
.y2
= h
-1;
454 a_focus_indicator
->texture
[2].data
.lineart
.x1
= w
-1;
455 a_focus_indicator
->texture
[2].data
.lineart
.y1
= h
-1;
456 a_focus_indicator
->texture
[2].data
.lineart
.x2
= 0;
457 a_focus_indicator
->texture
[2].data
.lineart
.y2
= h
-1;
458 a_focus_indicator
->texture
[3].data
.lineart
.x1
= 0;
459 a_focus_indicator
->texture
[3].data
.lineart
.y1
= wt
-1;
460 a_focus_indicator
->texture
[3].data
.lineart
.x2
= 0;
461 a_focus_indicator
->texture
[3].data
.lineart
.y2
= h
- wb
;
462 RrPaint(a_focus_indicator
, focus_indicator
.right
.win
,
465 x
= focus_cycle_target
->frame
->area
.x
;
466 y
= focus_cycle_target
->frame
->area
.y
+
467 focus_cycle_target
->frame
->area
.height
- wb
;
468 w
= focus_cycle_target
->frame
->area
.width
;
471 XMoveResizeWindow(ob_display
, focus_indicator
.bottom
.win
,
473 a_focus_indicator
->texture
[0].data
.lineart
.x1
= 0;
474 a_focus_indicator
->texture
[0].data
.lineart
.y1
= 0;
475 a_focus_indicator
->texture
[0].data
.lineart
.x2
= 0;
476 a_focus_indicator
->texture
[0].data
.lineart
.y2
= h
-1;
477 a_focus_indicator
->texture
[1].data
.lineart
.x1
= 0;
478 a_focus_indicator
->texture
[1].data
.lineart
.y1
= h
-1;
479 a_focus_indicator
->texture
[1].data
.lineart
.x2
= w
-1;
480 a_focus_indicator
->texture
[1].data
.lineart
.y2
= h
-1;
481 a_focus_indicator
->texture
[2].data
.lineart
.x1
= w
-1;
482 a_focus_indicator
->texture
[2].data
.lineart
.y1
= h
-1;
483 a_focus_indicator
->texture
[2].data
.lineart
.x2
= w
-1;
484 a_focus_indicator
->texture
[2].data
.lineart
.y2
= 0;
485 a_focus_indicator
->texture
[3].data
.lineart
.x1
= wl
-1;
486 a_focus_indicator
->texture
[3].data
.lineart
.y1
= 0;
487 a_focus_indicator
->texture
[3].data
.lineart
.x2
= w
- wr
;
488 a_focus_indicator
->texture
[3].data
.lineart
.y2
= 0;
489 RrPaint(a_focus_indicator
, focus_indicator
.bottom
.win
,
492 XMapWindow(ob_display
, focus_indicator
.top
.win
);
493 XMapWindow(ob_display
, focus_indicator
.left
.win
);
494 XMapWindow(ob_display
, focus_indicator
.right
.win
);
495 XMapWindow(ob_display
, focus_indicator
.bottom
.win
);
499 static gboolean
valid_focus_target(ObClient
*ft
)
501 /* we don't use client_can_focus here, because that doesn't let you
502 focus an iconic window, but we want to be able to, so we just check
503 if the focus flags on the window allow it, and its on the current
505 return ((ft
->type
== OB_CLIENT_TYPE_NORMAL
||
506 ft
->type
== OB_CLIENT_TYPE_DIALOG
||
507 (!client_has_group_siblings(ft
) &&
508 (ft
->type
== OB_CLIENT_TYPE_TOOLBAR
||
509 ft
->type
== OB_CLIENT_TYPE_MENU
||
510 ft
->type
== OB_CLIENT_TYPE_UTILITY
))) &&
512 ((ft
->can_focus
|| ft
->focus_notify
) &&
514 (ft
->desktop
== screen_desktop
|| ft
->desktop
== DESKTOP_ALL
)));
517 void focus_cycle(gboolean forward
, gboolean linear
,
518 gboolean dialog
, gboolean done
, gboolean cancel
)
520 static ObClient
*first
= NULL
;
521 static ObClient
*t
= NULL
;
522 static GList
*order
= NULL
;
523 GList
*it
, *start
, *list
;
527 focus_cycle_target
= NULL
;
532 if (!focus_order
[screen_desktop
])
535 if (!first
) first
= focus_client
;
536 if (!focus_cycle_target
) focus_cycle_target
= focus_client
;
538 if (linear
) list
= client_list
;
539 else list
= focus_order
[screen_desktop
];
541 start
= it
= g_list_find(list
, focus_cycle_target
);
542 if (!start
) /* switched desktops or something? */
543 start
= it
= forward
? g_list_last(list
) : g_list_first(list
);
544 if (!start
) goto done_cycle
;
549 if (it
== NULL
) it
= g_list_first(list
);
552 if (it
== NULL
) it
= g_list_last(list
);
555 if (valid_focus_target(ft
)) {
556 if (ft
!= focus_cycle_target
) { /* prevents flicker */
557 focus_cycle_target
= ft
;
558 focus_cycle_draw_indicator();
560 popup_cycle(ft
, dialog
);
563 } while (it
!= start
);
566 if (done
&& focus_cycle_target
)
567 client_activate(focus_cycle_target
, FALSE
);
571 focus_cycle_target
= NULL
;
575 focus_cycle_draw_indicator();
576 popup_cycle(ft
, FALSE
);
581 void focus_directional_cycle(ObDirection dir
,
582 gboolean dialog
, gboolean done
, gboolean cancel
)
584 static ObClient
*first
= NULL
;
588 focus_cycle_target
= NULL
;
593 if (!focus_order
[screen_desktop
])
596 if (!first
) first
= focus_client
;
597 if (!focus_cycle_target
) focus_cycle_target
= focus_client
;
599 if (focus_cycle_target
)
600 ft
= client_find_directional(focus_cycle_target
, dir
);
604 for (it
= focus_order
[screen_desktop
]; it
; it
= g_list_next(it
))
605 if (valid_focus_target(it
->data
))
610 if (ft
!= focus_cycle_target
) {/* prevents flicker */
611 focus_cycle_target
= ft
;
612 focus_cycle_draw_indicator();
615 if (focus_cycle_target
) {
616 popup_cycle(focus_cycle_target
, dialog
);
623 if (done
&& focus_cycle_target
)
624 client_activate(focus_cycle_target
, FALSE
);
627 focus_cycle_target
= NULL
;
629 focus_cycle_draw_indicator();
630 popup_cycle(ft
, FALSE
);
635 void focus_order_add_new(ObClient
*c
)
640 focus_order_to_top(c
);
643 if (d
== DESKTOP_ALL
) {
644 for (i
= 0; i
< screen_num_desktops
; ++i
) {
645 if (focus_order
[i
] && ((ObClient
*)focus_order
[i
]->data
)->iconic
)
646 focus_order
[i
] = g_list_insert(focus_order
[i
], c
, 0);
648 focus_order
[i
] = g_list_insert(focus_order
[i
], c
, 1);
651 if (focus_order
[d
] && ((ObClient
*)focus_order
[d
]->data
)->iconic
)
652 focus_order
[d
] = g_list_insert(focus_order
[d
], c
, 0);
654 focus_order
[d
] = g_list_insert(focus_order
[d
], c
, 1);
658 void focus_order_remove(ObClient
*c
)
663 if (d
== DESKTOP_ALL
) {
664 for (i
= 0; i
< screen_num_desktops
; ++i
)
665 focus_order
[i
] = g_list_remove(focus_order
[i
], c
);
667 focus_order
[d
] = g_list_remove(focus_order
[d
], c
);
670 static void to_top(ObClient
*c
, guint d
)
672 focus_order
[d
] = g_list_remove(focus_order
[d
], c
);
674 focus_order
[d
] = g_list_prepend(focus_order
[d
], c
);
678 /* insert before first iconic window */
679 for (it
= focus_order
[d
];
680 it
&& !((ObClient
*)it
->data
)->iconic
; it
= it
->next
);
681 focus_order
[d
] = g_list_insert_before(focus_order
[d
], it
, c
);
685 void focus_order_to_top(ObClient
*c
)
690 if (d
== DESKTOP_ALL
) {
691 for (i
= 0; i
< screen_num_desktops
; ++i
)
697 static void to_bottom(ObClient
*c
, guint d
)
699 focus_order
[d
] = g_list_remove(focus_order
[d
], c
);
701 focus_order
[d
] = g_list_append(focus_order
[d
], c
);
705 /* insert before first iconic window */
706 for (it
= focus_order
[d
];
707 it
&& !((ObClient
*)it
->data
)->iconic
; it
= it
->next
);
708 g_list_insert_before(focus_order
[d
], it
, c
);
712 void focus_order_to_bottom(ObClient
*c
)
717 if (d
== DESKTOP_ALL
) {
718 for (i
= 0; i
< screen_num_desktops
; ++i
)