From aaf3298d61cf663ba5226a8cd9964c7cccb03bcf Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Thu, 30 Jul 2026 00:06:52 -0500 Subject: [PATCH] fix(desktop): pickers stop eating the keyboard and the pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Committing a model with Enter left focus on the pill (Radix restores it to the trigger), so the next thing typed went nowhere instead of into the message being written. And with the cursor parked over the list, rows re-flowing under it as the query narrowed hover-stole the selection mid-type — Enter then committed whatever the mouse happened to be over. Both surfaces adopt the shared primitives: the model menu and every cmdk list (palette, model dialog, session picker, searchable selects) go pointer-inert until the mouse moves, and the model menu plus the command palette hand typing focus back on close. The release defers a frame and yields when something editable already claimed focus, so a palette action that opens a dialog or navigates keeps its own focus. Replaces the model menu's focus/blur highlight gate — pointer intent is the real signal, so the keyboard highlight no longer flickers off when Radix moves DOM focus onto a hovered row. --- .../src/app/chat/composer/model-pill.tsx | 16 +++++++-- apps/desktop/src/app/hooks/use-keybinds.ts | 19 ++++++++++ .../src/app/shell/model-menu-panel.tsx | 36 ++++++++++++------- apps/desktop/src/components/ui/command.tsx | 9 ++++- apps/desktop/src/store/command-palette.ts | 29 +++++++++++---- 5 files changed, 86 insertions(+), 23 deletions(-) diff --git a/apps/desktop/src/app/chat/composer/model-pill.tsx b/apps/desktop/src/app/chat/composer/model-pill.tsx index 26fbe0266af..e41e3189286 100644 --- a/apps/desktop/src/app/chat/composer/model-pill.tsx +++ b/apps/desktop/src/app/chat/composer/model-pill.tsx @@ -6,6 +6,7 @@ import { ModelMenuCloseContext } from '@/app/shell/model-menu-panel' import { Button } from '@/components/ui/button' import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from '@/components/ui/dropdown-menu' import { GlyphSpinner } from '@/components/ui/glyph-spinner' +import { releaseTypingFocus } from '@/components/ui/keyboard-first' import { Tip } from '@/components/ui/tooltip' import { useI18n } from '@/i18n' import { ChevronDown } from '@/lib/icons' @@ -143,8 +144,19 @@ export function ModelPill({ ) } + // Closing the menu ends its claim on the keyboard: Radix restores focus to + // this pill (a toolbar button), so without the release the Enter that + // committed a model also swallows whatever you type next. + const setMenuOpen = (next: boolean) => { + setOpen(next) + + if (!next) { + releaseTypingFocus() + } + } + return ( - +