From 0edc9deee5af65e5b5492290132e657a9a6af52f Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 7 Apr 2015 16:23:38 +0200 Subject: [PATCH] wayland: Create internal GdkWindow to be set as the DnD source During drag operations from another client, we currently set no window as the DnD source. There's paths in upper layers though that rely on it being set, just that we don't trigger these yet. --- gdk/wayland/gdkdevice-wayland.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index a22351b4d7..070837260a 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -95,6 +95,9 @@ struct _GdkWaylandDeviceData struct wl_surface *pointer_surface; guint current_output_scale; GSList *pointer_surface_outputs; + + /* Source/dest for non-local dnd */ + GdkWindow *foreign_dnd_window; }; struct _GdkWaylandDevice @@ -623,8 +626,10 @@ data_device_enter (void *data, dnd_owner = gdk_selection_owner_get_for_display (device->display, gdk_drag_get_selection (device->drop_context)); - if (dnd_owner) - _gdk_wayland_drag_context_set_source_window (device->drop_context, dnd_owner); + if (!dnd_owner) + dnd_owner = device->foreign_dnd_window; + + _gdk_wayland_drag_context_set_source_window (device->drop_context, dnd_owner); _gdk_wayland_drag_context_set_dest_window (device->drop_context, dest_window, serial); @@ -1838,6 +1843,26 @@ static const struct wl_surface_listener pointer_surface_listener = { pointer_surface_leave }; +static GdkWindow * +create_foreign_dnd_window (GdkDisplay *display) +{ + GdkWindowAttr attrs; + GdkScreen *screen; + guint mask; + + screen = gdk_display_get_default_screen (display); + + attrs.x = attrs.y = 0; + attrs.width = attrs.height = 1; + attrs.wclass = GDK_INPUT_OUTPUT; + attrs.window_type = GDK_WINDOW_TEMP; + attrs.visual = gdk_screen_get_system_visual (screen); + + mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; + + return gdk_window_new (gdk_screen_get_root_window (screen), &attrs, mask); +} + void _gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager, guint32 id, @@ -1857,6 +1882,7 @@ _gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager, device->device_manager = device_manager; device->touches = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_free); + device->foreign_dnd_window = create_foreign_dnd_window (display); device->wl_seat = wl_seat; wl_seat_add_listener (device->wl_seat, &seat_listener, device); @@ -1898,6 +1924,7 @@ _gdk_wayland_device_manager_remove_seat (GdkDeviceManager *manager, /* FIXME: destroy data_device */ g_clear_object (&device->keyboard_settings); g_hash_table_destroy (device->touches); + gdk_window_destroy (device->foreign_dnd_window); g_free (device); break;