gtkmenubutton: Popup menu/popover on GtkButton:clicked

This happens on button release, which is more convenient if the gesture
can be consumed by something else (eg. window dragging), and already behaves
correctly wrt cancelled gestures, broken grabs, etc.

This also allows us to unify pointer and keyboard behavior, popping up the
menu widget in a single place.
This commit is contained in:
Carlos Garnacho 2015-02-25 20:31:09 +01:00
parent 2e52e9964b
commit 0796d7b6ff

View File

@ -132,6 +132,7 @@ struct _GtkMenuButtonPrivate
GtkWidget *arrow_widget; GtkWidget *arrow_widget;
GtkArrowType arrow_type; GtkArrowType arrow_type;
gboolean use_popover; gboolean use_popover;
guint press_handled : 1;
}; };
enum enum
@ -405,60 +406,39 @@ popup_menu (GtkMenuButton *menu_button,
} }
static void static void
gtk_menu_button_toggled (GtkToggleButton *button) gtk_menu_button_clicked (GtkButton *button)
{ {
GtkMenuButton *menu_button = GTK_MENU_BUTTON (button); GtkMenuButton *menu_button = GTK_MENU_BUTTON (button);
GtkMenuButtonPrivate *priv = menu_button->priv; GtkMenuButtonPrivate *priv = menu_button->priv;
gboolean active; gboolean active = TRUE;
active = gtk_toggle_button_get_active (button); if (priv->menu && !gtk_widget_get_visible (priv->menu))
if (priv->menu)
{ {
if (active) GdkEvent *event;
{
if (!gtk_widget_get_visible (priv->menu)) event = gtk_get_current_event ();
{
/* we get here only when the menu is activated by a key popup_menu (menu_button,
* press, so that we can select the first menu item (event && event->type != GDK_BUTTON_RELEASE) ?
*/ (GdkEventButton *) event : NULL);
popup_menu (menu_button, NULL);
gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE); if (!event ||
} event->type == GDK_KEY_PRESS ||
} event->type == GDK_KEY_RELEASE)
else gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
if (event)
gdk_event_free (event);
} }
else if (priv->popover) else if (priv->popover && !gtk_widget_get_visible (priv->popover))
gtk_widget_set_visible (priv->popover, active); gtk_widget_show (priv->popover);
} else
active = FALSE;
static gboolean GTK_BUTTON_CLASS (gtk_menu_button_parent_class)->clicked (button);
gtk_menu_button_button_press_event (GtkWidget *widget,
GdkEventButton *event)
{
GtkMenuButton *menu_button = GTK_MENU_BUTTON (widget);
GtkMenuButtonPrivate *priv = menu_button->priv;
if (event->button == GDK_BUTTON_PRIMARY) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), active);
{ gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (button));
/* Filter out double/triple clicks */
if (event->type != GDK_BUTTON_PRESS)
return TRUE;
if (priv->menu && !gtk_widget_get_visible (priv->menu))
popup_menu (menu_button, event);
else if (priv->popover && !gtk_widget_get_visible (priv->popover))
gtk_widget_show (priv->popover);
else
return TRUE;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
return TRUE;
}
return GTK_WIDGET_CLASS (gtk_menu_button_parent_class)->button_press_event (widget, event);
} }
static void static void
@ -491,19 +471,18 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
GtkToggleButtonClass *toggle_button_class = GTK_TOGGLE_BUTTON_CLASS (klass); GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
gobject_class->set_property = gtk_menu_button_set_property; gobject_class->set_property = gtk_menu_button_set_property;
gobject_class->get_property = gtk_menu_button_get_property; gobject_class->get_property = gtk_menu_button_get_property;
gobject_class->dispose = gtk_menu_button_dispose; gobject_class->dispose = gtk_menu_button_dispose;
widget_class->state_flags_changed = gtk_menu_button_state_flags_changed; widget_class->state_flags_changed = gtk_menu_button_state_flags_changed;
widget_class->button_press_event = gtk_menu_button_button_press_event;
container_class->add = gtk_menu_button_add; container_class->add = gtk_menu_button_add;
container_class->remove = gtk_menu_button_remove; container_class->remove = gtk_menu_button_remove;
toggle_button_class->toggled = gtk_menu_button_toggled; button_class->clicked = gtk_menu_button_clicked;
/** /**
* GtkMenuButton:popup: * GtkMenuButton:popup: