]> Dogcows Code - chaz/openbox/blob - openbox/focus.c
color_black was unused
[chaz/openbox] / openbox / focus.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3 focus.c for the Openbox window manager
4 Copyright (c) 2003 Ben Jansens
5
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.
10
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.
15
16 See the COPYING file for a copy of the GNU General Public License.
17 */
18
19 #include "debug.h"
20 #include "event.h"
21 #include "openbox.h"
22 #include "grab.h"
23 #include "framerender.h"
24 #include "client.h"
25 #include "config.h"
26 #include "frame.h"
27 #include "screen.h"
28 #include "group.h"
29 #include "prop.h"
30 #include "focus.h"
31 #include "stacking.h"
32 #include "popup.h"
33 #include "render/render.h"
34
35 #include <X11/Xlib.h>
36 #include <glib.h>
37 #include <assert.h>
38
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;
43
44 struct {
45 InternalWindow top;
46 InternalWindow left;
47 InternalWindow right;
48 InternalWindow bottom;
49 } focus_indicator;
50
51 RrAppearance *a_focus_indicator;
52 RrColor *color_white;
53
54 static ObIconPopup *focus_cycle_popup;
55
56 static void focus_cycle_destructor(ObClient *client, gpointer data)
57 {
58 /* end cycling if the target disappears */
59 if (focus_cycle_target == client)
60 focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE);
61 }
62
63 static Window createWindow(Window parent, unsigned long mask,
64 XSetWindowAttributes *attrib)
65 {
66 return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
67 RrDepth(ob_rr_inst), InputOutput,
68 RrVisual(ob_rr_inst), mask, attrib);
69
70 }
71
72 void focus_startup(gboolean reconfig)
73 {
74 focus_cycle_popup = icon_popup_new(TRUE);
75
76 if (!reconfig) {
77 XSetWindowAttributes attr;
78
79 client_add_destructor(focus_cycle_destructor, NULL);
80
81 /* start with nothing focused */
82 focus_set_client(NULL);
83
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;
88
89 attr.override_redirect = True;
90 attr.background_pixel = BlackPixel(ob_display, ob_screen);
91 focus_indicator.top.win =
92 createWindow(RootWindow(ob_display, ob_screen),
93 CWOverrideRedirect | CWBackPixel, &attr);
94 focus_indicator.left.win =
95 createWindow(RootWindow(ob_display, ob_screen),
96 CWOverrideRedirect | CWBackPixel, &attr);
97 focus_indicator.right.win =
98 createWindow(RootWindow(ob_display, ob_screen),
99 CWOverrideRedirect | CWBackPixel, &attr);
100 focus_indicator.bottom.win =
101 createWindow(RootWindow(ob_display, ob_screen),
102 CWOverrideRedirect | CWBackPixel, &attr);
103
104 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.top));
105 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.left));
106 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.right));
107 stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.bottom));
108
109 color_white = RrColorNew(ob_rr_inst, 0xff, 0xff, 0xff);
110
111 a_focus_indicator = RrAppearanceNew(ob_rr_inst, 4);
112 a_focus_indicator->surface.grad = RR_SURFACE_SOLID;
113 a_focus_indicator->surface.relief = RR_RELIEF_FLAT;
114 a_focus_indicator->surface.primary = RrColorNew(ob_rr_inst,
115 0, 0, 0);
116 a_focus_indicator->texture[0].type = RR_TEXTURE_LINE_ART;
117 a_focus_indicator->texture[0].data.lineart.color = color_white;
118 a_focus_indicator->texture[1].type = RR_TEXTURE_LINE_ART;
119 a_focus_indicator->texture[1].data.lineart.color = color_white;
120 a_focus_indicator->texture[2].type = RR_TEXTURE_LINE_ART;
121 a_focus_indicator->texture[2].data.lineart.color = color_white;
122 a_focus_indicator->texture[3].type = RR_TEXTURE_LINE_ART;
123 a_focus_indicator->texture[3].data.lineart.color = color_white;
124 }
125 }
126
127 void focus_shutdown(gboolean reconfig)
128 {
129 guint i;
130
131 icon_popup_free(focus_cycle_popup);
132
133 if (!reconfig) {
134 client_remove_destructor(focus_cycle_destructor);
135
136 for (i = 0; i < screen_num_desktops; ++i)
137 g_list_free(focus_order[i]);
138 g_free(focus_order);
139
140 /* reset focus to root */
141 XSetInputFocus(ob_display, PointerRoot, RevertToNone, event_lasttime);
142
143 RrColorFree(color_white);
144
145 RrAppearanceFree(a_focus_indicator);
146
147 XDestroyWindow(ob_display, focus_indicator.top.win);
148 XDestroyWindow(ob_display, focus_indicator.left.win);
149 XDestroyWindow(ob_display, focus_indicator.right.win);
150 XDestroyWindow(ob_display, focus_indicator.bottom.win);
151 }
152 }
153
154 static void push_to_top(ObClient *client)
155 {
156 guint desktop;
157
158 desktop = client->desktop;
159 if (desktop == DESKTOP_ALL) desktop = screen_desktop;
160 focus_order[desktop] = g_list_remove(focus_order[desktop], client);
161 focus_order[desktop] = g_list_prepend(focus_order[desktop], client);
162 }
163
164 void focus_set_client(ObClient *client)
165 {
166 Window active;
167 ObClient *old;
168
169 #ifdef DEBUG_FOCUS
170 ob_debug("focus_set_client 0x%lx\n", client ? client->window : 0);
171 #endif
172
173 /* uninstall the old colormap, and install the new one */
174 screen_install_colormap(focus_client, FALSE);
175 screen_install_colormap(client, TRUE);
176
177 if (client == NULL) {
178 #ifdef DEBUG_FOCUS
179 ob_debug("actively focusing NONWINDOW\n");
180 #endif
181 /* when nothing will be focused, send focus to the backup target */
182 XSetInputFocus(ob_display, screen_support_win, RevertToNone,
183 event_lasttime);
184 XSync(ob_display, FALSE);
185 }
186
187 /* in the middle of cycling..? kill it. */
188 if (focus_cycle_target)
189 focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE);
190
191 old = focus_client;
192 focus_client = client;
193
194 /* move to the top of the list */
195 if (client != NULL)
196 push_to_top(client);
197
198 /* set the NET_ACTIVE_WINDOW hint, but preserve it on shutdown */
199 if (ob_state() != OB_STATE_EXITING) {
200 active = client ? client->window : None;
201 PROP_SET32(RootWindow(ob_display, ob_screen),
202 net_active_window, window, active);
203 }
204 }
205
206 /* finds the first transient that isn't 'skip' and ensure's that client_normal
207 is true for it */
208 static ObClient *find_transient_recursive(ObClient *c, ObClient *top, ObClient *skip)
209 {
210 GSList *it;
211 ObClient *ret;
212
213 for (it = c->transients; it; it = it->next) {
214 if (it->data == top) return NULL;
215 ret = find_transient_recursive(it->data, top, skip);
216 if (ret && ret != skip && client_normal(ret)) return ret;
217 if (it->data != skip && client_normal(it->data)) return it->data;
218 }
219 return NULL;
220 }
221
222 static ObClient* focus_fallback_transient(ObClient *top, ObClient *old)
223 {
224 ObClient *target = find_transient_recursive(top, top, old);
225 if (!target) {
226 /* make sure client_normal is true always */
227 if (!client_normal(top))
228 return NULL;
229 target = top; /* no transient, keep the top */
230 }
231 if (client_can_focus(target))
232 return target;
233 else
234 return NULL;
235 }
236
237 ObClient* focus_fallback_target(ObFocusFallbackType type)
238 {
239 GList *it;
240 ObClient *old = NULL;
241 ObClient *target = NULL;
242
243 old = focus_client;
244
245 if (type == OB_FOCUS_FALLBACK_UNFOCUSING && old) {
246 if (old->transient_for) {
247 gboolean trans = FALSE;
248
249 if (!config_focus_follow)
250 trans = TRUE;
251 else {
252 if ((target = client_under_pointer()) &&
253 client_search_transient
254 (client_search_top_transient(target), old))
255 {
256 trans = TRUE;
257 }
258 }
259
260 /* try for transient relations */
261 if (trans) {
262 if (old->transient_for == OB_TRAN_GROUP) {
263 for (it = focus_order[screen_desktop]; it; it = it->next) {
264 GSList *sit;
265
266 for (sit = old->group->members; sit; sit = sit->next)
267 if (sit->data == it->data)
268 if ((target =
269 focus_fallback_transient(sit->data, old)))
270 return target;
271 }
272 } else {
273 if ((target =
274 focus_fallback_transient(old->transient_for, old)))
275 return target;
276 }
277 }
278 }
279 }
280
281 if (config_focus_follow) {
282 if ((target = client_under_pointer()))
283 if (client_normal(target) && client_can_focus(target))
284 return target;
285 }
286
287 #if 0
288 /* try for group relations */
289 if (old->group) {
290 GSList *sit;
291
292 for (it = focus_order[screen_desktop]; it != NULL; it = it->next)
293 for (sit = old->group->members; sit; sit = sit->next)
294 if (sit->data == it->data)
295 if (sit->data != old && client_normal(sit->data))
296 if (client_can_focus(sit->data))
297 return sit->data;
298 }
299 #endif
300
301 for (it = focus_order[screen_desktop]; it != NULL; it = it->next)
302 if (type != OB_FOCUS_FALLBACK_UNFOCUSING || it->data != old)
303 if (client_normal(it->data) && client_can_focus(it->data))
304 return it->data;
305
306 return NULL;
307 }
308
309 void focus_fallback(ObFocusFallbackType type)
310 {
311 ObClient *new;
312
313 /* unfocus any focused clients.. they can be focused by Pointer events
314 and such, and then when I try focus them, I won't get a FocusIn event
315 at all for them.
316 */
317 focus_set_client(NULL);
318
319 if ((new = focus_fallback_target(type)))
320 client_focus(new);
321 }
322
323 static void popup_cycle(ObClient *c, gboolean show)
324 {
325 if (!show) {
326 icon_popup_hide(focus_cycle_popup);
327 } else {
328 Rect *a;
329 ObClient *p = c;
330 char *title;
331
332 a = screen_physical_area_monitor(0);
333 icon_popup_position(focus_cycle_popup, CenterGravity,
334 a->x + a->width / 2, a->y + a->height / 2);
335 /* icon_popup_size(focus_cycle_popup, a->height/2, a->height/16);
336 icon_popup_show(focus_cycle_popup, c->title,
337 client_icon(c, a->height/16, a->height/16));
338 */
339 /* XXX the size and the font extents need to be related on some level
340 */
341 icon_popup_size(focus_cycle_popup, POPUP_WIDTH, POPUP_HEIGHT);
342
343 /* use the transient's parent's title/icon */
344 while (p->transient_for && p->transient_for != OB_TRAN_GROUP)
345 p = p->transient_for;
346
347 if (p == c)
348 title = NULL;
349 else
350 title = g_strconcat((c->iconic ? c->icon_title : c->title),
351 " - ",
352 (p->iconic ? p->icon_title : p->title),
353 NULL);
354
355 icon_popup_show(focus_cycle_popup,
356 (title ? title :
357 (c->iconic ? c->icon_title : c->title)),
358 client_icon(p, 48, 48));
359 g_free(title);
360 }
361 }
362
363 void focus_cycle_draw_indicator()
364 {
365 if (!focus_cycle_target) {
366 XUnmapWindow(ob_display, focus_indicator.top.win);
367 XUnmapWindow(ob_display, focus_indicator.left.win);
368 XUnmapWindow(ob_display, focus_indicator.right.win);
369 XUnmapWindow(ob_display, focus_indicator.bottom.win);
370 } else {
371 /*
372 if (focus_cycle_target)
373 frame_adjust_focus(focus_cycle_target->frame, FALSE);
374 frame_adjust_focus(focus_cycle_target->frame, TRUE);
375 */
376 int x, y, w, h;
377 int wt, wl, wr, wb;
378
379 wt = wl = wr = wb = MAX(3,
380 ob_rr_theme->handle_height +
381 ob_rr_theme->bwidth * 2);
382
383 x = focus_cycle_target->frame->area.x;
384 y = focus_cycle_target->frame->area.y;
385 w = focus_cycle_target->frame->area.width;
386 h = wt;
387
388 XMoveResizeWindow(ob_display, focus_indicator.top.win,
389 x, y, w, h);
390 a_focus_indicator->texture[0].data.lineart.x1 = 0;
391 a_focus_indicator->texture[0].data.lineart.y1 = h-1;
392 a_focus_indicator->texture[0].data.lineart.x2 = 0;
393 a_focus_indicator->texture[0].data.lineart.y2 = 0;
394 a_focus_indicator->texture[1].data.lineart.x1 = 0;
395 a_focus_indicator->texture[1].data.lineart.y1 = 0;
396 a_focus_indicator->texture[1].data.lineart.x2 = w-1;
397 a_focus_indicator->texture[1].data.lineart.y2 = 0;
398 a_focus_indicator->texture[2].data.lineart.x1 = w-1;
399 a_focus_indicator->texture[2].data.lineart.y1 = 0;
400 a_focus_indicator->texture[2].data.lineart.x2 = w-1;
401 a_focus_indicator->texture[2].data.lineart.y2 = h-1;
402 a_focus_indicator->texture[3].data.lineart.x1 = (wl-1);
403 a_focus_indicator->texture[3].data.lineart.y1 = h-1;
404 a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
405 a_focus_indicator->texture[3].data.lineart.y2 = h-1;
406 RrPaint(a_focus_indicator, focus_indicator.top.win,
407 w, h);
408
409 x = focus_cycle_target->frame->area.x;
410 y = focus_cycle_target->frame->area.y;
411 w = wl;
412 h = focus_cycle_target->frame->area.height;
413
414 XMoveResizeWindow(ob_display, focus_indicator.left.win,
415 x, y, w, h);
416 a_focus_indicator->texture[0].data.lineart.x1 = w-1;
417 a_focus_indicator->texture[0].data.lineart.y1 = 0;
418 a_focus_indicator->texture[0].data.lineart.x2 = 0;
419 a_focus_indicator->texture[0].data.lineart.y2 = 0;
420 a_focus_indicator->texture[1].data.lineart.x1 = 0;
421 a_focus_indicator->texture[1].data.lineart.y1 = 0;
422 a_focus_indicator->texture[1].data.lineart.x2 = 0;
423 a_focus_indicator->texture[1].data.lineart.y2 = h-1;
424 a_focus_indicator->texture[2].data.lineart.x1 = 0;
425 a_focus_indicator->texture[2].data.lineart.y1 = h-1;
426 a_focus_indicator->texture[2].data.lineart.x2 = w-1;
427 a_focus_indicator->texture[2].data.lineart.y2 = h-1;
428 a_focus_indicator->texture[3].data.lineart.x1 = w-1;
429 a_focus_indicator->texture[3].data.lineart.y1 = wt-1;
430 a_focus_indicator->texture[3].data.lineart.x2 = w-1;
431 a_focus_indicator->texture[3].data.lineart.y2 = h - wb;
432 RrPaint(a_focus_indicator, focus_indicator.left.win,
433 w, h);
434
435 x = focus_cycle_target->frame->area.x +
436 focus_cycle_target->frame->area.width - wr;
437 y = focus_cycle_target->frame->area.y;
438 w = wr;
439 h = focus_cycle_target->frame->area.height ;
440
441 XMoveResizeWindow(ob_display, focus_indicator.right.win,
442 x, y, w, h);
443 a_focus_indicator->texture[0].data.lineart.x1 = 0;
444 a_focus_indicator->texture[0].data.lineart.y1 = 0;
445 a_focus_indicator->texture[0].data.lineart.x2 = w-1;
446 a_focus_indicator->texture[0].data.lineart.y2 = 0;
447 a_focus_indicator->texture[1].data.lineart.x1 = w-1;
448 a_focus_indicator->texture[1].data.lineart.y1 = 0;
449 a_focus_indicator->texture[1].data.lineart.x2 = w-1;
450 a_focus_indicator->texture[1].data.lineart.y2 = h-1;
451 a_focus_indicator->texture[2].data.lineart.x1 = w-1;
452 a_focus_indicator->texture[2].data.lineart.y1 = h-1;
453 a_focus_indicator->texture[2].data.lineart.x2 = 0;
454 a_focus_indicator->texture[2].data.lineart.y2 = h-1;
455 a_focus_indicator->texture[3].data.lineart.x1 = 0;
456 a_focus_indicator->texture[3].data.lineart.y1 = wt-1;
457 a_focus_indicator->texture[3].data.lineart.x2 = 0;
458 a_focus_indicator->texture[3].data.lineart.y2 = h - wb;
459 RrPaint(a_focus_indicator, focus_indicator.right.win,
460 w, h);
461
462 x = focus_cycle_target->frame->area.x;
463 y = focus_cycle_target->frame->area.y +
464 focus_cycle_target->frame->area.height - wb;
465 w = focus_cycle_target->frame->area.width;
466 h = wb;
467
468 XMoveResizeWindow(ob_display, focus_indicator.bottom.win,
469 x, y, w, h);
470 a_focus_indicator->texture[0].data.lineart.x1 = 0;
471 a_focus_indicator->texture[0].data.lineart.y1 = 0;
472 a_focus_indicator->texture[0].data.lineart.x2 = 0;
473 a_focus_indicator->texture[0].data.lineart.y2 = h-1;
474 a_focus_indicator->texture[1].data.lineart.x1 = 0;
475 a_focus_indicator->texture[1].data.lineart.y1 = h-1;
476 a_focus_indicator->texture[1].data.lineart.x2 = w-1;
477 a_focus_indicator->texture[1].data.lineart.y2 = h-1;
478 a_focus_indicator->texture[2].data.lineart.x1 = w-1;
479 a_focus_indicator->texture[2].data.lineart.y1 = h-1;
480 a_focus_indicator->texture[2].data.lineart.x2 = w-1;
481 a_focus_indicator->texture[2].data.lineart.y2 = 0;
482 a_focus_indicator->texture[3].data.lineart.x1 = wl-1;
483 a_focus_indicator->texture[3].data.lineart.y1 = 0;
484 a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
485 a_focus_indicator->texture[3].data.lineart.y2 = 0;
486 RrPaint(a_focus_indicator, focus_indicator.bottom.win,
487 w, h);
488
489 XMapWindow(ob_display, focus_indicator.top.win);
490 XMapWindow(ob_display, focus_indicator.left.win);
491 XMapWindow(ob_display, focus_indicator.right.win);
492 XMapWindow(ob_display, focus_indicator.bottom.win);
493 }
494 }
495
496 static gboolean valid_focus_target(ObClient *ft)
497 {
498 /* we don't use client_can_focus here, because that doesn't let you
499 focus an iconic window, but we want to be able to, so we just check
500 if the focus flags on the window allow it, and its on the current
501 desktop */
502 return ((ft->type == OB_CLIENT_TYPE_NORMAL ||
503 ft->type == OB_CLIENT_TYPE_DIALOG ||
504 (!client_has_group_siblings(ft) &&
505 (ft->type == OB_CLIENT_TYPE_TOOLBAR ||
506 ft->type == OB_CLIENT_TYPE_MENU ||
507 ft->type == OB_CLIENT_TYPE_UTILITY))) &&
508 !ft->transients &&
509 ((ft->can_focus || ft->focus_notify) &&
510 !ft->skip_taskbar &&
511 (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)));
512 }
513
514 void focus_cycle(gboolean forward, gboolean linear,
515 gboolean dialog, gboolean done, gboolean cancel)
516 {
517 static ObClient *first = NULL;
518 static ObClient *t = NULL;
519 static GList *order = NULL;
520 GList *it, *start, *list;
521 ObClient *ft = NULL;
522
523 if (cancel) {
524 focus_cycle_target = NULL;
525 goto done_cycle;
526 } else if (done)
527 goto done_cycle;
528
529 if (!focus_order[screen_desktop])
530 goto done_cycle;
531
532 if (!first) first = focus_client;
533 if (!focus_cycle_target) focus_cycle_target = focus_client;
534
535 if (linear) list = client_list;
536 else list = focus_order[screen_desktop];
537
538 start = it = g_list_find(list, focus_cycle_target);
539 if (!start) /* switched desktops or something? */
540 start = it = forward ? g_list_last(list) : g_list_first(list);
541 if (!start) goto done_cycle;
542
543 do {
544 if (forward) {
545 it = it->next;
546 if (it == NULL) it = g_list_first(list);
547 } else {
548 it = it->prev;
549 if (it == NULL) it = g_list_last(list);
550 }
551 ft = it->data;
552 if (valid_focus_target(ft)) {
553 if (ft != focus_cycle_target) { /* prevents flicker */
554 focus_cycle_target = ft;
555 focus_cycle_draw_indicator();
556 }
557 popup_cycle(ft, dialog);
558 return;
559 }
560 } while (it != start);
561
562 done_cycle:
563 if (done && focus_cycle_target)
564 client_activate(focus_cycle_target, FALSE);
565
566 t = NULL;
567 first = NULL;
568 focus_cycle_target = NULL;
569 g_list_free(order);
570 order = NULL;
571
572 focus_cycle_draw_indicator();
573 popup_cycle(ft, FALSE);
574
575 return;
576 }
577
578 void focus_directional_cycle(ObDirection dir,
579 gboolean dialog, gboolean done, gboolean cancel)
580 {
581 static ObClient *first = NULL;
582 ObClient *ft = NULL;
583
584 if (cancel) {
585 focus_cycle_target = NULL;
586 goto done_cycle;
587 } else if (done)
588 goto done_cycle;
589
590 if (!focus_order[screen_desktop])
591 goto done_cycle;
592
593 if (!first) first = focus_client;
594 if (!focus_cycle_target) focus_cycle_target = focus_client;
595
596 if (focus_cycle_target)
597 ft = client_find_directional(focus_cycle_target, dir);
598 else {
599 GList *it;
600
601 for (it = focus_order[screen_desktop]; it; it = g_list_next(it))
602 if (valid_focus_target(it->data))
603 ft = it->data;
604 }
605
606 if (ft) {
607 if (ft != focus_cycle_target) {/* prevents flicker */
608 focus_cycle_target = ft;
609 focus_cycle_draw_indicator();
610 }
611 }
612 if (focus_cycle_target) {
613 popup_cycle(focus_cycle_target, dialog);
614 if (dialog)
615 return;
616 }
617
618
619 done_cycle:
620 if (done && focus_cycle_target)
621 client_activate(focus_cycle_target, FALSE);
622
623 first = NULL;
624 focus_cycle_target = NULL;
625
626 focus_cycle_draw_indicator();
627 popup_cycle(ft, FALSE);
628
629 return;
630 }
631
632 void focus_order_add_new(ObClient *c)
633 {
634 guint d, i;
635
636 if (c->iconic)
637 focus_order_to_top(c);
638 else {
639 d = c->desktop;
640 if (d == DESKTOP_ALL) {
641 for (i = 0; i < screen_num_desktops; ++i) {
642 if (focus_order[i] && ((ObClient*)focus_order[i]->data)->iconic)
643 focus_order[i] = g_list_insert(focus_order[i], c, 0);
644 else
645 focus_order[i] = g_list_insert(focus_order[i], c, 1);
646 }
647 } else
648 if (focus_order[d] && ((ObClient*)focus_order[d]->data)->iconic)
649 focus_order[d] = g_list_insert(focus_order[d], c, 0);
650 else
651 focus_order[d] = g_list_insert(focus_order[d], c, 1);
652 }
653 }
654
655 void focus_order_remove(ObClient *c)
656 {
657 guint d, i;
658
659 d = c->desktop;
660 if (d == DESKTOP_ALL) {
661 for (i = 0; i < screen_num_desktops; ++i)
662 focus_order[i] = g_list_remove(focus_order[i], c);
663 } else
664 focus_order[d] = g_list_remove(focus_order[d], c);
665 }
666
667 static void to_top(ObClient *c, guint d)
668 {
669 focus_order[d] = g_list_remove(focus_order[d], c);
670 if (!c->iconic) {
671 focus_order[d] = g_list_prepend(focus_order[d], c);
672 } else {
673 GList *it;
674
675 /* insert before first iconic window */
676 for (it = focus_order[d];
677 it && !((ObClient*)it->data)->iconic; it = it->next);
678 focus_order[d] = g_list_insert_before(focus_order[d], it, c);
679 }
680 }
681
682 void focus_order_to_top(ObClient *c)
683 {
684 guint d, i;
685
686 d = c->desktop;
687 if (d == DESKTOP_ALL) {
688 for (i = 0; i < screen_num_desktops; ++i)
689 to_top(c, i);
690 } else
691 to_top(c, d);
692 }
693
694 static void to_bottom(ObClient *c, guint d)
695 {
696 focus_order[d] = g_list_remove(focus_order[d], c);
697 if (c->iconic) {
698 focus_order[d] = g_list_append(focus_order[d], c);
699 } else {
700 GList *it;
701
702 /* insert before first iconic window */
703 for (it = focus_order[d];
704 it && !((ObClient*)it->data)->iconic; it = it->next);
705 g_list_insert_before(focus_order[d], it, c);
706 }
707 }
708
709 void focus_order_to_bottom(ObClient *c)
710 {
711 guint d, i;
712
713 d = c->desktop;
714 if (d == DESKTOP_ALL) {
715 for (i = 0; i < screen_num_desktops; ++i)
716 to_bottom(c, i);
717 } else
718 to_bottom(c, d);
719 }
This page took 0.074745 seconds and 5 git commands to generate.