Skip to content

Debounce password prompt and auto-cancel on falling edge#261

Merged
dakra merged 1 commit into
mainfrom
feat/password-prompt-debounce-and-cancel
May 11, 2026
Merged

Debounce password prompt and auto-cancel on falling edge#261
dakra merged 1 commit into
mainfrom
feat/password-prompt-debounce-and-cancel

Conversation

@dakra
Copy link
Copy Markdown
Owner

@dakra dakra commented May 11, 2026

Summary

  • Debounce the rising edge (ghostel-password-prompt-debounce, default 0.2s): re-check the canonical+!echo heuristic at the deadline before opening read-passwd, so sub-200ms flips don't pop a modal prompt — matching ghostty's natural ~200 ms termios poll cadence.
  • Auto-cancel read-passwd on falling edge: when the heuristic flips off while our prompt is up (e.g. user kills the foreground program with C-c C-c), abort-recursive-edit closes the minibuffer.
  • Three gates ensure we abort only our own minibuffer: active flag, depth = outer+1, and the active minibuffer's buffer matches one captured by minibuffer-with-setup-hook (so cross-buffer M-x races and focus-switching don't clobber unrelated minibuffers).

Refs #244.

Test plan

  • make -j4 all — 343 tests pass (341 expected + 2 unrelated skips), lint clean.
  • 5 new ERT tests covering: debounce-defer, debounce-flicker-cancel, depth-gate, mb-identity-gate, falling-edge-aborts.
  • 2 existing tests let-bind debounce to 0 since they test edge logic, not the window.
  • Live: sudo -sread-passwd opens after 200 ms → switch to ghostel window → C-c C-c kills sudo → read-passwd auto-closes.
  • Live: leave running a few days to surface any regression in auth-source-style flows.

The canonical+!echo heuristic is identical to ghostty's, but ghostel
checks on every redraw (sub-100ms) and reacts with a modal `read-passwd'
minibuffer — so short-lived flips that ghostty's 200ms termios poller
silently misses become user-visible popups in ghostel.  Two defenses:

1. Debounce the rising edge.  `ghostel-password-prompt-debounce'
   (default 0.2s) schedules a confirm timer; the source chain only
   runs if the heuristic still reports password mode at the deadline.
   Sub-debounce flickers leave no trace beyond a brief mode-line
   indicator flash, matching ghostty's transient lock-icon UX.

2. Auto-cancel on falling edge.  When the heuristic flips off while
   our `read-passwd' is up, `abort-recursive-edit' closes it — useful
   when the user kills the foreground program (e.g. C-c C-c sending
   Ctrl+C to sudo) and expects the prompt to disappear with it.

Three gates ensure we only abort our own minibuffer:

  - Active flag: source chain is in flight.
  - Depth: `minibuffer-depth' equals the value captured before our
    prompt opened, plus one (our minibuffer is innermost).
  - Minibuffer identity: `(window-buffer (active-minibuffer-window))'
    matches the buffer captured by `minibuffer-with-setup-hook' when
    our `read-passwd' was entered.  The setup hook only captures when
    `minibuffer-selected-window' points at our buffer, so an unrelated
    minibuffer opened concurrently (cross-buffer M-x race) can't
    poison the capture.  Identity is robust to focus switching —
    `minibuffer-selected-window' alone returns nil once the user
    moves focus out of the minibuffer.

Refs #244.
@dakra dakra force-pushed the feat/password-prompt-debounce-and-cancel branch from 7480ee9 to c5c191e Compare May 11, 2026 07:57
@dakra dakra merged commit c5c191e into main May 11, 2026
21 of 22 checks passed
@dakra dakra deleted the feat/password-prompt-debounce-and-cancel branch May 11, 2026 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant