Change:
See the GIF directly. ! As shown above, the settings UI always scrolls automatically, so I cannot find the modification because it went away. Marking or deselecting any item may cause this issue. VS Code version: Code 1.31.0 (, 2019-02-05T22:35:56.624Z) OS version: Windows_NT x64 10.0.
Annoyed me so much. Note that it happens with dropdowns and selecting an item, and occasionally by inputting textbox and clicking to defocus it.
Having this exact problem as well. I just installed VS code and am having this problem while giving it a trial run. Sigh....
Maybe related to
This isn't what I thought it was, I have to assign to you I think the ListView renders the setting items with their default heights, then rerenders and saves the offset of the anchor element. Then it fixes the heights of the elements and maintains the offset of the anchor element. But since it measured the anchor element when the elements had default heights, the list will be shifted if the real heights were different from the default heights. Maybe an anchor element should be measured before rendering the items with default heights or something like that. I made the default heights more accurate which helps.
Why is the list re-rendered when a check box is clicked?
When the config service says something changed, we rerender everything. It seems unnecessary in this case but it's hard to tell that the change event came "from" this instance of the settings editor and also, some values can be normalized when they get back to us, and since it should be safe to rerender, I don't put a lot of effort into reducing unneeded renders. Another way to repro this, open two settings editors in two groups, change a setting in Group 1, and see the editor in Group 2 scroll. If this just can't really be fixed there are things I can do like updating the value of a rendered setting row without actually calling setChildren. But that only works for some settings, adds more complexity, etc.
It can definitely be fixed. I was just wondering why the rerender was needed. ;)
cc

Discussion:
getHeight(element: T): number; getTemplateId(element: T): string; hasDynamicHeight?(element: T): boolean; <ins> setDynamicHeight?(element: T, height: number): void; </ins> } export interface IListRenderer<T, TTemplateData> {

} item.size = row.domNode!.offsetHeight; <ins> if (this.virtualDelegate.setDynamicHeight) { this.virtualDelegate.setDynamicHeight(item.element, item.size); } </ins> item.lastDynamicHeightWidth = this.renderWidth; this.rowsContainer.removeChild(row.domNode!); this.cache.release(row);

hasDynamicHeight(element: N): boolean { return !!this.delegate.hasDynamicHeight && this.delegate.hasDynamicHeight(element.element); } <ins> setDynamicHeight(element: N, height: number): void { if (this.delegate.setDynamicHeight) { this.delegate.setDynamicHeight(element.element, height); } } </ins> } interface ITreeListTemplateData<T> {

} class SettingsTreeDelegate implements IListVirtualDelegate<SettingsTreeGroupChild> { <del> getHeight(element: SettingsTreeElement): number { </del> <ins> private heightCache = new WeakMap<SettingsTreeGroupChild, number>(); getHeight(element: SettingsTreeGroupChild): number { const cachedHeight = this.heightCache.get(element); if (typeof cachedHeight === 'number') { return cachedHeight; } </ins> if (element instanceof SettingsTreeGroupElement) { if (element.isFirstGroup) { return 31;

hasDynamicHeight(element: SettingsTreeGroupElement | SettingsTreeSettingElement | SettingsTreeNewExtensionsElement): boolean { return !(element instanceof SettingsTreeGroupElement); } <ins> setDynamicHeight(element: SettingsTreeGroupChild, height: number): void { this.heightCache.set(element, height); } </ins> } class NonCollapsibleObjectTreeModel<T> extends ObjectTreeModel<T> {