From 004aba44dfaba1af36362be1f32010842f24c6e3 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Wed, 26 Apr 2017 12:46:40 +0200 Subject: [PATCH] gtkdnd: restore drag window movement for the unmanaged case 5bb12474d975ee4b790c5 removed the dnd window movement code to let the gdk backends handle the window movement instead. While this works for X11/wayland the win32 backend still uses the unmanaged interface and expects the window movement to be handled on the gtk side. This restores the functionality in case the dnd is unmanaged. This fixes the drag window on Windows being stuck in the top left corner instead of following the drag position. https://bugzilla.gnome.org/show_bug.cgi?id=781737 --- gtk/gtkdnd.c | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index 443e1bcffb..6f8991744c 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -1233,6 +1233,20 @@ gtk_drag_dest_drop (GtkWidget *widget, * Source side * ***************/ + +static gboolean +gtk_drag_is_managed (GtkWidget *source_widget) +{ + return +#ifdef GDK_WINDOWING_X11 + GDK_IS_X11_DISPLAY (gtk_widget_get_display (source_widget)) || +#endif +#ifdef GDK_WINDOWING_WAYLAND + GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (source_widget)) || +#endif + FALSE; +} + /* Like gtk_drag_begin(), but also takes a GtkIconHelper * so that we can set the icon from the source site information */ @@ -1258,16 +1272,9 @@ gtk_drag_begin_internal (GtkWidget *widget, GdkWindow *ipc_window; gint start_x, start_y; GdkAtom selection; - gboolean managed = FALSE; + gboolean managed; - managed = -#ifdef GDK_WINDOWING_X11 - GDK_IS_X11_DISPLAY (gtk_widget_get_display (widget)) || -#endif -#ifdef GDK_WINDOWING_WAYLAND - GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (widget)) || -#endif - FALSE; + managed = gtk_drag_is_managed (widget); pointer = keyboard = NULL; ipc_widget = gtk_drag_get_ipc_widget (widget); @@ -1544,6 +1551,22 @@ icon_widget_destroyed (GtkWidget *widget, g_clear_object (&info->icon_widget); } +static void +gtk_drag_update_icon_window (GtkDragSourceInfo *info) +{ + if (!gtk_drag_is_managed (info->widget) && info->icon_window) + { + gtk_window_move (GTK_WINDOW (info->icon_window), + info->cur_x - info->hot_x, + info->cur_y - info->hot_y); + + if (gtk_widget_get_visible (info->icon_window)) + gdk_window_raise (gtk_widget_get_window (info->icon_window)); + else + gtk_widget_show (info->icon_window); + } +} + static void gtk_drag_set_icon_widget_internal (GdkDragContext *context, GtkWidget *widget, @@ -1604,6 +1627,7 @@ gtk_drag_set_icon_widget_internal (GdkDragContext *context, out: gtk_drag_update_cursor (info); + gtk_drag_update_icon_window (info); } /** @@ -2145,6 +2169,7 @@ gtk_drag_update_idle (gpointer data) info->possible_actions, &action, &possible_actions); + gtk_drag_update_icon_window (info); gdk_drag_find_window_for_screen (info->context, info->icon_window ? gtk_widget_get_window (info->icon_window) : NULL, info->cur_screen, info->cur_x, info->cur_y,