+static gboolean client_can_steal_focus(ObClient *self, Time steal_time,
+ Time launch_time)
+{
+ gboolean steal;
+ gboolean relative_focused;
+ gboolean parent_focused;
+
+ steal = TRUE;
+
+ parent_focused = (focus_client != NULL &&
+ client_search_focus_parent(self));
+ 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_type(OB_DEBUG_FOCUS,
+ "Want to focus new window 0x%x at time %u "
+ "launched at %u (last user interaction time %u)\n",
+ self->window, steal_time, launch_time,
+ event_last_user_time);
+
+ /* if it's on another desktop */
+ if (!(self->desktop == screen_desktop ||
+ self->desktop == DESKTOP_ALL) &&
+ /* the timestamp is from before you changed desktops */
+ launch_time && screen_desktop_user_time &&
+ !event_time_after(launch_time, screen_desktop_user_time))
+ {
+ steal = FALSE;
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "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 (!parent_focused &&
+ event_last_user_time && launch_time &&
+ 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_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because the user is "
+ "working in another window that is not "
+ "its parent\n");
+ }
+ /* If the new window is a transient (and its relatives aren't
+ focused) */
+ else if (client_has_parent(self) && !relative_focused) {
+ steal = FALSE;
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because it is a "
+ "transient, and its relatives aren't focused\n");
+ }
+ /* 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_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because a globally "
+ "active client has focus\n");
+ }
+ /* 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_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because another window "
+ "would get the focus anyway\n");
+ }
+ /* Don't move focus if the window is not visible on the current
+ desktop and none of its relatives are focused */
+ else if (!(self->desktop == screen_desktop ||
+ self->desktop == DESKTOP_ALL) &&
+ !relative_focused)
+ {
+ steal = FALSE;
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because it is on "
+ "another desktop and no relatives are focused ");
+ }
+ }
+
+ if (!steal)
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Focus stealing prevention activated for %s at "
+ "time %u (last user interaction time %u)\n",
+ self->title, steal_time, event_last_user_time);
+ return steal;
+}
+