checkbutton: Some fixes when used with GActions
This addresses some oddities when using GtkCheckButton as GtkActionable, in particular related to keynav.
Take the following sample program:
Sample program
static void
update_label (GActionGroup *group,
GtkWidget *label)
{
g_autoptr(GVariant) state = NULL;
state = g_action_group_get_action_state (group, "action");
gtk_label_set_label (GTK_LABEL (label), g_variant_get_string (state, NULL));
}
static void
on_state_changed (GActionGroup *group,
const char *action_name,
GVariant *value,
gpointer user_data)
{
GtkWidget *label = user_data;
update_label (group, label);
}
static void
activate_action (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
g_action_change_state (G_ACTION (action), parameter);
}
static void
change_action_state (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
g_simple_action_set_state (action, state);
}
static void
on_app_startup (GApplication *application,
gpointer user_data)
{
static GActionEntry entries[] = {
{ "action", activate_action, "s", "'foo'", change_action_state }
};
g_action_map_add_action_entries (G_ACTION_MAP (application),
entries, G_N_ELEMENTS (entries),
application);
}
static void
on_app_activated (GApplication *application,
gpointer user_data)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *box, *label, *button, *group;
window = gtk_application_window_new (GTK_APPLICATION (application));
gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
gtk_window_set_child (GTK_WINDOW (window), box);
label = gtk_label_new ("");
gtk_widget_set_margin_bottom (label, 24);
gtk_box_append (GTK_BOX (box), label);
button = gtk_check_button_new_with_label ("Foo");
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button),
"app.action::foo");
gtk_box_append (GTK_BOX (box), button);
group = button;
button = gtk_check_button_new_with_label ("Bar");
gtk_check_button_set_group (GTK_CHECK_BUTTON (button),
GTK_CHECK_BUTTON (group));
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button),
"app.action::bar");
gtk_box_append (GTK_BOX (box), button);
group = button;
button = gtk_check_button_new_with_label ("Baz");
gtk_check_button_set_group (GTK_CHECK_BUTTON (button),
GTK_CHECK_BUTTON (group));
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button),
"app.action::baz");
gtk_box_append (GTK_BOX (box), button);
g_signal_connect (application,
"action-state-changed::action", G_CALLBACK (on_state_changed),
label);
update_label (G_ACTION_GROUP (application), label);
}
gtk_window_present (GTK_WINDOW (window));
}
int
main (int argc, char *argv[]) {
g_autoptr (GtkApplication) app = NULL;
app = gtk_application_new ("org.gnome.fmuellner.Example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "startup", G_CALLBACK (on_app_startup), NULL);
g_signal_connect (app, "activate", G_CALLBACK (on_app_activated), NULL);
return g_application_run (G_APPLICATION (app), argc, argv);
}
- clicking a button will update the action's state (as reflected in the label above)
- using arrow keys to move between buttons will move the check, but not update the action
- activating the focused button with enter/space will toggle its check, but not update the action either
Step 1 is working as expected, this MR addresses 2 and 3.
Edited by Florian Müllner