@@ -488,28 +488,25 @@ export class BrowserUrlBarWidget extends Disposable {
488488
489489 let currentValue = picker . value ;
490490
491- // Preserve the user's current selection across re-renders (typing,
492- // per-provider refresh) by matching the previously active item's id.
493- // Without this, setting `picker.items` snaps activeItems back to the
494- // first row, so e.g. opening/closing a tab while the user is
495- // arrow-keyed onto an open-tab suggestion would yank them back to
496- // "Go to".
497- const restoreActiveById = ( previousId : string | undefined , items : readonly ( IUrlPickerItem | IQuickPickSeparator ) [ ] ) => {
498- if ( previousId === undefined ) {
499- return ;
500- }
501- const match = items . find ( ( i ) : i is IUrlPickerItem => i . type !== 'separator' && i . id === previousId ) ;
502- if ( match ) {
503- picker . activeItems = [ match ] ;
504- }
505- } ;
506-
507491 // Rebuild `picker.items` from the synchronous "Go to" entry plus each
508492 // provider's current cached suggestions, in provider sort order.
509- const render = ( ) => {
510- const previousActiveId = picker . activeItems [ 0 ] ?. id ;
511- const items = this . _buildSuggestionItems ( currentValue ) ;
512- const hasGo = items . some ( i => i . type !== 'separator' ) ;
493+ //
494+ // `preserveSelection` distinguishes the two re-render triggers:
495+ // - User typing (`false`): reset the active item to the default
496+ // "Go to" entry. Starting/continuing a query should always default
497+ // back to "Go to" rather than sticking on a streamed-in suggestion.
498+ // - Background provider refresh (`true`): keep the user's current
499+ // selection (e.g. an arrow-keyed suggestion) so updating one
500+ // provider's results (a tab opening/closing) doesn't yank focus
501+ // back to "Go to".
502+ //
503+ // The active item is set explicitly rather than relying on the quick
504+ // pick's implicit first-row selection, which can otherwise land on a
505+ // suggestion as asynchronous results stream in.
506+ const render = ( preserveSelection : boolean ) => {
507+ const previousActiveId = preserveSelection ? picker . activeItems [ 0 ] ?. id : undefined ;
508+ const defaultItems = this . _buildSuggestionItems ( currentValue ) ;
509+ const items : ( IUrlPickerItem | IQuickPickSeparator ) [ ] = [ ...defaultItems ] ;
513510 for ( const provider of this . _suggestionProviders ) {
514511 const state = providerStates . get ( provider ) ;
515512 if ( ! state || state . suggestions . length === 0 ) {
@@ -531,10 +528,18 @@ export class BrowserUrlBarWidget extends Disposable {
531528 }
532529 }
533530 picker . items = items ;
534- if ( ! hasGo ) {
535- picker . activeItems = [ ] ;
536- }
537- restoreActiveById ( previousActiveId , items ) ;
531+
532+ // Only the synchronous items from `_buildSuggestionItems` (e.g. the
533+ // "Go to" entry) are eligible for default focus; provider suggestions
534+ // are never auto-focused. Restore the prior selection on a background
535+ // refresh; otherwise (typing, or the prior item disappeared) fall back
536+ // to the first default item, or to nothing when there are none.
537+ const defaultActive = defaultItems . find ( ( i ) : i is IUrlPickerItem => i . type !== 'separator' ) ;
538+ const restored = previousActiveId !== undefined
539+ ? items . find ( ( i ) : i is IUrlPickerItem => i . type !== 'separator' && i . id === previousActiveId )
540+ : undefined ;
541+ const active = restored ?? defaultActive ;
542+ picker . activeItems = active ? [ active ] : [ ] ;
538543 } ;
539544
540545 // Re-fetch a single provider against the current value, cancelling
@@ -557,7 +562,7 @@ export class BrowserUrlBarWidget extends Disposable {
557562 return ;
558563 }
559564 state . suggestions = results ;
560- render ( ) ;
565+ render ( true ) ;
561566 } ,
562567 ( ) => { /* keep prior cached suggestions on error */ }
563568 ) ;
@@ -569,7 +574,7 @@ export class BrowserUrlBarWidget extends Disposable {
569574 }
570575 } ;
571576
572- render ( ) ;
577+ render ( false ) ;
573578 refreshAllProviders ( ) ;
574579
575580 // Per-provider state change: refresh only that provider so unrelated
@@ -595,7 +600,7 @@ export class BrowserUrlBarWidget extends Disposable {
595600 } ) ) ;
596601 disposables . add ( picker . onDidChangeValue ( value => {
597602 currentValue = value ;
598- render ( ) ;
603+ render ( false ) ;
599604 refreshAllProviders ( ) ;
600605 // Mirror the picker's typed value into the display continuously,
601606 // running URL renderers so decorations stay live. The picker is
0 commit comments