summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openbox/action.c2
-rw-r--r--openbox/client.c20
-rw-r--r--openbox/client.h3
-rw-r--r--openbox/event.c14
-rw-r--r--openbox/focus.c93
-rw-r--r--openbox/focus.h11
-rw-r--r--openbox/openbox.c2
-rw-r--r--openbox/screen.c4
8 files changed, 69 insertions, 80 deletions
diff --git a/openbox/action.c b/openbox/action.c
index 6d455f1f..73524ae4 100644
--- a/openbox/action.c
+++ b/openbox/action.c
@@ -1172,7 +1172,7 @@ void action_focus(union ActionData *data)
void action_unfocus (union ActionData *data)
{
if (data->client.any.c == focus_client)
- focus_fallback(OB_FOCUS_FALLBACK_UNFOCUSING);
+ focus_fallback(FALSE);
}
void action_iconify(union ActionData *data)
diff --git a/openbox/client.c b/openbox/client.c
index e7c7f62a..b49d3ff8 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -78,6 +78,7 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y);
static void client_restore_session_state(ObClient *self);
static void client_restore_session_stacking(ObClient *self);
static ObAppSettings *client_get_settings_state(ObClient *self);
+static void client_unfocus(ObClient *self);
void client_startup(gboolean reconfig)
{
@@ -2515,10 +2516,10 @@ static void client_iconify_recursive(ObClient *self,
ob_debug("%sconifying window: 0x%lx\n", (iconic ? "I" : "Uni"),
self->window);
- self->iconic = iconic;
-
if (iconic) {
if (self->functions & OB_CLIENT_FUNC_ICONIFY) {
+ self->iconic = iconic;
+
/* update the focus lists.. iconic windows go to the bottom of
the list, put the new iconic window at the 'top of the
bottom'. */
@@ -2527,6 +2528,8 @@ static void client_iconify_recursive(ObClient *self,
changed = TRUE;
}
} else {
+ self->iconic = iconic;
+
if (curdesk)
client_set_desktop(self, screen_desktop, FALSE);
@@ -3031,14 +3034,7 @@ gboolean client_focus(ObClient *self)
ob_debug("Focusing client \"%s\" at time %u\n", self->title, event_curtime);
if (self->can_focus) {
- /* RevertToPointerRoot causes much more headache than RevertToNone, so
- I choose to use it always, hopefully to find errors quicker, if any
- are left. (I hate X. I hate focus events.)
-
- Update: Changing this to RevertToNone fixed a bug with mozilla (bug
- #799. So now it is RevertToNone again.
- */
- XSetInputFocus(ob_display, self->window, RevertToNone,
+ XSetInputFocus(ob_display, self->window, RevertToPointerRoot,
event_curtime);
}
@@ -3073,13 +3069,13 @@ gboolean client_focus(ObClient *self)
/* Used when the current client is closed or otherwise hidden, focus_last will
then prevent focus from going to the mouse pointer
*/
-void client_unfocus(ObClient *self)
+static void client_unfocus(ObClient *self)
{
if (focus_client == self) {
#ifdef DEBUG_FOCUS
ob_debug("client_unfocus for %lx\n", self->window);
#endif
- focus_fallback(OB_FOCUS_FALLBACK_CLOSED);
+ focus_fallback(FALSE);
}
}
diff --git a/openbox/client.h b/openbox/client.h
index 38480a66..cbb80ede 100644
--- a/openbox/client.h
+++ b/openbox/client.h
@@ -494,9 +494,6 @@ gboolean client_can_focus(ObClient *self);
*/
gboolean client_focus(ObClient *self);
-/*! Remove focus from the client window */
-void client_unfocus(ObClient *self);
-
/*! Activates the client for use, focusing, uniconifying it, etc. To be used
when the user deliberately selects a window for use.
@param here If true, then the client is brought to the current desktop;
diff --git a/openbox/event.c b/openbox/event.c
index 7eef8017..d4d921ef 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -422,7 +422,7 @@ static void event_process(const XEvent *ec, gpointer data)
}
}
-#if 0 /* focus debugging stuff */
+#if 1 /* focus debugging stuff */
if (e->type == FocusIn || e->type == FocusOut) {
gint mode = e->xfocus.mode;
gint detail = e->xfocus.detail;
@@ -655,8 +655,12 @@ static void event_handle_client(ObClient *client, XEvent *e)
case FocusOut:
/* Look for the followup FocusIn */
if (!XCheckIfEvent(ob_display, &ce, look_for_focusin, NULL)) {
- /* There is no FocusIn, move focus where we can still hear events*/
- focus_fallback(OB_FOCUS_FALLBACK_NOFOCUS);
+ /* There is no FocusIn, this means focus went to a window that
+ is not being managed. most likely, this went to PointerRoot
+ or None, meaning the window is no longer around so fallback
+ focus, but not to that window */
+ ob_debug("Focus went to a black hole !\n");
+ focus_fallback(FALSE);
} else if (ce.xany.window == e->xany.window) {
/* If focus didn't actually move anywhere, there is nothing to do*/
break;
@@ -667,7 +671,9 @@ static void event_handle_client(ObClient *client, XEvent *e)
if (ed.ignored) {
/* The FocusIn was ignored, this means it was on a window
that isn't a client. */
- focus_fallback(OB_FOCUS_FALLBACK_NOFOCUS);
+ ob_debug("Focus went to an unmanaged window 0x%x !\n",
+ ce.xfocus.window);
+ focus_fallback(TRUE);
}
}
diff --git a/openbox/focus.c b/openbox/focus.c
index 201a4349..3fba876b 100644
--- a/openbox/focus.c
+++ b/openbox/focus.c
@@ -248,7 +248,7 @@ static ObClient* focus_fallback_transient(ObClient *top, ObClient *old)
return NULL;
}
-ObClient* focus_fallback_target(ObFocusFallbackType type)
+ObClient* focus_fallback_target(gboolean allow_refocus)
{
GList *it;
ObClient *old;
@@ -256,60 +256,57 @@ ObClient* focus_fallback_target(ObFocusFallbackType type)
old = focus_client;
- if ((type == OB_FOCUS_FALLBACK_UNFOCUSING
- || type == OB_FOCUS_FALLBACK_CLOSED) && old) {
- if (old->transient_for) {
- gboolean trans = FALSE;
-
- 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;
-
- /* try for transient relations */
- if (trans) {
- if (old->transient_for == OB_TRAN_GROUP) {
- for (it = focus_order[screen_desktop]; it;
- it = g_list_next(it))
+ if (!allow_refocus && old && old->transient_for) {
+ gboolean trans = FALSE;
+
+ 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;
+
+ /* try for transient relations */
+ if (trans) {
+ if (old->transient_for == OB_TRAN_GROUP) {
+ for (it = focus_order[screen_desktop]; it;
+ it = g_list_next(it))
+ {
+ GSList *sit;
+
+ for (sit = old->group->members; sit;
+ sit = g_slist_next(sit))
{
- GSList *sit;
-
- 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 (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;
+ }
}
}
}
ob_debug("trying pointer stuff\n");
- if (config_focus_follow &&
- (type == OB_FOCUS_FALLBACK_UNFOCUSING || !config_focus_last))
+ if (config_focus_follow && !config_focus_last)
{
if ((target = client_under_pointer()))
- if (client_normal(target) && client_can_focus(target) &&
- client_validate(target)) {
- ob_debug("found in pointer stuff\n");
- return target;
- }
+ if (allow_refocus || target != old)
+ if (client_normal(target) && client_can_focus(target) &&
+ client_validate(target)) {
+ ob_debug("found in pointer stuff\n");
+ return target;
+ }
}
#if 0
@@ -328,7 +325,7 @@ ObClient* focus_fallback_target(ObFocusFallbackType type)
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 (allow_refocus || it->data != old)
if (client_normal(it->data) && client_can_focus(it->data) &&
client_validate(it->data))
{
@@ -344,7 +341,7 @@ ObClient* focus_fallback_target(ObFocusFallbackType type)
return NULL;
}
-void focus_fallback(ObFocusFallbackType type)
+void focus_fallback(gboolean allow_refocus)
{
ObClient *new;
@@ -354,7 +351,7 @@ void focus_fallback(ObFocusFallbackType type)
*/
focus_set_client(NULL);
- if ((new = focus_fallback_target(type)))
+ if ((new = focus_fallback_target(allow_refocus)))
client_focus(new);
}
diff --git a/openbox/focus.h b/openbox/focus.h
index 81cd5ffe..e71cd2d7 100644
--- a/openbox/focus.h
+++ b/openbox/focus.h
@@ -50,17 +50,10 @@ void focus_shutdown(gboolean reconfig);
send focus anywhere, its called by the Focus event handlers */
void focus_set_client(struct _ObClient *client);
-typedef enum {
- OB_FOCUS_FALLBACK_UNFOCUSING, /*!< forcefully remove focus from the
- current window */
- OB_FOCUS_FALLBACK_CLOSED, /*!< closed the window with focus */
- OB_FOCUS_FALLBACK_NOFOCUS /*!< nothing has focus for some reason */
-} ObFocusFallbackType;
-
-struct _ObClient* focus_fallback_target(ObFocusFallbackType type);
+struct _ObClient* focus_fallback_target(gboolean allow_refocus);
/*! Call this when you need to focus something! */
-void focus_fallback(ObFocusFallbackType type);
+void focus_fallback(gboolean allow_refocus);
/*! Cycle focus amongst windows. */
void focus_cycle(gboolean forward, gboolean linear, gboolean interactive,
diff --git a/openbox/openbox.c b/openbox/openbox.c
index 8d491a42..c355747f 100644
--- a/openbox/openbox.c
+++ b/openbox/openbox.c
@@ -278,7 +278,7 @@ gint main(gint argc, gchar **argv)
if (!reconfigure) {
/* get all the existing windows */
client_manage_all();
- focus_fallback(OB_FOCUS_FALLBACK_NOFOCUS);
+ focus_fallback(TRUE);
} else {
GList *it;
diff --git a/openbox/screen.c b/openbox/screen.c
index dcb9cd13..0d4f2fb3 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -463,7 +463,7 @@ void screen_set_desktop(guint num)
event_ignore_queued_enters();
- focus_hilite = focus_fallback_target(OB_FOCUS_FALLBACK_NOFOCUS);
+ focus_hilite = focus_fallback_target(TRUE);
if (focus_hilite) {
frame_adjust_focus(focus_hilite->frame, TRUE);
@@ -893,7 +893,7 @@ void screen_show_desktop(gboolean show)
client_validate(it->data) && client_focus(it->data))
break;
} else {
- focus_fallback(OB_FOCUS_FALLBACK_NOFOCUS);
+ focus_fallback(TRUE);
}
show = !!show; /* make it boolean */