diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-11-15 21:52:07 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-11-15 21:52:07 -0500 |
commit | 6891f401107ce400729de86f75e7160d99c3f1cf (patch) | |
tree | ffe7b537658b9b7980fe923b24fbacdb8529cae9 | |
parent | cdbf24c3af93e84ffc1ad5587dd2bc49a5969299 (diff) | |
download | gtk+-6891f401107ce400729de86f75e7160d99c3f1cf.tar.gz |
modelbutton: Fix keynav for check and radio
The expected behavior when activating check or radio
menuitems via keynav is that Space toggles the item
but keeps the menu open, while Return toggles the
item and closes the menu.
-rw-r--r-- | gtk/gtkmodelbutton.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c index 9efed319aa..501dc5e087 100644 --- a/gtk/gtkmodelbutton.c +++ b/gtk/gtkmodelbutton.c @@ -179,6 +179,7 @@ struct _GtkModelButton guint active : 1; guint centered : 1; guint iconic : 1; + guint keep_open : 1; }; typedef struct _GtkModelButtonClass GtkModelButtonClass; @@ -1044,7 +1045,7 @@ gtk_model_button_clicked (GtkModelButton *self) gtk_popover_menu_set_open_submenu (menu, submenu); gtk_popover_menu_set_parent_menu (GTK_POPOVER_MENU (submenu), GTK_WIDGET (menu)); } - else if (self->role == GTK_BUTTON_ROLE_NORMAL) + else if (!self->keep_open) { GtkWidget *popover; @@ -1057,6 +1058,20 @@ gtk_model_button_clicked (GtkModelButton *self) gtk_action_helper_activate (self->action_helper); } +static gboolean +toggle_cb (GtkWidget *widget, + GVariant *args, + gpointer user_data) +{ + GtkModelButton *self = GTK_MODEL_BUTTON (widget); + + self->keep_open = self->role != GTK_BUTTON_ROLE_NORMAL; + g_signal_emit (widget, signals[SIGNAL_CLICKED], 0); + self->keep_open = FALSE; + + return TRUE; +} + static void gtk_model_button_finalize (GObject *object) { @@ -1128,6 +1143,14 @@ gtk_model_button_class_init (GtkModelButtonClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); + GtkShortcutAction *action; + guint activate_keyvals[] = { + GDK_KEY_Return, GDK_KEY_ISO_Enter, GDK_KEY_KP_Enter + }; + guint toggle_keyvals[] = { + GDK_KEY_space, GDK_KEY_KP_Space + }; + int i; object_class->dispose = gtk_model_button_dispose; object_class->finalize = gtk_model_button_finalize; @@ -1277,6 +1300,30 @@ gtk_model_button_class_init (GtkModelButtonClass *class) gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT); gtk_widget_class_set_css_name (widget_class, I_("modelbutton")); gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_MENU_ITEM); + + action = gtk_signal_action_new ("clicked"); + for (i = 0; i < G_N_ELEMENTS (activate_keyvals); i++) + { + GtkShortcut *shortcut; + + shortcut = gtk_shortcut_new (gtk_keyval_trigger_new (activate_keyvals[i], 0), + g_object_ref (action)); + gtk_widget_class_add_shortcut (widget_class, shortcut); + g_object_unref (shortcut); + } + g_object_unref (action); + + action = gtk_callback_action_new (toggle_cb, NULL, NULL); + for (i = 0; i < G_N_ELEMENTS (toggle_keyvals); i++) + { + GtkShortcut *shortcut; + + shortcut = gtk_shortcut_new (gtk_keyval_trigger_new (toggle_keyvals[i], 0), + g_object_ref (action)); + gtk_widget_class_add_shortcut (widget_class, shortcut); + g_object_unref (shortcut); + } + g_object_unref (action); } static void |