[PATCH xserver 1/2] xwayland: make sure release events are posted only to wm window

Tiago Vignatti tiago.vignatti at intel.com
Fri Jul 20 09:38:10 PDT 2012


An implicit passive grab is always installed (ActivateImplicitGrab) when
button is down and, on the code in question, the ButtonPress event is sent
to the XWM. So from now on, all the events will be delivered only to the
XWM window because of the grab; that's what we want. Later, when the button is
released, the fake ButtonRelease will be sent accordingly and the grab itself
deactivated. But the fundamental part to understand is: DeliverGrabbedEvent is
always called *before* DeactivateGrab (in ProcessDeviceEvent).

This patch doesn't make any changes on the semantics. It just ensures what
we've been doing so far is reasonable.

Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---
 hw/xfree86/xwayland/xwayland-input.c |   22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
index d9f352f..aaa9cbe 100644
--- a/hw/xfree86/xwayland/xwayland-input.c
+++ b/hw/xfree86/xwayland/xwayland-input.c
@@ -267,33 +267,43 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
 {
     struct xwl_seat *xwl_seat = data;
     DeviceIntPtr dev = xwl_seat->pointer;
+    DeviceIntPtr dev_master = dev->master;
     int i;
     int sx = wl_fixed_to_int(sx_w);
     int sy = wl_fixed_to_int(sy_w);
     ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
+    WindowPtr wmWindow;
 
     xwl_seat->xwl_screen->serial = serial;
     xwl_seat->pointer_enter_serial = serial;
 
     xwl_seat->focus_window = wl_surface_get_user_data(surface);
+    wmWindow = xwl_seat->focus_window->window;
 
     (*pScreen->SetCursorPosition) (dev, pScreen, sx, sy, TRUE);
 
-    SetDeviceRedirectWindow(xwl_seat->pointer, xwl_seat->focus_window->window);
+    SetDeviceRedirectWindow(xwl_seat->pointer, wmWindow);
 
-    /* Ideally, X clients shouldn't see these button releases.  When
+    /* In principle, X clients shouldn't see button releases.  When
      * the pointer leaves a window with buttons down, it means that
      * the wayland compositor has grabbed the pointer.  The button
      * release event is consumed by whatever grab in the compositor
      * and won't be sent to clients (the X server is a client).
      * However, we need to reset X's idea of which buttons are up and
      * down, and they're all up (by definition) when the pointer
-     * enters a window.  We should figure out a way to swallow these
-     * events, perhaps using an X grab whenever the pointer is not in
-     * any X window, but for now just send the events. */
+     * enters a window. The implicit passive grab installed when buttons
+     * are down (ActivateImplicitGrab) ensures that all events, including
+     * the fake ButtonRelease one, will route to the WM window only. The
+     * grab gets deactivated only after ButtonRelease is sent. */
     for (i = 0; i < dev->button->numButtons; i++)
-	if (BitIsOn(dev->button->down, i))
+	if (BitIsOn(dev->button->down, i)) {
+	    if ((dev_master->deviceGrab.grab &&
+		dev_master->deviceGrab.grab->window == wmWindow) ||
+		dev_master->deviceGrab.activeGrab)
 		xf86PostButtonEvent(dev, TRUE, i, 0, 0, 0);
+	    else
+		ErrorF("Implementation fail\n");
+	}
 
     (*pScreen->DisplayCursor)(dev, pScreen, dev->spriteInfo->sprite->current);
 }
-- 
1.7.9.5



More information about the wayland-devel mailing list