Skip to content

Commit b358daf

Browse files
bpaserolramos15
andauthored
UI freeze when trusting/untrusting current folder (fix microsoft#159224) (microsoft#159258)
* UI freeze when trusting/untrusting current folder (fix microsoft#159224) * Consolidate a few of the resolver events Co-authored-by: Logan Ramos <[email protected]>
1 parent 8d28ffa commit b358daf

File tree

6 files changed

+58
-26
lines changed

6 files changed

+58
-26
lines changed

src/vs/workbench/browser/parts/editor/editor.contribution.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ import { FileAccess } from 'vs/base/common/network';
6565
import { Codicon } from 'vs/base/common/codicons';
6666
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
6767
import { UntitledTextEditorInputSerializer, UntitledTextEditorWorkingCopyEditorHandler } from 'vs/workbench/services/untitled/common/untitledTextEditorHandler';
68-
import { DynamicEditorResolverConfigurations } from 'vs/workbench/browser/parts/editor/editorConfiguration';
68+
import { DynamicEditorConfigurations } from 'vs/workbench/browser/parts/editor/editorConfiguration';
6969

7070
//#region Editor Registrations
7171

@@ -125,7 +125,7 @@ Registry.as<IEditorFactoryRegistry>(EditorExtensions.EditorFactory).registerEdit
125125
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(EditorAutoSave, LifecyclePhase.Ready);
126126
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(EditorStatus, LifecyclePhase.Ready);
127127
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(UntitledTextEditorWorkingCopyEditorHandler, LifecyclePhase.Ready);
128-
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DynamicEditorResolverConfigurations, LifecyclePhase.Ready);
128+
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DynamicEditorConfigurations, LifecyclePhase.Ready);
129129

130130
registerEditorContribution(FloatingClickMenu.ID, FloatingClickMenu);
131131
registerEditorContribution(OpenWorkspaceButtonContribution.ID, OpenWorkspaceButtonContribution);

src/vs/workbench/browser/parts/editor/editorConfiguration.ts

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuratio
1212
import { IEditorResolverService, RegisteredEditorInfo, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService';
1313
import { IJSONSchemaMap } from 'vs/base/common/jsonSchema';
1414
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
15+
import { coalesce } from 'vs/base/common/arrays';
16+
import { Event } from 'vs/base/common/event';
1517

16-
export class DynamicEditorResolverConfigurations extends Disposable implements IWorkbenchContribution {
18+
export class DynamicEditorConfigurations extends Disposable implements IWorkbenchContribution {
1719

1820
private static readonly AUTO_LOCK_DEFAULT_ENABLED = new Set<string>(['terminalEditor']);
1921

@@ -29,10 +31,11 @@ export class DynamicEditorResolverConfigurations extends Disposable implements I
2931
}
3032
];
3133

32-
private configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
34+
private readonly configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
35+
3336
private autoLockConfigurationNode: IConfigurationNode | undefined;
3437
private defaultBinaryEditorConfigurationNode: IConfigurationNode | undefined;
35-
private editorAssociationsConfiguratioNnode: IConfigurationNode | undefined;
38+
private editorAssociationsConfigurationNode: IConfigurationNode | undefined;
3639

3740
constructor(
3841
@IEditorResolverService private readonly editorResolverService: IEditorResolverService,
@@ -42,40 +45,40 @@ export class DynamicEditorResolverConfigurations extends Disposable implements I
4245

4346
// Editor configurations are getting updated very aggressively
4447
// (atleast 20 times) while the extensions are getting registered.
45-
// As such push out the dynamic editor auto lock configuration
46-
// until after extensions registered.
48+
// As such push out the dynamic configuration until after extensions
49+
// are registered.
4750
(async () => {
4851
await extensionService.whenInstalledExtensionsRegistered();
4952

50-
this.updateConfiguration();
53+
this.updateDynamicEditorConfigurations();
5154
this.registerListeners();
5255
})();
5356
}
5457

5558
private registerListeners(): void {
5659

57-
// Registered editors
58-
this._register(this.editorResolverService.onDidChangeEditorRegistrations(() => this.updateConfiguration()));
60+
// Registered editors (debounced to reduce perf overhead)
61+
Event.debounce(this.editorResolverService.onDidChangeEditorRegistrations, (_, e) => e)(() => this.updateDynamicEditorConfigurations());
5962
}
6063

61-
private updateConfiguration(): void {
62-
const lockableEditors = [...this.editorResolverService.getEditors(), ...DynamicEditorResolverConfigurations.AUTO_LOCK_EXTRA_EDITORS];
64+
private updateDynamicEditorConfigurations(): void {
65+
const lockableEditors = [...this.editorResolverService.getEditors(), ...DynamicEditorConfigurations.AUTO_LOCK_EXTRA_EDITORS];
6366
const binaryEditorCandidates = this.editorResolverService.getEditors().filter(e => e.priority !== RegisteredEditorPriority.exclusive).map(e => e.id);
6467

6568
// Build config from registered editors
6669
const autoLockGroupConfiguration: IJSONSchemaMap = Object.create(null);
6770
for (const editor of lockableEditors) {
6871
autoLockGroupConfiguration[editor.id] = {
6972
type: 'boolean',
70-
default: DynamicEditorResolverConfigurations.AUTO_LOCK_DEFAULT_ENABLED.has(editor.id),
73+
default: DynamicEditorConfigurations.AUTO_LOCK_DEFAULT_ENABLED.has(editor.id),
7174
description: editor.label
7275
};
7376
}
7477

7578
// Build default config too
7679
const defaultAutoLockGroupConfiguration = Object.create(null);
7780
for (const editor of lockableEditors) {
78-
defaultAutoLockGroupConfiguration[editor.id] = DynamicEditorResolverConfigurations.AUTO_LOCK_DEFAULT_ENABLED.has(editor.id);
81+
defaultAutoLockGroupConfiguration[editor.id] = DynamicEditorConfigurations.AUTO_LOCK_DEFAULT_ENABLED.has(editor.id);
7982
}
8083

8184
// Register settng for auto locking groups
@@ -109,8 +112,8 @@ export class DynamicEditorResolverConfigurations extends Disposable implements I
109112
};
110113

111114
// Registers setting for editorAssociations
112-
const oldEditorAssociationsConfigurationNode = this.editorAssociationsConfiguratioNnode;
113-
this.editorAssociationsConfiguratioNnode = {
115+
const oldEditorAssociationsConfigurationNode = this.editorAssociationsConfigurationNode;
116+
this.editorAssociationsConfigurationNode = {
114117
...workbenchConfigurationNodeBase,
115118
properties: {
116119
'workbench.editorAssociations': {
@@ -126,8 +129,17 @@ export class DynamicEditorResolverConfigurations extends Disposable implements I
126129
}
127130
};
128131

129-
this.configurationRegistry.updateConfigurations({ add: [this.autoLockConfigurationNode], remove: oldAutoLockConfigurationNode ? [oldAutoLockConfigurationNode] : [] });
130-
this.configurationRegistry.updateConfigurations({ add: [this.defaultBinaryEditorConfigurationNode], remove: oldDefaultBinaryEditorConfigurationNode ? [oldDefaultBinaryEditorConfigurationNode] : [] });
131-
this.configurationRegistry.updateConfigurations({ add: [this.editorAssociationsConfiguratioNnode], remove: oldEditorAssociationsConfigurationNode ? [oldEditorAssociationsConfigurationNode] : [] });
132+
this.configurationRegistry.updateConfigurations({
133+
add: [
134+
this.autoLockConfigurationNode,
135+
this.defaultBinaryEditorConfigurationNode,
136+
this.editorAssociationsConfigurationNode
137+
],
138+
remove: coalesce([
139+
oldAutoLockConfigurationNode,
140+
oldDefaultBinaryEditorConfigurationNode,
141+
oldEditorAssociationsConfigurationNode
142+
])
143+
});
132144
}
133145
}

src/vs/workbench/contrib/customEditor/browser/customEditors.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,12 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ
6565
this._focusedCustomEditorIsEditable = CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE.bindTo(contextKeyService);
6666

6767
this._contributedEditors = this._register(new ContributedCustomEditors(storageService));
68-
this.registerContributionPoints();
68+
// Register the contribution points only emitting one change from the resolver
69+
this.editorResolverService.bufferChangeEvents(this.registerContributionPoints.bind(this));
6970

7071
this._register(this._contributedEditors.onChange(() => {
71-
this.registerContributionPoints();
72+
// Register the contribution points only emitting one change from the resolver
73+
this.editorResolverService.bufferChangeEvents(this.registerContributionPoints.bind(this));
7274
this.updateContexts();
7375
this._onDidChangeEditorTypes.fire();
7476
}));

src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,16 @@ export class NotebookProviderInfoStore extends Disposable {
6161
@INotebookEditorModelResolverService private readonly _notebookEditorModelResolverService: INotebookEditorModelResolverService
6262
) {
6363
super();
64+
6465
this._memento = new Memento(NotebookProviderInfoStore.CUSTOM_EDITORS_STORAGE_ID, storageService);
6566

6667
const mementoObject = this._memento.getMemento(StorageScope.PROFILE, StorageTarget.MACHINE);
67-
for (const info of (mementoObject[NotebookProviderInfoStore.CUSTOM_EDITORS_ENTRY_ID] || []) as NotebookEditorDescriptor[]) {
68-
this.add(new NotebookProviderInfo(info));
69-
}
68+
// Process the notebook contributions but buffer changes from the resolver
69+
this._editorResolverService.bufferChangeEvents(() => {
70+
for (const info of (mementoObject[NotebookProviderInfoStore.CUSTOM_EDITORS_ENTRY_ID] || []) as NotebookEditorDescriptor[]) {
71+
this.add(new NotebookProviderInfo(info));
72+
}
73+
});
7074

7175
this._register(extensionService.onDidRegisterExtensions(() => {
7276
if (!this._handled) {

src/vs/workbench/services/editor/browser/editorResolverService.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { findGroup } from 'vs/workbench/services/editor/common/editorGroupFinder
2727
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
2828
import { PreferredGroup } from 'vs/workbench/services/editor/common/editorService';
2929
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
30-
import { Emitter } from 'vs/base/common/event';
30+
import { PauseableEmitter } from 'vs/base/common/event';
3131

3232
interface RegisteredEditor {
3333
globPattern: string | glob.IRelativePattern;
@@ -42,7 +42,7 @@ export class EditorResolverService extends Disposable implements IEditorResolver
4242
readonly _serviceBrand: undefined;
4343

4444
// Events
45-
private readonly _onDidChangeEditorRegistrations = this._register(new Emitter<void>());
45+
private readonly _onDidChangeEditorRegistrations = this._register(new PauseableEmitter<void>());
4646
readonly onDidChangeEditorRegistrations = this._onDidChangeEditorRegistrations.event;
4747

4848
// Constants
@@ -216,6 +216,15 @@ export class EditorResolverService extends Disposable implements IEditorResolver
216216
};
217217
}
218218

219+
bufferChangeEvents(callback: Function): void {
220+
this._onDidChangeEditorRegistrations.pause();
221+
try {
222+
callback();
223+
} finally {
224+
this._onDidChangeEditorRegistrations.resume();
225+
}
226+
}
227+
219228
registerEditor(
220229
globPattern: string | glob.IRelativePattern,
221230
editorInfo: RegisteredEditorInfo,

src/vs/workbench/services/editor/common/editorResolverService.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ export interface IEditorResolverService {
140140
*/
141141
readonly onDidChangeEditorRegistrations: Event<void>;
142142

143+
/**
144+
* Given a callback, run the callback pausing the registration emitter
145+
*/
146+
bufferChangeEvents(callback: Function): void;
147+
143148
/**
144149
* Registers a specific editor. Editors with the same glob pattern and ID will be grouped together by the resolver.
145150
* This allows for registration of the factories in different locations

0 commit comments

Comments
 (0)