X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=f97bd43062d97b4168d66a606ab2df776278db66;hb=c6b22725640c2c1ab1023996807e750a11bd72f8;hp=1931d87eaf755e0fc6f4db2b0ce6565e133b7b55;hpb=dacc9dac7a8232180fb824fe2eea7d026def99c9;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 1931d87e..f97bd430 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -214,7 +214,7 @@ void client_manage(Window window) ObAppSettings *settings; gboolean transient = FALSE; Rect place, *monitor; - Time map_time; + Time launch_time, map_time; grab_server(TRUE); @@ -253,6 +253,8 @@ void client_manage(Window window) ob_debug("Managing window: 0x%lx\n", window); + map_time = event_get_server_time(); + /* choose the events we want to receive on the CLIENT window */ attrib_set.event_mask = CLIENT_EVENTMASK; attrib_set.do_not_propagate_mask = CLIENT_NOPROPAGATEMASK; @@ -300,7 +302,7 @@ void client_manage(Window window) client_setup_decor_and_functions(self, FALSE); /* tell startup notification that this app started */ - map_time = sn_app_started(self->startup_id, self->class); + launch_time = sn_app_started(self->startup_id, self->class); /* do this after we have a frame.. it uses the frame to help determine the WM_STATE to apply. */ @@ -451,6 +453,13 @@ void client_manage(Window window) if (activate) { gboolean raise = FALSE; + /* 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, map_time, launch_time, + event_last_user_time); + if (menu_frame_visible || moveresize_in_progress) { activate = FALSE; raise = TRUE; @@ -462,10 +471,10 @@ void client_manage(Window window) /* if it's on another desktop */ else if (!(self->desktop == screen_desktop || - self->desktop == DESKTOP_ALL) && - /* the timestamp is from before you changed desktops */ - map_time && screen_desktop_user_time && - !event_time_after(map_time, screen_desktop_user_time)) + 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)) { activate = FALSE; raise = TRUE; @@ -477,11 +486,21 @@ void client_manage(Window window) else if (focus_client && client_search_focus_tree_full(self) == NULL && client_search_focus_group_full(self) == NULL) { - /* If its a transient (and parents aren't focused) and the time - is ambiguous (either the current focus target doesn't have - a timestamp, or they are the same (we probably inherited it - from them) */ - if (client_has_parent(self)) { + /* If the user is working in another window right now, then don't + steal focus */ + if (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, + map_time - OB_EVENT_USER_TIME_DELAY)) + { + activate = FALSE; + ob_debug_type(OB_DEBUG_FOCUS, + "Not focusing the window because the user is " + "working in another window\n"); + } + /* If its a transient (and its parents aren't focused) */ + else if (client_has_parent(self)) { activate = FALSE; ob_debug_type(OB_DEBUG_FOCUS, "Not focusing the window because it is a " @@ -507,9 +526,22 @@ void client_manage(Window window) "Not focusing the window because another window " "would get the focus anyway\n"); } + else if (!(self->desktop == screen_desktop || + self->desktop == DESKTOP_ALL)) + { + activate = FALSE; + raise = TRUE; + ob_debug_type(OB_DEBUG_FOCUS, + "Not focusing the window because it is on " + "another desktop and no relatives are focused "); + } } if (!activate) { + ob_debug_type(OB_DEBUG_FOCUS, + "Focus stealing prevention activated for %s at " + "time %u (last user interactioon time %u)\n", + self->title, map_time, event_last_user_time); /* if the client isn't focused, then hilite it so the user knows it is there */ client_hilite(self, TRUE); @@ -3773,7 +3805,7 @@ static void detect_edge(Rect area, ObDirection dir, gint edge_start, edge_size, head, tail; gboolean skip_head = FALSE, skip_tail = FALSE; - switch(dir) { + switch (dir) { case OB_DIRECTION_NORTH: case OB_DIRECTION_SOUTH: edge_start = area.x; @@ -3793,7 +3825,7 @@ static void detect_edge(Rect area, ObDirection dir, edge_start, edge_size)) return; - switch(dir) { + switch (dir) { case OB_DIRECTION_NORTH: head = RECT_BOTTOM(area); tail = RECT_TOP(area); @@ -3802,38 +3834,54 @@ static void detect_edge(Rect area, ObDirection dir, head = RECT_TOP(area); tail = RECT_BOTTOM(area); break; - case OB_DIRECTION_EAST: - head = RECT_LEFT(area); - tail = RECT_RIGHT(area); - break; case OB_DIRECTION_WEST: head = RECT_RIGHT(area); tail = RECT_LEFT(area); break; + case OB_DIRECTION_EAST: + head = RECT_LEFT(area); + tail = RECT_RIGHT(area); + break; default: g_assert_not_reached(); } - switch(dir) { + switch (dir) { case OB_DIRECTION_NORTH: case OB_DIRECTION_WEST: + /* check if our window is past the head of this window */ if (my_head <= head + 1) skip_head = TRUE; + /* check if our window's tail is past the tail of this window */ if (my_head + my_size - 1 <= tail) skip_tail = TRUE; - if (head < *dest) + /* check if the head of this window is closer than the previously + chosen edge (take into account that the previously chosen + edge might have been a tail, not a head) */ + if (head + (*near_edge ? 0 : my_size) < *dest) skip_head = TRUE; - if (tail - my_size < *dest) + /* check if the tail of this window is closer than the previously + chosen edge (take into account that the previously chosen + edge might have been a head, not a tail) */ + if (tail - (!*near_edge ? 0 : my_size) < *dest) skip_tail = TRUE; break; case OB_DIRECTION_SOUTH: case OB_DIRECTION_EAST: + /* check if our window is past the head of this window */ if (my_head >= head - 1) skip_head = TRUE; + /* check if our window's tail is past the tail of this window */ if (my_head - my_size + 1 >= tail) skip_tail = TRUE; - if (head > *dest) + /* check if the head of this window is closer than the previously + chosen edge (take into account that the previously chosen + edge might have been a tail, not a head) */ + if (head - (*near_edge ? 0 : my_size) > *dest) skip_head = TRUE; - if (tail + my_size > *dest) + /* check if the tail of this window is closer than the previously + chosen edge (take into account that the previously chosen + edge might have been a head, not a tail) */ + if (tail + (!*near_edge ? 0 : my_size) > *dest) skip_tail = TRUE; break; default: @@ -3852,7 +3900,6 @@ static void detect_edge(Rect area, ObDirection dir, *dest = tail; *near_edge = FALSE; } - } void client_find_edge_directional(ObClient *self, ObDirection dir, @@ -3870,7 +3917,7 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, mon = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &self->frame->area); - switch(dir) { + switch (dir) { case OB_DIRECTION_NORTH: if (my_head >= RECT_TOP(*mon) + 1) edge = RECT_TOP(*mon) - 1; @@ -3902,7 +3949,7 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, *dest = edge; *near_edge = TRUE; - for(it = client_list; it; it = g_list_next(it)) { + for (it = client_list; it; it = g_list_next(it)) { ObClient *cur = it->data; /* skip windows to not bump into */