Skip to content

Commit

Permalink
improve presets menu click behavior
Browse files Browse the repository at this point in the history
fixes 17889
  • Loading branch information
dterrahe authored and TurboGit committed Dec 11, 2024
1 parent a140abc commit 4676fec
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 41 deletions.
3 changes: 2 additions & 1 deletion src/develop/imageop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);

Expand Down
15 changes: 6 additions & 9 deletions src/gui/presets.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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);
Expand All @@ -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
Expand Down
69 changes: 38 additions & 31 deletions src/libs/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));

Expand All @@ -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)
{
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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",

This comment has been minimized.

Copy link
@dterrahe

dterrahe Dec 13, 2024

Author Member

@TurboGit This must also be changed to "button-press-event". It causes a crash when clicking the module-groups presets/preferences hamburger under Windows (but curiously works fine under linux).

This comment has been minimized.

Copy link
@TurboGit

TurboGit Dec 13, 2024

Member

Good catch, now done. Thanks!

G_CALLBACK(presets_popup_callback), module);
G_CALLBACK(_presets_popup_callback), module);
}
module->expander = NULL;
return NULL;
Expand Down Expand Up @@ -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);

Expand All @@ -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));
Expand All @@ -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));
Expand Down Expand Up @@ -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;
}
}
Expand Down

0 comments on commit 4676fec

Please sign in to comment.