fix(setup): drain stale keypresses between TUI screen transitions (#186)

* fix(setup): drain stale keypresses between TUI screen transitions

The picker's vim-style j/k navigation can leave buffered keypresses in
crossterm's event queue that leak into the next input field, corrupting
pre-populated values like client_id.

* refactor: extract drain logic into helper, add changeset
This commit is contained in:
Hafez
2026-03-05 18:39:05 +01:00
committed by GitHub
parent 62d6ddbfa9
commit 5205467ecb
2 changed files with 16 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@googleworkspace/cli": patch
---
fix(setup): drain stale keypresses between TUI screen transitions
+11
View File
@@ -448,6 +448,15 @@ fn run_picker_loop(
}
}
/// Drains any queued crossterm events to prevent stale keypresses from leaking
/// between TUI interactions.
fn drain_pending_events() -> std::io::Result<()> {
while crossterm::event::poll(std::time::Duration::ZERO)? {
let _ = event::read()?;
}
Ok(())
}
// ── Setup Wizard (unified TUI session) ──────────────────────────
/// Status of a single setup step.
@@ -536,6 +545,7 @@ impl SetupWizard {
multiselect: bool,
) -> std::io::Result<PickerResult> {
let mut picker = PickerState::new(title, help_text, items, multiselect);
drain_pending_events()?;
loop {
let steps_snapshot = self.steps.clone();
let msg = self.message.clone();
@@ -598,6 +608,7 @@ impl SetupWizard {
initial: Option<&str>,
) -> std::io::Result<InputResult> {
let mut input = InputState::new(title, help_text, initial);
drain_pending_events()?;
loop {
let steps_snapshot = self.steps.clone();
let msg = self.message.clone();