diff --git a/src/renderer/src/components/browser-pane/BrowserAddressBar.tsx b/src/renderer/src/components/browser-pane/BrowserAddressBar.tsx index 111044d2..050bfa7d 100644 --- a/src/renderer/src/components/browser-pane/BrowserAddressBar.tsx +++ b/src/renderer/src/components/browser-pane/BrowserAddressBar.tsx @@ -162,8 +162,11 @@ export default function BrowserAddressBar({ } }, [open, suggestions.length]) + // Why: auto-select the top suggestion so Enter navigates to the best match + // without an extra ArrowDown. Fall back to clearing selection when nothing + // matches so stale highlights don't persist. useEffect(() => { - setSelectedValue('') + setSelectedValue(suggestions[0]?.url ?? '') }, [suggestions]) return ( diff --git a/src/renderer/src/components/browser-pane/BrowserFind.tsx b/src/renderer/src/components/browser-pane/BrowserFind.tsx index 65e47f57..f0a375f4 100644 --- a/src/renderer/src/components/browser-pane/BrowserFind.tsx +++ b/src/renderer/src/components/browser-pane/BrowserFind.tsx @@ -15,9 +15,19 @@ export default function BrowserFind({ }: BrowserFindProps): React.JSX.Element | null { const inputRef = useRef(null) const [query, setQuery] = useState('') + const [debouncedQuery, setDebouncedQuery] = useState('') const [activeMatch, setActiveMatch] = useState(0) const [totalMatches, setTotalMatches] = useState(0) + // Why: findInPage re-highlights the active match on every call, which causes + // a visible flash as the user types. Debounce to only re-run once typing + // settles. Enter (findNext/findPrevious) still uses the live `query` so + // explicit navigation is immediate. + useEffect(() => { + const id = setTimeout(() => setDebouncedQuery(query), 200) + return () => clearTimeout(id) + }, [query]) + const safeFindInPage = useCallback( (text: string, opts?: Electron.FindInPageOptions): void => { const webview = webviewRef.current @@ -70,16 +80,16 @@ export default function BrowserFind({ }, [isOpen, safeStopFindInPage]) useEffect(() => { - if (!query) { + if (!debouncedQuery) { safeStopFindInPage() setActiveMatch(0) setTotalMatches(0) return } if (isOpen) { - safeFindInPage(query) + safeFindInPage(debouncedQuery) } - }, [query, isOpen, safeFindInPage, safeStopFindInPage]) + }, [debouncedQuery, isOpen, safeFindInPage, safeStopFindInPage]) // Why: this effect captures `webviewRef.current` into a local variable, so // if the webview element were replaced while `isOpen` stays true the listener diff --git a/src/renderer/src/components/browser-pane/BrowserPane.tsx b/src/renderer/src/components/browser-pane/BrowserPane.tsx index e26dc516..f69f0c54 100644 --- a/src/renderer/src/components/browser-pane/BrowserPane.tsx +++ b/src/renderer/src/components/browser-pane/BrowserPane.tsx @@ -505,6 +505,13 @@ function BrowserPagePane({ }, [browserTab.id, browserTab.url]) useEffect(() => { + // Why: if the user is actively typing in the address bar (focused), do not + // clobber their in-progress query when an async URL update lands (e.g., the + // configured default URL resolving after a new tab opens). Syncing will + // resume on the next legitimate URL change after the input loses focus. + if (document.activeElement === addressBarInputRef.current) { + return + } setAddressBarValue(toDisplayUrl(browserTab.url)) }, [browserTab.url]) @@ -1056,7 +1063,11 @@ function BrowserPagePane({ activeLoadFailureRef.current = null lastKnownWebviewUrlRef.current = normalizeBrowserNavigationUrl(currentUrl) ?? currentUrl rememberLiveBrowserUrl(browserTab.id, currentUrl) - setAddressBarValue(toDisplayUrl(currentUrl)) + // Why: don't overwrite in-progress typing. See comment on the + // browserTab.url sync effect above. + if (document.activeElement !== addressBarInputRef.current) { + setAddressBarValue(toDisplayUrl(currentUrl)) + } onSetUrlRef.current(browserTab.id, currentUrl) if (keepAddressBarFocusRef.current && currentUrl === ORCA_BROWSER_BLANK_URL) { focusAddressBarNow() @@ -1083,7 +1094,10 @@ function BrowserPagePane({ } lastKnownWebviewUrlRef.current = normalizeBrowserNavigationUrl(currentUrl) ?? currentUrl rememberLiveBrowserUrl(browserTab.id, currentUrl) - setAddressBarValue(toDisplayUrl(currentUrl)) + // Why: don't overwrite in-progress typing (see above). + if (document.activeElement !== addressBarInputRef.current) { + setAddressBarValue(toDisplayUrl(currentUrl)) + } onSetUrlRef.current(browserTab.id, currentUrl) onUpdatePageStateRef.current(browserTab.id, { title: webview.getTitle() || currentUrl,