diff options
| -rw-r--r-- | openbox/client.c | 74 | ||||
| -rw-r--r-- | openbox/client.h | 9 | ||||
| -rw-r--r-- | openbox/event.c | 7 | ||||
| -rw-r--r-- | openbox/event.h | 3 | ||||
| -rw-r--r-- | openbox/focus.c | 4 |
5 files changed, 88 insertions, 9 deletions
diff --git a/openbox/client.c b/openbox/client.c index bdfe9391..35afb318 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -712,13 +712,59 @@ static gboolean client_can_steal_focus(ObClient *self, self->window, steal_time, launch_time, event_last_user_time); - /* if it's on another desktop... */ + /* + if no launch time is provided for an application, make one up. + + if the window is related to other existing windows + and one of those windows was the last used + then we will give it a launch time equal to the last user time, + which will end up giving the window focus probably. + else + the window is related to other windows, but you are not working in + them? + seems suspicious, so we will give it a launch time of + NOW - STEAL_INTERVAL, + so it will be given focus only if we didn't use something else + during the steal interval. + else + the window is all on its own, so we can't judge it. give it a launch + time equal to the last user time, so it will probably take focus. + + this way running things from a terminal will give them focus, but popups + without a launch time shouldn't steal focus so easily. + */ + + if (!launch_time) { + if (client_has_relative(self)) { + if (event_last_user_time && client_search_focus_group_full(self)) { + /* our relative is focused */ + launch_time = event_last_user_time; + ob_debug("Unknown launch time, using %u window in active " + "group", launch_time); + } + else { + /* has relatives which are not being used. suspicious */ + launch_time = event_time() - OB_EVENT_USER_TIME_DELAY; + ob_debug("Unknown launch time, using %u window in inactive " + "group", launch_time); + } + } + else { + /* the window is on its own, probably the user knows it is going + to appear */ + launch_time = event_last_user_time; + ob_debug("Unknown launch time, using %u for solo window", + launch_time); + } + } + + /* if it's on another desktop + then if allow_other_desktop is false, we don't want to let it steal + focus, unless it was launched after we changed desktops + */ if (!(self->desktop == screen_desktop || self->desktop == DESKTOP_ALL) && - /* and (we dont know when it launched, and we don't want to allow - focus stealing from other desktops */ - ((!launch_time && !allow_other_desktop) || - /* or the timestamp is from before you changed desktops) */ + (!allow_other_desktop || (screen_desktop_user_time && !event_time_after(launch_time, screen_desktop_user_time)))) { @@ -731,9 +777,9 @@ static gboolean client_can_steal_focus(ObClient *self, steal focus */ if (!relative_focused && event_last_user_time && - (!launch_time || - (event_time_after(event_last_user_time, launch_time) && - event_last_user_time != launch_time)) && + /* last user time must be strictly > launch_time to block focus */ + (event_time_after(event_last_user_time, launch_time) && + event_last_user_time != launch_time) && event_time_after(event_last_user_time, steal_time - OB_EVENT_USER_TIME_DELAY)) { @@ -2437,6 +2483,11 @@ gboolean client_has_parent(ObClient *self) return self->parents != NULL; } +gboolean client_has_children(ObClient *self) +{ + return self->transients != NULL; +} + gboolean client_is_oldfullscreen(const ObClient *self, const Rect *area) { @@ -4461,6 +4512,13 @@ gboolean client_has_group_siblings(ObClient *self) return self->group && self->group->members->next; } +gboolean client_has_relative(ObClient *self) +{ + return client_has_parent(self) || + client_has_group_siblings(self) || + client_has_children(self); +} + /*! Returns TRUE if the client is running on the same machine as Openbox */ gboolean client_on_localhost(ObClient *self) { diff --git a/openbox/client.h b/openbox/client.h index 47da397a..b36bef5a 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -657,6 +657,10 @@ RrImage* client_icon(ObClient *self); transient for */ gboolean client_has_parent(ObClient *self); +/*! Return TRUE if the client has some transient children, and FALSE otherwise. +*/ +gboolean client_has_children(ObClient *self); + /*! Searches a client's immediate parents for a focused window. The function does not check for the passed client, only for *ONE LEVEL* of its parents. If no focused parent is found, NULL is returned. @@ -741,6 +745,11 @@ ObClient* client_under_pointer(void); gboolean client_has_group_siblings(ObClient *self); +/*! Returns TRUE if the client has a transient child, a parent, or a + group member. Returns FALSE otherwise. +*/ +gboolean client_has_relative(ObClient *self); + /*! Returns TRUE if the client is running on the same machine as Openbox */ gboolean client_on_localhost(ObClient *self); diff --git a/openbox/event.c b/openbox/event.c index a72f07b2..b0a53dba 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -273,7 +273,7 @@ static void event_set_curtime(XEvent *e) which can happen if the clock goes backwards, we erase the last specified user_time */ if (t && event_last_user_time && event_time_after(event_last_user_time, t)) - event_last_user_time = CurrentTime; + event_reset_user_time(); event_sourcetime = CurrentTime; event_curtime = t; @@ -2251,3 +2251,8 @@ void event_update_user_time(void) { event_last_user_time = event_time(); } + +void event_reset_user_time(void) +{ + event_last_user_time = CurrentTime; +} diff --git a/openbox/event.h b/openbox/event.h index ef0e4165..4d9984e1 100644 --- a/openbox/event.h +++ b/openbox/event.h @@ -85,4 +85,7 @@ Time event_source_time(void); */ void event_update_user_time(void); +/*! Reset the timestamp for when the user has last used the focused window. */ +void event_reset_user_time(void); + #endif diff --git a/openbox/focus.c b/openbox/focus.c index 8c023618..a4626bf8 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -100,6 +100,10 @@ void focus_set_client(ObClient *client) active = client ? client->window : None; OBT_PROP_SET32(obt_root(ob_screen), NET_ACTIVE_WINDOW, WINDOW, active); } + + /* when focus is moved to a new window, the last_user_time timestamp would + no longer be valid, as it applies for the focused window */ + event_reset_user_time(); } static ObClient* focus_fallback_target(gboolean allow_refocus, |
