fw: button lock with key-combo Back+Down - #1838
Open
unki wants to merge 10 commits into
Open
Conversation
Author
|
I've gone with Back + Down because I'm already used to similar button combinations on other watches. I couldn't find that combination being used or reserved for anything else, though. It should be easy to change later if needed. Or even make it configurable. |
An interrupted update leaves the chip in boot mode, where it stops answering CHIP_ID_REG read. Force-updating in case this happens. Signed-off-by: Sergei Gureev <git@bemyak.net>
Add a buttonLockHoldMs preference storing how long the Back+Down combo must be held to toggle the upcoming button lock feature. A value of 0 (the default) disables the feature. The handler accepts only the values offered by the Settings UI (0/1/2/3/5/10 seconds). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Andreas Unterkircher <unki@netshadow.net>
Holding Back+Down for the configured duration locks all button input; holding the combo again unlocks. While locked, button events are masked from every task in the kernel event loop; on touch-capable boards the touch sensor is disabled too, restored to the persisted touch pref on unlock. Lock/unlock gives a vibe pulse and a brief popup, and pressing a button while locked shows an unlock hint. The module delivers a button UP only if its DOWN was delivered, keeping click recognizers balanced, and cancels the back-button force-quit timer when the combo becomes pending so holding the combo inside an app does not force-quit it. The first combo button may still perform its normal press action, matching quick launch combo behavior. Locked state is RAM-only: a reboot always unlocks. The ISR-level hardware reset combo and the back-quickpress coredump remain functional while locked. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Andreas Unterkircher <unki@netshadow.net>
New row in Settings > System opening an option menu with the button lock hold duration: Off (default), 1, 2, 3, 5 or 10 seconds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Andreas Unterkircher <unki@netshadow.net>
Cover combo detection, configurable hold duration, abort on early release or third button, input swallowing and hint popup while locked, touch pref restoration on unlock, single toggle per continuous hold and the timer-fire-after-release race. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Andreas Unterkircher <unki@netshadow.net>
With the buttons locked, an incoming notification (push message, calendar alert, ...) stays on top of the watchface and pressing a button gives no visible reaction - neither the "Hold Back + Down to unlock" hint nor, after performing the unlock combo, the "Buttons Unlocked" confirmation. Only the vibe hints that the lock reacted at all. Cause: the button lock popups were pushed on the ModalPriorityGeneric window stack. Modal windows composite by priority (Discreet < Generic < Phone < Notification < Alert < Voice < Critical < Alarm), and notification windows live at ModalPriorityNotification, so the lock dialogs were created correctly but sat invisibly underneath the notification until their 1.8 s timeout popped them again. Fix: push the popups at ModalPriorityAlert instead. The priority was chosen deliberately: - Above Notification and Phone, so the hint and lock/unlock feedback are visible in exactly the scenarios where the lock's behavior is otherwise inexplicable (notification or incoming call on screen). - Same level as the crash and low-battery dialogs: within one stack the newest window is on top, so a lock toast briefly overlays them and reveals them again when it times out - nothing is dismissed or lost. - Deliberately below Critical (BT pairing requests) and Alarm (alarm ring): those must never be masked by a lock toast, and going higher would buy nothing - a higher-priority window simply covers our dialog, which times out silently underneath. In critical-battery mode the modal floor is raised to ModalPriorityAlarm anyway, so no popup of ours shows there regardless of this choice. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Andreas Unterkircher <unki@netshadow.net>
unki
force-pushed
the
feature/button-lock-with-key-combo
branch
from
August 12, 2026 19:01
b289db7 to
e4a7d09
Compare
touch_nav_dispatch() runs on the app task, which is unprivileged for third-party apps (prv_init_from_info_common sets is_unprivileged on every app loaded from its PebbleProcessInfo header). Its first statement read the touch service's nav gates directly, taking the kernel-owned mutex over kernel-owned statics, so any app that opted into touch navigation faulted on its first touch: PC 0x120ffa68 -> touch_nav_enabled services/touch/touch.c:86 LR 0x12142e83 -> touch_nav_dispatch recognizer/touch_nav.c:459 Add sys_touch_nav_enabled() and sys_touch_app_nav_active(), mirroring the existing sys_touch_service_is_enabled(), and call those instead. The recognizers had the same problem one level down: tap, pan, swipe and the menu_layer double-tap window all called rtc_get_ticks(), which reaches xTaskGetTickCount(). Route those nine call sites through the existing sys_get_ticks(). Built-in system apps are privileged and never hit either path, which is why the system UI scrolled by touch while third-party apps died. This also affected the documented recognizer route: window_attach_recognizer was unusable because recognizer_manager_handle_touch_event() is only reached from touch_nav.c:496 and :527, both downstream of the fault. Verified on QEMU pebble-emery and on obelix hardware: tap, touch scroll and double-tap in a third-party app that calls app_touch_navigation_enable(true). Fixes coredevices#1865 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Laurent Dinclaux <laurent@gecka.nc> Signed-off-by: Joshua Jun <lets@throw.rocks>
…ton-lock-with-key-combo
|
Would it make sense to have this as a Quick Launch action and simply introduce a Back+Down quick launch? |
Author
|
Hi @HobbitJack
Basically yes, feasible. But I guess only for the locking half.
|
…-with-key-combo Signed-off-by: Andreas Unterkircher <unki@netshadow.net> # Conflicts: # src/fw/shell/normal/prefs.c # src/fw/shell/normal/prefs_values.h.inc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fw: add Button Lock (hold Back+Down to lock all input)
Summary
Adds an opt-in Button Lock feature: holding Back + Down for a
configurable duration locks all button input (and the touchscreen on
touch-capable boards); holding the same combo again unlocks. This prevents
accidental actions — scrolling notifications away, launching apps, dismissing
alarms — while the watch is worn during sports, sleep, or when it brushes
against a sleeve.
The feature is off by default and enabled via Settings → System → Button
Lock, where the hold duration is chosen from Off / 1 / 2 / 3 / 5 / 10
seconds.
User experience
Hold Back+Down for the configured time → short vibe + "Buttons Locked"
popup. All input is now ignored.
Press any button while locked → brief hint popup (backlight still works):
Hold Back+Down again → double vibe + "Buttons Unlocked" popup, input works
again.
The popups are plain text
SimpleDialogs on theModalPriorityAlertmodalstack with a 1.8 s timeout (matching ActionToggle's result timeout), pushed
from KernelMain. Alert outranks notifications and the incoming-call UI, so
the feedback stays visible when one of those is on screen, while remaining
below BT pairing requests and alarms, which must never be hidden by a lock
toast.
Lock process
Locking:
%%{init: {'theme': 'base', 'themeVariables': {'fontSize': '18px', 'lineColor': '#8a8a8a', 'textColor': '#333333', 'edgeLabelBackground': '#e8e8e8', 'noteBkgColor': '#fff3c4', 'noteTextColor': '#5c4a00', 'noteBorderColor': '#d4b106'}}}%% stateDiagram-v2 direction LR classDef unlocked fill:#a5d6a7,stroke:#2e7d32,color:#1b5e20 classDef pending fill:#ffe082,stroke:#f57f17,color:#7a4f01 classDef locked fill:#ef9a9a,stroke:#c62828,color:#7f1d1d state "Combo pending" as Pending [*] --> Unlocked Unlocked --> Pending : Back+Down both held (feature enabled) Pending --> Unlocked : released early / third button pressed Pending --> Locked : hold timer fires (short vibe + "Buttons Locked") Locked --> Locked : any button press → swallowed, hint popup note right of Pending force-quit timer cancelled, watchface click recognizers reset, hold timer armed (1-10 s), further DOWNs swallowed end note note right of Locked button events masked from every task, touch sensor disabled, backlight and HW reset combo still work end note class Unlocked unlocked class Pending pending class Locked lockedUnlocking:
%%{init: {'theme': 'base', 'themeVariables': {'fontSize': '18px', 'lineColor': '#8a8a8a', 'textColor': '#333333', 'edgeLabelBackground': '#e8e8e8', 'noteBkgColor': '#fff3c4', 'noteTextColor': '#5c4a00', 'noteBorderColor': '#d4b106'}}}%% stateDiagram-v2 direction LR classDef unlocked fill:#a5d6a7,stroke:#2e7d32,color:#1b5e20 classDef pending fill:#ffe082,stroke:#f57f17,color:#7a4f01 classDef locked fill:#ef9a9a,stroke:#c62828,color:#7f1d1d state "Combo pending" as PendingU Locked --> PendingU : Back+Down both held PendingU --> Locked : released early / third button pressed PendingU --> Unlocked : hold timer fires (double vibe + "Buttons Unlocked") note right of PendingU same 1-10 s hold timer; works with a notification or call on screen end note note right of Unlocked touch restored to the persisted user pref end note class Unlocked unlocked class PendingU pending class Locked lockedA continuous hold toggles exactly once; the combo must be fully released
before it can trigger again.
Implementation
src/fw/shell/normal/button_lock.c(new) — self-contained statemachine, patterned after the PRF
getting_started_button_combomonitor:a held-buttons bitset plus a
new_timerfor the hold, toggling onKernelMain via
launcher_task_add_callback().launcher_handle_button_event(); the module is consulted first and, whenit swallows an event, the full
task_maskis set so no task (app, modal,watchface, event-service subscribers) sees it.
delivered, so click recognizers never see an unbalanced press. When the
combo forms on the watchface, the click manager is reset (same as the
existing Quick Launch combos) so the first button's 400 ms long-click can't
fire mid-hold. The back-button force-quit timer is cancelled when the combo
becomes pending, so locking inside an app doesn't force-quit it.
existing
touch_service_set_globally_enabled(false)kill switch; unlockingrestores the persisted touch preference rather than blindly enabling. A
phone-side write of the touch pref while locked only updates the pref, so
it cannot re-enable the sensor mid-lock.
buttonLockHoldMsshell pref (0= disabled, default);the handler rejects values not offered by the UI. Not added to the phone
sync whitelist for now.
shells get inert stubs, and the hardware reset combo is handled at ISR
level in the button driver, below anything the lock can mask.
Testing
tests/fw/shell/normal/test_button_lock.c(11 cases):combo detection, configurable hold duration, abort on early release or a
third button, swallowing + hint popup while locked, touch restoration to
the persisted pref, exactly-one-toggle per continuous hold, and the
timer-fires-after-release race.
./pbl testsuite passes.qemu_gabbro): settings round-trip, lock,hint popup on keypress while locked, unlock, normal input afterwards.
obelix@pvt(normal) andqemu_gabbro; the PRF linkfailures for
obelix@pvtare pre-existing onmainand unchanged by thisseries.
Commits
fw/shell: add button lock hold duration preferencefw/shell/normal: add button lock servicefw/apps/settings: add Button Lock option to System settingstests/fw/shell/normal: add button lock unit testfw/shell/normal: raise button lock popups above notifications🤖 Generated with Claude Code