static guint ignore_enter_focus = 0;
static gboolean menu_can_hide;
static gboolean focus_left_screen = FALSE;
-/*! This variable is used for focus fallback. If we fallback to a window, we
- set this to the window. And when focus goes somewhere after that, it will
- be set to NULL. If between falling back to that window and something
- getting focused, the window gets unmanaged, then if there are no incoming
- FocusIn events, we fallback again because focus has just gotten itself lost.
- */
-static ObClient *focus_tried = NULL;
#ifdef USE_SM
static void ice_handler(gint fd, gpointer conn)
IceAddConnectionWatch(ice_watch, NULL);
#endif
- client_add_destructor(focus_delay_client_dest, NULL);
+ client_add_destroy_notify(focus_delay_client_dest, NULL);
}
void event_shutdown(gboolean reconfig)
IceRemoveConnectionWatch(ice_watch, NULL);
#endif
- client_remove_destructor(focus_delay_client_dest);
+ client_remove_destroy_notify(focus_delay_client_dest);
}
static Window event_get_window(XEvent *e)
return FALSE;
}
+ /* This means focus moved to the frame window */
+ if (detail == NotifyInferior && !in_client_only)
+ return TRUE;
+
+ /* It was on a client, was it a valid one?
+ It's possible to get a FocusIn event for a client that was managed
+ but has disappeared. Don't even parse those FocusIn events.
+ */
+ {
+ ObWindow *w = g_hash_table_lookup(window_map, &e->xfocus.window);
+ if (!w || !WINDOW_IS_CLIENT(w))
+ return FALSE;
+ }
+
/* This means focus moved from the root window to a client */
if (detail == NotifyVirtual)
return TRUE;
/* This means focus moved from one client to another */
if (detail == NotifyNonlinearVirtual)
return TRUE;
- /* This means focus moved to the frame window */
- if (detail == NotifyInferior && !in_client_only)
- return TRUE;
/* Otherwise.. */
return FALSE;
}
}
-static Bool look_for_focusin(Display *d, XEvent *e, XPointer arg)
+static Bool event_look_for_focusin(Display *d, XEvent *e, XPointer arg)
{
return e->type == FocusIn && wanted_focusevent(e, FALSE);
}
-static Bool look_for_focusin_client(Display *d, XEvent *e, XPointer arg)
+Bool event_look_for_focusin_client(Display *d, XEvent *e, XPointer arg)
{
- return e->type == FocusIn && wanted_focusevent(e, TRUE) &&
- e->xfocus.window != screen_support_win;
+ return e->type == FocusIn && wanted_focusevent(e, TRUE);
}
static void print_focusevent(XEvent *e)
e->xfocus.detail == NotifyInferior)
{
XEvent ce;
+
ob_debug_type(OB_DEBUG_FOCUS,
"Focus went to pointer root/none or to our frame "
"window\n");
But if the other focus in is something like PointerRoot then we
still want to fall back.
*/
- if (XCheckIfEvent(ob_display, &ce, look_for_focusin_client, NULL)){
+ if (XCheckIfEvent(ob_display, &ce, event_look_for_focusin_client,
+ NULL))
+ {
XPutBackEvent(ob_display, &ce);
ob_debug_type(OB_DEBUG_FOCUS,
" but another FocusIn is coming\n");
focus_left_screen = FALSE;
if (!focus_left_screen)
- focus_tried = focus_fallback(TRUE);
+ focus_fallback(TRUE);
}
- } else if (client && client != focus_client) {
+ }
+ else if (client != focus_client) {
focus_left_screen = FALSE;
frame_adjust_focus(client->frame, TRUE);
focus_set_client(client);
client_calc_layer(client);
client_bring_helper_windows(client);
-
- focus_tried = NULL; /* focus isn't "trying" to go anywhere now */
}
} else if (e->type == FocusOut) {
gboolean nomove = FALSE;
XEvent ce;
/* Look for the followup FocusIn */
- if (!XCheckIfEvent(ob_display, &ce, look_for_focusin, NULL)) {
+ if (!XCheckIfEvent(ob_display, &ce, event_look_for_focusin, NULL)) {
/* There is no FocusIn, this means focus went to a window that
is not being managed, or a window on another screen. */
Window win, root;
ob_debug_type(OB_DEBUG_FOCUS,
"Focus went to an unmanaged window 0x%x !\n",
ce.xfocus.window);
- focus_tried = focus_fallback(TRUE);
+ focus_fallback(TRUE);
}
}
if (client && !nomove) {
frame_adjust_focus(client->frame, FALSE);
+ if (client == focus_client)
+ focus_set_client(NULL);
/* focus_set_client has already been called for sure */
client_calc_layer(client);
}
screen_set_num_desktops(d);
} else if (msgtype == prop_atoms.net_showing_desktop) {
screen_show_desktop(e->xclient.data.l[0] != 0, NULL);
- } else if (msgtype == prop_atoms.openbox_control) {
+ } else if (msgtype == prop_atoms.ob_control) {
if (e->xclient.data.l[0] == 1)
ob_reconfigure();
else if (e->xclient.data.l[0] == 2)
client->window, e->xunmap.event, e->xunmap.from_configure,
client->ignore_unmaps);
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 and it "
- "is being unmanaged:\n");
- if (XCheckIfEvent(ob_display, &ce, look_for_focusin_client, NULL)){
- XPutBackEvent(ob_display, &ce);
- ob_debug_type(OB_DEBUG_FOCUS,
- " but another FocusIn is coming\n");
- } else {
- ob_debug_type(OB_DEBUG_FOCUS,
- " so falling back focus again.\n");
- focus_tried = focus_fallback(TRUE);
- }
- }
break;
case DestroyNotify:
ob_debug("DestroyNotify for window 0x%x\n", client->window);
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 and it "
- "is being unmanaged:\n");
- if (XCheckIfEvent(ob_display, &ce, look_for_focusin_client, NULL)){
- XPutBackEvent(ob_display, &ce);
- ob_debug_type(OB_DEBUG_FOCUS,
- " but another FocusIn is coming\n");
- } else {
- ob_debug_type(OB_DEBUG_FOCUS,
- " so falling back focus again.\n");
- focus_tried = focus_fallback(TRUE);
- }
- }
break;
case ReparentNotify:
/* this is when the client is first taken captive in the frame */
ob_debug("ReparentNotify for window 0x%x\n", client->window);
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 and it "
- "is being unmanaged:\n");
- if (XCheckIfEvent(ob_display, &ce, look_for_focusin_client, NULL)){
- XPutBackEvent(ob_display, &ce);
- ob_debug_type(OB_DEBUG_FOCUS,
- " but another FocusIn is coming\n");
- } else {
- ob_debug_type(OB_DEBUG_FOCUS,
- " so falling back focus again.\n");
- focus_tried = focus_fallback(TRUE);
- }
- }
break;
case MapRequest:
ob_debug("MapRequest for 0x%lx\n", client->window);