try catch weird racey corner case where we try fallback to a window but it unmaps as we do so, so focus ends up going to nowhere

This commit is contained in:
Dana Jansens 2007-05-12 00:54:44 +00:00
parent 3bee91aaf9
commit 1d6c07c24b
3 changed files with 32 additions and 5 deletions

View file

@ -98,6 +98,7 @@ Time event_curtime = CurrentTime;
static guint ignore_enter_focus = 0; static guint ignore_enter_focus = 0;
static gboolean menu_can_hide; static gboolean menu_can_hide;
static gboolean focus_left_screen = FALSE; static gboolean focus_left_screen = FALSE;
static ObClient *focus_tried = NULL;
#ifdef USE_SM #ifdef USE_SM
static void ice_handler(gint fd, gpointer conn) static void ice_handler(gint fd, gpointer conn)
@ -498,7 +499,7 @@ static void event_process(const XEvent *ec, gpointer data)
focus_left_screen = FALSE; focus_left_screen = FALSE;
if (!focus_left_screen) if (!focus_left_screen)
focus_fallback(TRUE); focus_tried = focus_fallback(TRUE);
} }
} else if (client && client != focus_client) { } else if (client && client != focus_client) {
focus_left_screen = FALSE; focus_left_screen = FALSE;
@ -506,6 +507,8 @@ static void event_process(const XEvent *ec, gpointer data)
focus_set_client(client); focus_set_client(client);
client_calc_layer(client); client_calc_layer(client);
client_bring_helper_windows(client); client_bring_helper_windows(client);
focus_tried = NULL; /* focus isn't "trying" to go anywhere now */
} }
} else if (e->type == FocusOut) { } else if (e->type == FocusOut) {
gboolean nomove = FALSE; gboolean nomove = FALSE;
@ -547,7 +550,7 @@ static void event_process(const XEvent *ec, gpointer data)
ob_debug_type(OB_DEBUG_FOCUS, ob_debug_type(OB_DEBUG_FOCUS,
"Focus went to an unmanaged window 0x%x !\n", "Focus went to an unmanaged window 0x%x !\n",
ce.xfocus.window); ce.xfocus.window);
focus_fallback(TRUE); focus_tried = focus_fallback(TRUE);
} }
} }
@ -1075,10 +1078,24 @@ static void event_handle_client(ObClient *client, XEvent *e)
client->window, e->xunmap.event, e->xunmap.from_configure, client->window, e->xunmap.event, e->xunmap.from_configure,
client->ignore_unmaps); client->ignore_unmaps);
client_unmanage(client); client_unmanage(client);
/* we were trying to focus this window but it's gone */
if (client == focus_tried) {
ob_debug_type(OB_DEBUG_FOCUS, "Tried to focus window 0x%x but it "
"is being unmanaged. Falling back focus again.\n");
focus_tried = focus_fallback(TRUE);
}
break; break;
case DestroyNotify: case DestroyNotify:
ob_debug("DestroyNotify for window 0x%x\n", client->window); ob_debug("DestroyNotify for window 0x%x\n", client->window);
client_unmanage(client); client_unmanage(client);
/* we were trying to focus this window but it's gone */
if (client == focus_tried) {
ob_debug_type(OB_DEBUG_FOCUS, "Tried to focus window 0x%x but it "
"is being unmanaged. Falling back focus again.\n");
focus_tried = focus_fallback(TRUE);
}
break; break;
case ReparentNotify: case ReparentNotify:
/* this is when the client is first taken captive in the frame */ /* this is when the client is first taken captive in the frame */
@ -1097,6 +1114,13 @@ static void event_handle_client(ObClient *client, XEvent *e)
ob_debug("ReparentNotify for window 0x%x\n", client->window); ob_debug("ReparentNotify for window 0x%x\n", client->window);
client_unmanage(client); client_unmanage(client);
/* we were trying to focus this window but it's gone */
if (client == focus_tried) {
ob_debug_type(OB_DEBUG_FOCUS, "Tried to focus window 0x%x but it "
"is being unmanaged. Falling back focus again.\n");
focus_tried = focus_fallback(TRUE);
}
break; break;
case MapRequest: case MapRequest:
ob_debug("MapRequest for 0x%lx\n", client->window); ob_debug("MapRequest for 0x%lx\n", client->window);

View file

@ -255,7 +255,7 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old)
return desktop; return desktop;
} }
void focus_fallback(gboolean allow_refocus) ObClient* focus_fallback(gboolean allow_refocus)
{ {
ObClient *new; ObClient *new;
ObClient *old = focus_client; ObClient *old = focus_client;
@ -266,8 +266,11 @@ void focus_fallback(gboolean allow_refocus)
*/ */
focus_nothing(); focus_nothing();
if ((new = focus_fallback_target(allow_refocus, old))) if ((new = focus_fallback_target(allow_refocus, old))) {
client_focus(new); client_focus(new);
return new;
} else
return NULL;
} }
void focus_nothing() void focus_nothing()

View file

@ -49,7 +49,7 @@ struct _ObClient* focus_fallback_target(gboolean allow_refocus,
struct _ObClient *old); struct _ObClient *old);
/*! Call this when you need to focus something! */ /*! Call this when you need to focus something! */
void focus_fallback(gboolean allow_refocus); struct _ObClient* focus_fallback(gboolean allow_refocus);
/*! Cycle focus amongst windows. */ /*! Cycle focus amongst windows. */
void focus_cycle(gboolean forward, gboolean all_desktops, void focus_cycle(gboolean forward, gboolean all_desktops,