[gtk+/wayland-selections: 3/17] wayland: Improve implicit grab serial retrieval



commit cda72867b8cbdb8c60053e0d3849e34d611773ec
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Aug 13 21:05:58 2014 +0200

    wayland: Improve implicit grab serial retrieval
    
    _gdk_wayland_device_get_button_press_serial() has been replaced by
    _gdk_wayland_device_get_implicit_grab_serial(), which takes a touch/pointer
    event and figures out the relevant serial, and
    _gdk_wayland_device_get_last_implicit_grab_serial() which returns
    the most recent serial.
    
    The button press serial was currently using when operating popping up
    xdg_shell/surface popups and window menus, so this is now touch aware, of
    some sort.

 gdk/wayland/gdkdevice-wayland.c  |   46 ++++++++++++++++++++++++++++++++++++-
 gdk/wayland/gdkprivate-wayland.h |    5 +++-
 gdk/wayland/gdkwindow-wayland.c  |   20 +++++++++-------
 3 files changed, 59 insertions(+), 12 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index 9dda3d7..cc2be21 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -1820,9 +1820,51 @@ _gdk_wayland_device_manager_new (GdkDisplay *display)
 }
 
 uint32_t
-_gdk_wayland_device_get_button_press_serial (GdkWaylandDeviceData *device)
+_gdk_wayland_device_get_implicit_grab_serial (GdkWaylandDevice *device,
+                                              const GdkEvent   *event)
 {
-  return device->button_press_serial;
+  GdkEventSequence *sequence = NULL;
+  GdkWaylandTouchData *touch = NULL;
+
+  if (event)
+    sequence = gdk_event_get_event_sequence (event);
+
+  if (sequence)
+    touch = gdk_wayland_device_get_touch (device->device,
+                                          GDK_EVENT_SEQUENCE_TO_SLOT (sequence));
+  if (touch)
+    return touch->touch_down_serial;
+  else
+    return device->device->button_press_serial;
+}
+
+uint32_t
+_gdk_wayland_device_get_last_implicit_grab_serial (GdkWaylandDevice  *device,
+                                                   GdkEventSequence **sequence)
+{
+  GdkWaylandTouchData *touch;
+  GHashTableIter iter;
+  uint32_t serial = 0;
+
+  g_hash_table_iter_init (&iter, device->device->touches);
+
+  if (sequence)
+    *sequence = NULL;
+
+  if (device->device->button_press_serial > serial)
+    serial = device->device->button_press_serial;
+
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &touch))
+    {
+      if (touch->touch_down_serial > serial)
+        {
+          if (sequence)
+            *sequence = GDK_SLOT_TO_EVENT_SEQUENCE (touch->id);
+          serial = touch->touch_down_serial;
+        }
+    }
+
+  return serial;
 }
 
 static GdkAtom
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index aaaa8d7..e1867f6 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -143,7 +143,10 @@ void              _gdk_wayland_device_manager_remove_seat (GdkDeviceManager *dev
 typedef struct _GdkWaylandDeviceData GdkWaylandDeviceData;
 
 GdkKeymap *_gdk_wayland_device_get_keymap (GdkDevice *device);
-uint32_t _gdk_wayland_device_get_button_press_serial(GdkWaylandDeviceData *device);
+uint32_t _gdk_wayland_device_get_implicit_grab_serial(GdkWaylandDevice *device,
+                                                      const GdkEvent   *event);
+uint32_t _gdk_wayland_device_get_last_implicit_grab_serial (GdkWaylandDevice  *device,
+                                                            GdkEventSequence **seqence);
 
 void     _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event);
 GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display);
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index f26c3e0..097058a 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -963,7 +963,8 @@ gdk_wayland_window_create_xdg_popup (GdkWindow            *window,
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
   GdkWindowImplWayland *parent_impl = GDK_WINDOW_IMPL_WAYLAND (parent->impl);
-  GdkWaylandDeviceData *device;
+  GdkDeviceManager *device_manager;
+  GdkWaylandDevice *device;
   int x, y;
   int parent_x, parent_y;
 
@@ -973,7 +974,8 @@ gdk_wayland_window_create_xdg_popup (GdkWindow            *window,
   if (!parent_impl->surface)
     return;
 
-  device = wl_seat_get_user_data (seat);
+  device_manager = gdk_display_get_device_manager (GDK_DISPLAY (display_wayland));
+  device = GDK_WAYLAND_DEVICE (gdk_device_manager_get_client_pointer (device_manager));
 
   gdk_wayland_window_get_fake_root_coords (parent, &parent_x, &parent_y);
 
@@ -984,7 +986,7 @@ gdk_wayland_window_create_xdg_popup (GdkWindow            *window,
                                              impl->surface,
                                              parent_impl->surface,
                                              seat,
-                                             _gdk_wayland_device_get_button_press_serial (device),
+                                             _gdk_wayland_device_get_last_implicit_grab_serial (device, 
NULL),
                                              x, y, flags);
 
   xdg_popup_add_listener (impl->xdg_popup, &xdg_popup_listener, window);
@@ -1917,15 +1919,16 @@ gdk_wayland_window_show_window_menu (GdkWindow *window,
                                      GdkEvent  *event)
 {
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
-  GdkEventButton *event_button = (GdkEventButton *) event;
   struct wl_seat *seat;
+  GdkWaylandDevice *device;
   double x, y;
-  GdkWaylandDeviceData *device;
 
   switch (event->type)
     {
     case GDK_BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+    case GDK_TOUCH_BEGIN:
+    case GDK_TOUCH_END:
       break;
     default:
       return FALSE;
@@ -1934,14 +1937,13 @@ gdk_wayland_window_show_window_menu (GdkWindow *window,
   if (!impl->xdg_surface)
     return FALSE;
 
-  seat = gdk_wayland_device_get_wl_seat (event_button->device);
-  device = wl_seat_get_user_data (seat);
-
+  device = GDK_WAYLAND_DEVICE (gdk_event_get_device (event));
+  seat = gdk_wayland_device_get_wl_seat (GDK_DEVICE (device));
   gdk_event_get_coords (event, &x, &y);
 
   xdg_surface_show_window_menu (impl->xdg_surface,
                                 seat,
-                                _gdk_wayland_device_get_button_press_serial (device),
+                                _gdk_wayland_device_get_implicit_grab_serial (device, event),
                                 x, y);
   return TRUE;
 }


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