[mutter/wip/wayland] wayland: Update to the new grab API



commit e61297053ceeaca11f0787c2faa83ff5fd3c5bef
Author: Neil Roberts <neil linux intel com>
Date:   Thu Jan 12 14:59:48 2012 +0000

    wayland: Update to the new grab API
    
    This uses the new grab API from Wayland commit 5ffe9f4708. The grab
    interface implementation has been removed so that it can just use the
    default one which is now in the wayland-server code.

 src/wayland/meta-wayland-input-device.c |  228 ++++++++++++-------------------
 src/wayland/meta-wayland-input-device.h |    4 +
 src/wayland/meta-wayland-private.h      |    2 +
 src/wayland/meta-wayland.c              |   12 ++
 4 files changed, 108 insertions(+), 138 deletions(-)
---
diff --git a/src/wayland/meta-wayland-input-device.c b/src/wayland/meta-wayland-input-device.c
index 89b71dc..b5affe9 100644
--- a/src/wayland/meta-wayland-input-device.c
+++ b/src/wayland/meta-wayland-input-device.c
@@ -33,64 +33,7 @@ struct _MetaWaylandInputDevice
 {
   struct wl_input_device parent;
 
-  /* Last position of the pointer */
-  float pointer_x, pointer_y;
-
-  /* Position of the pointer within the surface */
-  int32_t pointer_sx, pointer_sy;
-};
-
-static void
-implicit_grab_motion (struct wl_grab *grab,
-                      uint32_t time,
-                      int32_t x,
-                      int32_t y)
-{
-  struct wl_resource *resource;
-
-  resource = grab->input_device->pointer_focus_resource;
-
-  if (resource)
-    {
-      MetaWaylandSurface *surface =
-        (MetaWaylandSurface *) grab->input_device->pointer_focus;
-      float sx, sy;
-
-      clutter_actor_transform_stage_point (surface->actor,
-                                           x,
-                                           y,
-                                           &sx,
-                                           &sy);
-
-      wl_resource_post_event (resource, WL_INPUT_DEVICE_MOTION,
-                              time, x, y, (int32_t) sx, (int32_t) sy);
-    }
-}
-
-static void
-implicit_grab_button (struct wl_grab *grab,
-                      uint32_t time,
-                      int32_t button,
-                      int32_t state)
-{
-  struct wl_resource *resource;
-
-  resource = grab->input_device->pointer_focus_resource;
-
-  if (resource)
-    wl_resource_post_event (resource, WL_INPUT_DEVICE_BUTTON,
-                            time, button, state);
-}
-
-static void
-implicit_grab_end(struct wl_grab *grab, uint32_t time)
-{
-}
-
-static const struct wl_grab_interface implicit_grab_interface = {
-  implicit_grab_motion,
-  implicit_grab_button,
-  implicit_grab_end
+  ClutterActor *current_stage;
 };
 
 static void
@@ -143,8 +86,6 @@ meta_wayland_input_device_new (struct wl_display *display)
 
   wl_input_device_init (&device->parent);
 
-  device->parent.implicit_grab.interface = &implicit_grab_interface;
-
   wl_display_add_global (display,
                          &wl_input_device_interface,
                          device,
@@ -154,73 +95,23 @@ meta_wayland_input_device_new (struct wl_display *display)
 }
 
 static void
-set_pointer_focus_for_event (MetaWaylandInputDevice *input_device,
-                             const ClutterEvent *event)
-{
-  struct wl_input_device *device =
-    (struct wl_input_device *) input_device;
-  struct wl_surface *surface;
-
-  clutter_event_get_coords (event,
-                            &input_device->pointer_x,
-                            &input_device->pointer_y);
-
-  if (CLUTTER_WAYLAND_IS_SURFACE (event->any.source))
-    {
-      ClutterWaylandSurface *surface_actor =
-        CLUTTER_WAYLAND_SURFACE (event->any.source);
-      float fsx, fsy;
-
-      surface = clutter_wayland_surface_get_surface (surface_actor);
-
-      clutter_actor_transform_stage_point (event->any.source,
-                                           input_device->pointer_x,
-                                           input_device->pointer_y,
-                                           &fsx, &fsy);
-      input_device->pointer_sx = fsx;
-      input_device->pointer_sy = fsy;
-    }
-  else
-    {
-      surface = NULL;
-      input_device->pointer_sx = input_device->pointer_x;
-      input_device->pointer_sy = input_device->pointer_y;
-    }
-
-  wl_input_device_set_pointer_focus (device,
-                                     surface,
-                                     event->any.time,
-                                     input_device->pointer_x,
-                                     input_device->pointer_y,
-                                     input_device->pointer_sx,
-                                     input_device->pointer_sy);
-}
-
-static void
 handle_motion_event (MetaWaylandInputDevice *input_device,
                      const ClutterMotionEvent *event)
 {
   struct wl_input_device *device =
     (struct wl_input_device *) input_device;
 
-  if (device->grab)
-    device->grab->interface->motion (device->grab,
-                                     event->time,
-                                     event->x,
-                                     event->y);
-  else
-    {
-      set_pointer_focus_for_event (input_device, (const ClutterEvent *) event);
-
-      if (device->pointer_focus_resource)
-        wl_resource_post_event (device->pointer_focus_resource,
-                                WL_INPUT_DEVICE_MOTION,
-                                time,
-                                (int32_t) input_device->pointer_x,
-                                (int32_t) input_device->pointer_y,
-                                input_device->pointer_sx,
-                                input_device->pointer_sy);
-    }
+  device->x = event->x;
+  device->y = event->y;
+
+  meta_wayland_input_device_repick (input_device,
+                                    event->time,
+                                    event->source);
+
+  device->grab->interface->motion (device->grab,
+                                   event->time,
+                                   device->grab->x,
+                                   device->grab->y);
 }
 
 static void
@@ -229,7 +120,6 @@ handle_button_event (MetaWaylandInputDevice *input_device,
 {
   struct wl_input_device *device =
     (struct wl_input_device *) input_device;
-  struct wl_surface *surface = device->pointer_focus;
   gboolean state = event->type == CLUTTER_BUTTON_PRESS;
   uint32_t button;
 
@@ -250,24 +140,22 @@ handle_button_event (MetaWaylandInputDevice *input_device,
       break;
     }
 
-  if (state && surface && device->grab == NULL)
-    wl_input_device_start_grab (device,
-                                &device->implicit_grab,
-                                button,
-                                event->time);
-
-  if (device->grab)
-    device->grab->interface->button (device->grab,
-                                     event->time,
-                                     button,
-                                     state);
-
-  if (!state && device->grab && device->grab_button == button)
+  if (state)
     {
-      wl_input_device_end_grab (device, event->time);
-
-      set_pointer_focus_for_event (input_device, (const ClutterEvent *) event);
+      if (device->button_count == 0)
+        {
+          device->grab_button = button;
+          device->grab_time = event->time;
+          device->grab_x = device->x;
+          device->grab_y = device->y;
+        }
+
+      device->button_count++;
     }
+  else
+    device->button_count--;
+
+  device->grab->interface->button (device->grab, event->time, button, state);
 }
 
 void
@@ -291,3 +179,67 @@ meta_wayland_input_device_handle_event (MetaWaylandInputDevice *input_device,
       break;
     }
 }
+
+/* The actor argument can be NULL in which case a Clutter pick will be
+   performed to determine the right actor. An actor should only be
+   passed if the repick is being performed due to an event in which
+   case Clutter will have already performed a pick so we can avoid
+   redundantly doing another one */
+void
+meta_wayland_input_device_repick (MetaWaylandInputDevice *device,
+                                  uint32_t                time,
+                                  ClutterActor           *actor)
+{
+  struct wl_input_device *input_device = (struct wl_input_device *) device;
+  struct wl_surface *surface;
+  MetaWaylandSurface *focus;
+
+  if (actor == NULL && device->current_stage)
+    {
+      ClutterStage *stage = CLUTTER_STAGE (device->current_stage);
+      actor = clutter_stage_get_actor_at_pos (stage,
+                                              CLUTTER_PICK_REACTIVE,
+                                              input_device->x, input_device->y);
+    }
+
+  if (actor)
+    device->current_stage = clutter_actor_get_stage (actor);
+  else
+    device->current_stage = NULL;
+
+  if (CLUTTER_WAYLAND_IS_SURFACE (actor))
+    {
+      ClutterWaylandSurface *wl_surface = CLUTTER_WAYLAND_SURFACE (actor);
+      float ax, ay;
+
+      clutter_actor_transform_stage_point (actor,
+                                           input_device->x, input_device->y,
+                                           &ax, &ay);
+      input_device->current_x = ax;
+      input_device->current_y = ay;
+
+      surface = clutter_wayland_surface_get_surface (wl_surface);
+    }
+  else
+    surface = NULL;
+
+  if (surface != input_device->current)
+    {
+      const struct wl_grab_interface *interface = input_device->grab->interface;
+      interface->focus (input_device->grab, time, surface,
+                        input_device->current_x, input_device->current_y);
+      input_device->current = surface;
+    }
+
+  focus = (MetaWaylandSurface *) input_device->grab->focus;
+  if (focus)
+    {
+      float ax, ay;
+
+      clutter_actor_transform_stage_point (focus->actor,
+                                           input_device->x, input_device->y,
+                                           &ax, &ay);
+      input_device->grab->x = ax;
+      input_device->grab->y = ay;
+    }
+}
diff --git a/src/wayland/meta-wayland-input-device.h b/src/wayland/meta-wayland-input-device.h
index bcb4068..12a0e9f 100644
--- a/src/wayland/meta-wayland-input-device.h
+++ b/src/wayland/meta-wayland-input-device.h
@@ -29,4 +29,8 @@ MetaWaylandInputDevice *meta_wayland_input_device_new          (struct wl_displa
 void                    meta_wayland_input_device_handle_event (MetaWaylandInputDevice *input_device,
                                                                 const ClutterEvent     *event);
 
+void                    meta_wayland_input_device_repick       (MetaWaylandInputDevice *input_device,
+                                                                uint32_t                time,
+                                                                ClutterActor           *actor);
+
 #endif /* META_WAYLAND_INPUT_H */
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index 563b9a9..cd10bd9 100644
--- a/src/wayland/meta-wayland-private.h
+++ b/src/wayland/meta-wayland-private.h
@@ -129,4 +129,6 @@ void                    meta_wayland_handle_sig_child       (void);
 
 MetaWaylandSurface     *meta_wayland_lookup_surface_for_xid (guint32 xid);
 
+void                    meta_wayland_compositor_repick      (MetaWaylandCompositor *compositor);
+
 #endif /* META_WAYLAND_PRIVATE_H */
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index e07e34b..de4f92c 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -344,6 +344,16 @@ const struct wl_surface_interface meta_wayland_surface_interface = {
   meta_wayland_surface_frame
 };
 
+/* This should be called whenever the window stacking changes to
+   update the current position on all of the input devices */
+void
+meta_wayland_compositor_repick (MetaWaylandCompositor *compositor)
+{
+  meta_wayland_input_device_repick (compositor->input_device,
+                                    get_time (),
+                                    NULL);
+}
+
 static void
 meta_wayland_surface_free (MetaWaylandSurface *surface)
 {
@@ -364,6 +374,8 @@ meta_wayland_surface_free (MetaWaylandSurface *surface)
     }
 
   g_slice_free (MetaWaylandSurface, surface);
+
+  meta_wayland_compositor_repick (compositor);
 }
 
 static void



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