From b4853da2496efb62d1b9f891dc0ce9d0679caf1c Mon Sep 17 00:00:00 2001 From: Hari Rana Date: Wed, 25 Jun 2025 12:03:53 -0400 Subject: [PATCH] event-editor/multi-choice: Add keyboard interaction A significant portion of the behavior was guided by the "Date Picker Spin Button Example" page in the ARIA Authoring Practices Guide (APG): https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/examples/datepicker-spinbuttons/ Related: https://gitlab.gnome.org/GNOME/gnome-calendar/-/issues/1036 Part-of: --- src/gui/event-editor/gcal-multi-choice.blp | 4 ++ src/gui/event-editor/gcal-multi-choice.c | 46 ++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/gui/event-editor/gcal-multi-choice.blp b/src/gui/event-editor/gcal-multi-choice.blp index 97aba31b..2418371d 100644 --- a/src/gui/event-editor/gcal-multi-choice.blp +++ b/src/gui/event-editor/gcal-multi-choice.blp @@ -26,6 +26,10 @@ template $GcalMultiChoice: Box { "popup", ] + EventControllerKey { + key-pressed => $key_pressed_cb(template); + } + Stack stack { hexpand: true; vexpand: true; diff --git a/src/gui/event-editor/gcal-multi-choice.c b/src/gui/event-editor/gcal-multi-choice.c index cadfad16..0ba2c9e2 100644 --- a/src/gui/event-editor/gcal-multi-choice.c +++ b/src/gui/event-editor/gcal-multi-choice.c @@ -234,6 +234,51 @@ button_clicked_cb (GtkWidget *button, g_assert_not_reached (); } +static gboolean +key_pressed_cb (GcalMultiChoice *self, + guint keyval, + guint keycode, + GdkModifierType state, + GtkEventControllerKey *event_controller) +{ + gboolean is_active; + gint old_value; + + g_assert (GCAL_IS_MULTI_CHOICE (self)); + g_assert (GTK_IS_EVENT_CONTROLLER_KEY (event_controller)); + + switch (keyval) + { + case GDK_KEY_space: + case GDK_KEY_KP_Space: + case GDK_KEY_Return: + case GDK_KEY_ISO_Enter: + case GDK_KEY_KP_Enter: + is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->button)); + if (self->popover) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->button), !is_active); + return TRUE; + + case GDK_KEY_Up: + case GDK_KEY_KP_Up: + old_value = self->value; + go_up (self); + if (old_value == self->value) + gtk_widget_error_bell (GTK_WIDGET (self)); + return TRUE; + + case GDK_KEY_Down: + case GDK_KEY_KP_Down: + old_value = self->value; + go_down (self); + if (old_value == self->value) + gtk_widget_error_bell (GTK_WIDGET (self)); + return TRUE; + } + + return FALSE; +} + static void button_toggled_cb (GcalMultiChoice *self) { @@ -588,6 +633,7 @@ gcal_multi_choice_class_init (GcalMultiChoiceClass *class) gtk_widget_class_bind_template_callback (widget_class, button_clicked_cb); gtk_widget_class_bind_template_callback (widget_class, button_toggled_cb); + gtk_widget_class_bind_template_callback (widget_class, key_pressed_cb); gtk_widget_class_set_css_name (widget_class, "navigator"); }