[mutter/wip/wayland] wayland: Don't synthesize button press and release events



commit 40a055f89ab6bc17d4e9153f8363643ffd5efb77
Author: Neil Roberts <neil linux intel com>
Date:   Wed Jan 18 21:26:29 2012 +0000

    wayland: Don't synthesize button press and release events
    
    The Wayland compositor synthesizes X mouse events for the rest of
    Mutter so that it won't suffer from problems with lag when updating
    the position of the X window compared to the position of the Wayland
    surface while dragging a window. This was causing problems for button
    press events because the synthesized events always contain the X
    window for the frame instead of the application window. This was
    messing up the synchronous passive grab that the X server does when
    the user clicks on an inactive window. The device was then getting
    frozen to wait for a response from the window manager but the response
    was never being sent so the server would stop sending events to
    clients. To fix this it now only synthesizes motion events and not
    button press and release events.

 src/core/display.c         |   11 ++-----
 src/wayland/meta-wayland.c |   68 +++++++++++++++++++------------------------
 2 files changed, 33 insertions(+), 46 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index ffba916..a25bf29 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -2678,7 +2678,7 @@ event_callback (XEvent  *event,
 {
   MetaDisplay *display = data;
 
-  /* Under Wayland we want to filter out mouse events so we can
+  /* Under Wayland we want to filter out mouse motion events so we can
      synthesize them from the Clutter events instead. This is
      necessary because the position in the mouse events is passed to
      the X server relative to the position of the surface. The X
@@ -2689,13 +2689,8 @@ event_callback (XEvent  *event,
      position from the surface position. Instead we bypass the
      translation altogether by directly using the Clutter events */
 #ifdef HAVE_WAYLAND
-  switch (event->type)
-    {
-    case ButtonPress:
-    case ButtonRelease:
-    case MotionNotify:
-      return FALSE;
-    }
+  if (event->type == MotionNotify)
+    return FALSE;
 #endif
 
   return meta_display_handle_event (display, event);
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index c0f995a..8490017 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -1068,7 +1068,7 @@ event_cb (ClutterActor *stage,
     (struct wl_input_device *) compositor->input_device;
   MetaWaylandSurface *surface;
   MetaDisplay *display;
-  XEvent xevent;
+  XMotionEvent xevent;
 
   meta_wayland_input_device_handle_event (compositor->input_device, event);
 
@@ -1076,45 +1076,42 @@ event_cb (ClutterActor *stage,
   if (!display)
     return FALSE;
 
-  /* We want to synthesize X events for mouse related events so that
-     we don't have to rely on the X server's window position being
+  /* We want to synthesize X events for mouse motion events so that we
+     don't have to rely on the X server's window position being
      synched with the surface positoin. See the comment in
      event_callback() in display.c */
 
   switch (event->type)
     {
     case CLUTTER_BUTTON_PRESS:
-      xevent.type = ButtonPress;
-      xevent.xbutton.button = event->button.button;
-      xevent.xbutton.same_screen = TRUE;
-
       if (compositor->implicit_grab_surface == NULL)
         {
           compositor->implicit_grab_button = event->button.button;
           compositor->implicit_grab_surface = device->current;
         }
-      break;
+      return FALSE;
 
     case CLUTTER_BUTTON_RELEASE:
-      xevent.type = ButtonRelease;
-      xevent.xbutton.button = event->button.button;
-      xevent.xbutton.same_screen = TRUE;
-      break;
+      if (event->type == CLUTTER_BUTTON_RELEASE &&
+          compositor->implicit_grab_surface &&
+          event->button.button == compositor->implicit_grab_button)
+        compositor->implicit_grab_surface = NULL;
+      return FALSE;
 
     case CLUTTER_MOTION:
-      xevent.type = MotionNotify;
-      xevent.xmotion.is_hint = NotifyNormal;
-      xevent.xbutton.same_screen = TRUE;
       break;
 
     default:
       return FALSE;
     }
 
-  xevent.xany.serial = 0;
-  xevent.xany.send_event = False;
-  xevent.xany.display = display->xdisplay;
-  xevent.xbutton.root = DefaultRootWindow (display->xdisplay);
+  xevent.type = MotionNotify;
+  xevent.is_hint = NotifyNormal;
+  xevent.same_screen = TRUE;
+  xevent.serial = 0;
+  xevent.send_event = False;
+  xevent.display = display->xdisplay;
+  xevent.root = DefaultRootWindow (display->xdisplay);
 
   if (compositor->implicit_grab_surface)
     surface = (MetaWaylandSurface *) compositor->implicit_grab_surface;
@@ -1123,8 +1120,8 @@ event_cb (ClutterActor *stage,
 
   if (surface == (MetaWaylandSurface *) device->current)
     {
-      xevent.xbutton.x = device->current_x;
-      xevent.xbutton.y = device->current_y;
+      xevent.x = device->current_x;
+      xevent.y = device->current_y;
     }
   else if (surface)
     {
@@ -1133,35 +1130,30 @@ event_cb (ClutterActor *stage,
       clutter_actor_transform_stage_point (surface->actor,
                                            device->x, device->y,
                                            &ax, &ay);
-      xevent.xbutton.x = ax;
-      xevent.xbutton.y = ay;
+      xevent.x = ax;
+      xevent.y = ay;
     }
   else
     {
-      xevent.xbutton.x = device->x;
-      xevent.xbutton.y = device->y;
+      xevent.x = device->x;
+      xevent.y = device->y;
     }
 
   if (surface && surface->xid != None)
-    xevent.xbutton.window = surface->xid;
+    xevent.window = surface->xid;
   else
-    xevent.xbutton.window = xevent.xbutton.root;
+    xevent.window = xevent.root;
 
   /* Mutter doesn't really know about the sub-windows. This assumes it
      doesn't care either */
-  xevent.xbutton.subwindow = xevent.xbutton.window;
-  xevent.xbutton.time = event->any.time;
-  xevent.xbutton.x_root = device->x;
-  xevent.xbutton.y_root = device->y;
+  xevent.subwindow = xevent.window;
+  xevent.time = event->any.time;
+  xevent.x_root = device->x;
+  xevent.y_root = device->y;
   /* The Clutter state flags exactly match the X values */
-  xevent.xbutton.state = clutter_event_get_state (event);
-
-  if (event->type == CLUTTER_BUTTON_RELEASE &&
-      compositor->implicit_grab_surface &&
-      event->button.button == compositor->implicit_grab_button)
-    compositor->implicit_grab_surface = NULL;
+  xevent.state = clutter_event_get_state (event);
 
-  meta_display_handle_event (display, &xevent);
+  meta_display_handle_event (display, (XEvent *) &xevent);
 
   return FALSE;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]