[gtk+] wayland: Implement DND icon hotspot API



commit 561833334b470fd668c38b32e327660cba29e829
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Tue Dec 8 18:19:33 2015 +0800

    wayland: Implement DND icon hotspot API
    
    In Wayland, the hotspot of a DND icon is set using the buffer offset in
    wl_buffer.attach. To implement this, add a private API to cause the
    next wl_surface.attach to offset the new buffer with a given offset.
    Setting a DND icon hotspot sets this offset while also queuing a redraw
    of the window to trigger the wl_surface.attach.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=759168

 gdk/wayland/gdkdnd-wayland.c     |   16 ++++++++++++++--
 gdk/wayland/gdkprivate-wayland.h |    4 ++++
 gdk/wayland/gdkwindow-wayland.c  |   22 +++++++++++++++++++++-
 3 files changed, 39 insertions(+), 3 deletions(-)
---
diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c
index f20a0e7..fd0d0a3 100644
--- a/gdk/wayland/gdkdnd-wayland.c
+++ b/gdk/wayland/gdkdnd-wayland.c
@@ -306,8 +306,20 @@ gdk_wayland_drag_context_set_hotspot (GdkDragContext *context,
                                       gint            hot_x,
                                       gint            hot_y)
 {
-  GDK_WAYLAND_DRAG_CONTEXT (context)->hot_x = hot_x;
-  GDK_WAYLAND_DRAG_CONTEXT (context)->hot_y = hot_y;
+  GdkWaylandDragContext *context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context);
+  gint prev_hot_x = context_wayland->hot_x;
+  gint prev_hot_y = context_wayland->hot_y;
+  const GdkRectangle damage_rect = { .width = 1, .height = 1 };
+
+  context_wayland->hot_x = hot_x;
+  context_wayland->hot_y = hot_y;
+
+  if (prev_hot_x == hot_x && prev_hot_y == hot_y)
+    return;
+
+  _gdk_wayland_window_offset_next_wl_buffer (context_wayland->dnd_window,
+                                             -hot_x, -hot_y);
+  gdk_window_invalidate_rect (context_wayland->dnd_window, &damage_rect, FALSE);
 }
 
 static void
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index 00db37f..c4b5185 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -104,6 +104,10 @@ void            _gdk_wayland_window_register_dnd (GdkWindow *window);
 GdkDragContext *_gdk_wayland_window_drag_begin (GdkWindow *window,
                                                GdkDevice *device,
                                                GList     *targets);
+void            _gdk_wayland_window_offset_next_wl_buffer (GdkWindow *window,
+                                                           int        x,
+                                                           int        y);
+
 GdkDragContext * _gdk_wayland_drop_context_new (struct wl_data_device *data_device);
 void _gdk_wayland_drag_context_set_source_window (GdkDragContext *context,
                                                   GdkWindow      *window);
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index 60dfc59..9354c0d 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -121,6 +121,8 @@ struct _GdkWindowImplWayland
   GdkWindow *transient_for;
 
   cairo_surface_t *cairo_surface;
+  int pending_buffer_offset_x;
+  int pending_buffer_offset_y;
 
   gchar *title;
 
@@ -564,7 +566,10 @@ gdk_wayland_window_attach_image (GdkWindow *window)
   /* Attach this new buffer to the surface */
   wl_surface_attach (impl->surface,
                      _gdk_wayland_shm_surface_get_wl_buffer (impl->cairo_surface),
-                     0, 0);
+                     impl->pending_buffer_offset_x,
+                     impl->pending_buffer_offset_y);
+  impl->pending_buffer_offset_x = 0;
+  impl->pending_buffer_offset_y = 0;
 
   /* Only set the buffer scale if supported by the compositor */
   display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
@@ -2742,3 +2747,18 @@ gdk_wayland_window_set_dbus_properties_libgtk_only (GdkWindow  *window,
 
   maybe_set_gtk_surface_dbus_properties (window);
 }
+
+void
+_gdk_wayland_window_offset_next_wl_buffer (GdkWindow *window,
+                                           int        x,
+                                           int        y)
+{
+  GdkWindowImplWayland *impl;
+
+  g_return_if_fail (GDK_IS_WAYLAND_WINDOW (window));
+
+  impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+
+  impl->pending_buffer_offset_x = x;
+  impl->pending_buffer_offset_y = y;
+}


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