From 682068f8879654da436aaf518ffe5be7edcdddbd Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 13 Jan 2020 20:07:27 +0100 Subject: [PATCH 1/5] gdk/x11: Serialize gtype content formats before sending Xdnd enter This ensures GType handlers get serialized to mimetypes at the time the drag dest inspects the XdndTypeList property. --- gdk/x11/gdkdrag-x11.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gdk/x11/gdkdrag-x11.c b/gdk/x11/gdkdrag-x11.c index 724099dab0..55e157b52a 100644 --- a/gdk/x11/gdkdrag-x11.c +++ b/gdk/x11/gdkdrag-x11.c @@ -1061,6 +1061,7 @@ xdnd_send_enter (GdkX11Drag *drag_x11) { GdkDrag *drag = GDK_DRAG (drag_x11); GdkDisplay *display = gdk_drag_get_display (drag); + GdkContentFormats *formats; const char * const *atoms; gsize i, n_atoms; XEvent xev; @@ -1080,7 +1081,10 @@ xdnd_send_enter (GdkX11Drag *drag_x11) GDK_DISPLAY_NOTE (display, DND, g_message ("Sending enter source window %#lx XDND protocol version %d\n", GDK_SURFACE_XID (drag_x11->ipc_surface), drag_x11->version)); - atoms = gdk_content_formats_get_mime_types (gdk_drag_get_formats (drag), &n_atoms); + formats = gdk_content_formats_ref (gdk_drag_get_formats (drag)); + formats = gdk_content_formats_union_serialize_mime_types (formats); + + atoms = gdk_content_formats_get_mime_types (formats, &n_atoms); if (n_atoms > 3) { From fe36c24b076bb4eb725832037fc731cd944d1773 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 14 Jan 2020 00:02:12 +0100 Subject: [PATCH 2/5] gdk/x11: Ensure to sync type list after sending XdndEnter Otherwise we are not ensured the GdkDrop is up-to-date, might even be a stale one from an older DnD operation. --- gdk/x11/gdkdrag-x11.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/gdk/x11/gdkdrag-x11.c b/gdk/x11/gdkdrag-x11.c index 55e157b52a..4bf609a1de 100644 --- a/gdk/x11/gdkdrag-x11.c +++ b/gdk/x11/gdkdrag-x11.c @@ -1506,23 +1506,6 @@ gdk_x11_drag_drag_motion (GdkDrag *drag, } } - /* When we have a Xdnd target, make sure our XdndActionList - * matches the current actions; - */ - if (protocol == GDK_DRAG_PROTO_XDND && drag_x11->xdnd_actions != gdk_drag_get_actions (drag)) - { - if (proxy_xid) - { - GdkDisplay *display = gdk_drag_get_display (drag); - GdkDrop *drop = GDK_X11_DISPLAY (display)->current_drop; - - if (drop && GDK_SURFACE_XID (gdk_drop_get_surface (drop)) == proxy_xid) - gdk_x11_drop_read_actions (drop); - else - xdnd_set_actions (drag_x11); - } - } - if (drag_x11->proxy_xid != proxy_xid) { /* Send a leave to the last destination */ @@ -1562,6 +1545,23 @@ gdk_x11_drag_drag_motion (GdkDrag *drag, drag_x11->current_action = gdk_drag_get_selected_action (drag); } + /* When we have a Xdnd target, make sure our XdndActionList + * matches the current actions; + */ + if (protocol == GDK_DRAG_PROTO_XDND && drag_x11->xdnd_actions != gdk_drag_get_actions (drag)) + { + if (proxy_xid) + { + GdkDisplay *display = gdk_drag_get_display (drag); + GdkDrop *drop = GDK_X11_DISPLAY (display)->current_drop; + + if (drop && GDK_SURFACE_XID (gdk_drop_get_surface (drop)) == proxy_xid) + gdk_x11_drop_read_actions (drop); + else + xdnd_set_actions (drag_x11); + } + } + /* Send a drag-motion event */ drag_x11->last_x = x_root; From 5aad3d7d0ea50ce2a1122687b0382a1021fd03a0 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 14 Jan 2020 00:03:29 +0100 Subject: [PATCH 3/5] gdk/x11: Ensure to hide DnD surface after failed operation The drag source might be cached and held alive, only disposed after future drag begin operations. Ensure the drag surface gets hidden properly or might might stay transparent but mapped till then. --- gdk/x11/gdkdrag-x11.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gdk/x11/gdkdrag-x11.c b/gdk/x11/gdkdrag-x11.c index 4bf609a1de..b525186f85 100644 --- a/gdk/x11/gdkdrag-x11.c +++ b/gdk/x11/gdkdrag-x11.c @@ -1818,6 +1818,7 @@ struct _GdkDragAnim { static void gdk_drag_anim_destroy (GdkDragAnim *anim) { + gdk_surface_hide (anim->drag->drag_surface); g_object_unref (anim->drag); g_slice_free (GdkDragAnim, anim); } From 4716c9ae2f6ad5cc703168a94aae1b7cb5525571 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 16 Jan 2020 15:02:16 +0100 Subject: [PATCH 4/5] gdkdrag/x11: Drop timestamp argument from gdk_drag_do_leave() This is not necessary for the XdndLeave message, nor used. --- gdk/x11/gdkdrag-x11.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gdk/x11/gdkdrag-x11.c b/gdk/x11/gdkdrag-x11.c index b525186f85..87535b24ef 100644 --- a/gdk/x11/gdkdrag-x11.c +++ b/gdk/x11/gdkdrag-x11.c @@ -1304,8 +1304,7 @@ xdnd_precache_atoms (GdkDisplay *display) /* Source side */ static void -gdk_drag_do_leave (GdkX11Drag *drag_x11, - guint32 time) +gdk_drag_do_leave (GdkX11Drag *drag_x11) { if (drag_x11->proxy_xid) { @@ -1509,7 +1508,7 @@ gdk_x11_drag_drag_motion (GdkDrag *drag, if (drag_x11->proxy_xid != proxy_xid) { /* Send a leave to the last destination */ - gdk_drag_do_leave (drag_x11, time); + gdk_drag_do_leave (drag_x11); drag_x11->drag_status = GDK_DRAG_STATUS_DRAG; /* Check if new destination accepts drags, and which protocol */ From 357e215fb8dddec9775e4112cec099e959d0badc Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 16 Jan 2020 15:03:24 +0100 Subject: [PATCH 5/5] gdkdrag/x11: Issue XdndLeave on cancellation According to XDND "The XdndLeave message cancels the session.", issue one when cancelling a drag, so the dest side has an opportunity to forget about the GdkDrop. --- gdk/x11/gdkdrag-x11.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gdk/x11/gdkdrag-x11.c b/gdk/x11/gdkdrag-x11.c index 87535b24ef..ed78c284ba 100644 --- a/gdk/x11/gdkdrag-x11.c +++ b/gdk/x11/gdkdrag-x11.c @@ -2141,6 +2141,7 @@ static void gdk_x11_drag_cancel (GdkDrag *drag, GdkDragCancelReason reason) { + gdk_drag_do_leave (GDK_X11_DRAG (drag)); drag_ungrab (drag); gdk_drag_drop_done (drag, FALSE); }