From 4dc8deea2243c7e41520a241ccbfa34bb6b750a4 Mon Sep 17 00:00:00 2001 From: Diederik ter Rahe Date: Mon, 9 Sep 2024 11:30:51 -0400 Subject: [PATCH] prevent jitter when dragging into empty side panel space --- src/develop/imageop.c | 21 +++++++++------------ src/dtgtk/expander.c | 7 ++++++- src/gui/gtk.c | 5 ++--- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/develop/imageop.c b/src/develop/imageop.c index 165f9c2be4ed..8029c0190204 100644 --- a/src/develop/imageop.c +++ b/src/develop/imageop.c @@ -2984,7 +2984,7 @@ GtkWidget *dt_iop_gui_header_button(dt_iop_module_t *module, static gboolean _on_drag_motion(GtkWidget *widget, GdkDragContext *dc, gint x, gint y, guint time, dt_iop_module_t *dest) { - if(y < 0) return FALSE; // handled by panel after failing on current module and then sent to last item. + gdk_drag_status(dc, 0, time); GtkWidget *src_widget = gtk_widget_get_ancestor(gtk_drag_get_source_widget(dc), DTGTK_TYPE_EXPANDER); @@ -2993,7 +2993,7 @@ static gboolean _on_drag_motion(GtkWidget *widget, GdkDragContext *dc, gint x, g for(GList *iop = darktable.develop->iop; iop; iop = iop->next) if(((dt_iop_module_t *)iop->data)->expander == src_widget) src = iop->data; - if(!src || dest == src) return FALSE; + if(!src || dest == src) return TRUE; const gboolean above = y < gtk_widget_get_allocated_height(dest->header); @@ -3007,18 +3007,15 @@ static gboolean _on_drag_motion(GtkWidget *widget, GdkDragContext *dc, gint x, g } while (!dest->expander || !gtk_widget_get_visible(dest->expander)); } - if(dest == src) return FALSE; + if(dest == src) return TRUE; if(x != DND_DROP) { - if(!(src->iop_order < dest->iop_order - ? dt_ioppr_check_can_move_after_iop(darktable.develop->iop, src, dest) - : dt_ioppr_check_can_move_before_iop(darktable.develop->iop, src, dest))) - return FALSE; - - dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), TRUE, !above); - - gdk_drag_status(dc, GDK_ACTION_COPY, time); + gboolean allow = src->iop_order < dest->iop_order + ? dt_ioppr_check_can_move_after_iop(darktable.develop->iop, src, dest) + : dt_ioppr_check_can_move_before_iop(darktable.develop->iop, src, dest); + dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), allow, !above); + if(allow) gdk_drag_status(dc, GDK_ACTION_COPY, time); } else { @@ -3027,7 +3024,7 @@ static gboolean _on_drag_motion(GtkWidget *widget, GdkDragContext *dc, gint x, g if(!(src->iop_order < dest->iop_order ? dt_ioppr_move_iop_after(darktable.develop, src, dest) : dt_ioppr_move_iop_before(darktable.develop, src, dest))) - return FALSE; + return TRUE; // we move the headers int position = 0; diff --git a/src/dtgtk/expander.c b/src/dtgtk/expander.c index ecef4506d98a..894aab5a1dcf 100644 --- a/src/dtgtk/expander.c +++ b/src/dtgtk/expander.c @@ -185,7 +185,11 @@ static void _expander_resize(GtkWidget *widget, GdkRectangle *allocation, gpoint void dtgtk_expander_set_drag_hover(GtkDarktableExpander *expander, gboolean hover, gboolean below) { - GtkWidget *widget = GTK_WIDGET(expander); + GtkWidget *widget = expander ? GTK_WIDGET(expander) : _drop_widget; + // don't remove drop zone when switching between last expander and empty space to avoid jitter + static guint hovertime; + guint time = gtk_get_current_event_time(); + if(!widget || (!hover && widget == _drop_widget && time == hovertime)) return; dt_gui_remove_class(widget, "module_drop_after"); dt_gui_remove_class(widget, "module_drop_before"); @@ -193,6 +197,7 @@ void dtgtk_expander_set_drag_hover(GtkDarktableExpander *expander, gboolean hove if(hover) { _drop_widget = widget; + hovertime = time; if(below) dt_gui_add_class(widget, "module_drop_before"); diff --git a/src/gui/gtk.c b/src/gui/gtk.c index 20dc6800de45..52cf072aa13b 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -2236,10 +2236,9 @@ static gboolean _on_drag_motion_drop(GtkWidget *widget, GdkDragContext *dc, gint return ret; } -static void _on_drag_leave(GtkDarktableExpander *widget, GdkDragContext *dc, guint time, gpointer user_data) +static void _on_drag_leave(GtkWidget *widget, GdkDragContext *dc, guint time, gpointer user_data) { - for(GList *m = gtk_container_get_children(GTK_CONTAINER(widget)); m; m = g_list_delete_link(m, m)) - dtgtk_expander_set_drag_hover(m->data, FALSE, FALSE); + dtgtk_expander_set_drag_hover(NULL, FALSE, FALSE); } static gboolean _remove_modules_visibility(gpointer key,