X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Ffocus.c;h=201a43492bf88103c26c5f152d92e7becd0040c0;hb=6b7cc88c9d4ae2019f3b8fcd300dd3069f2bc680;hp=3b4dd14537c6b641194ba73376b7355bc5066729;hpb=2aa5cd3574b2bbdc103cb7626aa1ff77ea2c0046;p=chaz%2Fopenbox diff --git a/openbox/focus.c b/openbox/focus.c index 3b4dd145..201a4349 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -1,7 +1,8 @@ /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- focus.c for the Openbox window manager - Copyright (c) 2003 Ben Jansens + Copyright (c) 2006 Mikael Magnusson + Copyright (c) 2003-2007 Dana Jansens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -55,16 +56,18 @@ static ObIconPopup *focus_cycle_popup; static void focus_cycle_destructor(ObClient *client, gpointer data) { - /* end cycling if the target disappears */ + /* end cycling if the target disappears. CurrentTime is fine, time won't + be used + */ if (focus_cycle_target == client) - focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE); + focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, CurrentTime); } static Window createWindow(Window parent, gulong mask, - XSetWindowAttributes *attrib) + XSetWindowAttributes *attrib) { return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0, - RrDepth(ob_rr_inst), InputOutput, + RrDepth(ob_rr_inst), InputOutput, RrVisual(ob_rr_inst), mask, attrib); } @@ -86,25 +89,20 @@ void focus_startup(gboolean reconfig) focus_indicator.right.obwin.type = Window_Internal; focus_indicator.bottom.obwin.type = Window_Internal; - attr.save_under = True; attr.override_redirect = True; attr.background_pixel = BlackPixel(ob_display, ob_screen); focus_indicator.top.win = createWindow(RootWindow(ob_display, ob_screen), - CWOverrideRedirect | CWBackPixel | CWSaveUnder, - &attr); + CWOverrideRedirect | CWBackPixel, &attr); focus_indicator.left.win = createWindow(RootWindow(ob_display, ob_screen), - CWOverrideRedirect | CWBackPixel | CWSaveUnder, - &attr); + CWOverrideRedirect | CWBackPixel, &attr); focus_indicator.right.win = createWindow(RootWindow(ob_display, ob_screen), - CWOverrideRedirect | CWBackPixel | CWSaveUnder, - &attr); + CWOverrideRedirect | CWBackPixel, &attr); focus_indicator.bottom.win = createWindow(RootWindow(ob_display, ob_screen), - CWOverrideRedirect | CWBackPixel | CWSaveUnder, - &attr); + CWOverrideRedirect | CWBackPixel, &attr); stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.top)); stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.left)); @@ -143,7 +141,7 @@ void focus_shutdown(gboolean reconfig) g_free(focus_order); /* reset focus to root */ - XSetInputFocus(ob_display, PointerRoot, RevertToNone, event_lasttime); + XSetInputFocus(ob_display, PointerRoot, RevertToNone, CurrentTime); RrColorFree(color_white); @@ -185,13 +183,15 @@ void focus_set_client(ObClient *client) #endif /* when nothing will be focused, send focus to the backup target */ XSetInputFocus(ob_display, screen_support_win, RevertToNone, - event_lasttime); + event_curtime); XSync(ob_display, FALSE); } - /* in the middle of cycling..? kill it. */ + /* in the middle of cycling..? kill it. CurrentTime is fine, time won't + be used. + */ if (focus_cycle_target) - focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE); + focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, CurrentTime); old = focus_client; focus_client = client; @@ -205,6 +205,10 @@ void focus_set_client(ObClient *client) active = client ? client->window : None; PROP_SET32(RootWindow(ob_display, ob_screen), net_active_window, window, active); + + /* remove hiliting from the window when it gets focused */ + if (client != NULL) + client_hilite(client, FALSE); } } @@ -216,11 +220,15 @@ static ObClient *find_transient_recursive(ObClient *c, ObClient *top, GSList *it; ObClient *ret; - for (it = c->transients; it; it = it->next) { + for (it = c->transients; it; it = g_slist_next(it)) { if (it->data == top) return NULL; ret = find_transient_recursive(it->data, top, skip); - if (ret && ret != skip && client_normal(ret)) return ret; - if (it->data != skip && client_normal(it->data)) return it->data; + if (ret && ret != skip && client_normal(ret) && + client_can_focus(ret) && client_validate(ret)) + return ret; + if (it->data != skip && client_normal(it->data) && + client_can_focus(it->data) && client_validate(it->data)) + return it->data; } return NULL; } @@ -243,51 +251,65 @@ static ObClient* focus_fallback_transient(ObClient *top, ObClient *old) ObClient* focus_fallback_target(ObFocusFallbackType type) { GList *it; - ObClient *old = NULL; + ObClient *old; ObClient *target = NULL; old = focus_client; - if (type == OB_FOCUS_FALLBACK_UNFOCUSING && old) { + if ((type == OB_FOCUS_FALLBACK_UNFOCUSING + || type == OB_FOCUS_FALLBACK_CLOSED) && old) { if (old->transient_for) { gboolean trans = FALSE; - if (!config_focus_follow) + if (!config_focus_follow || config_focus_last) + trans = TRUE; + else if ((target = client_under_pointer()) && + client_search_transient + (client_search_top_parent(target), old)) trans = TRUE; - else { - if ((target = client_under_pointer()) && - client_search_transient - (client_search_top_transient(target), old)) - { - trans = TRUE; - } - } /* try for transient relations */ if (trans) { if (old->transient_for == OB_TRAN_GROUP) { - for (it = focus_order[screen_desktop]; it; it = it->next) { + for (it = focus_order[screen_desktop]; it; + it = g_list_next(it)) + { GSList *sit; - for (sit = old->group->members; sit; sit = sit->next) + for (sit = old->group->members; sit; + sit = g_slist_next(sit)) + { if (sit->data == it->data) if ((target = focus_fallback_transient(sit->data, old))) + { + ob_debug("found in transient #1\n"); return target; + } + } } } else { if ((target = focus_fallback_transient(old->transient_for, old))) + { + ob_debug("found in transient #2\n"); return target; + } } } } } - if (config_focus_follow) { + ob_debug("trying pointer stuff\n"); + if (config_focus_follow && + (type == OB_FOCUS_FALLBACK_UNFOCUSING || !config_focus_last)) + { if ((target = client_under_pointer())) - if (client_normal(target) && client_can_focus(target)) + if (client_normal(target) && client_can_focus(target) && + client_validate(target)) { + ob_debug("found in pointer stuff\n"); return target; + } } #if 0 @@ -295,8 +317,8 @@ ObClient* focus_fallback_target(ObFocusFallbackType type) if (old->group) { GSList *sit; - for (it = focus_order[screen_desktop]; it != NULL; it = it->next) - for (sit = old->group->members; sit; sit = sit->next) + for (it = focus_order[screen_desktop]; it; it = g_list_next(it)) + for (sit = old->group->members; sit; sit = g_slist_next(sit)) if (sit->data == it->data) if (sit->data != old && client_normal(sit->data)) if (client_can_focus(sit->data)) @@ -304,10 +326,20 @@ ObClient* focus_fallback_target(ObFocusFallbackType type) } #endif - for (it = focus_order[screen_desktop]; it != NULL; it = it->next) + ob_debug("trying the focus order\n"); + for (it = focus_order[screen_desktop]; it; it = g_list_next(it)) if (type != OB_FOCUS_FALLBACK_UNFOCUSING || it->data != old) - if (client_normal(it->data) && client_can_focus(it->data)) + if (client_normal(it->data) && client_can_focus(it->data) && + client_validate(it->data)) + { + ob_debug("found in focus order\n"); return it->data; + } + + /* XXX fallback to the "desktop window" if one exists ? + could store it while going through all the windows in the loop right + above this.. + */ return NULL; } @@ -333,7 +365,7 @@ static void popup_cycle(ObClient *c, gboolean show) } else { Rect *a; ObClient *p = c; - gchar *title; + gchar *title = NULL; a = screen_physical_area_monitor(0); icon_popup_position(focus_cycle_popup, CenterGravity, @@ -350,14 +382,13 @@ static void popup_cycle(ObClient *c, gboolean show) while (p->transient_for && p->transient_for != OB_TRAN_GROUP) p = p->transient_for; - if (p == c) - title = NULL; - else - title = g_strconcat((c->iconic ? c->icon_title : c->title), + if (p != c && !strcmp("", (c->iconic ? c->icon_title : c->title))) + title = g_strdup(p->iconic ? p->icon_title : p->title); + /*title = g_strconcat((c->iconic ? c->icon_title : c->title), " - ", (p->iconic ? p->icon_title : p->title), NULL); - + */ icon_popup_show(focus_cycle_popup, (title ? title : (c->iconic ? c->icon_title : c->title)), @@ -383,8 +414,9 @@ void focus_cycle_draw_indicator() gint wt, wl, wr, wb; wt = wl = wr = wb = MAX(3, - ob_rr_theme->handle_height + - ob_rr_theme->bwidth * 2); + MAX(1, MAX(ob_rr_theme->paddingx, + ob_rr_theme->paddingy)) * 2 + + ob_rr_theme->fbwidth * 2); x = focus_cycle_target->frame->area.x; y = focus_cycle_target->frame->area.y; @@ -512,7 +544,7 @@ static gboolean valid_focus_target(ObClient *ft) ft->type == OB_CLIENT_TYPE_MENU || ft->type == OB_CLIENT_TYPE_UTILITY))) && ((ft->can_focus || ft->focus_notify) && - !ft->skip_taskbar && + !ft->skip_pager && (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)) && ft == client_focus_target(ft)) return TRUE; @@ -533,8 +565,8 @@ static gboolean valid_focus_target(ObClient *ft) return FALSE; } -void focus_cycle(gboolean forward, gboolean linear, - gboolean dialog, gboolean done, gboolean cancel) +void focus_cycle(gboolean forward, gboolean linear, gboolean interactive, + gboolean dialog, gboolean done, gboolean cancel, Time time) { static ObClient *first = NULL; static ObClient *t = NULL; @@ -542,20 +574,26 @@ void focus_cycle(gboolean forward, gboolean linear, GList *it, *start, *list; ObClient *ft = NULL; - if (cancel) { - focus_cycle_target = NULL; - goto done_cycle; - } else if (done) - goto done_cycle; + if (interactive) { + if (cancel) { + focus_cycle_target = NULL; + goto done_cycle; + } else if (done) + goto done_cycle; - if (!focus_order[screen_desktop]) - goto done_cycle; + if (!focus_order[screen_desktop]) + goto done_cycle; - if (!first) first = focus_client; - if (!focus_cycle_target) focus_cycle_target = focus_client; + if (!first) first = focus_client; - if (linear) list = client_list; - else list = focus_order[screen_desktop]; + if (linear) list = client_list; + else list = focus_order[screen_desktop]; + } else { + if (!focus_order[screen_desktop]) + goto done_cycle; + list = client_list; + } + if (!focus_cycle_target) focus_cycle_target = focus_client; start = it = g_list_find(list, focus_cycle_target); if (!start) /* switched desktops or something? */ @@ -572,18 +610,24 @@ void focus_cycle(gboolean forward, gboolean linear, } ft = it->data; if (valid_focus_target(ft)) { - if (ft != focus_cycle_target) { /* prevents flicker */ + if (interactive) { + if (ft != focus_cycle_target) { /* prevents flicker */ + focus_cycle_target = ft; + focus_cycle_draw_indicator(); + } + popup_cycle(ft, dialog); + return; + } else if (ft != focus_cycle_target) { focus_cycle_target = ft; - focus_cycle_draw_indicator(); + done = TRUE; + break; } - popup_cycle(ft, dialog); - return; } } while (it != start); done_cycle: if (done && focus_cycle_target) - client_activate(focus_cycle_target, FALSE); + client_activate(focus_cycle_target, FALSE, TRUE, time); t = NULL; first = NULL; @@ -591,18 +635,24 @@ done_cycle: g_list_free(order); order = NULL; - focus_cycle_draw_indicator(); - popup_cycle(ft, FALSE); + if (interactive) { + focus_cycle_draw_indicator(); + popup_cycle(ft, FALSE); + } return; } -void focus_directional_cycle(ObDirection dir, - gboolean dialog, gboolean done, gboolean cancel) +void focus_directional_cycle(ObDirection dir, gboolean interactive, + gboolean dialog, gboolean done, gboolean cancel, + Time time) { static ObClient *first = NULL; ObClient *ft = NULL; + if (!interactive) + return; + if (cancel) { focus_cycle_target = NULL; goto done_cycle; @@ -640,7 +690,7 @@ void focus_directional_cycle(ObDirection dir, done_cycle: if (done && focus_cycle_target) - client_activate(focus_cycle_target, FALSE); + client_activate(focus_cycle_target, FALSE, TRUE, time); first = NULL; focus_cycle_target = NULL; @@ -661,12 +711,14 @@ void focus_order_add_new(ObClient *c) d = c->desktop; if (d == DESKTOP_ALL) { for (i = 0; i < screen_num_desktops; ++i) { + g_assert(!g_list_find(focus_order[i], c)); if (focus_order[i] && ((ObClient*)focus_order[i]->data)->iconic) focus_order[i] = g_list_insert(focus_order[i], c, 0); else focus_order[i] = g_list_insert(focus_order[i], c, 1); } } else { + g_assert(!g_list_find(focus_order[d], c)); if (focus_order[d] && ((ObClient*)focus_order[d]->data)->iconic) focus_order[d] = g_list_insert(focus_order[d], c, 0); else @@ -697,7 +749,7 @@ static void to_top(ObClient *c, guint d) /* insert before first iconic window */ for (it = focus_order[d]; - it && !((ObClient*)it->data)->iconic; it = it->next); + it && !((ObClient*)it->data)->iconic; it = g_list_next(it)); focus_order[d] = g_list_insert_before(focus_order[d], it, c); } } @@ -724,8 +776,8 @@ static void to_bottom(ObClient *c, guint d) /* insert before first iconic window */ for (it = focus_order[d]; - it && !((ObClient*)it->data)->iconic; it = it->next); - g_list_insert_before(focus_order[d], it, c); + it && !((ObClient*)it->data)->iconic; it = g_list_next(it)); + focus_order[d] = g_list_insert_before(focus_order[d], it, c); } }