From 67fd1f0c5286b7a7e41ec18ece561a95b0d89613 Mon Sep 17 00:00:00 2001 From: Niels De Graef Date: Wed, 8 Dec 2021 00:09:08 +0100 Subject: [PATCH] app: Popup menu at pointer in GimpEditor Rather than trying to fix up our own heuristics using a `GtkMenuPositionFunc`, use the API that GTK provides to have popup nicely placed near the pointer, which also has the benefit of nicely integrating with GDK backends such as Wayland. --- app/widgets/gimpcomponenteditor.c | 2 +- app/widgets/gimpcontainertreeview.c | 2 +- app/widgets/gimpeditor.c | 17 +++++++++++++++ app/widgets/gimpeditor.h | 3 +++ app/widgets/gimperrorconsole.c | 2 +- app/widgets/gimpgradienteditor.c | 32 +++++++++++------------------ 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/app/widgets/gimpcomponenteditor.c b/app/widgets/gimpcomponenteditor.c index d7f401f813..62bc6c45ee 100644 --- a/app/widgets/gimpcomponenteditor.c +++ b/app/widgets/gimpcomponenteditor.c @@ -503,7 +503,7 @@ gimp_component_editor_button_press (GtkWidget *widget, if (gdk_event_triggers_context_menu ((GdkEvent *) bevent)) { - gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL); + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (editor), (GdkEvent *) bevent); } else if (bevent->type == GDK_BUTTON_PRESS && bevent->button == 1 && column != editor->eye_column) diff --git a/app/widgets/gimpcontainertreeview.c b/app/widgets/gimpcontainertreeview.c index a87245d591..af1c335a4d 100644 --- a/app/widgets/gimpcontainertreeview.c +++ b/app/widgets/gimpcontainertreeview.c @@ -1629,7 +1629,7 @@ gimp_container_tree_view_button (GtkWidget *widget, { if (gdk_event_triggers_context_menu ((GdkEvent *) bevent)) { - gimp_editor_popup_menu (GIMP_EDITOR (tree_view), NULL, NULL); + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (tree_view), (GdkEvent *) bevent); } return TRUE; diff --git a/app/widgets/gimpeditor.c b/app/widgets/gimpeditor.c index 625571227e..c84cd5718e 100644 --- a/app/widgets/gimpeditor.c +++ b/app/widgets/gimpeditor.c @@ -465,6 +465,23 @@ gimp_editor_popup_menu (GimpEditor *editor, return FALSE; } +gboolean +gimp_editor_popup_menu_at_pointer (GimpEditor *editor, + const GdkEvent *trigger_event) +{ + g_return_val_if_fail (GIMP_IS_EDITOR (editor), FALSE); + + if (editor->priv->ui_manager && editor->priv->ui_path) + { + gimp_ui_manager_update (editor->priv->ui_manager, editor->priv->popup_data); + gimp_ui_manager_ui_popup_at_pointer (editor->priv->ui_manager, editor->priv->ui_path, + trigger_event, NULL, NULL); + return TRUE; + } + + return FALSE; +} + GtkWidget * gimp_editor_add_button (GimpEditor *editor, const gchar *icon_name, diff --git a/app/widgets/gimpeditor.h b/app/widgets/gimpeditor.h index c840861a08..0ba60b96eb 100644 --- a/app/widgets/gimpeditor.h +++ b/app/widgets/gimpeditor.h @@ -58,6 +58,9 @@ void gimp_editor_create_menu (GimpEditor *editor, gboolean gimp_editor_popup_menu (GimpEditor *editor, GimpMenuPositionFunc position_func, gpointer position_data); +gboolean gimp_editor_popup_menu_at_pointer + (GimpEditor *editor, + const GdkEvent *trigger_event); GtkWidget * gimp_editor_add_button (GimpEditor *editor, const gchar *icon_name, diff --git a/app/widgets/gimperrorconsole.c b/app/widgets/gimperrorconsole.c index ccb473654b..8c9cf59b6a 100644 --- a/app/widgets/gimperrorconsole.c +++ b/app/widgets/gimperrorconsole.c @@ -272,7 +272,7 @@ gimp_error_console_button_press (GtkWidget *widget, { if (gdk_event_triggers_context_menu ((GdkEvent *) bevent)) { - return gimp_editor_popup_menu (GIMP_EDITOR (console), NULL, NULL); + return gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (console), (GdkEvent *) bevent); } return FALSE; diff --git a/app/widgets/gimpgradienteditor.c b/app/widgets/gimpgradienteditor.c index 754a167333..d4eaeeaecb 100644 --- a/app/widgets/gimpgradienteditor.c +++ b/app/widgets/gimpgradienteditor.c @@ -190,10 +190,7 @@ static void control_do_hint (GimpGradientEditor *editor, gint x, gint y); static void control_button_press (GimpGradientEditor *editor, - gint x, - gint y, - guint button, - guint state); + GdkEventButton *bevent); static gboolean control_point_in_handle (GimpGradientEditor *editor, GimpGradient *gradient, gint x, @@ -1141,7 +1138,7 @@ view_events (GtkWidget *widget, if (gdk_event_triggers_context_menu ((GdkEvent *) bevent)) { - gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL); + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (editor), event); } else if (bevent->button == 1) { @@ -1338,9 +1335,7 @@ control_events (GtkWidget *widget, editor->control_last_x = bevent->x; editor->control_click_time = bevent->time; - control_button_press (editor, - bevent->x, bevent->y, - bevent->button, bevent->state); + control_button_press (editor, bevent); if (editor->control_drag_mode != GRAD_DRAG_NONE) { @@ -1610,10 +1605,7 @@ control_do_hint (GimpGradientEditor *editor, static void control_button_press (GimpGradientEditor *editor, - gint x, - gint y, - guint button, - guint state) + GdkEventButton *bevent) { GimpGradient *gradient; GimpGradientSegment *seg; @@ -1623,19 +1615,19 @@ control_button_press (GimpGradientEditor *editor, gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data); - if (button == 3) + if (gdk_event_triggers_context_menu ((GdkEvent *) bevent)) { - gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL); + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (editor), (GdkEvent *) bevent); return; } /* Find the closest handle */ - xpos = control_calc_g_pos (editor, x); + xpos = control_calc_g_pos (editor, bevent->x); seg_get_closest_handle (gradient, xpos, &seg, &handle); - in_handle = control_point_in_handle (editor, gradient, x, y, seg, handle); + in_handle = control_point_in_handle (editor, gradient, bevent->x, bevent->y, seg, handle); /* Now see what we have */ @@ -1647,7 +1639,7 @@ control_button_press (GimpGradientEditor *editor, if (seg != NULL) { /* Left handle of some segment */ - if (state & GDK_SHIFT_MASK) + if (bevent->state & GDK_SHIFT_MASK) { if (seg->prev != NULL) { @@ -1677,7 +1669,7 @@ control_button_press (GimpGradientEditor *editor, /* Right handle of last segment */ seg = gimp_gradient_segment_get_last (gradient->segments); - if (state & GDK_SHIFT_MASK) + if (bevent->state & GDK_SHIFT_MASK) { control_extend_selection (editor, seg, xpos); gimp_gradient_editor_update (editor); @@ -1692,7 +1684,7 @@ control_button_press (GimpGradientEditor *editor, break; case GRAD_DRAG_MIDDLE: - if (state & GDK_SHIFT_MASK) + if (bevent->state & GDK_SHIFT_MASK) { control_extend_selection (editor, seg, xpos); gimp_gradient_editor_update (editor); @@ -1719,7 +1711,7 @@ control_button_press (GimpGradientEditor *editor, editor->control_last_gx = xpos; editor->control_orig_pos = xpos; - if (state & GDK_SHIFT_MASK) + if (bevent->state & GDK_SHIFT_MASK) editor->control_compress = TRUE; } }