summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openbox/action.c2
-rw-r--r--openbox/client.c22
-rw-r--r--openbox/client.h7
-rw-r--r--openbox/event.c33
-rw-r--r--openbox/focus.c111
-rw-r--r--openbox/openbox.c2
-rw-r--r--openbox/screen.c2
7 files changed, 73 insertions, 106 deletions
diff --git a/openbox/action.c b/openbox/action.c
index 3f43a238..50191859 100644
--- a/openbox/action.c
+++ b/openbox/action.c
@@ -1296,7 +1296,7 @@ void action_focus(union ActionData *data)
go moving on us */
event_halt_focus_delay();
- client_focus(data->client.any.c);
+ client_focus(data->client.any.c, FALSE);
}
} else {
/* focus action on something other than a client, make keybindings
diff --git a/openbox/client.c b/openbox/client.c
index 837dd019..fa4aae95 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -2842,7 +2842,7 @@ void client_fullscreen(ObClient *self, gboolean fs)
if (fs) {
/* try focus us when we go into fullscreen mode */
- client_focus(self);
+ client_focus(self, FALSE);
}
}
@@ -3336,10 +3336,8 @@ gboolean client_can_focus(ObClient *self)
return TRUE;
}
-gboolean client_focus(ObClient *self)
+gboolean client_focus(ObClient *self, gboolean checkinvalid)
{
- gboolean error;
-
/* choose the correct target */
self = client_focus_target(self);
@@ -3365,8 +3363,9 @@ gboolean client_focus(ObClient *self)
if (keyboard_interactively_grabbed())
keyboard_interactive_cancel();
- error = FALSE;
- xerror_set_ignore(TRUE);
+ if (checkinvalid)
+ xerror_set_ignore(TRUE);
+ xerror_occured = FALSE;
if (self->can_focus) {
/* This can cause a BadMatch error with CurrentTime, or if an app
@@ -3390,13 +3389,10 @@ gboolean client_focus(ObClient *self)
XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
}
- /* This calls XSync, which will cause the FocusIn to come back to us.
- That's important for desktop switches, since otherwise we'll have no
- FocusIn on the queue and end up falling back again. */
- xerror_set_ignore(FALSE);
- if (!xerror_occured) error = TRUE;
+ if (checkinvalid)
+ xerror_set_ignore(FALSE);
- return !error;
+ return !xerror_occured;
}
/*! Present the client to the user.
@@ -3430,7 +3426,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise)
if (raise)
stacking_raise(CLIENT_AS_WINDOW(self));
- client_focus(self);
+ client_focus(self, FALSE);
}
void client_activate(ObClient *self, gboolean here, gboolean user)
diff --git a/openbox/client.h b/openbox/client.h
index 5526c282..9019c62d 100644
--- a/openbox/client.h
+++ b/openbox/client.h
@@ -532,9 +532,10 @@ ObClient *client_focus_target(ObClient *self);
gboolean client_can_focus(ObClient *self);
/*! Attempt to focus the client window
- NOTE: You should validate the client before calling this !! (client_validate)
-*/
-gboolean client_focus(ObClient *self);
+ If you care if focus actually went to the window or not, pass checkinvalid
+ as TRUE.
+ */
+gboolean client_focus(ObClient *self, gboolean checkinvalid);
/*! Activates the client for use, focusing, uniconifying it, etc. To be used
when the user deliberately selects a window for use.
diff --git a/openbox/event.c b/openbox/event.c
index a2571f0e..9d10698b 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -307,10 +307,6 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only)
return FALSE;
}
- /* This means focus moved to the frame window */
- if (detail == NotifyInferior && !in_client_only)
- return TRUE;
-
/* It was on a client, was it a valid one?
It's possible to get a FocusIn event for a client that was managed
but has disappeared.
@@ -351,9 +347,6 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only)
/* This means focus moved from one client to another */
if (detail == NotifyNonlinearVirtual)
return TRUE;
- /* This means focus had moved to our frame window and now moved off */
- if (detail == NotifyNonlinear)
- return TRUE;
/* Otherwise.. */
return FALSE;
@@ -484,9 +477,7 @@ static void event_process(const XEvent *ec, gpointer data)
{
XEvent ce;
- ob_debug_type(OB_DEBUG_FOCUS,
- "Focus went to pointer root/none or to our frame "
- "window\n");
+ ob_debug_type(OB_DEBUG_FOCUS, "Focus went to pointer root/none\n");
/* If another FocusIn is in the queue then don't fallback yet. This
fixes the fun case of:
@@ -508,40 +499,24 @@ static void event_process(const XEvent *ec, gpointer data)
ob_debug_type(OB_DEBUG_FOCUS,
" but another FocusIn is coming\n");
} else {
- /* Focus has been reverted to the root window, nothing, or to
- our frame window.
+ /* Focus has been reverted to the root window or nothing.
FocusOut events come after UnmapNotify, so we don't need to
worry about focusing an invalid window
*/
- /* In this case we know focus is in our screen */
- if (e->xfocus.detail == NotifyInferior)
- focus_left_screen = FALSE;
-
if (!focus_left_screen)
focus_fallback(TRUE);
}
}
else if (!client)
{
- XEvent ce;
-
ob_debug_type(OB_DEBUG_FOCUS,
"Focus went to a window that is already gone\n");
/* If you send focus to a window and then it disappears, you can
get the FocusIn FocusOut for it, after it is unmanaged.
- */
- if (XCheckIfEvent(ob_display, &ce, event_look_for_focusin_client,
- NULL))
- {
- XPutBackEvent(ob_display, &ce);
- ob_debug_type(OB_DEBUG_FOCUS,
- " but another FocusIn is coming\n");
- } else {
- focus_fallback(TRUE);
- }
+ Just wait for the next FocusOut/FocusIn pair. */
}
else if (client != focus_client) {
focus_left_screen = FALSE;
@@ -1718,7 +1693,7 @@ static gboolean focus_delay_func(gpointer data)
event_curtime = d->time;
if (focus_client != d->client) {
- if (client_focus(d->client) && config_focus_raise)
+ if (client_focus(d->client, FALSE) && config_focus_raise)
stacking_raise(CLIENT_AS_WINDOW(d->client));
}
event_curtime = old;
diff --git a/openbox/focus.c b/openbox/focus.c
index 47c3846f..60e6ea99 100644
--- a/openbox/focus.c
+++ b/openbox/focus.c
@@ -190,91 +190,86 @@ void focus_set_client(ObClient *client)
}
}
-static ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old)
+static ObClient* focus_fallback_target(gboolean allow_refocus)
{
GList *it;
- ObClient *target = NULL;
- ObClient *desktop = NULL;
+ ObClient *c;
+ ObClient *old = focus_client;
ob_debug_type(OB_DEBUG_FOCUS, "trying pointer stuff\n");
if (config_focus_follow && !config_focus_last)
- {
- if ((target = client_under_pointer()))
- if (allow_refocus || target != old)
- if (client_normal(target) && client_can_focus(target)) {
- ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n");
- return target;
- }
- }
-
-#if 0
- /* try for group relations */
- if (old->group) {
- GSList *sit;
-
- 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))
- return sit->data;
+ if ((c = client_under_pointer()) &&
+ (allow_refocus || c != old) &&
+ (client_normal(c) &&
+ client_focus(c, TRUE)))
+ {
+ ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n");
+ return c;
}
-#endif
ob_debug_type(OB_DEBUG_FOCUS, "trying omnipresentness\n");
- if (allow_refocus && old && old->desktop == DESKTOP_ALL &&
- client_normal(old))
+ if (allow_refocus && old &&
+ old->desktop == DESKTOP_ALL &&
+ client_normal(old) &&
+ client_focus(old, TRUE))
{
+ ob_debug_type(OB_DEBUG_FOCUS, "found in omnipresentness\n");
return old;
}
ob_debug_type(OB_DEBUG_FOCUS, "trying the focus order\n");
- for (it = focus_order; it; it = g_list_next(it))
- if (allow_refocus || it->data != old) {
- ObClient *c = it->data;
- /* fallback focus to a window if:
- 1. it is actually focusable, cuz if it's not then we're sending
- focus off to nothing. this includes if it is visible right now
- 2. it is on the current desktop. this ignores omnipresent
- windows, which are problematic in their own rite.
- 3. it is a normal type window, don't fall back onto a dock or
- a splashscreen or a desktop window (save the desktop as a
- backup fallback though)
- */
- if (client_can_focus(c))
- {
- if (c->desktop == screen_desktop && client_normal(c)) {
- ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n");
- return it->data;
- } else if (c->type == OB_CLIENT_TYPE_DESKTOP &&
- desktop == NULL)
- desktop = c;
- }
+ for (it = focus_order; it; it = g_list_next(it)) {
+ c = it->data;
+ /* fallback focus to a window if:
+ 1. it is on the current desktop. this ignores omnipresent
+ windows, which are problematic in their own rite.
+ 2. it is a normal type window, don't fall back onto a dock or
+ a splashscreen or a desktop window (save the desktop as a
+ backup fallback though)
+ */
+ if (c->desktop == screen_desktop &&
+ client_normal(c) &&
+ (allow_refocus || c != old) &&
+ client_focus(c, TRUE))
+ {
+ ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n");
+ return c;
}
+ }
- /* as a last resort fallback to the desktop window if there is one.
- (if there's more than one, then the one most recently focused.)
- */
- ob_debug_type(OB_DEBUG_FOCUS, "found desktop: \n", !!desktop);
- return desktop;
+ ob_debug_type(OB_DEBUG_FOCUS, "trying a desktop window\n");
+ for (it = focus_order; it; it = g_list_next(it)) {
+ c = it->data;
+ /* fallback focus to a window if:
+ 1. it is on the current desktop. this ignores omnipresent
+ windows, which are problematic in their own rite.
+ 2. it is a normal type window, don't fall back onto a dock or
+ a splashscreen or a desktop window (save the desktop as a
+ backup fallback though)
+ */
+ if (c->type == OB_CLIENT_TYPE_DESKTOP &&
+ (allow_refocus || c != old) &&
+ client_focus(c, TRUE))
+ {
+ ob_debug_type(OB_DEBUG_FOCUS, "found a desktop window\n");
+ return c;
+ }
+ }
+
+ return NULL;
}
ObClient* focus_fallback(gboolean allow_refocus)
{
ObClient *new;
- ObClient *old;
-
- old = focus_client;
- new = focus_fallback_target(allow_refocus, focus_client);
/* unfocus any focused clients.. they can be focused by Pointer events
and such, and then when we try focus them, we won't get a FocusIn
event at all for them. */
focus_nothing();
- if (new)
- client_focus(new);
+ new = focus_fallback_target(allow_refocus);
return new;
}
diff --git a/openbox/openbox.c b/openbox/openbox.c
index 78b53223..419d2b55 100644
--- a/openbox/openbox.c
+++ b/openbox/openbox.c
@@ -311,7 +311,7 @@ gint main(gint argc, gchar **argv)
(w = g_hash_table_lookup(window_map, &xid)) &&
WINDOW_IS_CLIENT(w))
{
- client_focus(WINDOW_AS_CLIENT(w));
+ client_focus(WINDOW_AS_CLIENT(w), FALSE);
}
} else {
GList *it;
diff --git a/openbox/screen.c b/openbox/screen.c
index 45246297..23821301 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -942,7 +942,7 @@ void screen_show_desktop(gboolean show, ObClient *show_only)
ObClient *c = it->data;
if (c->type == OB_CLIENT_TYPE_DESKTOP &&
(c->desktop == screen_desktop || c->desktop == DESKTOP_ALL) &&
- client_focus(it->data))
+ client_focus(it->data, FALSE))
break;
}
}