+ g_slice_free(ObClient, self);
+}
+
+static gboolean client_can_steal_focus(ObClient *self,
+ gboolean allow_other_desktop,
+ gboolean request_from_user,
+ Time steal_time,
+ Time launch_time)
+{
+ gboolean steal;
+ gboolean relative_focused;
+
+ steal = TRUE;
+
+ relative_focused = (focus_client != NULL &&
+ (client_search_focus_tree_full(self) != NULL ||
+ client_search_focus_group_full(self) != NULL));
+
+ /* This is focus stealing prevention */
+ ob_debug("Want to focus window 0x%x at time %u "
+ "launched at %u (last user interaction time %u) "
+ "request from %s, allow other desktop: %s",
+ self->window, steal_time, launch_time,
+ event_last_user_time,
+ (request_from_user ? "user" : "other"),
+ (allow_other_desktop ? "yes" : "no"));
+
+ /*
+ 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 if (!request_from_user) {
+ /* 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 {
+ /* has relatives which are not being used, but the user seems
+ to want to go there! */
+ launch_time = event_last_user_time;
+ ob_debug("Unknown launch time, using %u - user request",
+ 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 - independent window",
+ launch_time);
+ }
+ }
+
+ /* if it's on another desktop
+ then if allow_other_desktop is true, we don't want to let it steal
+ focus, unless it was launched after we changed desktops and the request
+ came from the user
+ */
+ if (!(self->desktop == screen_desktop ||
+ self->desktop == DESKTOP_ALL) &&
+ (!allow_other_desktop ||
+ (request_from_user && screen_desktop_user_time &&
+ !event_time_after(launch_time, screen_desktop_user_time))))
+ {
+ steal = FALSE;
+ ob_debug("Not focusing the window because its on another desktop\n");
+ }
+ /* If something is focused... */
+ else if (focus_client) {
+ /* If the user is working in another window right now, then don't
+ steal focus */
+ if (!relative_focused &&
+ event_last_user_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))
+ {
+ steal = FALSE;
+ ob_debug("Not focusing the window because the user is "
+ "working in another window that is not its relative");
+ }
+ /* Don't move focus if it's not going to go to this window
+ anyway */
+ else if (client_focus_target(self) != self) {
+ steal = FALSE;
+ ob_debug("Not focusing the window because another window "
+ "would get the focus anyway");
+ }
+ /* For requests that don't come from the user */
+ else if (!request_from_user) {
+ /* If the new window is a transient (and its relatives aren't
+ focused) */
+ if (client_has_parent(self) && !relative_focused) {
+ steal = FALSE;
+ ob_debug("Not focusing the window because it is a "
+ "transient, and its relatives aren't focused");
+ }
+ /* Don't steal focus from globally active clients.
+ I stole this idea from KWin. It seems nice.
+ */
+ else if (!(focus_client->can_focus || focus_client->focus_notify))
+ {
+ steal = FALSE;
+ ob_debug("Not focusing the window because a globally "
+ "active client has focus");
+ }
+ /* Don't move focus if the window is not visible on the current
+ desktop and none of its relatives are focused */
+ else if (!allow_other_desktop &&
+ !screen_compare_desktops(self->desktop, screen_desktop) &&
+ !relative_focused)
+ {
+ steal = FALSE;
+ ob_debug("Not focusing the window because it is on "
+ "another desktop and no relatives are focused ");
+ }
+ }
+ }
+
+ if (!steal)
+ ob_debug("Focus stealing prevention activated for %s at "
+ "time %u (last user interaction time %u)",
+ self->title, steal_time, event_last_user_time);
+ else
+ ob_debug("Allowing focus stealing for %s at time %u (last user "
+ "interaction time %u)",
+ self->title, steal_time, event_last_user_time);
+ return steal;