X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=e4d853441bfbb54f4fb76b9c77be8b3b9bc9a88b;hb=8e4fcae64d029fbe5f0edc444b0152d6d4b512e3;hp=35afb318ca9ef40d1e2ea5a901fa5c92501f9e7f;hpb=c5c34cca1c9b57424fa7ca686995126f627903ab;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 35afb318..e4d85344 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -110,6 +110,7 @@ static void client_ping_event(ObClient *self, gboolean dead); static void client_prompt_kill(ObClient *self); static gboolean client_can_steal_focus(ObClient *self, gboolean allow_other_desktop, + gboolean request_from_user, Time steal_time, Time launch_time); void client_startup(gboolean reconfig) @@ -255,6 +256,15 @@ void client_manage(Window window, ObPrompt *prompt) /* the session should get the last say though */ client_restore_session_state(self); + /* don't put helper/modal windows on a different desktop if they are + related to the focused window. */ + if (!screen_compare_desktops(self->desktop, screen_desktop) && + focus_client && client_search_transient(focus_client, self) && + (client_helper(self) || self->modal)) + { + self->desktop = screen_desktop; + } + /* tell startup notification that this app started */ launch_time = sn_app_started(self->startup_id, self->class, self->name); @@ -302,8 +312,10 @@ void client_manage(Window window, ObPrompt *prompt) 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); + do_activate = client_can_steal_focus( + self, settings->focus == 1, + (!!launch_time || settings->focus == 1), + event_time(), launch_time); else do_activate = FALSE; @@ -434,6 +446,10 @@ void client_manage(Window window, ObPrompt *prompt) client_apply_startup_state(self, place.x, place.y, place.width, place.height); + /* set the initial value of the desktop hint, when one wasn't requested + on map. */ + OBT_PROP_SET32(self->window, NET_WM_DESKTOP, CARDINAL, self->desktop); + /* grab mouse bindings before showing the window */ mouse_grab_for_client(self, TRUE); @@ -694,6 +710,7 @@ void client_fake_unmanage(ObClient *self) static gboolean client_can_steal_focus(ObClient *self, gboolean allow_other_desktop, + gboolean request_from_user, Time steal_time, Time launch_time) { @@ -708,9 +725,14 @@ static gboolean client_can_steal_focus(ObClient *self, /* This is focus stealing prevention */ ob_debug("Want to focus window 0x%x at time %u " - "launched at %u (last user interaction time %u)", + "launched at %u (last user interaction time %u) " + "request from %s, allow other desktop: %s, " + "desktop switch time %u", self->window, steal_time, launch_time, - event_last_user_time); + event_last_user_time, + (request_from_user ? "user" : "other"), + (allow_other_desktop ? "yes" : "no"), + screen_desktop_user_time); /* if no launch time is provided for an application, make one up. @@ -739,37 +761,51 @@ static gboolean client_can_steal_focus(ObClient *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 " + ob_debug("Unknown launch time, using %u - window in active " "group", launch_time); } - else { + 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 " + 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 for solo window", + ob_debug("Unknown launch time, using %u - independent 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 + and if allow_other_desktop is true, we generally let it steal focus. + but if it didn't come from the user, don't let it steal unless it was + launched before the user switched desktops. + 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 || - (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 (!screen_compare_desktops(screen_desktop, self->desktop)) { + /* must be allowed */ + if (!allow_other_desktop) { + steal = FALSE; + ob_debug("Not focusing the window because its on another desktop"); + } + /* if we don't know when the desktop changed, but request is from an + application, don't let it change desktop on you */ + else if (!request_from_user) { + steal = FALSE; + ob_debug("Not focusing the window because non-user request"); + } } /* If something is focused... */ else if (focus_client) { @@ -787,23 +823,6 @@ static gboolean client_can_steal_focus(ObClient *self, 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("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 it's not going to go to this window anyway */ else if (client_focus_target(self) != self) { @@ -811,15 +830,34 @@ static gboolean client_can_steal_focus(ObClient *self, 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 */ - else if (!(self->desktop == screen_desktop || - self->desktop == DESKTOP_ALL) && - !relative_focused) - { - steal = FALSE; - ob_debug("Not focusing the window because it is on " - "another desktop and no relatives are focused "); + /* 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 "); + } } } @@ -827,6 +865,10 @@ static gboolean client_can_steal_focus(ObClient *self, 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; } @@ -2771,9 +2813,6 @@ static void client_apply_startup_state(ObClient *self, self->area = oldarea; client_configure(self, x, y, w, h, FALSE, TRUE, FALSE); - /* set the desktop hint, to make sure that it always exists */ - OBT_PROP_SET32(self->window, NET_WM_DESKTOP, CARDINAL, self->desktop); - /* nothing to do for the other states: skip_taskbar skip_pager @@ -2853,6 +2892,13 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, the updated frame dimensions. */ frame_adjust_area(self->frame, FALSE, TRUE, TRUE); + /* cap any X windows at the size of an unsigned short */ + *w = MIN(*w, + G_MAXUSHORT - self->frame->size.left - self->frame->size.right); + *h = MIN(*h, + G_MAXUSHORT - self->frame->size.top - self->frame->size.bottom); + + /* gets the frame's position */ frame_client_gravity(self->frame, x, y); @@ -3891,6 +3937,9 @@ gboolean client_focus(ObClient *self) return FALSE; } + /* if we have helper windows they should be there with the window */ + client_bring_helper_windows(self); + ob_debug_type(OB_DEBUG_FOCUS, "Focusing client \"%s\" (0x%x) at time %u", self->title, self->window, event_time()); @@ -3961,13 +4010,10 @@ void client_activate(ObClient *self, gboolean desktop, gboolean here, gboolean raise, gboolean unshade, gboolean user) { - if ((user && (desktop || - self->desktop == DESKTOP_ALL || - self->desktop == screen_desktop)) || - client_can_steal_focus(self, desktop, event_time(), CurrentTime)) - { + self = client_focus_target(self); + + if (client_can_steal_focus(self, desktop, user, event_time(), CurrentTime)) client_present(self, here, raise, unshade); - } else client_hilite(self, TRUE); } @@ -3986,7 +4032,7 @@ static void client_bring_windows_recursive(ObClient *self, if (((helpers && client_helper(self)) || (modals && self->modal)) && - ((self->desktop != desktop && self->desktop != DESKTOP_ALL) || + (!screen_compare_desktops(self->desktop, desktop) || (iconic && self->iconic))) { if (iconic && self->iconic) @@ -4300,32 +4346,26 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, } /* search for edges of clients */ - if (((dir == OB_DIRECTION_NORTH || dir == OB_DIRECTION_SOUTH) && - !self->max_vert) || - ((dir == OB_DIRECTION_EAST || dir == OB_DIRECTION_WEST) && - !self->max_horz)) - { - for (it = client_list; it; it = g_list_next(it)) { - ObClient *cur = it->data; + for (it = client_list; it; it = g_list_next(it)) { + ObClient *cur = it->data; - /* skip windows to not bump into */ - if (cur == self) - continue; - if (cur->iconic) - continue; - if (self->desktop != cur->desktop && cur->desktop != DESKTOP_ALL && - cur->desktop != screen_desktop) - continue; + /* skip windows to not bump into */ + if (cur == self) + continue; + if (cur->iconic) + continue; + if (self->desktop != cur->desktop && cur->desktop != DESKTOP_ALL && + cur->desktop != screen_desktop) + continue; - ob_debug("trying window %s", cur->title); + ob_debug("trying window %s", cur->title); - detect_edge(cur->frame->area, dir, my_head, my_size, my_edge_start, - my_edge_size, dest, near_edge); - } - dock_get_area(&dock_area); - detect_edge(dock_area, dir, my_head, my_size, my_edge_start, + detect_edge(cur->frame->area, dir, my_head, my_size, my_edge_start, my_edge_size, dest, near_edge); } + dock_get_area(&dock_area); + detect_edge(dock_area, dir, my_head, my_size, my_edge_start, + my_edge_size, dest, near_edge); g_slice_free(Rect, a); }