[gtk+] wayland: Implement DND icon hotspot API
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] wayland: Implement DND icon hotspot API
- Date: Tue, 8 Dec 2015 17:32:30 +0000 (UTC)
commit 3ab9d96623bc30678cbffc3bf9ec5133e714e87c
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 | 26 ++++++++++++++++++++++++--
gdk/wayland/gdkprivate-wayland.h | 4 ++++
gdk/wayland/gdkwindow-wayland.c | 33 ++++++++++++++++++++++++++++++++-
3 files changed, 60 insertions(+), 3 deletions(-)
---
diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c
index f20a0e7..0bb3279 100644
--- a/gdk/wayland/gdkdnd-wayland.c
+++ b/gdk/wayland/gdkdnd-wayland.c
@@ -24,6 +24,7 @@
#include "gdkproperty.h"
#include "gdkprivate-wayland.h"
#include "gdkdisplay-wayland.h"
+#include "gdkwaylandwindow.h"
#include "gdkdeviceprivate.h"
@@ -48,6 +49,8 @@ struct _GdkWaylandDragContext
uint32_t serial;
gdouble x;
gdouble y;
+ gint prev_hot_x;
+ gint prev_hot_y;
gint hot_x;
gint hot_y;
};
@@ -306,8 +309,27 @@ 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);
+
+ context_wayland->prev_hot_x = context_wayland->hot_x;
+ context_wayland->prev_hot_y = context_wayland->hot_x;
+ context_wayland->hot_x = hot_x;
+ context_wayland->hot_y = hot_y;
+
+ if (context_wayland->prev_hot_x == hot_x &&
+ context_wayland->prev_hot_x == hot_x)
+ return;
+
+ _gdk_wayland_window_offset_next_wl_buffer (context_wayland->dnd_window,
+ -hot_x, -hot_y);
+ gdk_window_invalidate_rect (context_wayland->dnd_window,
+ &(GdkRectangle) {
+ .x = 0,
+ .y = 0,
+ .width = 1,
+ .height = 1,
+ },
+ 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..9a01d42 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));
@@ -2564,6 +2569,32 @@ gdk_wayland_window_get_wl_surface (GdkWindow *window)
return GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface;
}
+/**
+ * gdk_wayland_window_offset_next_wl_buffer:
+ * @window (type GdkWaylandWindow): a #GdkWindow
+ * @x: x offset which the next buffer should be attached at
+ * @y: y offset which the next buffer should be attached at
+ *
+ * Make GDK attach the next buffer at the given offset. This is useful for
+ * DND icons which may have a hotspot other than (0, 0).
+ *
+ * Since: 3.20
+ */
+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;
+}
+
static struct wl_egl_window *
gdk_wayland_window_get_wl_egl_window (GdkWindow *window)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]