diff --git a/CHANGELOG.md b/CHANGELOG.md index 8727171..bfab844 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Feat: **Ghostty switches to the right tab when several sessions share a directory** ([#63](https://github.com/grimmerk/codev/issues/63)). Ghostty's tip builds expose each terminal's `tty` (ghostty-org/ghostty#11922), so switching now works the way it does in iTerm2 and Terminal.app: by tty and by `/rename` title, in the order the session's process provenance calls for, and only then by working directory. Before, a session without a custom title went to the first tab in its directory — measured on one machine with 16 sessions sharing `~/git`, every one of them landed on the same tab. Detection's fallback cross-reference uses the tty the same way. **Stable Ghostty (1.3.1 and earlier) has no `tty`**, so there CodeV behaves exactly as before — title, then directory — until a release ships it - Fix: detection's fallback cross-reference no longer gives a running process to the wrong session when one `/rename` title contains another (`Fix` inside `Fix backend`). Every terminal (iTerm2, cmux, Terminal.app, Ghostty) took the first title its tab matched, from every transcript in the directory; it now takes the longest match among the sessions actually queued for that process. One function for all four, where there used to be four copies +- Fix: **closing Settings puts the cursor back in the search box.** Opening Settings moves focus into its panel, as before; but closing it with the same button left focus on that button, so typing searched nothing until you clicked a row or switched apps and back. The Settings button counts as part of the panel, which the switcher deliberately never steals focus from, so its click-to-refocus skipped it. Closing the panel now hands focus back to the current tab's search box ## 1.0.93 diff --git a/src/popup.tsx b/src/popup.tsx index d871811..7da38ec 100644 --- a/src/popup.tsx +++ b/src/popup.tsx @@ -59,6 +59,7 @@ const PopupDefaultExample = ({ switcherMode, openToTab, onOpenToTabConsumed, + onClosed, }: { workingFolderPath?: string; saveCallback?: (key: string, value: string) => void; @@ -66,6 +67,7 @@ const PopupDefaultExample = ({ switcherMode?: string; openToTab?: 'general' | 'sessions' | 'accounts' | 'shortcuts' | null; onOpenToTabConsumed?: () => void; + onClosed?: () => void; }) => { const [isOpen, setIsOpen] = useState(false); const [launchAtLogin, setLaunchAtLogin] = useState(false); @@ -505,6 +507,21 @@ const PopupDefaultExample = ({ } }, [openToTab]); + // Hand focus back to the parent when the panel closes. While open, the + // Popup's focus trap holds focus inside the panel; the Settings button that + // closes it keeps focus afterwards, and the switcher's click-to-refocus + // skips it (it is part of the panel), so typing went nowhere until the user + // clicked elsewhere. The timeout runs after any focus the trap returns on + // deactivate, which it also defers with a 0ms timeout. + const wasOpenRef = useRef(false); + useEffect(() => { + const wasOpen = wasOpenRef.current; + wasOpenRef.current = isOpen; + if (!wasOpen || isOpen || !onClosed) return; + const timer = setTimeout(onClosed, 0); + return () => clearTimeout(timer); + }, [isOpen]); + const handleLaunchAtLoginChange = (checked: boolean) => { setLaunchAtLogin(checked); window.electronAPI.setLoginItemSettings(checked); diff --git a/src/switcher-ui.tsx b/src/switcher-ui.tsx index 6d2c0f1..7c544d6 100644 --- a/src/switcher-ui.tsx +++ b/src/switcher-ui.tsx @@ -2635,6 +2635,7 @@ function SwitcherApp() { switcherMode={mode} openToTab={settingsOpenToTab} onOpenToTabConsumed={() => setSettingsOpenToTab(null)} + onClosed={forceFocusOnInput} saveCallback={(key: string, value: string) => { if (key === 'sessionDisplayMode') { setSessionDisplayMode(value);