summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openbox/client.c74
-rw-r--r--openbox/client.h9
-rw-r--r--openbox/event.c7
-rw-r--r--openbox/event.h3
-rw-r--r--openbox/focus.c4
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,