From 02726edcdcac4bb1c41b0e0e8cbf2d4ea5babd7a Mon Sep 17 00:00:00 2001 From: 3urobeat Date: Wed, 16 Sep 2026 18:44:24 +0200 Subject: [PATCH] feat: Mask PIN input on lockscreen --- .../companion_radio/ui-new/KeyboardWidget.h | 18 +++++++++++++++++- examples/companion_radio/ui-new/UITask.cpp | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/examples/companion_radio/ui-new/KeyboardWidget.h b/examples/companion_radio/ui-new/KeyboardWidget.h index 34f70e4e..9d73965a 100644 --- a/examples/companion_radio/ui-new/KeyboardWidget.h +++ b/examples/companion_radio/ui-new/KeyboardWidget.h @@ -297,6 +297,7 @@ struct KeyboardWidget { bool accent_active = false; // true while the Hold-Enter accent popup is open int accent_group = -1; // index into KB_ACCENT_VARIANTS for the held cell's base letter int accent_sel = 0; // selected variant within that group + bool pin_kb_mask_enabled = false; // Whether pin keyboard should mask input int row, col; int page; // see totalPages()/scriptAt()/pageIsSymbols() below bool caps; @@ -438,6 +439,7 @@ struct KeyboardWidget { page = 0; caps = false; caps_lock = false; + pin_kb_mask_enabled = false; t9_cell = -1; t9_cycle = 0; _ph_menu.active = false; @@ -451,9 +453,10 @@ struct KeyboardWidget { } // Open keyboard in PIN mode - void beginPin(const char* initial = "", int max = KB_MAX_LEN) { + void beginPin(const char* initial = "", int max = KB_MAX_LEN, bool mask = false) { if (prefs) prefs->keyboard_type = 2; // Force number input begin(initial, max); + pin_kb_mask_enabled = mask; // Mask input of number field } // Insert one UTF-8 codepoint (a grid cell's own glyph, or a picked accent @@ -622,6 +625,19 @@ struct KeyboardWidget { } else { linebuf[0] = '\0'; } + // Mask input when pin_kb_mask is enabled + if (pin_kb_mask_enabled) { + char masked[KB_PREVIEW_BYTES + 2]; + int mi = 0; + int blen = (int)strlen(linebuf); + for (int bi = 0; bi < blen; ) { + int u = kbUtf8CharBytesAt(linebuf, bi, blen); + masked[mi++] = (u == 1 && linebuf[bi] == '_') ? '_' : '*'; + bi += u; + } + masked[mi] = '\0'; + strncpy(linebuf, masked, sizeof(linebuf)); + } char linebuf_t[KB_PREVIEW_BYTES + 2]; display.translateUTF8ToBlocks(linebuf_t, linebuf, sizeof(linebuf_t)); display.setCursor(0, pl * lh); diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 3ab78ac4..5d4b6fd0 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -2261,7 +2261,7 @@ void UITask::beginUnlockPrompt() { _unlock_kb = true; // Track that keyboard is visible and is waiting for input int max_len = _node_prefs ? (int)sizeof(_node_prefs->lock_screen_password) - 1 : 32; _lock_pin_restore_kb_type = _node_prefs ? _node_prefs->keyboard_type : 0; - _kb.beginPin("", max_len); + _kb.beginPin("", max_len, true); // Pass true to hide input _kb.clearPlaceholders(); _lock_wake_until = millis() + 5000; // keep the display on while typing _next_refresh = 0;