mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 08:02:24 +00:00
Every confirmation dialog in the app was built as `&[Cancel, Delete]`, and gpui hands answer 0 to the platform first — which NSAlert draws on the *right* and gives Return. So the app shipped 14 dialogs with the buttons mirrored: Delete sat on the left, exactly where a decade of macOS has trained people to expect Cancel, and Cancel sat on the right holding the default. Escape was worse: it did nothing at all, anywhere. gpui only sets the Escape key equivalent on a `PromptButton::cancel`, and every call site passed plain strings, which become `PromptButton::Other`. There was no way to dismiss any of these dialogs from the keyboard except by pressing Return. A shared `ui::confirm_answers(action, keep)` now builds the pair, so the arrangement is decided in one place: | | Before | After | |---|---|---| | Right button (Return) | Cancel | the action | | Left button | the action | Cancel | | Escape | nothing | Cancel | | Space / initial focus | Cancel | Cancel | | `Ok(1)` means | act | — | | `Ok(0)` means | cancel | act | Verified on the file-tree delete, end to end: Escape leaves both files in place, Return removes only the one that was right-clicked. Also checked on the ⌘W busy-pane guard, where Escape and Space keep the tab and Return closes it. Two prompts keep their own shape and say why in a comment: - The daemon-mismatch prompt at launch offers Quit and Restart Server and nothing else. With no answer that leaves things alone there is nothing safe to give Escape, so Quit stays on Return — it loses no sessions, while restarting the server ends every one of them. - The unsaved-editor prompt has three answers. Save keeps answer 0, Cancel is marked so it takes Escape, and Discard sits on the far left where nothing lands by reflex. gpui puts the initial keyboard focus on Discard so it stays reachable without a mouse.