[gtk/wip/matthiasc/context-menu: 22/23] link button: Use new context menu api



commit 2522c7bf4f5055c303cfa83d6268d67237697610
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jun 12 01:34:19 2019 +0000

    link button: Use new context menu api

 gtk/gtklinkbutton.c | 120 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 71 insertions(+), 49 deletions(-)
---
diff --git a/gtk/gtklinkbutton.c b/gtk/gtklinkbutton.c
index f867b63c91..7c68d9380f 100644
--- a/gtk/gtklinkbutton.c
+++ b/gtk/gtklinkbutton.c
@@ -60,8 +60,7 @@
 #include "gtklabel.h"
 #include "gtkmain.h"
 #include "gtkmarshalers.h"
-#include "gtkmenu.h"
-#include "gtkmenuitem.h"
+#include "gtkpopovermenu.h"
 #include "gtkprivate.h"
 #include "gtkshow.h"
 #include "gtksizerequest.h"
@@ -97,6 +96,7 @@ struct _GtkLinkButtonPrivate
 
   gboolean visited;
 
+  GActionMap *context_actions;
   GtkWidget *popup_menu;
 };
 
@@ -223,6 +223,43 @@ gtk_link_button_class_init (GtkLinkButtonClass *klass)
   gtk_widget_class_set_css_name (widget_class, I_("button"));
 }
 
+static void copy_activate_cb (GSimpleAction *action,
+                              GVariant      *parameter,
+                              gpointer       user_data);
+
+static void
+gtk_link_button_add_context_actions (GtkLinkButton *link_button)
+{
+  GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
+
+  GActionEntry entries[] = {
+    { "copy-clipboard", copy_activate_cb, NULL, NULL, NULL },
+  };
+
+  GSimpleActionGroup *actions = g_simple_action_group_new ();
+
+  priv->context_actions = G_ACTION_MAP (actions);
+
+  g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), link_button);
+
+  gtk_widget_insert_action_group (GTK_WIDGET (link_button), "context", G_ACTION_GROUP (actions));
+}
+
+static GMenuModel *
+gtk_link_button_get_menu_model (void)
+{
+  GMenu *menu, *section;
+
+  menu = g_menu_new ();
+
+  section = g_menu_new ();
+  g_menu_append (section, _("_Copy URL"), "context.copy-clipboard");
+  g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
+  g_object_unref (section);
+
+  return G_MENU_MODEL (menu);
+}
+
 static void
 gtk_link_button_init (GtkLinkButton *link_button)
 {
@@ -261,6 +298,7 @@ gtk_link_button_init (GtkLinkButton *link_button)
   gtk_style_context_add_class (context, "link");
 
   gtk_widget_set_cursor_from_name (GTK_WIDGET (link_button), "pointer");
+  gtk_link_button_add_context_actions (link_button);
 }
 
 static void
@@ -270,7 +308,10 @@ gtk_link_button_finalize (GObject *object)
   GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
 
   g_free (priv->uri);
-  
+
+  g_clear_object (&priv->context_actions);
+  g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
+
   G_OBJECT_CLASS (gtk_link_button_parent_class)->finalize (object);
 }
 
@@ -320,19 +361,11 @@ gtk_link_button_set_property (GObject      *object,
 }
 
 static void
-popup_menu_detach (GtkWidget *attach_widget,
-                  GtkMenu   *menu)
-{
-  GtkLinkButton *link_button = GTK_LINK_BUTTON (attach_widget);
-  GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
-
-  priv->popup_menu = NULL;
-}
-
-static void
-copy_activate_cb (GtkWidget     *widget,
-                 GtkLinkButton *link_button)
+copy_activate_cb (GSimpleAction *action,
+                  GVariant      *parameter,
+                  gpointer       user_data)
 {
+  GtkLinkButton *link_button = user_data;
   GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
 
   gdk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (link_button)),
@@ -340,45 +373,35 @@ copy_activate_cb (GtkWidget     *widget,
 }
 
 static void
-gtk_link_button_do_popup (GtkLinkButton  *link_button,
-                          const GdkEvent *event)
+gtk_link_button_do_popup (GtkLinkButton *link_button,
+                          double         x,
+                          double         y)
 {
   GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
 
-  if (gtk_widget_get_realized (GTK_WIDGET (link_button)))
+  if (!priv->popup_menu)
     {
-      GtkWidget *menu_item;
-
-      if (priv->popup_menu)
-       gtk_widget_destroy (priv->popup_menu);
-
-      priv->popup_menu = gtk_menu_new ();
-      gtk_style_context_add_class (gtk_widget_get_style_context (priv->popup_menu),
-                                   GTK_STYLE_CLASS_CONTEXT_MENU);
+      GMenuModel *model;
 
-      gtk_menu_attach_to_widget (GTK_MENU (priv->popup_menu),
-                                GTK_WIDGET (link_button),
-                                popup_menu_detach);
+      model = gtk_link_button_get_menu_model ();
+      priv->popup_menu = gtk_popover_menu_new_from_model (GTK_WIDGET (link_button), model);
+      gtk_popover_set_position (GTK_POPOVER (priv->popup_menu), GTK_POS_BOTTOM);
 
-      menu_item = gtk_menu_item_new_with_mnemonic (_("Copy URL"));
-      g_signal_connect (menu_item, "activate",
-                       G_CALLBACK (copy_activate_cb), link_button);
-      gtk_widget_show (menu_item);
-      gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menu_item);
+      gtk_popover_set_has_arrow (GTK_POPOVER (priv->popup_menu), FALSE);
+      gtk_widget_set_halign (priv->popup_menu, GTK_ALIGN_START);
 
-      if (event && gdk_event_triggers_context_menu (event))
-        gtk_menu_popup_at_pointer (GTK_MENU (priv->popup_menu), event);
-      else
-        {
-          gtk_menu_popup_at_widget (GTK_MENU (priv->popup_menu),
-                                    GTK_WIDGET (link_button),
-                                    GDK_GRAVITY_SOUTH,
-                                    GDK_GRAVITY_NORTH_WEST,
-                                    event);
+      g_object_unref (model);
+    }
 
-          gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->popup_menu), FALSE);
-        }
+  if (x != -1 && y != -1)
+    {
+      GdkRectangle rect = { x, y, 1, 1 };
+      gtk_popover_set_pointing_to (GTK_POPOVER (priv->popup_menu), &rect);
     }
+  else
+    gtk_popover_set_pointing_to (GTK_POPOVER (priv->popup_menu), NULL);
+
+  gtk_popover_popup (GTK_POPOVER (priv->popup_menu));
 }
 
 static void
@@ -399,7 +422,7 @@ gtk_link_button_pressed_cb (GtkGestureClick *gesture,
   if (gdk_event_triggers_context_menu (event) &&
       priv->uri != NULL)
     {
-      gtk_link_button_do_popup (link_button, event);
+      gtk_link_button_do_popup (link_button, x, y);
       gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
     }
   else
@@ -445,9 +468,8 @@ gtk_link_button_clicked (GtkButton *button)
 static gboolean
 gtk_link_button_popup_menu (GtkWidget *widget)
 {
-  gtk_link_button_do_popup (GTK_LINK_BUTTON (widget), NULL);
-
-  return TRUE; 
+  gtk_link_button_do_popup (GTK_LINK_BUTTON (widget), -1, -1);
+  return TRUE;
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]