From e590cd2b9997182f4c3cf36c2f923d8e890a8472 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Wed, 14 Jul 2010 16:08:16 -0400 Subject: [PATCH] Don't screw up the event mask when "managing" our own windows When we do pseudo-management on an override-redirect window, we have to be careful to augment the existing event mask, not replace it, or delivery of pointer events will be disrupted. When we unmanage a window, we shouldn't try to unselect events at all, since that will interfere with event selection done by GDK. http://bugzilla.gnome.org/show_bug.cgi?id=597763 --- src/core/window.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index ec92091cd..a9ab88958 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -636,7 +636,11 @@ meta_window_new_with_attrs (MetaDisplay *display, if (attrs->override_redirect) event_mask |= StructureNotifyMask; - XSelectInput (display->xdisplay, xwindow, event_mask); + /* If the window is from this client (a menu, say) we need to augment + * the event mask, not replace it. For windows from other clients, + * attrs->your_event_mask will be empty at this point. + */ + XSelectInput (display->xdisplay, xwindow, attrs->your_event_mask | event_mask); has_shape = FALSE; #ifdef HAVE_SHAPE @@ -1518,19 +1522,24 @@ meta_window_unmanage (MetaWindow *window, XRemoveFromSaveSet (window->display->xdisplay, window->xwindow); - /* Don't get events on not-managed windows */ - XSelectInput (window->display->xdisplay, - window->xwindow, - NoEventMask); + /* Even though the window is now unmanaged, we can't unselect events. This + * window might be a window from this process, like a GdkMenu, in + * which case it will have pointer events and so forth selected + * for it by GDK. There's no way to disentangle those events from the events + * we've selected. Even for a window from a different X client, + * GDK could also have selected events for it for IPC purposes, so we + * can't unselect in that case either. + * + * Similarly, we can't unselected for events on window->user_time_window. + * It might be our own GDK focus window, or it might be a window that a + * different client is using for multiple different things: + * _NET_WM_USER_TIME_WINDOW and IPC, perhaps. + */ - /* Stop getting events for the window's _NET_WM_USER_TIME_WINDOW too */ if (window->user_time_window != None) { meta_display_unregister_x_window (window->display, window->user_time_window); - XSelectInput (window->display->xdisplay, - window->user_time_window, - NoEventMask); window->user_time_window = None; }