From 7a24ea0c1966ccdd07cd8774811fbafe694f028d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= <gael@xfce.org>
Date: Mon, 23 May 2022 12:14:27 +0200
Subject: [PATCH] libxfce4panel: Add new function
 `xfce_panel_plugin_popup_menu()`

MR: !80
---
 docs/reference/libxfce4panel-sections.txt |  1 +
 libxfce4panel/libxfce4panel.symbols       |  1 +
 libxfce4panel/xfce-panel-plugin.c         | 87 +++++++++++++++++++++++
 libxfce4panel/xfce-panel-plugin.h         |  5 ++
 4 files changed, 94 insertions(+)

diff --git a/docs/reference/libxfce4panel-sections.txt b/docs/reference/libxfce4panel-sections.txt
index 58e832ec2..e96f0180f 100644
--- a/docs/reference/libxfce4panel-sections.txt
+++ b/docs/reference/libxfce4panel-sections.txt
@@ -111,6 +111,7 @@ xfce_panel_plugin_register_menu
 xfce_panel_plugin_arrow_type
 xfce_panel_plugin_position_widget
 xfce_panel_plugin_position_menu
+xfce_panel_plugin_popup_menu
 xfce_panel_plugin_focus_widget
 xfce_panel_plugin_block_autohide
 xfce_panel_plugin_lookup_rc_file
diff --git a/libxfce4panel/libxfce4panel.symbols b/libxfce4panel/libxfce4panel.symbols
index a09f6b673..7bc6f2006 100644
--- a/libxfce4panel/libxfce4panel.symbols
+++ b/libxfce4panel/libxfce4panel.symbols
@@ -123,6 +123,7 @@ xfce_panel_plugin_arrow_type
 xfce_panel_plugin_remove
 xfce_panel_plugin_position_widget
 xfce_panel_plugin_position_menu
+xfce_panel_plugin_popup_menu
 xfce_panel_plugin_focus_widget
 xfce_panel_plugin_block_autohide
 xfce_panel_plugin_lookup_rc_file G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT
diff --git a/libxfce4panel/xfce-panel-plugin.c b/libxfce4panel/xfce-panel-plugin.c
index 9300857a4..512aca272 100644
--- a/libxfce4panel/xfce-panel-plugin.c
+++ b/libxfce4panel/xfce-panel-plugin.c
@@ -2729,6 +2729,93 @@ xfce_panel_plugin_position_menu (GtkMenu  *menu,
 
 
 
+/**
+ * xfce_panel_plugin_popup_menu:
+ * @plugin        : an #XfcePanelPlugin.
+ * @menu          : a #GtkMenu.
+ * @widget        : (allow-none): the #GtkWidget to align @menu with or %NULL
+ *                  to pop up @menu at pointer.
+ * @trigger_event : (allow-none): the #GdkEvent that initiated this request or
+ *                  %NULL if it's the current event.
+ *
+ * Pops up @menu at @widget if @widget is non-%NULL and if appropriate given
+ * the panel position, otherwise pops up @menu at pointer.
+ *
+ * As a convenience, xfce_panel_plugin_popup_menu() calls
+ * xfce_panel_plugin_register_menu() for the @menu.
+ *
+ * For a custom widget that will be used as a popup menu, use
+ * xfce_panel_plugin_position_widget() instead.
+ *
+ * See also: gtk_menu_popup_at_widget() and gtk_menu_popup_at_pointer().
+ *
+ * Since: 4.17.2
+ **/
+void
+xfce_panel_plugin_popup_menu (XfcePanelPlugin *plugin,
+                              GtkMenu         *menu,
+                              GtkWidget       *widget,
+                              const GdkEvent  *trigger_event)
+{
+  GdkGravity widget_anchor, menu_anchor;
+  gboolean   popup_at_widget = TRUE;
+
+  g_return_if_fail (XFCE_IS_PANEL_PLUGIN (plugin));
+  g_return_if_fail (GTK_IS_MENU (menu));
+
+  /* check if conditions are met to pop up menu at widget */
+  if (widget != NULL)
+    {
+      switch (plugin->priv->screen_position)
+        {
+          case XFCE_SCREEN_POSITION_NW_H:
+          case XFCE_SCREEN_POSITION_N:
+          case XFCE_SCREEN_POSITION_NE_H:
+            widget_anchor = GDK_GRAVITY_SOUTH_WEST;
+            menu_anchor = GDK_GRAVITY_NORTH_WEST;
+            break;
+
+          case XFCE_SCREEN_POSITION_NW_V:
+          case XFCE_SCREEN_POSITION_W:
+          case XFCE_SCREEN_POSITION_SW_V:
+            widget_anchor = GDK_GRAVITY_NORTH_EAST;
+            menu_anchor = GDK_GRAVITY_NORTH_WEST;
+            break;
+
+          case XFCE_SCREEN_POSITION_NE_V:
+          case XFCE_SCREEN_POSITION_E:
+          case XFCE_SCREEN_POSITION_SE_V:
+            widget_anchor = GDK_GRAVITY_NORTH_WEST;
+            menu_anchor = GDK_GRAVITY_NORTH_EAST;
+            break;
+
+          case XFCE_SCREEN_POSITION_SW_H:
+          case XFCE_SCREEN_POSITION_S:
+          case XFCE_SCREEN_POSITION_SE_H:
+            widget_anchor = GDK_GRAVITY_NORTH_WEST;
+            menu_anchor = GDK_GRAVITY_SOUTH_WEST;
+            break;
+
+          default:
+            popup_at_widget = FALSE;
+            break;
+        }
+    }
+  else
+    popup_at_widget = FALSE;
+
+  /* register the menu */
+  xfce_panel_plugin_register_menu (plugin, menu);
+
+  /* pop up the menu */
+  if (popup_at_widget)
+    gtk_menu_popup_at_widget (menu, widget, widget_anchor, menu_anchor, trigger_event);
+  else
+    gtk_menu_popup_at_pointer (menu, trigger_event);
+}
+
+
+
 /**
  * xfce_panel_plugin_focus_widget:
  * @plugin : an #XfcePanelPlugin.
diff --git a/libxfce4panel/xfce-panel-plugin.h b/libxfce4panel/xfce-panel-plugin.h
index dee753983..8368caa60 100644
--- a/libxfce4panel/xfce-panel-plugin.h
+++ b/libxfce4panel/xfce-panel-plugin.h
@@ -236,6 +236,11 @@ void                  xfce_panel_plugin_position_menu       (GtkMenu           *
                                                              gboolean          *push_in,
                                                              gpointer           panel_plugin);
 
+void                  xfce_panel_plugin_popup_menu          (XfcePanelPlugin   *plugin,
+                                                             GtkMenu           *menu,
+                                                             GtkWidget         *widget,
+                                                             const GdkEvent    *trigger_event);
+
 void                  xfce_panel_plugin_focus_widget        (XfcePanelPlugin   *plugin,
                                                              GtkWidget         *widget);
 
-- 
GitLab