1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 focus.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 See the COPYING file for a copy of the GNU General Public License.
24 #include "framerender.h"
34 #include "render/render.h"
40 ObClient
*focus_client
, *focus_hilite
;
41 GList
**focus_order
; /* these lists are created when screen_startup
42 sets the number of desktops */
43 ObClient
*focus_cycle_target
;
49 InternalWindow bottom
;
52 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. CurrentTime is fine, time won't
62 if (focus_cycle_target
== client
)
63 focus_cycle(TRUE
, TRUE
, TRUE
, TRUE
, TRUE
, TRUE
, CurrentTime
);
66 static Window
createWindow(Window parent
, gulong mask
,
67 XSetWindowAttributes
*attrib
)
69 return XCreateWindow(ob_display
, parent
, 0, 0, 1, 1, 0,
70 RrDepth(ob_rr_inst
), InputOutput
,
71 RrVisual(ob_rr_inst
), mask
, attrib
);
75 void focus_startup(gboolean reconfig
)
77 focus_cycle_popup
= icon_popup_new(TRUE
);
80 XSetWindowAttributes attr
;
82 client_add_destructor(focus_cycle_destructor
, NULL
);
84 /* start with nothing focused */
85 focus_set_client(NULL
);
87 focus_indicator
.top
.obwin
.type
= Window_Internal
;
88 focus_indicator
.left
.obwin
.type
= Window_Internal
;
89 focus_indicator
.right
.obwin
.type
= Window_Internal
;
90 focus_indicator
.bottom
.obwin
.type
= Window_Internal
;
92 attr
.override_redirect
= True
;
93 attr
.background_pixel
= BlackPixel(ob_display
, ob_screen
);
94 focus_indicator
.top
.win
=
95 createWindow(RootWindow(ob_display
, ob_screen
),
96 CWOverrideRedirect
| CWBackPixel
, &attr
);
97 focus_indicator
.left
.win
=
98 createWindow(RootWindow(ob_display
, ob_screen
),
99 CWOverrideRedirect
| CWBackPixel
, &attr
);
100 focus_indicator
.right
.win
=
101 createWindow(RootWindow(ob_display
, ob_screen
),
102 CWOverrideRedirect
| CWBackPixel
, &attr
);
103 focus_indicator
.bottom
.win
=
104 createWindow(RootWindow(ob_display
, ob_screen
),
105 CWOverrideRedirect
| CWBackPixel
, &attr
);
107 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.top
));
108 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.left
));
109 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.right
));
110 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator
.bottom
));
112 color_white
= RrColorNew(ob_rr_inst
, 0xff, 0xff, 0xff);
114 a_focus_indicator
= RrAppearanceNew(ob_rr_inst
, 4);
115 a_focus_indicator
->surface
.grad
= RR_SURFACE_SOLID
;
116 a_focus_indicator
->surface
.relief
= RR_RELIEF_FLAT
;
117 a_focus_indicator
->surface
.primary
= RrColorNew(ob_rr_inst
,
119 a_focus_indicator
->texture
[0].type
= RR_TEXTURE_LINE_ART
;
120 a_focus_indicator
->texture
[0].data
.lineart
.color
= color_white
;
121 a_focus_indicator
->texture
[1].type
= RR_TEXTURE_LINE_ART
;
122 a_focus_indicator
->texture
[1].data
.lineart
.color
= color_white
;
123 a_focus_indicator
->texture
[2].type
= RR_TEXTURE_LINE_ART
;
124 a_focus_indicator
->texture
[2].data
.lineart
.color
= color_white
;
125 a_focus_indicator
->texture
[3].type
= RR_TEXTURE_LINE_ART
;
126 a_focus_indicator
->texture
[3].data
.lineart
.color
= color_white
;
130 void focus_shutdown(gboolean reconfig
)
134 icon_popup_free(focus_cycle_popup
);
137 client_remove_destructor(focus_cycle_destructor
);
139 for (i
= 0; i
< screen_num_desktops
; ++i
)
140 g_list_free(focus_order
[i
]);
143 /* reset focus to root */
144 XSetInputFocus(ob_display
, PointerRoot
, RevertToNone
, CurrentTime
);
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. CurrentTime is fine, time won't
193 if (focus_cycle_target
)
194 focus_cycle(TRUE
, TRUE
, TRUE
, TRUE
, TRUE
, TRUE
, CurrentTime
);
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
);
209 /* remove hiliting from the window when it gets focused */
211 client_hilite(client
, FALSE
);
215 /* finds the first transient that isn't 'skip' and ensure's that client_normal
217 static ObClient
*find_transient_recursive(ObClient
*c
, ObClient
*top
,
223 for (it
= c
->transients
; it
; it
= g_slist_next(it
)) {
224 if (it
->data
== top
) return NULL
;
225 ret
= find_transient_recursive(it
->data
, top
, skip
);
226 if (ret
&& ret
!= skip
&& client_normal(ret
) &&
227 client_can_focus(ret
) && client_validate(ret
))
229 if (it
->data
!= skip
&& client_normal(it
->data
) &&
230 client_can_focus(it
->data
) && client_validate(it
->data
))
236 static ObClient
* focus_fallback_transient(ObClient
*top
, ObClient
*old
)
238 ObClient
*target
= find_transient_recursive(top
, top
, old
);
240 /* make sure client_normal is true always */
241 if (!client_normal(top
))
243 target
= top
; /* no transient, keep the top */
245 if (client_can_focus(target
))
251 ObClient
* focus_fallback_target(gboolean allow_refocus
)
255 ObClient
*target
= NULL
;
259 if (!allow_refocus
&& old
&& old
->transient_for
) {
260 gboolean trans
= FALSE
;
262 if (!config_focus_follow
|| config_focus_last
)
264 else if ((target
= client_under_pointer()) &&
265 client_search_transient
266 (client_search_top_parent(target
), old
))
269 /* try for transient relations */
271 if (old
->transient_for
== OB_TRAN_GROUP
) {
272 for (it
= focus_order
[screen_desktop
]; it
;
273 it
= g_list_next(it
))
277 for (sit
= old
->group
->members
; sit
;
278 sit
= g_slist_next(sit
))
280 if (sit
->data
== it
->data
)
282 focus_fallback_transient(sit
->data
, old
)))
284 ob_debug("found in transient #1\n");
291 focus_fallback_transient(old
->transient_for
, old
)))
293 ob_debug("found in transient #2\n");
300 ob_debug("trying pointer stuff\n");
301 if (config_focus_follow
&& !config_focus_last
)
303 if ((target
= client_under_pointer()))
304 if (allow_refocus
|| target
!= old
)
305 if (client_normal(target
) && client_can_focus(target
) &&
306 client_validate(target
)) {
307 ob_debug("found in pointer stuff\n");
313 /* try for group relations */
317 for (it
= focus_order
[screen_desktop
]; it
; it
= g_list_next(it
))
318 for (sit
= old
->group
->members
; sit
; sit
= g_slist_next(sit
))
319 if (sit
->data
== it
->data
)
320 if (sit
->data
!= old
&& client_normal(sit
->data
))
321 if (client_can_focus(sit
->data
))
326 ob_debug("trying the focus order\n");
327 for (it
= focus_order
[screen_desktop
]; it
; it
= g_list_next(it
))
328 if (allow_refocus
|| it
->data
!= old
)
329 if (client_normal(it
->data
) && client_can_focus(it
->data
) &&
330 client_validate(it
->data
))
332 ob_debug("found in focus order\n");
336 /* XXX fallback to the "desktop window" if one exists ?
337 could store it while going through all the windows in the loop right
344 void focus_fallback(gboolean allow_refocus
)
348 /* unfocus any focused clients.. they can be focused by Pointer events
349 and such, and then when I try focus them, I won't get a FocusIn event
352 focus_set_client(NULL
);
354 if ((new = focus_fallback_target(allow_refocus
)))
358 static void popup_cycle(ObClient
*c
, gboolean show
)
361 icon_popup_hide(focus_cycle_popup
);
367 a
= screen_physical_area_monitor(0);
368 icon_popup_position(focus_cycle_popup
, CenterGravity
,
369 a
->x
+ a
->width
/ 2, a
->y
+ a
->height
/ 2);
370 /* icon_popup_size(focus_cycle_popup, a->height/2, a->height/16);
371 icon_popup_show(focus_cycle_popup, c->title,
372 client_icon(c, a->height/16, a->height/16));
374 /* XXX the size and the font extents need to be related on some level
376 icon_popup_size(focus_cycle_popup
, POPUP_WIDTH
, POPUP_HEIGHT
);
378 /* use the transient's parent's title/icon */
379 while (p
->transient_for
&& p
->transient_for
!= OB_TRAN_GROUP
)
380 p
= p
->transient_for
;
382 if (p
!= c
&& !strcmp("", (c
->iconic
? c
->icon_title
: c
->title
)))
383 title
= g_strdup(p
->iconic
? p
->icon_title
: p
->title
);
384 /*title = g_strconcat((c->iconic ? c->icon_title : c->title),
386 (p->iconic ? p->icon_title : p->title),
389 icon_popup_show(focus_cycle_popup
,
391 (c
->iconic
? c
->icon_title
: c
->title
)),
392 client_icon(p
, 48, 48));
397 void focus_cycle_draw_indicator()
399 if (!focus_cycle_target
) {
400 XUnmapWindow(ob_display
, focus_indicator
.top
.win
);
401 XUnmapWindow(ob_display
, focus_indicator
.left
.win
);
402 XUnmapWindow(ob_display
, focus_indicator
.right
.win
);
403 XUnmapWindow(ob_display
, focus_indicator
.bottom
.win
);
406 if (focus_cycle_target)
407 frame_adjust_focus(focus_cycle_target->frame, FALSE);
408 frame_adjust_focus(focus_cycle_target->frame, TRUE);
413 wt
= wl
= wr
= wb
= MAX(3,
414 MAX(1, MAX(ob_rr_theme
->paddingx
,
415 ob_rr_theme
->paddingy
)) * 2 +
416 ob_rr_theme
->fbwidth
* 2);
418 x
= focus_cycle_target
->frame
->area
.x
;
419 y
= focus_cycle_target
->frame
->area
.y
;
420 w
= focus_cycle_target
->frame
->area
.width
;
423 XMoveResizeWindow(ob_display
, focus_indicator
.top
.win
,
425 a_focus_indicator
->texture
[0].data
.lineart
.x1
= 0;
426 a_focus_indicator
->texture
[0].data
.lineart
.y1
= h
-1;
427 a_focus_indicator
->texture
[0].data
.lineart
.x2
= 0;
428 a_focus_indicator
->texture
[0].data
.lineart
.y2
= 0;
429 a_focus_indicator
->texture
[1].data
.lineart
.x1
= 0;
430 a_focus_indicator
->texture
[1].data
.lineart
.y1
= 0;
431 a_focus_indicator
->texture
[1].data
.lineart
.x2
= w
-1;
432 a_focus_indicator
->texture
[1].data
.lineart
.y2
= 0;
433 a_focus_indicator
->texture
[2].data
.lineart
.x1
= w
-1;
434 a_focus_indicator
->texture
[2].data
.lineart
.y1
= 0;
435 a_focus_indicator
->texture
[2].data
.lineart
.x2
= w
-1;
436 a_focus_indicator
->texture
[2].data
.lineart
.y2
= h
-1;
437 a_focus_indicator
->texture
[3].data
.lineart
.x1
= (wl
-1);
438 a_focus_indicator
->texture
[3].data
.lineart
.y1
= h
-1;
439 a_focus_indicator
->texture
[3].data
.lineart
.x2
= w
- wr
;
440 a_focus_indicator
->texture
[3].data
.lineart
.y2
= h
-1;
441 RrPaint(a_focus_indicator
, focus_indicator
.top
.win
,
444 x
= focus_cycle_target
->frame
->area
.x
;
445 y
= focus_cycle_target
->frame
->area
.y
;
447 h
= focus_cycle_target
->frame
->area
.height
;
449 XMoveResizeWindow(ob_display
, focus_indicator
.left
.win
,
451 a_focus_indicator
->texture
[0].data
.lineart
.x1
= w
-1;
452 a_focus_indicator
->texture
[0].data
.lineart
.y1
= 0;
453 a_focus_indicator
->texture
[0].data
.lineart
.x2
= 0;
454 a_focus_indicator
->texture
[0].data
.lineart
.y2
= 0;
455 a_focus_indicator
->texture
[1].data
.lineart
.x1
= 0;
456 a_focus_indicator
->texture
[1].data
.lineart
.y1
= 0;
457 a_focus_indicator
->texture
[1].data
.lineart
.x2
= 0;
458 a_focus_indicator
->texture
[1].data
.lineart
.y2
= h
-1;
459 a_focus_indicator
->texture
[2].data
.lineart
.x1
= 0;
460 a_focus_indicator
->texture
[2].data
.lineart
.y1
= h
-1;
461 a_focus_indicator
->texture
[2].data
.lineart
.x2
= w
-1;
462 a_focus_indicator
->texture
[2].data
.lineart
.y2
= h
-1;
463 a_focus_indicator
->texture
[3].data
.lineart
.x1
= w
-1;
464 a_focus_indicator
->texture
[3].data
.lineart
.y1
= wt
-1;
465 a_focus_indicator
->texture
[3].data
.lineart
.x2
= w
-1;
466 a_focus_indicator
->texture
[3].data
.lineart
.y2
= h
- wb
;
467 RrPaint(a_focus_indicator
, focus_indicator
.left
.win
,
470 x
= focus_cycle_target
->frame
->area
.x
+
471 focus_cycle_target
->frame
->area
.width
- wr
;
472 y
= focus_cycle_target
->frame
->area
.y
;
474 h
= focus_cycle_target
->frame
->area
.height
;
476 XMoveResizeWindow(ob_display
, focus_indicator
.right
.win
,
478 a_focus_indicator
->texture
[0].data
.lineart
.x1
= 0;
479 a_focus_indicator
->texture
[0].data
.lineart
.y1
= 0;
480 a_focus_indicator
->texture
[0].data
.lineart
.x2
= w
-1;
481 a_focus_indicator
->texture
[0].data
.lineart
.y2
= 0;
482 a_focus_indicator
->texture
[1].data
.lineart
.x1
= w
-1;
483 a_focus_indicator
->texture
[1].data
.lineart
.y1
= 0;
484 a_focus_indicator
->texture
[1].data
.lineart
.x2
= w
-1;
485 a_focus_indicator
->texture
[1].data
.lineart
.y2
= h
-1;
486 a_focus_indicator
->texture
[2].data
.lineart
.x1
= w
-1;
487 a_focus_indicator
->texture
[2].data
.lineart
.y1
= h
-1;
488 a_focus_indicator
->texture
[2].data
.lineart
.x2
= 0;
489 a_focus_indicator
->texture
[2].data
.lineart
.y2
= h
-1;
490 a_focus_indicator
->texture
[3].data
.lineart
.x1
= 0;
491 a_focus_indicator
->texture
[3].data
.lineart
.y1
= wt
-1;
492 a_focus_indicator
->texture
[3].data
.lineart
.x2
= 0;
493 a_focus_indicator
->texture
[3].data
.lineart
.y2
= h
- wb
;
494 RrPaint(a_focus_indicator
, focus_indicator
.right
.win
,
497 x
= focus_cycle_target
->frame
->area
.x
;
498 y
= focus_cycle_target
->frame
->area
.y
+
499 focus_cycle_target
->frame
->area
.height
- wb
;
500 w
= focus_cycle_target
->frame
->area
.width
;
503 XMoveResizeWindow(ob_display
, focus_indicator
.bottom
.win
,
505 a_focus_indicator
->texture
[0].data
.lineart
.x1
= 0;
506 a_focus_indicator
->texture
[0].data
.lineart
.y1
= 0;
507 a_focus_indicator
->texture
[0].data
.lineart
.x2
= 0;
508 a_focus_indicator
->texture
[0].data
.lineart
.y2
= h
-1;
509 a_focus_indicator
->texture
[1].data
.lineart
.x1
= 0;
510 a_focus_indicator
->texture
[1].data
.lineart
.y1
= h
-1;
511 a_focus_indicator
->texture
[1].data
.lineart
.x2
= w
-1;
512 a_focus_indicator
->texture
[1].data
.lineart
.y2
= h
-1;
513 a_focus_indicator
->texture
[2].data
.lineart
.x1
= w
-1;
514 a_focus_indicator
->texture
[2].data
.lineart
.y1
= h
-1;
515 a_focus_indicator
->texture
[2].data
.lineart
.x2
= w
-1;
516 a_focus_indicator
->texture
[2].data
.lineart
.y2
= 0;
517 a_focus_indicator
->texture
[3].data
.lineart
.x1
= wl
-1;
518 a_focus_indicator
->texture
[3].data
.lineart
.y1
= 0;
519 a_focus_indicator
->texture
[3].data
.lineart
.x2
= w
- wr
;
520 a_focus_indicator
->texture
[3].data
.lineart
.y2
= 0;
521 RrPaint(a_focus_indicator
, focus_indicator
.bottom
.win
,
524 XMapWindow(ob_display
, focus_indicator
.top
.win
);
525 XMapWindow(ob_display
, focus_indicator
.left
.win
);
526 XMapWindow(ob_display
, focus_indicator
.right
.win
);
527 XMapWindow(ob_display
, focus_indicator
.bottom
.win
);
531 static gboolean
valid_focus_target(ObClient
*ft
)
533 /* we don't use client_can_focus here, because that doesn't let you
534 focus an iconic window, but we want to be able to, so we just check
535 if the focus flags on the window allow it, and its on the current
537 if ((ft
->type
== OB_CLIENT_TYPE_NORMAL
||
538 ft
->type
== OB_CLIENT_TYPE_DIALOG
||
539 (!client_has_group_siblings(ft
) &&
540 (ft
->type
== OB_CLIENT_TYPE_TOOLBAR
||
541 ft
->type
== OB_CLIENT_TYPE_MENU
||
542 ft
->type
== OB_CLIENT_TYPE_UTILITY
))) &&
543 ((ft
->can_focus
|| ft
->focus_notify
) &&
545 (ft
->desktop
== screen_desktop
|| ft
->desktop
== DESKTOP_ALL
)) &&
546 ft
== client_focus_target(ft
))
552 for (it = ft->transients; it; it = g_slist_next(it)) {
553 ObClient *c = it->data;
555 if (c->frame->visible)
565 void focus_cycle(gboolean forward
, gboolean linear
, gboolean interactive
,
566 gboolean dialog
, gboolean done
, gboolean cancel
, Time time
)
568 static ObClient
*first
= NULL
;
569 static ObClient
*t
= NULL
;
570 static GList
*order
= NULL
;
571 GList
*it
, *start
, *list
;
576 focus_cycle_target
= NULL
;
581 if (!focus_order
[screen_desktop
])
584 if (!first
) first
= focus_client
;
586 if (linear
) list
= client_list
;
587 else list
= focus_order
[screen_desktop
];
589 if (!focus_order
[screen_desktop
])
593 if (!focus_cycle_target
) focus_cycle_target
= focus_client
;
595 start
= it
= g_list_find(list
, focus_cycle_target
);
596 if (!start
) /* switched desktops or something? */
597 start
= it
= forward
? g_list_last(list
) : g_list_first(list
);
598 if (!start
) goto done_cycle
;
603 if (it
== NULL
) it
= g_list_first(list
);
606 if (it
== NULL
) it
= g_list_last(list
);
609 if (valid_focus_target(ft
)) {
611 if (ft
!= focus_cycle_target
) { /* prevents flicker */
612 focus_cycle_target
= ft
;
613 focus_cycle_draw_indicator();
615 popup_cycle(ft
, dialog
);
617 } else if (ft
!= focus_cycle_target
) {
618 focus_cycle_target
= ft
;
623 } while (it
!= start
);
626 if (done
&& focus_cycle_target
)
627 client_activate(focus_cycle_target
, FALSE
, TRUE
, time
);
631 focus_cycle_target
= NULL
;
636 focus_cycle_draw_indicator();
637 popup_cycle(ft
, FALSE
);
643 void focus_directional_cycle(ObDirection dir
, gboolean interactive
,
644 gboolean dialog
, gboolean done
, gboolean cancel
,
647 static ObClient
*first
= NULL
;
654 focus_cycle_target
= NULL
;
659 if (!focus_order
[screen_desktop
])
662 if (!first
) first
= focus_client
;
663 if (!focus_cycle_target
) focus_cycle_target
= focus_client
;
665 if (focus_cycle_target
)
666 ft
= client_find_directional(focus_cycle_target
, dir
);
670 for (it
= focus_order
[screen_desktop
]; it
; it
= g_list_next(it
))
671 if (valid_focus_target(it
->data
))
676 if (ft
!= focus_cycle_target
) {/* prevents flicker */
677 focus_cycle_target
= ft
;
678 focus_cycle_draw_indicator();
681 if (focus_cycle_target
) {
682 popup_cycle(focus_cycle_target
, dialog
);
689 if (done
&& focus_cycle_target
)
690 client_activate(focus_cycle_target
, FALSE
, TRUE
, time
);
693 focus_cycle_target
= NULL
;
695 focus_cycle_draw_indicator();
696 popup_cycle(ft
, FALSE
);
701 void focus_order_add_new(ObClient
*c
)
706 focus_order_to_top(c
);
709 if (d
== DESKTOP_ALL
) {
710 for (i
= 0; i
< screen_num_desktops
; ++i
) {
711 g_assert(!g_list_find(focus_order
[i
], c
));
712 if (focus_order
[i
] && ((ObClient
*)focus_order
[i
]->data
)->iconic
)
713 focus_order
[i
] = g_list_insert(focus_order
[i
], c
, 0);
715 focus_order
[i
] = g_list_insert(focus_order
[i
], c
, 1);
718 g_assert(!g_list_find(focus_order
[d
], c
));
719 if (focus_order
[d
] && ((ObClient
*)focus_order
[d
]->data
)->iconic
)
720 focus_order
[d
] = g_list_insert(focus_order
[d
], c
, 0);
722 focus_order
[d
] = g_list_insert(focus_order
[d
], c
, 1);
727 void focus_order_remove(ObClient
*c
)
732 if (d
== DESKTOP_ALL
) {
733 for (i
= 0; i
< screen_num_desktops
; ++i
)
734 focus_order
[i
] = g_list_remove(focus_order
[i
], c
);
736 focus_order
[d
] = g_list_remove(focus_order
[d
], c
);
739 static void to_top(ObClient
*c
, guint d
)
741 focus_order
[d
] = g_list_remove(focus_order
[d
], c
);
743 focus_order
[d
] = g_list_prepend(focus_order
[d
], c
);
747 /* insert before first iconic window */
748 for (it
= focus_order
[d
];
749 it
&& !((ObClient
*)it
->data
)->iconic
; it
= g_list_next(it
));
750 focus_order
[d
] = g_list_insert_before(focus_order
[d
], it
, c
);
754 void focus_order_to_top(ObClient
*c
)
759 if (d
== DESKTOP_ALL
) {
760 for (i
= 0; i
< screen_num_desktops
; ++i
)
766 static void to_bottom(ObClient
*c
, guint d
)
768 focus_order
[d
] = g_list_remove(focus_order
[d
], c
);
770 focus_order
[d
] = g_list_append(focus_order
[d
], c
);
774 /* insert before first iconic window */
775 for (it
= focus_order
[d
];
776 it
&& !((ObClient
*)it
->data
)->iconic
; it
= g_list_next(it
));
777 focus_order
[d
] = g_list_insert_before(focus_order
[d
], it
, c
);
781 void focus_order_to_bottom(ObClient
*c
)
786 if (d
== DESKTOP_ALL
) {
787 for (i
= 0; i
< screen_num_desktops
; ++i
)