From 9da53cb4a78bb1e34a1e26b157800322aa09950c Mon Sep 17 00:00:00 2001 From: Josephine Pfeiffer Date: Tue, 16 Jun 2026 14:10:45 +0200 Subject: [PATCH] libnmt-newt: add a hotkey mechanism to NmtNewtForm nmt-newt has no per-widget key interception. Add a generic hook to NmtNewtForm: nmt_newt_form_add_hotkey() registers a key, and a "hotkey" signal is emitted when it (or Esc) is pressed. A handler returning TRUE consumes the key before the form's default handling, so Esc can cancel a transient mode instead of closing the form. This is used by the connection-list search added next. --- src/libnmt-newt/nmt-newt-form.c | 64 +++++++++++++++++++++++++++++++++ src/libnmt-newt/nmt-newt-form.h | 3 ++ 2 files changed, 67 insertions(+) diff --git a/src/libnmt-newt/nmt-newt-form.c b/src/libnmt-newt/nmt-newt-form.c index 3565799c6a..9f372e0b8d 100644 --- a/src/libnmt-newt/nmt-newt-form.c +++ b/src/libnmt-newt/nmt-newt-form.c @@ -38,6 +38,7 @@ typedef struct { gboolean dirty; NmtNewtWidget *focus; + GArray *hotkeys; #ifdef HAVE_NEWTFORMGETSCROLLPOSITION int scroll_position = 0; #endif @@ -60,6 +61,7 @@ enum { enum { QUIT, + HOTKEY, LAST_SIGNAL }; @@ -118,6 +120,7 @@ nmt_newt_form_finalize(GObject *object) g_free(priv->title_lc); g_clear_object(&priv->focus); + nm_clear_pointer(&priv->hotkeys, g_array_unref); G_OBJECT_CLASS(nmt_newt_form_parent_class)->finalize(object); } @@ -211,6 +214,12 @@ nmt_newt_form_build(NmtNewtForm *form) priv->form = newtForm(NULL, NULL, NEWT_FLAG_NOF12); newtFormAddHotKey(priv->form, NEWT_KEY_ESCAPE); + if (priv->hotkeys) { + guint h; + + for (h = 0; h < priv->hotkeys->len; h++) + newtFormAddHotKey(priv->form, nm_g_array_index(priv->hotkeys, int, h)); + } cos = nmt_newt_widget_get_components(priv->content); for (i = 0; cos[i]; i++) @@ -270,6 +279,17 @@ nmt_newt_form_iterate(NmtNewtForm *form) newtFormSetTimer(priv->form, 1); newtFormRun(priv->form, &es); + if (es.reason == NEWT_EXIT_HOTKEY) { + gboolean handled = FALSE; + + /* Give listeners (eg, the connection-list search) a chance to consume the + * key. Esc is included, so a listener can make it cancel a transient mode + * instead of closing the form. */ + g_signal_emit(form, signals[HOTKEY], 0, (int) es.u.key, &handled); + if (handled) + return; + } + if (es.reason == NEWT_EXIT_HOTKEY || es.reason == NEWT_EXIT_ERROR) { /* The user hit Esc or there was an error. */ g_clear_object(&priv->focus); @@ -434,6 +454,28 @@ nmt_newt_form_set_focus(NmtNewtForm *form, NmtNewtWidget *widget) g_object_ref(priv->focus); } +/** + * nmt_newt_form_add_hotkey: + * @form: an #NmtNewtForm + * @key: a key code (eg, a character, or an %NEWT_KEY_ value) + * + * Registers @key as a hotkey on @form. When the user presses it, the + * #NmtNewtForm::hotkey signal is emitted; a handler returning %TRUE consumes + * the key, otherwise the form's default handling applies. + */ +void +nmt_newt_form_add_hotkey(NmtNewtForm *form, int key) +{ + NmtNewtFormPrivate *priv = NMT_NEWT_FORM_GET_PRIVATE(form); + + if (!priv->hotkeys) + priv->hotkeys = g_array_new(FALSE, FALSE, sizeof(int)); + g_array_append_val(priv->hotkeys, key); + + if (priv->form) + newtFormAddHotKey(priv->form, key); +} + static void nmt_newt_form_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { @@ -579,6 +621,28 @@ nmt_newt_form_class_init(NmtNewtFormClass *form_class) G_TYPE_NONE, 0); + /** + * NmtNewtForm::hotkey: + * @form: the #NmtNewtForm + * @key: the key that was pressed + * + * Emitted when a key registered via nmt_newt_form_add_hotkey() (or Esc) is + * pressed. A handler returning %TRUE consumes the key; otherwise the form's + * default handling applies (Esc closes the form). + * + * Returns: %TRUE if the key was handled. + */ + signals[HOTKEY] = g_signal_new("hotkey", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(NmtNewtFormClass, hotkey), + g_signal_accumulator_true_handled, + NULL, + NULL, + G_TYPE_BOOLEAN, + 1, + G_TYPE_INT); + /** * NmtNewtForm:title: * diff --git a/src/libnmt-newt/nmt-newt-form.h b/src/libnmt-newt/nmt-newt-form.h index 6a2ff9dcb2..7e5b7dd60c 100644 --- a/src/libnmt-newt/nmt-newt-form.h +++ b/src/libnmt-newt/nmt-newt-form.h @@ -26,6 +26,7 @@ typedef struct { /* signals */ void (*quit)(NmtNewtForm *form); + gboolean (*hotkey)(NmtNewtForm *form, int key); /* methods */ void (*show)(NmtNewtForm *form); @@ -45,4 +46,6 @@ void nmt_newt_form_quit(NmtNewtForm *form); void nmt_newt_form_set_focus(NmtNewtForm *form, NmtNewtWidget *widget); +void nmt_newt_form_add_hotkey(NmtNewtForm *form, int key); + #endif /* NMT_NEWT_FORM_H */