link button: Use new context menu api

This commit is contained in:
Matthias Clasen 2019-06-12 01:34:19 +00:00
parent 10ce2076f9
commit 6452aeef3c

View File

@ -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;
GMenuModel *model;
if (priv->popup_menu)
gtk_widget_destroy (priv->popup_menu);
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);
priv->popup_menu = gtk_menu_new ();
gtk_style_context_add_class (gtk_widget_get_style_context (priv->popup_menu),
GTK_STYLE_CLASS_CONTEXT_MENU);
gtk_popover_set_has_arrow (GTK_POPOVER (priv->popup_menu), FALSE);
gtk_widget_set_halign (priv->popup_menu, GTK_ALIGN_START);
gtk_menu_attach_to_widget (GTK_MENU (priv->popup_menu),
GTK_WIDGET (link_button),
popup_menu_detach);
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);
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);
gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->popup_menu), FALSE);
}
g_object_unref (model);
}
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