X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=openbox%2Fclient.c;h=35afb318ca9ef40d1e2ea5a901fa5c92501f9e7f;hb=9c356d370ab3e5a6b28e38ce8289d80bf35c8828;hp=8eeb052bf4ec4eb0804c8219f52fcb122d7d4c2d;hpb=d614bebf6a0c4b79d62cf4f703ee6a511fd0b904;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 8eeb052b..35afb318 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -192,7 +192,8 @@ void client_manage(Window window, ObPrompt *prompt) { ObClient *self; XSetWindowAttributes attrib_set; - gboolean activate = FALSE; + gboolean try_activate = FALSE; + gboolean do_activate; ObAppSettings *settings; gboolean transient = FALSE; Rect place; @@ -284,7 +285,7 @@ void client_manage(Window window, ObPrompt *prompt) FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, settings->focus == 1)) { - activate = TRUE; + try_activate = TRUE; } /* remove the client's border */ @@ -298,6 +299,14 @@ void client_manage(Window window, ObPrompt *prompt) /* where the frame was placed is where the window was originally */ place = self->area; + ob_debug("Going to try activate new window? %s", + try_activate ? "yes" : "no"); + if (try_activate) + do_activate = client_can_steal_focus(self, settings->focus, + event_time(), launch_time); + else + do_activate = FALSE; + /* figure out placement for the window if the window is new */ if (ob_state() == OB_STATE_RUNNING) { ob_debug("Positioned: %s @ %d %d", @@ -316,7 +325,8 @@ void client_manage(Window window, ObPrompt *prompt) "program + user specified" : "BADNESS !?")))), place.width, place.height); - obplaced = place_client(self, &place.x, &place.y, settings); + obplaced = place_client(self, do_activate, &place.x, &place.y, + settings); /* watch for buggy apps that ask to be placed at (0,0) when there is a strut there */ @@ -424,13 +434,30 @@ void client_manage(Window window, ObPrompt *prompt) client_apply_startup_state(self, place.x, place.y, place.width, place.height); - ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s", - activate ? "yes" : "no"); - if (activate) { - activate = client_can_steal_focus(self, settings->focus, - event_time(), launch_time); + /* grab mouse bindings before showing the window */ + mouse_grab_for_client(self, TRUE); + + /* this has to happen before we try focus the window, but we want it to + happen after the client's stacking has been determined or it looks bad + */ + { + gulong ignore_start; + if (!config_focus_under_mouse) + ignore_start = event_start_ignore_all_enters(); + + client_show(self); + + if (!config_focus_under_mouse) + event_end_ignore_all_enters(ignore_start); + } - if (!activate) { + /* activate/hilight/raise the window */ + if (try_activate) { + if (do_activate) { + gboolean stacked = client_restore_session_stacking(self); + client_present(self, FALSE, !stacked, TRUE); + } + else { /* if the client isn't stealing focus, then hilite it so the user knows it is there, but don't do this if we're restoring from a session */ @@ -450,27 +477,6 @@ void client_manage(Window window, ObPrompt *prompt) stacking_raise(CLIENT_AS_WINDOW(self)); } - mouse_grab_for_client(self, TRUE); - - /* this has to happen before we try focus the window, but we want it to - happen after the client's stacking has been determined or it looks bad - */ - { - gulong ignore_start; - if (!config_focus_under_mouse) - ignore_start = event_start_ignore_all_enters(); - - client_show(self); - - if (!config_focus_under_mouse) - event_end_ignore_all_enters(ignore_start); - } - - if (activate) { - gboolean stacked = client_restore_session_stacking(self); - client_present(self, FALSE, !stacked, TRUE); - } - /* add to client list/map */ client_list = g_list_append(client_list, self); window_add(&self->window, CLIENT_AS_WINDOW(self)); @@ -693,63 +699,100 @@ static gboolean client_can_steal_focus(ObClient *self, { 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 window 0x%x at time %u " - "launched at %u (last user interaction time %u)", - self->window, steal_time, launch_time, - event_last_user_time); + ob_debug("Want to focus window 0x%x at time %u " + "launched at %u (last user interaction time %u)", + self->window, steal_time, launch_time, + event_last_user_time); + + /* + 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... */ + /* 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)))) { steal = FALSE; - ob_debug_type(OB_DEBUG_FOCUS, - "Not focusing the window because its on another " - "desktop\n"); + 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 (!parent_focused && + 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)) { 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"); + ob_debug("Not focusing the window because the user is " + "working in another window that is not its relative"); } /* 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"); + 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. @@ -758,17 +801,15 @@ static gboolean client_can_steal_focus(ObClient *self, focus_client->focus_notify)) { steal = FALSE; - ob_debug_type(OB_DEBUG_FOCUS, - "Not focusing the window because a globally " - "active client has focus"); + ob_debug("Not focusing the window because a globally " + "active client has focus"); } /* 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"); + ob_debug("Not focusing the window because another window " + "would get the focus anyway"); } /* Don't move focus if the window is not visible on the current desktop and none of its relatives are focused */ @@ -777,17 +818,15 @@ static gboolean client_can_steal_focus(ObClient *self, !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 "); + ob_debug("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)", - self->title, steal_time, event_last_user_time); + ob_debug("Focus stealing prevention activated for %s at " + "time %u (last user interaction time %u)", + self->title, steal_time, event_last_user_time); return steal; } @@ -2444,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) { @@ -4468,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) {