From 4676fec3a8f8d445d98357cde25841cbbf214403 Mon Sep 17 00:00:00 2001 From: Diederik ter Rahe Date: Mon, 9 Dec 2024 19:41:46 -0500 Subject: [PATCH] improve presets menu click behavior fixes 17889 --- src/develop/imageop.c | 3 +- src/gui/presets.c | 15 ++++------ src/libs/lib.c | 69 ++++++++++++++++++++++++------------------- 3 files changed, 46 insertions(+), 41 deletions(-) diff --git a/src/develop/imageop.c b/src/develop/imageop.c index f1be0830823a..4ef8b781d709 100644 --- a/src/develop/imageop.c +++ b/src/develop/imageop.c @@ -2515,6 +2515,7 @@ static gboolean _iop_plugin_header_button_release(GtkWidget *w, gpointer user_data) { if(e->type == GDK_2BUTTON_PRESS || e->type == GDK_3BUTTON_PRESS) return TRUE; + if(GTK_IS_BUTTON(gtk_get_event_widget((GdkEvent*)e))) return FALSE; dt_iop_module_t *module = (dt_iop_module_t *)user_data; @@ -2966,7 +2967,7 @@ GtkWidget *dt_iop_gui_header_button(dt_iop_module_t *module, g_signal_connect(button, "enter-notify-event", G_CALLBACK(_header_enter_notify_callback), GINT_TO_POINTER(element)); - g_signal_connect(button, "button-release-event", G_CALLBACK(callback), module); + g_signal_connect(button, "button-press-event", G_CALLBACK(callback), module); dt_action_define(&module->so->actions, NULL, NULL, button, NULL); gtk_widget_show(button); diff --git a/src/gui/presets.c b/src/gui/presets.c index b938aef2ff12..03638c96fc22 100644 --- a/src/gui/presets.c +++ b/src/gui/presets.c @@ -1257,15 +1257,14 @@ static gboolean _menuitem_button_preset(GtkMenuItem *menuitem, GdkEventButton *event, dt_iop_module_t *module) { - static guint click_time = 0; - if(event->type == GDK_BUTTON_PRESS) - click_time = event->time; + static guint click_time = G_MAXINT; + gboolean long_click = dt_gui_long_click(event->time, click_time); gchar *name = g_object_get_data(G_OBJECT(menuitem), "dt-preset-name"); if(event->button == 1 || (module->flags() & IOP_FLAGS_ONE_INSTANCE)) { - if(event->type == GDK_BUTTON_PRESS) + if(click_time > event->time) { GtkContainer *menu = GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(menuitem))); for(GList *c = gtk_container_get_children(menu); c; c = g_list_delete_link(c, c)) @@ -1277,11 +1276,8 @@ static gboolean _menuitem_button_preset(GtkMenuItem *menuitem, } else if(event->button == 3 && event->type == GDK_BUTTON_RELEASE) { - if(dt_gui_long_click(event->time, click_time)) - { + if(long_click) dt_shortcut_copy_lua((dt_action_t*)module, name); - return TRUE; - } else { dt_iop_module_t *new_module = dt_iop_gui_duplicate(module, FALSE); @@ -1298,7 +1294,8 @@ static gboolean _menuitem_button_preset(GtkMenuItem *menuitem, dt_iop_connect_accels_multi(module->so); } - return dt_gui_long_click(event->time, click_time); // keep menu open on long click + click_time = event->type == GDK_BUTTON_PRESS ? event->time : G_MAXINT; + return long_click; // keep menu open on long click } // need to catch "activate" signal as well to handle keyboard diff --git a/src/libs/lib.c b/src/libs/lib.c index 0a8aeefbc251..d24a65754212 100644 --- a/src/libs/lib.c +++ b/src/libs/lib.c @@ -403,25 +403,19 @@ void dt_lib_presets_update(const gchar *preset, static void _menuitem_activate_preset(GtkMenuItem *menuitem, dt_lib_module_info_t *minfo) { - GdkEvent *event = gtk_get_current_event(); - if(event->type == GDK_KEY_PRESS) - dt_lib_presets_apply(g_object_get_data(G_OBJECT(menuitem), "dt-preset-name"), - minfo->plugin_name, minfo->version); - gdk_event_free(event); + dt_lib_presets_apply(g_object_get_data(G_OBJECT(menuitem), "dt-preset-name"), + minfo->plugin_name, minfo->version); } static gboolean _menuitem_button_preset(GtkMenuItem *menuitem, GdkEventButton *event, dt_lib_module_info_t *minfo) { - char *name = g_object_get_data(G_OBJECT(menuitem), "dt-preset-name"); - - if(event->button == 1) - dt_lib_presets_apply(name, minfo->plugin_name, minfo->version); - else - dt_shortcut_copy_lua((dt_action_t*)minfo->module, name); + if(event->button == 1) return FALSE; - return FALSE; + dt_shortcut_copy_lua((dt_action_t*)minfo->module, + g_object_get_data(G_OBJECT(menuitem), "dt-preset-name")); + return TRUE; } static void free_module_info(GtkWidget *widget, @@ -516,7 +510,7 @@ static void dt_lib_presets_popup_menu_show(dt_lib_module_info_t *minfo, g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(_menuitem_activate_preset), minfo); - g_signal_connect(G_OBJECT(mi), "button-press-event", + g_signal_connect(G_OBJECT(mi), "button-release-event", G_CALLBACK(_menuitem_button_preset), minfo); gtk_widget_set_tooltip_text(mi, (const char *)sqlite3_column_text(stmt, 3)); gtk_widget_set_has_tooltip(mi, TRUE); @@ -891,15 +885,18 @@ void dt_lib_unload_module(dt_lib_module_t *module) g_module_close(module->module); } -static void dt_lib_gui_reset_callback(GtkButton *button, - gpointer user_data) +static gboolean _lib_gui_reset_callback(GtkButton *button, + GdkEventButton *e, + gpointer user_data) { dt_lib_module_t *module = (dt_lib_module_t *)user_data; module->gui_reset(module); + return TRUE; } -static void presets_popup_callback(GtkButton *button, - dt_lib_module_t *module) +static gboolean _presets_popup_callback(GtkButton *button, + GdkEventButton *e, + dt_lib_module_t *module) { dt_lib_module_info_t *mi = calloc(1, sizeof(dt_lib_module_info_t)); @@ -918,8 +915,9 @@ static void presets_popup_callback(GtkButton *button, if(button) dtgtk_button_set_active(DTGTK_BUTTON(button), FALSE); -} + return TRUE; +} void dt_lib_gui_set_expanded(dt_lib_module_t *module, gboolean expanded) { @@ -958,9 +956,9 @@ gboolean dt_lib_gui_get_expanded(dt_lib_module_t *module) return dtgtk_expander_get_expanded(DTGTK_EXPANDER(module->expander)); } -static gboolean _lib_plugin_header_button_release(GtkWidget *w, - GdkEventButton *e, - gpointer user_data) +static gboolean _lib_plugin_arrow_button_press(GtkWidget *w, + GdkEventButton *e, + gpointer user_data) { if(e->type == GDK_2BUTTON_PRESS || e->type == GDK_3BUTTON_PRESS) return TRUE; @@ -1015,13 +1013,21 @@ static gboolean _lib_plugin_header_button_release(GtkWidget *w, else if(e->button == 3) { if(gtk_widget_get_sensitive(module->presets_button)) - presets_popup_callback(NULL, module); + _presets_popup_callback(NULL, NULL, module); return TRUE; } return FALSE; } +static gboolean _lib_plugin_header_button_release(GtkWidget *w, + GdkEventButton *e, + gpointer user_data) +{ + if(GTK_IS_BUTTON(gtk_get_event_widget((GdkEvent*)e))) return FALSE; + return _lib_plugin_arrow_button_press(w, e, user_data); +} + static void show_module_callback(dt_lib_module_t *module) { /* bail out if module is static */ @@ -1198,7 +1204,7 @@ GtkWidget *dt_lib_gui_get_expander(dt_lib_module_t *module) // because not automatically registered via lib if presets btn // has been loaded to be shown outside expander g_signal_connect(G_OBJECT(module->presets_button), "clicked", - G_CALLBACK(presets_popup_callback), module); + G_CALLBACK(_presets_popup_callback), module); } module->expander = NULL; return NULL; @@ -1244,8 +1250,8 @@ GtkWidget *dt_lib_gui_get_expander(dt_lib_module_t *module) module->arrow = dtgtk_button_new(dtgtk_cairo_paint_solid_arrow, 0, NULL); gtk_widget_set_tooltip_text(module->arrow, _("show module")); - g_signal_connect(G_OBJECT(module->arrow), "button-release-event", - G_CALLBACK(_lib_plugin_header_button_release), module); + g_signal_connect(G_OBJECT(module->arrow), "button-press-event", + G_CALLBACK(_lib_plugin_arrow_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); @@ -1269,8 +1275,8 @@ GtkWidget *dt_lib_gui_get_expander(dt_lib_module_t *module) /* add preset button if module has implementation */ module->presets_button = dtgtk_button_new(dtgtk_cairo_paint_presets, 0, NULL); gtk_widget_set_tooltip_text(module->presets_button, _("presets and preferences")); - g_signal_connect(G_OBJECT(module->presets_button), "clicked", - G_CALLBACK(presets_popup_callback), module); + g_signal_connect(G_OBJECT(module->presets_button), "button-press-event", + G_CALLBACK(_presets_popup_callback), module); g_signal_connect(G_OBJECT(module->presets_button), "enter-notify-event", G_CALLBACK(_header_enter_notify_callback), GINT_TO_POINTER(DT_ACTION_ELEMENT_PRESETS)); @@ -1283,8 +1289,8 @@ GtkWidget *dt_lib_gui_get_expander(dt_lib_module_t *module) /* add reset button if module has implementation */ module->reset_button = dtgtk_button_new(dtgtk_cairo_paint_reset, 0, NULL); - g_signal_connect(G_OBJECT(module->reset_button), "clicked", - G_CALLBACK(dt_lib_gui_reset_callback), module); + g_signal_connect(G_OBJECT(module->reset_button), "button-press-event", + G_CALLBACK(_lib_gui_reset_callback), module); g_signal_connect(G_OBJECT(module->reset_button), "enter-notify-event", G_CALLBACK(_header_enter_notify_callback), GINT_TO_POINTER(DT_ACTION_ELEMENT_RESET)); @@ -1543,11 +1549,12 @@ static float _action_process(gpointer target, show_module_callback(module); break; case DT_ACTION_ELEMENT_RESET: - if(module->gui_reset) dt_lib_gui_reset_callback(NULL, module); + if(module->gui_reset) + _lib_gui_reset_callback(NULL, NULL, module); break; case DT_ACTION_ELEMENT_PRESETS: if(module->get_params || module->set_preferences) - presets_popup_callback(NULL, module); + _presets_popup_callback(NULL, NULL, module); break; } }