[mutter/wip/dnd-surface3: 1/11] wayland: Add enter/leave methods to the grab vtable



commit 80f03b75a8122c1680b3a5d9700b212a951a32dd
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Oct 6 16:29:18 2014 +0200

    wayland: Add enter/leave methods to the grab vtable
    
    This is to make enter/leave behavior dependent on the current
    grab. These vmethods should take care of what enter/leave means
    in the grab context, performing any event delivery or client
    resource management necessary.
    
    The code that used to maintain the focus_surface and deliver
    crossing events to the affected clients has been split into
    these new vmethods, and used by both the default and popup
    grab modes.
    
    It is now a responsibility of grab implementations to call
    meta_wayland_pointer_set_focus() on their motion handler if
    they wish the focus_surface to be up-to-date, and get the
    enter/leave methods accordingly run.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=728030

 src/wayland/meta-wayland-pointer.c |  171 +++++++++++++++++++++---------------
 src/wayland/meta-wayland-pointer.h |    4 +
 2 files changed, 104 insertions(+), 71 deletions(-)
---
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index 3fc05ec..cdcb32d 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -57,6 +57,8 @@
 #define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
 
 static void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer);
+static void broadcast_focus (MetaWaylandPointer *pointer,
+                             struct wl_resource *resource);
 
 static void
 unbind_resource (struct wl_resource *resource)
@@ -181,10 +183,100 @@ default_grab_button (MetaWaylandPointerGrab *grab,
     meta_wayland_pointer_set_focus (pointer, pointer->current);
 }
 
+static void
+move_resources (struct wl_list *destination, struct wl_list *source)
+{
+  wl_list_insert_list (destination, source);
+  wl_list_init (source);
+}
+
+static void
+move_resources_for_client (struct wl_list *destination,
+                          struct wl_list *source,
+                          struct wl_client *client)
+{
+  struct wl_resource *resource, *tmp;
+  wl_resource_for_each_safe (resource, tmp, source)
+    {
+      if (wl_resource_get_client (resource) == client)
+        {
+          wl_list_remove (wl_resource_get_link (resource));
+          wl_list_insert (destination, wl_resource_get_link (resource));
+        }
+    }
+}
+
+static void
+default_grab_enter (MetaWaylandPointerGrab *grab,
+                    MetaWaylandSurface     *surface)
+{
+  MetaWaylandPointer *pointer = grab->pointer;
+  struct wl_resource *resource;
+  struct wl_list *l;
+  ClutterPoint pos;
+
+  wl_resource_add_destroy_listener (surface->resource, &pointer->focus_surface_listener);
+
+  clutter_input_device_get_coords (pointer->device, NULL, &pos);
+
+  meta_window_handle_enter (surface->window,
+                            /* XXX -- can we reliably get a timestamp for setting focus? */
+                            clutter_get_current_event_time (),
+                            pos.x, pos.y);
+
+  move_resources_for_client (&pointer->focus_resource_list,
+                             &pointer->resource_list,
+                             wl_resource_get_client (pointer->focus_surface->resource));
+
+  l = &pointer->focus_resource_list;
+
+  if (!wl_list_empty (l))
+    {
+      struct wl_client *client = wl_resource_get_client (surface->resource);
+      struct wl_display *display = wl_client_get_display (client);
+
+      pointer->focus_serial = wl_display_next_serial (display);
+
+      wl_resource_for_each (resource, l)
+        {
+          broadcast_focus (pointer, resource);
+        }
+    }
+}
+
+static void
+default_grab_leave (MetaWaylandPointerGrab *grab,
+                    MetaWaylandSurface     *surface)
+{
+  MetaWaylandPointer *pointer = grab->pointer;
+  struct wl_resource *resource;
+  struct wl_list *l;
+
+  l = &pointer->focus_resource_list;
+
+  if (!wl_list_empty (l))
+    {
+      struct wl_client *client = wl_resource_get_client (surface->resource);
+      struct wl_display *display = wl_client_get_display (client);
+      uint32_t serial = wl_display_next_serial (display);
+
+      wl_resource_for_each (resource, l)
+        {
+          wl_pointer_send_leave (resource, serial, surface->resource);
+        }
+
+      move_resources (&pointer->resource_list, &pointer->focus_resource_list);
+    }
+
+  wl_list_remove (&pointer->focus_surface_listener.link);
+}
+
 static const MetaWaylandPointerGrabInterface default_pointer_grab_interface = {
   default_grab_focus,
   default_grab_motion,
-  default_grab_button
+  default_grab_button,
+  default_grab_enter,
+  default_grab_leave
 };
 
 void
@@ -446,29 +538,6 @@ meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer,
 }
 
 static void
-move_resources (struct wl_list *destination, struct wl_list *source)
-{
-  wl_list_insert_list (destination, source);
-  wl_list_init (source);
-}
-
-static void
-move_resources_for_client (struct wl_list *destination,
-                          struct wl_list *source,
-                          struct wl_client *client)
-{
-  struct wl_resource *resource, *tmp;
-  wl_resource_for_each_safe (resource, tmp, source)
-    {
-      if (wl_resource_get_client (resource) == client)
-        {
-          wl_list_remove (wl_resource_get_link (resource));
-          wl_list_insert (destination, wl_resource_get_link (resource));
-        }
-    }
-}
-
-static void
 broadcast_focus (MetaWaylandPointer *pointer,
                  struct wl_resource *resource)
 {
@@ -490,60 +559,18 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
 
   if (pointer->focus_surface != NULL)
     {
-      struct wl_resource *resource;
-      struct wl_list *l;
-
-      l = &pointer->focus_resource_list;
-      if (!wl_list_empty (l))
-        {
-          struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
-          struct wl_display *display = wl_client_get_display (client);
-          uint32_t serial = wl_display_next_serial (display);
-
-          wl_resource_for_each (resource, l)
-            {
-              wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource);
-            }
-
-          move_resources (&pointer->resource_list, &pointer->focus_resource_list);
-        }
+      if (pointer->grab->interface->leave)
+        pointer->grab->interface->leave (pointer->grab, pointer->focus_surface);
 
-      wl_list_remove (&pointer->focus_surface_listener.link);
       pointer->focus_surface = NULL;
     }
 
   if (surface != NULL)
     {
-      struct wl_resource *resource;
-      struct wl_list *l;
-      ClutterPoint pos;
-
       pointer->focus_surface = surface;
-      wl_resource_add_destroy_listener (pointer->focus_surface->resource, &pointer->focus_surface_listener);
-
-      clutter_input_device_get_coords (pointer->device, NULL, &pos);
-
-      meta_window_handle_enter (pointer->focus_surface->window,
-                                /* XXX -- can we reliably get a timestamp for setting focus? */
-                                clutter_get_current_event_time (),
-                                pos.x, pos.y);
 
-      move_resources_for_client (&pointer->focus_resource_list,
-                                 &pointer->resource_list,
-                                 wl_resource_get_client (pointer->focus_surface->resource));
-
-      l = &pointer->focus_resource_list;
-      if (!wl_list_empty (l))
-        {
-          struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
-          struct wl_display *display = wl_client_get_display (client);
-          pointer->focus_serial = wl_display_next_serial (display);
-
-          wl_resource_for_each (resource, l)
-            {
-              broadcast_focus (pointer, resource);
-            }
-        }
+      if (pointer->grab->interface->enter)
+        pointer->grab->interface->enter (pointer->grab, pointer->focus_surface);
     }
 }
 
@@ -623,7 +650,9 @@ popup_grab_button (MetaWaylandPointerGrab *grab,
 static MetaWaylandPointerGrabInterface popup_grab_interface = {
   popup_grab_focus,
   popup_grab_motion,
-  popup_grab_button
+  popup_grab_button,
+  default_grab_enter,
+  default_grab_leave
 };
 
 static void
diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h
index 6bd01a8..9e4739c 100644
--- a/src/wayland/meta-wayland-pointer.h
+++ b/src/wayland/meta-wayland-pointer.h
@@ -36,6 +36,10 @@ struct _MetaWaylandPointerGrabInterface
                  const ClutterEvent     *event);
   void (*button) (MetaWaylandPointerGrab *grab,
                  const ClutterEvent     *event);
+  void (*enter) (MetaWaylandPointerGrab *grab,
+                 MetaWaylandSurface     *surface);
+  void (*leave) (MetaWaylandPointerGrab *grab,
+                 MetaWaylandSurface     *surface);
 };
 
 struct _MetaWaylandPointerGrab


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