/* -*- 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
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);
}
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));
g_free(focus_order);
/* reset focus to root */
- XSetInputFocus(ob_display, PointerRoot, RevertToNone, event_lasttime);
+ XSetInputFocus(ob_display, PointerRoot, RevertToNone, CurrentTime);
RrColorFree(color_white);
#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;
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);
}
}
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;
}
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
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))
}
#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;
}
} else {
Rect *a;
ObClient *p = c;
- gchar *title;
+ gchar *title = NULL;
a = screen_physical_area_monitor(0);
icon_popup_position(focus_cycle_popup, CenterGravity,
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)),
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;
ft->type == OB_CLIENT_TYPE_MENU ||
ft->type == OB_CLIENT_TYPE_UTILITY))) &&
((ft->can_focus || ft->focus_notify) &&
- !ft->skip_taskbar &&
- (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)))
+ !ft->skip_pager &&
+ (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)) &&
+ ft == client_focus_target(ft))
+ return TRUE;
+/*
{
GSList *it;
}
return TRUE;
}
+*/
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;
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? */
}
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;
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;
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;
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
- if (focus_order[d] && ((ObClient*)focus_order[d]->data)->iconic)
+ } 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
focus_order[d] = g_list_insert(focus_order[d], c, 1);
+ }
}
}
/* 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);
}
}
/* 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);
}
}