@@ -32,7 +32,7 @@ import { attachSuggestEnabledInputBoxStyler, SuggestEnabledInput } from 'vs/work
32
32
import { SettingsTarget , SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets' ;
33
33
import { commonlyUsedData , tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout' ;
34
34
import { AbstractSettingRenderer , ISettingLinkClickEvent , ISettingOverrideClickEvent , resolveExtensionsSettings , resolveSettingsTree , SettingsTree , SettingTreeRenderers } from 'vs/workbench/parts/preferences/browser/settingsTree' ;
35
- import { ISettingsEditorViewState , parseQuery , SearchResultIdx , SearchResultModel , SettingsTreeGroupChild , SettingsTreeGroupElement , SettingsTreeModel } from 'vs/workbench/parts/preferences/browser/settingsTreeModels' ;
35
+ import { ISettingsEditorViewState , parseQuery , SearchResultIdx , SearchResultModel , SettingsTreeElement , SettingsTreeGroupChild , SettingsTreeGroupElement , SettingsTreeModel , SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels' ;
36
36
import { settingsTextInputBorder } from 'vs/workbench/parts/preferences/browser/settingsWidgets' ;
37
37
import { createTOCIterator , TOCTree , TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree' ;
38
38
import { CONTEXT_SETTINGS_EDITOR , CONTEXT_SETTINGS_SEARCH_FOCUS , CONTEXT_TOC_ROW_FOCUS , IPreferencesSearchService , ISearchProvider , MODIFIED_SETTING_TAG , SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/parts/preferences/common/preferences' ;
@@ -124,6 +124,9 @@ export class SettingsEditor2 extends BaseEditor {
124
124
125
125
private editorMemento : IEditorMemento < ISettingsEditor2State > ;
126
126
127
+ private tocFocusedElement : SettingsTreeGroupElement ;
128
+ private settingsTreeScrollTop = 0 ;
129
+
127
130
constructor (
128
131
@ITelemetryService telemetryService : ITelemetryService ,
129
132
@IConfigurationService private readonly configurationService : IConfigurationService ,
@@ -542,21 +545,22 @@ export class SettingsEditor2 extends BaseEditor {
542
545
this . viewState ) ) ;
543
546
544
547
this . _register ( this . tocTree . onDidChangeFocus ( e => {
545
- this . tocTree . setSelection ( e . elements ) ;
546
548
const element : SettingsTreeGroupElement = e . elements [ 0 ] ;
549
+ if ( this . tocFocusedElement === e . elements [ 0 ] ) {
550
+ return ;
551
+ }
552
+
553
+ this . tocFocusedElement = element ;
554
+ this . tocTree . setSelection ( e . elements ) ;
547
555
if ( this . searchResultModel ) {
548
556
if ( this . viewState . filterToCategory !== element ) {
549
557
this . viewState . filterToCategory = element ;
550
558
this . renderTree ( ) ;
551
559
this . settingsTree . scrollTop = 0 ;
552
560
}
553
- } else if ( element ) {
561
+ } else if ( element && ( ! e . browserEvent || ! ( < any > e . browserEvent ) . fromScroll ) ) {
554
562
this . settingsTree . reveal ( element , 0 ) ;
555
563
}
556
-
557
- // else if (element && (!e.payload || !e.payload.fromScroll)) {
558
- // this.settingsTree.reveal(element, 0);
559
- // }
560
564
} ) ) ;
561
565
562
566
this . _register ( this . tocTree . onDidFocus ( ( ) => {
@@ -606,7 +610,17 @@ export class SettingsEditor2 extends BaseEditor {
606
610
this . settingsTree . getHTMLElement ( ) . attributes . removeNamedItem ( 'tabindex' ) ;
607
611
608
612
this . _register ( this . settingsTree . onDidScroll ( ( ) => {
609
- this . updateTreeScrollSync ( ) ;
613
+ if ( this . settingsTree . scrollTop === this . settingsTreeScrollTop ) {
614
+ return ;
615
+ }
616
+
617
+ this . settingsTreeScrollTop = this . settingsTree . scrollTop ;
618
+
619
+ // setTimeout because calling setChildren on the settingsTree can trigger onDidScroll, so it fires when
620
+ // setChildren has called on the settings tree but not the toc tree yet, so their rendered elements are out of sync
621
+ setTimeout ( ( ) => {
622
+ this . updateTreeScrollSync ( ) ;
623
+ } , 0 ) ;
610
624
} ) ) ;
611
625
}
612
626
@@ -642,29 +656,56 @@ export class SettingsEditor2 extends BaseEditor {
642
656
return ;
643
657
}
644
658
645
- // this.updateTreePagingByScroll();
646
-
647
- // const element = this.tocTreeModel.children[0];
648
- // const elementToSync = this.settingsTree.getFirstVisibleElement();
649
- // const element = elementToSync instanceof SettingsTreeSettingElement ? elementToSync.parent :
650
- // elementToSync instanceof SettingsTreeGroupElement ? elementToSync :
651
- // null;
652
-
653
- // if (element && this.tocTree.getSelection()[0] !== element) {
654
- // this.tocTree.reveal(element);
655
- // const elementTop = this.tocTree.getRelativeTop(element);
656
- // collapseAll(this.tocTree, element);
657
- // if (elementTop < 0 || elementTop > 1) {
658
- // this.tocTree.reveal(element);
659
- // } else {
660
- // this.tocTree.reveal(element, elementTop);
661
- // }
662
-
663
- // this.tocTree.expand(element);
664
-
665
- // this.tocTree.setSelection([element]);
666
- // this.tocTree.setFocus(element, { fromScroll: true });
667
- // }
659
+ // Hack, see https://github.com/Microsoft/vscode/issues/64749
660
+ const settingItems = this . settingsTree . getHTMLElement ( ) . querySelectorAll ( '.setting-item' ) ;
661
+ const firstEl = settingItems [ 1 ] || settingItems [ 0 ] ;
662
+ if ( ! firstEl ) {
663
+ return ;
664
+ }
665
+
666
+ const firstSettingId = this . settingRenderers . getIdForDOMElementInSetting ( < HTMLElement > firstEl ) ;
667
+ const elementToSync = this . settingsTreeModel . getElementById ( firstSettingId ) ;
668
+ const element = elementToSync instanceof SettingsTreeSettingElement ? elementToSync . parent :
669
+ elementToSync instanceof SettingsTreeGroupElement ? elementToSync :
670
+ null ;
671
+
672
+ if ( element && this . tocTree . getSelection ( ) [ 0 ] !== element ) {
673
+ const ancestors = this . getAncestors ( element ) ;
674
+ ancestors . forEach ( e => this . tocTree . expand ( < SettingsTreeGroupElement > e ) ) ;
675
+
676
+ this . tocTree . reveal ( element ) ;
677
+ const elementTop = this . tocTree . getRelativeTop ( element ) ;
678
+ this . tocTree . collapseAll ( ) ;
679
+
680
+ ancestors . forEach ( e => this . tocTree . expand ( < SettingsTreeGroupElement > e ) ) ;
681
+ if ( elementTop < 0 || elementTop > 1 ) {
682
+ this . tocTree . reveal ( element ) ;
683
+ } else {
684
+ this . tocTree . reveal ( element , elementTop ) ;
685
+ }
686
+
687
+ this . tocTree . expand ( element ) ;
688
+
689
+ this . tocTree . setSelection ( [ element ] ) ;
690
+
691
+ const fakeKeyboardEvent = new KeyboardEvent ( 'keydown' ) ;
692
+ ( < any > fakeKeyboardEvent ) . fromScroll = true ;
693
+ this . tocTree . setFocus ( [ element ] , fakeKeyboardEvent ) ;
694
+ }
695
+ }
696
+
697
+ private getAncestors ( element : SettingsTreeElement ) : SettingsTreeElement [ ] {
698
+ const ancestors : any [ ] = [ ] ;
699
+
700
+ while ( element . parent ) {
701
+ if ( element . parent . id !== 'root' ) {
702
+ ancestors . push ( element . parent ) ;
703
+ }
704
+
705
+ element = element . parent ;
706
+ }
707
+
708
+ return ancestors . reverse ( ) ;
668
709
}
669
710
670
711
private updateChangedSetting ( key : string , value : any ) : Promise < void > {
@@ -843,10 +884,11 @@ export class SettingsEditor2 extends BaseEditor {
843
884
} else {
844
885
this . settingsTreeModel = this . instantiationService . createInstance ( SettingsTreeModel , this . viewState ) ;
845
886
this . settingsTreeModel . update ( resolvedSettingsRoot ) ;
846
- this . refreshTree ( ) ;
847
-
848
887
this . tocTreeModel . settingsTreeRoot = this . settingsTreeModel . root as SettingsTreeGroupElement ;
888
+
849
889
this . refreshTOCTree ( ) ;
890
+ this . refreshTree ( ) ;
891
+
850
892
this . tocTree . collapseAll ( ) ;
851
893
}
852
894
@@ -980,7 +1022,6 @@ export class SettingsEditor2 extends BaseEditor {
980
1022
981
1023
this . viewState . filterToCategory = null ;
982
1024
this . tocTreeModel . currentSearchModel = this . searchResultModel ;
983
- this . refreshTOCTree ( ) ;
984
1025
this . onSearchModeToggled ( ) ;
985
1026
986
1027
if ( this . searchResultModel ) {
@@ -995,6 +1036,8 @@ export class SettingsEditor2 extends BaseEditor {
995
1036
this . refreshTree ( ) ;
996
1037
this . renderResultCountMessages ( ) ;
997
1038
}
1039
+
1040
+ this . refreshTOCTree ( ) ;
998
1041
}
999
1042
1000
1043
return Promise . resolve ( null ) ;
0 commit comments