From 2139d3b80d8723bd4223134c637453742108d292 Mon Sep 17 00:00:00 2001 From: Diederik ter Rahe Date: Wed, 11 Sep 2024 10:46:10 -0400 Subject: [PATCH 1/3] remove unnecessary single use lib fields --- src/libs/ioporder.c | 11 ++++++----- src/libs/lib.c | 23 +++++++++-------------- src/libs/lib.h | 2 -- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/libs/ioporder.c b/src/libs/ioporder.c index 34480db17867..a65e5a63630f 100644 --- a/src/libs/ioporder.c +++ b/src/libs/ioporder.c @@ -54,10 +54,13 @@ int position(const dt_lib_module_t *self) return 880; } -void update(dt_lib_module_t *self) +static void _update(dt_lib_module_t *self) { dt_lib_ioporder_t *d = (dt_lib_ioporder_t *)self->data; + if(self->arrow) gtk_widget_destroy(self->arrow); + self->arrow = NULL; + const dt_iop_order_t kind = dt_ioppr_get_iop_order_list_kind(darktable.develop->iop_order_list); @@ -123,7 +126,7 @@ static void _image_loaded_callback(gpointer instance, gpointer user_data) if(dt_view_get_current() == DT_VIEW_DARKROOM) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; - update(self); + _update(self); } } @@ -132,8 +135,6 @@ void gui_init(dt_lib_module_t *self) dt_lib_ioporder_t *d = (dt_lib_ioporder_t *)malloc(sizeof(dt_lib_ioporder_t)); self->data = (void *)d; - self->no_control_widgets = TRUE; - d->current_mode = -1; d->last_custom_iop_order = NULL; @@ -224,7 +225,7 @@ int set_params(dt_lib_module_t *self, const void *params, int size) dt_dev_pixelpipe_rebuild(darktable.develop); - update(self); + _update(self); g_list_free_full(iop_order_list, free); return 0; diff --git a/src/libs/lib.c b/src/libs/lib.c index 2e0e8bc13dca..558befa9c0ad 100644 --- a/src/libs/lib.c +++ b/src/libs/lib.c @@ -1243,14 +1243,11 @@ GtkWidget *dt_lib_gui_get_expander(dt_lib_module_t *module) /* add the expand indicator icon */ module->arrow = dtgtk_button_new(dtgtk_cairo_paint_solid_arrow, 0, NULL); - if(!module->no_control_widgets) - { - gtk_widget_set_tooltip_text(module->arrow, _("show module")); - g_signal_connect(G_OBJECT(module->arrow), "button-press-event", - G_CALLBACK(_lib_plugin_header_button_press), module); - dt_action_define(&module->actions, NULL, NULL, module->arrow, NULL); - gtk_box_pack_start(GTK_BOX(header), module->arrow, FALSE, FALSE, 0); - } + gtk_widget_set_tooltip_text(module->arrow, _("show module")); + g_signal_connect(G_OBJECT(module->arrow), "button-press-event", + G_CALLBACK(_lib_plugin_header_button_press), module); + dt_action_define(&module->actions, NULL, NULL, module->arrow, NULL); + gtk_box_pack_start(GTK_BOX(header), module->arrow, FALSE, FALSE, 0); /* add module label */ GtkWidget *label = gtk_label_new(""); @@ -1269,10 +1266,6 @@ GtkWidget *dt_lib_gui_get_expander(dt_lib_module_t *module) dt_action_define(&module->actions, NULL, NULL, label_evb, NULL); gtk_box_pack_start(GTK_BOX(header), label_evb, FALSE, FALSE, 0); - /* second label */ - module->label = gtk_label_new(""); - gtk_box_pack_start(GTK_BOX(header), module->label, TRUE, TRUE, 0); - /* add preset button if module has implementation */ module->presets_button = dtgtk_button_new(dtgtk_cairo_paint_presets, 0, NULL); g_signal_connect(G_OBJECT(module->presets_button), "clicked", @@ -1320,8 +1313,10 @@ GtkWidget *dt_lib_gui_get_expander(dt_lib_module_t *module) void dt_lib_gui_set_label(dt_lib_module_t *module, const char *label) { - if(module->expander) - gtk_label_set_text(GTK_LABEL(module->label), label); + if(!module->expander) return; + GtkWidget *header = DTGTK_EXPANDER(module->expander)->header; + gtk_box_set_center_widget(GTK_BOX(header), gtk_label_new(label)); + gtk_widget_show_all(header); } static void _preferences_changed(gpointer instance, gpointer self) diff --git a/src/libs/lib.h b/src/libs/lib.h index 1dec02c50a6e..04d1319c4cdc 100644 --- a/src/libs/lib.h +++ b/src/libs/lib.h @@ -115,13 +115,11 @@ typedef struct dt_lib_module_t /** does gui need to be updated if visible */ gboolean gui_uptodate; - GtkWidget *label; GtkWidget *arrow; GtkWidget *reset_button; GtkWidget *presets_button; gboolean pref_based_presets; - gboolean no_control_widgets; } dt_lib_module_t; typedef struct dt_lib_module_info_t From bf30fd16a46adfdf3569aa3601f3f39dcb5c0b07 Mon Sep 17 00:00:00 2001 From: Diederik ter Rahe Date: Thu, 12 Sep 2024 11:55:25 -0400 Subject: [PATCH 2/3] support swapping left/right panels in darkroom --- data/darktableconfig.xml.in | 7 ++++ src/develop/imageop.c | 12 +------ src/gui/gtk.c | 67 +++++++++++++++---------------------- src/gui/gtk.h | 7 ++-- src/libs/history.c | 1 - src/views/darkroom.c | 2 -- src/views/view.c | 11 ++++-- 7 files changed, 46 insertions(+), 61 deletions(-) diff --git a/data/darktableconfig.xml.in b/data/darktableconfig.xml.in index 5f32e0c3ee77..d6c2638dc812 100644 --- a/data/darktableconfig.xml.in +++ b/data/darktableconfig.xml.in @@ -3084,6 +3084,13 @@ position of the scopes module position the scopes at the top-left or top-right of the screen + + plugins/darkroom/panel_swap + bool + false + swap the utility and processing modules panels + move the list of processing modules to the left of the screen + plugins/darkroom/histogram/histogram diff --git a/src/develop/imageop.c b/src/develop/imageop.c index 8029c0190204..21f79e27ef66 100644 --- a/src/develop/imageop.c +++ b/src/develop/imageop.c @@ -532,18 +532,8 @@ static void _gui_delete_callback(GtkButton *button, dt_iop_module_t *module) // we remove the plugin effectively if(!dt_iop_is_hidden(module)) { - // we just hide the module to avoid lots of gtk critical warnings - gtk_widget_hide(module->expander); - - // we move the module far away, to avoid problems when reordering instance after that - // FIXME: ????? - gtk_box_reorder_child(dt_ui_get_container(darktable.gui->ui, - DT_UI_CONTAINER_PANEL_RIGHT_CENTER), - module->expander, -1); - dt_iop_gui_cleanup_module(module); gtk_widget_grab_focus(dt_ui_center(darktable.gui->ui)); - gtk_widget_destroy(module->widget); } // we remove all references in the history stack and dev->iop @@ -1731,7 +1721,6 @@ static void _init_module_so(void *m) } dt_iop_gui_cleanup_module(module_instance); - gtk_widget_destroy(module_instance->widget); dt_iop_cleanup_module(module_instance); darktable.control->accel_initialising = FALSE; @@ -2199,6 +2188,7 @@ void dt_iop_gui_cleanup_module(dt_iop_module_t *module) g_slist_free_full(module->widget_list, g_free); module->widget_list = NULL; module->gui_cleanup(module); + gtk_widget_destroy(module->expander ?: module->widget); dt_iop_gui_cleanup_blending(module); } diff --git a/src/gui/gtk.c b/src/gui/gtk.c index ee9eca17a5db..a7c910e21316 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -1802,6 +1802,13 @@ static void _init_main_table(GtkWidget *container) N_("tabs"), NULL, &_action_def_focus_tabs); } +void dt_ui_container_swap_left_right(struct dt_ui_t *ui, + gboolean swap) +{ + if(swap ^ strcmp("left", gtk_widget_get_name(gtk_widget_get_ancestor(*ui->containers, DTGTK_TYPE_SIDE_PANEL)))) + for(GtkWidget **c = ui->containers; c < ui->containers + 3; c++) {GtkWidget *tmp = *c; *c = c[3]; c[3] = tmp;} +} + GtkBox *dt_ui_get_container(struct dt_ui_t *ui, const dt_ui_container_t c) { @@ -2212,16 +2219,17 @@ static gboolean _ui_init_panel_container_center_scroll_event(GtkWidget *widget, != dt_conf_get_bool("darkroom/ui/sidebar_scroll_default")); } -static gboolean _on_drag_motion_drop(GtkWidget *widget, GdkDragContext *dc, gint x, gint y, guint time, gboolean drop) +static gboolean _on_drag_motion_drop(GtkWidget *empty, GdkDragContext *dc, gint x, gint y, guint time, gboolean drop) { + GtkWidget *widget = gtk_widget_get_parent(empty); if(drop) gtk_widget_set_opacity(gtk_drag_get_source_widget(dc), 1.0); gboolean ret = TRUE; gpointer last = NULL; for(GList *m = gtk_container_get_children(GTK_CONTAINER(widget)); m; m = g_list_delete_link(m, m)) - if(gtk_widget_get_visible(GTK_WIDGET(m->data))) last = m->data; + if(m->data != empty && gtk_widget_get_visible(GTK_WIDGET(m->data))) last = m->data; if(last) - g_signal_emit_by_name(last, "drag-motion", dc, drop ? -1 : x, y, time, &ret); + g_signal_emit_by_name(last, "drag-motion", dc, drop ? -1 : x, G_MAXINT, time, &ret); else if(dt_view_get_current() == DT_VIEW_DARKROOM) gdk_drag_status(dc, 0, time); // don't allow dropping in empty panel on other side else if(drop) @@ -2303,23 +2311,11 @@ static gboolean _side_panel_press(GtkWidget *widget, GdkEvent *event, gpointer user_data) { - if(event->button.button != GDK_BUTTON_SECONDARY - || !GTK_IS_VIEWPORT(gtk_get_event_widget(event))) - return FALSE; - - _add_remove_modules(NULL); + if(event->button.button == GDK_BUTTON_SECONDARY) + _add_remove_modules(NULL); return TRUE; } -static gboolean _side_panel_motion(GtkWidget *widget, - GdkEvent *event, - gpointer user_data) -{ - gtk_widget_set_tooltip_text(widget, GTK_IS_VIEWPORT(gtk_get_event_widget(event)) - ? _("right-click to show/hide modules") : NULL); - return FALSE; -} - static gboolean _side_panel_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data) @@ -2333,15 +2329,9 @@ static GtkWidget *_ui_init_panel_container_center(GtkWidget *container, const gboolean left) { GtkWidget *widget; - GtkAdjustment *a[4]; - - a[0] = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 100, 1, 10, 10)); - a[1] = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 100, 1, 10, 10)); - a[2] = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 100, 1, 10, 10)); - a[3] = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 100, 1, 10, 10)); /* create the scrolled window */ - widget = gtk_scrolled_window_new(a[0], a[1]); + widget = gtk_scrolled_window_new(NULL, GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 100, 1, 10, 10))); gtk_widget_set_can_focus(widget, TRUE); gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(widget), left ? GTK_CORNER_TOP_LEFT : GTK_CORNER_TOP_RIGHT); @@ -2358,35 +2348,32 @@ static GtkWidget *_ui_init_panel_container_center(GtkWidget *container, : darktable.gui->widgets.left_border), "scroll-event", G_CALLBACK(_borders_scrolled), widget); - /* create the scrolled viewport */ - container = widget; - widget = gtk_viewport_new(a[2], a[3]); - gtk_viewport_set_shadow_type(GTK_VIEWPORT(widget), GTK_SHADOW_NONE); - gtk_container_add(GTK_CONTAINER(container), widget); - /* avoid scrolling with wheel, it's distracting (you'll end up over * a control, and scroll it's value) */ g_signal_connect(G_OBJECT(widget), "scroll-event", G_CALLBACK(_ui_init_panel_container_center_scroll_event), NULL); - g_signal_connect(widget, "button-press-event", G_CALLBACK(_side_panel_press), NULL); - g_signal_connect(widget, "motion-notify-event", G_CALLBACK(_side_panel_motion), NULL); - gtk_widget_add_events(widget, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); - dt_action_t *ac = dt_action_define(&darktable.control->actions_global, NULL, - N_("show/hide modules"), widget, NULL); - dt_action_register(ac, NULL, _add_remove_modules, 0, 0); /* create the container */ container = widget; widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_widget_set_name(widget, "plugins_vbox_left"); gtk_container_add(GTK_CONTAINER(container), widget); - gtk_drag_dest_set(widget, 0, NULL, 0, GDK_ACTION_COPY); - g_signal_connect(widget, "drag-motion", G_CALLBACK(_on_drag_motion_drop), GINT_TO_POINTER(FALSE)); - g_signal_connect(widget, "drag-drop", G_CALLBACK(_on_drag_motion_drop), GINT_TO_POINTER(TRUE)); - g_signal_connect(widget, "drag-leave", G_CALLBACK(_on_drag_leave), NULL); g_signal_connect_swapped(widget, "draw", G_CALLBACK(_side_panel_draw), NULL); + GtkWidget *empty = gtk_event_box_new(); + gtk_widget_set_tooltip_text(empty, _("right-click to show/hide modules")); + gtk_box_pack_end(GTK_BOX(widget), empty, TRUE, TRUE, 0); + gtk_drag_dest_set(empty, 0, NULL, 0, GDK_ACTION_COPY); + g_signal_connect(empty, "drag-motion", G_CALLBACK(_on_drag_motion_drop), GINT_TO_POINTER(FALSE)); + g_signal_connect(empty, "drag-drop", G_CALLBACK(_on_drag_motion_drop), GINT_TO_POINTER(TRUE)); + g_signal_connect(empty, "drag-leave", G_CALLBACK(_on_drag_leave), NULL); + g_signal_connect(empty, "button-press-event", G_CALLBACK(_side_panel_press), NULL); + gtk_widget_add_events(empty, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); + dt_action_t *ac = dt_action_define(&darktable.control->actions_global, NULL, + N_("show/hide modules"), empty, NULL); + dt_action_register(ac, NULL, _add_remove_modules, 0, 0); + return widget; } diff --git a/src/gui/gtk.h b/src/gui/gtk.h index 4c86117b2a72..6953da12ff8d 100644 --- a/src/gui/gtk.h +++ b/src/gui/gtk.h @@ -47,10 +47,6 @@ typedef struct dt_gui_widgets_t GtkWidget *bottom_border; GtkWidget *top_border; - /* left panel */ - GtkGrid *panel_left; // panel grid 3 rows, top,center,bottom and file on center - GtkGrid *panel_right; - /* resize of left/right panels */ gboolean panel_handle_dragging; int panel_handle_x, panel_handle_y; @@ -324,6 +320,9 @@ typedef enum dt_ui_border_t DT_UI_BORDER_SIZE } dt_ui_border_t; +/** \brief swap the container in the left and right panels */ +void dt_ui_container_swap_left_right(struct dt_ui_t *ui, + gboolean swap); /** \brief add's a widget to a defined container */ void dt_ui_container_add_widget(struct dt_ui_t *ui, const dt_ui_container_t c, diff --git a/src/libs/history.c b/src/libs/history.c index d29b0dd513b2..1926799ff686 100644 --- a/src/libs/history.c +++ b/src/libs/history.c @@ -428,7 +428,6 @@ static gboolean _check_deleted_instances(dt_develop_t *dev, // this is copied from dt_iop_gui_delete_callback(), not sure // why the above sentence... dt_iop_gui_cleanup_module(mod); - gtk_widget_destroy(mod->widget); } iop_list = g_list_remove_link(iop_list, modules); diff --git a/src/views/darkroom.c b/src/views/darkroom.c index f7398d69aa0d..8f7fed8988e4 100644 --- a/src/views/darkroom.c +++ b/src/views/darkroom.c @@ -1075,7 +1075,6 @@ static gboolean _dev_load_requested_image(gpointer user_data) if(!dt_iop_is_hidden(module)) { dt_iop_gui_cleanup_module(module); - gtk_widget_destroy(module->expander); } // we remove the module from the list @@ -2878,7 +2877,6 @@ void leave(dt_view_t *self) } GtkWidget *box = GTK_WIDGET(dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER)); - gtk_container_foreach(GTK_CONTAINER(box), (GtkCallback)gtk_widget_destroy, NULL); GtkScrolledWindow *sw = GTK_SCROLLED_WINDOW(gtk_widget_get_ancestor(box, GTK_TYPE_SCROLLED_WINDOW)); if(sw) gtk_scrolled_window_set_propagate_natural_width(sw, TRUE); diff --git a/src/views/view.c b/src/views/view.c index 34da7aef3759..518fd11f41d8 100644 --- a/src/views/view.c +++ b/src/views/view.c @@ -349,6 +349,12 @@ gboolean dt_view_manager_switch_by_view(dt_view_manager_t *vm, /* change current view to the new view */ vm->current_view = new_view; + dt_view_type_flags_t view_type = new_view->view(new_view); + + if(new_view != old_view) // implement preference toggle only on view change + dt_ui_container_swap_left_right(darktable.gui->ui, view_type == DT_VIEW_DARKROOM + && dt_conf_get_bool("plugins/darkroom/panel_swap")); + /* restore visible stat of panels for the new view */ dt_ui_restore_panels(darktable.gui->ui); @@ -381,7 +387,7 @@ gboolean dt_view_manager_switch_by_view(dt_view_manager_t *vm, dt_lib_gui_set_expanded(plugin, expanded); dt_lib_set_visible(plugin, TRUE); } - else if(new_view != old_view && plugin->views(plugin) & new_view->view(new_view)) + else if(new_view != old_view && plugin->views(plugin) & view_type) { dt_lib_gui_get_expander(plugin); // connect modulegroups presets button @@ -401,7 +407,6 @@ gboolean dt_view_manager_switch_by_view(dt_view_manager_t *vm, if(!strcmp(plugin->plugin_name,"module_toolbox") || !strcmp(plugin->plugin_name,"view_toolbox")) { - dt_view_type_flags_t view_type = new_view->view(new_view); if(view_type == DT_VIEW_LIGHTTABLE) dt_gui_add_help_link(w, "lighttable_mode"); if(view_type == DT_VIEW_DARKROOM) @@ -422,7 +427,7 @@ gboolean dt_view_manager_switch_by_view(dt_view_manager_t *vm, /* update the scrollbars */ dt_ui_update_scrollbars(darktable.gui->ui); - dt_shortcuts_select_view(new_view->view(new_view)); + dt_shortcuts_select_view(view_type); /* update sticky accels window */ if(vm->accels_window.window && vm->accels_window.sticky) dt_view_accels_refresh(vm); From 4e326c8859d7e6f5a8956f282aad4b846f4f9892 Mon Sep 17 00:00:00 2001 From: Diederik ter Rahe Date: Fri, 13 Sep 2024 11:58:34 -0400 Subject: [PATCH 3/3] scroll module during d&d even if not valid move --- src/develop/imageop.c | 20 ++++++++++++-------- src/dtgtk/expander.c | 20 ++++++++++++-------- src/dtgtk/expander.h | 2 +- src/gui/gtk.c | 2 +- src/libs/lib.c | 13 +++++++------ 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/develop/imageop.c b/src/develop/imageop.c index 21f79e27ef66..2d6eac372e4c 100644 --- a/src/develop/imageop.c +++ b/src/develop/imageop.c @@ -2975,13 +2975,15 @@ 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) { gdk_drag_status(dc, 0, time); + dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), FALSE, TRUE, time); - GtkWidget *src_widget = gtk_widget_get_ancestor(gtk_drag_get_source_widget(dc), - DTGTK_TYPE_EXPANDER); + GtkWidget *src_header = gtk_drag_get_source_widget(dc); + if(!src_header) return TRUE; + GtkWidget *src_expander = gtk_widget_get_ancestor(src_header, DTGTK_TYPE_EXPANDER); dt_iop_module_t *src = NULL; for(GList *iop = darktable.develop->iop; iop; iop = iop->next) - if(((dt_iop_module_t *)iop->data)->expander == src_widget) + if(((dt_iop_module_t *)iop->data)->expander == src_expander) src = iop->data; if(!src || dest == src) return TRUE; @@ -3001,11 +3003,13 @@ static gboolean _on_drag_motion(GtkWidget *widget, GdkDragContext *dc, gint x, g if(x != DND_DROP) { - 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); + 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)) + { + dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), TRUE, !above, time); + gdk_drag_status(dc, GDK_ACTION_COPY, time); + } } else { diff --git a/src/dtgtk/expander.c b/src/dtgtk/expander.c index 894aab5a1dcf..cd2f555c8d63 100644 --- a/src/dtgtk/expander.c +++ b/src/dtgtk/expander.c @@ -183,23 +183,25 @@ static void _expander_resize(GtkWidget *widget, GdkRectangle *allocation, gpoint + dt_conf_get_int("darkroom/ui/transition_duration") * 1000), NULL); } -void dtgtk_expander_set_drag_hover(GtkDarktableExpander *expander, gboolean hover, gboolean below) +void dtgtk_expander_set_drag_hover(GtkDarktableExpander *expander, gboolean allow, gboolean below, guint time) { 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; + static guint last_time; + if(!widget || (!allow && !below && widget == _drop_widget && time == last_time)) return; dt_gui_remove_class(widget, "module_drop_after"); dt_gui_remove_class(widget, "module_drop_before"); - if(hover) + if(allow || below) { _drop_widget = widget; - hovertime = time; + _last_expanded = NULL; + last_time = time; - if(below) + if(!allow) + gtk_widget_queue_resize(widget); + else if(below) dt_gui_add_class(widget, "module_drop_before"); else dt_gui_add_class(widget, "module_drop_after"); @@ -211,7 +213,7 @@ static void _expander_drag_leave(GtkDarktableExpander *widget, guint time, gpointer user_data) { - dtgtk_expander_set_drag_hover(widget, FALSE, FALSE); + dtgtk_expander_set_drag_hover(widget, FALSE, FALSE, time); } // FIXME: default highlight for the dnd is barely visible @@ -226,6 +228,7 @@ static void _expander_drag_begin(GtkWidget *widget, GdkDragContext *context, gpo // hack to render not transparent dt_gui_add_class(widget, "module_drag_icon"); + gtk_widget_size_allocate(widget, &allocation); gtk_widget_draw(widget, cr); dt_gui_remove_class(widget, "module_drag_icon"); @@ -244,6 +247,7 @@ static void _expander_drag_begin(GtkWidget *widget, GdkDragContext *context, gpo static void _expander_drag_end(GtkWidget *widget, GdkDragContext *context, gpointer user_data) { + dtgtk_expander_set_drag_hover(NULL, FALSE, FALSE, 0); _drop_widget = NULL; gtk_widget_set_opacity(widget, 1.0); } diff --git a/src/dtgtk/expander.h b/src/dtgtk/expander.h index d09cc4ed1ba6..f52eb4c609a5 100644 --- a/src/dtgtk/expander.h +++ b/src/dtgtk/expander.h @@ -45,7 +45,7 @@ GtkWidget *dtgtk_expander_get_body_event_box(GtkDarktableExpander *expander); void dtgtk_expander_set_expanded(GtkDarktableExpander *expander, gboolean expanded); gboolean dtgtk_expander_get_expanded(GtkDarktableExpander *expander); -void dtgtk_expander_set_drag_hover(GtkDarktableExpander *expander, gboolean hover, gboolean below); +void dtgtk_expander_set_drag_hover(GtkDarktableExpander *expander, gboolean allow, gboolean below, guint time); GtkWidget *dtgtk_expander_new(GtkWidget *header, GtkWidget *body); diff --git a/src/gui/gtk.c b/src/gui/gtk.c index a7c910e21316..1f8897149cab 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -2248,7 +2248,7 @@ static gboolean _on_drag_motion_drop(GtkWidget *empty, GdkDragContext *dc, gint static void _on_drag_leave(GtkWidget *widget, GdkDragContext *dc, guint time, gpointer user_data) { - dtgtk_expander_set_drag_hover(NULL, FALSE, FALSE); + dtgtk_expander_set_drag_hover(NULL, FALSE, FALSE, time); } static gboolean _remove_modules_visibility(gpointer key, diff --git a/src/libs/lib.c b/src/libs/lib.c index 558befa9c0ad..099a02251a6b 100644 --- a/src/libs/lib.c +++ b/src/libs/lib.c @@ -1098,17 +1098,18 @@ static gboolean _on_drag_motion(GtkWidget *widget, } else { - dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), FALSE, FALSE); + dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), FALSE, TRUE, time); gdk_drag_status(dc, 0, time); - GtkWidget *src_widget = gtk_widget_get_ancestor(gtk_drag_get_source_widget(dc), - DTGTK_TYPE_EXPANDER); + GtkWidget *src_header = gtk_drag_get_source_widget(dc); + if(!src_header) return TRUE; + GtkWidget *src_expander = gtk_widget_get_ancestor(src_header, DTGTK_TYPE_EXPANDER); for(GList *lib = darktable.lib->plugins; lib; lib = lib->next) - if(((dt_lib_module_t *)lib->data)->expander == src_widget) + if(((dt_lib_module_t *)lib->data)->expander == src_expander) src = lib->data; - if(!src_widget || !src || dest == src ) return TRUE; + if(!src_expander || !src || dest == src ) return TRUE; src_panel = GTK_CONTAINER(gtk_widget_get_parent(src->expander)); dest_panel = GTK_CONTAINER(gtk_widget_get_parent(dest->expander)); @@ -1132,7 +1133,7 @@ static gboolean _on_drag_motion(GtkWidget *widget, if(x != DND_DROP) { - dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), TRUE, below); + dtgtk_expander_set_drag_hover(DTGTK_EXPANDER(widget), TRUE, below, time); gdk_drag_status(dc, GDK_ACTION_COPY, time); return TRUE;