Skip to content

Commit 24036d7

Browse files
authored
Tweak lifecycle phases (microsoft#63899)
* lifecycle - signal READY earlier to allow commands to run * lifecycle - move READY phase as last thing into shell * workbench - isCreated() => isRestored() * lifecycle - tweak phase
1 parent bb0242c commit 24036d7

39 files changed

Lines changed: 104 additions & 89 deletions

File tree

src/vs/code/electron-main/window.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
466466

467467
private registerNavigationListenerOn(command: 'swipe' | 'app-command', back: 'left' | 'browser-backward', forward: 'right' | 'browser-forward', acrossEditors: boolean) {
468468
this._win.on(command as 'swipe' /* | 'app-command' */, (e: Electron.Event, cmd: string) => {
469-
if (this._readyState !== ReadyState.READY) {
469+
if (!this.isReady) {
470470
return; // window must be ready
471471
}
472472

src/vs/code/electron-main/windows.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,9 @@ export class WindowsManager implements IWindowsMainService {
216216
});
217217
});
218218

219-
// React to workbench loaded events from windows
220-
ipc.on('vscode:workbenchLoaded', (event: any, windowId: number) => {
221-
this.logService.trace('IPC#vscode-workbenchLoaded');
219+
// React to workbench ready events from windows
220+
ipc.on('vscode:workbenchReady', (event: any, windowId: number) => {
221+
this.logService.trace('IPC#vscode-workbenchReady');
222222

223223
const win = this.getWindowById(windowId);
224224
if (win) {

src/vs/platform/lifecycle/common/lifecycle.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,35 @@ export function StartupKindToString(startupKind: StartupKind): string {
8484
}
8585

8686
export const enum LifecyclePhase {
87+
88+
/**
89+
* The first phase signals that we are about to startup getting ready.
90+
*/
8791
Starting = 1,
88-
Restoring = 2,
89-
Running = 3,
92+
93+
/**
94+
* Services are ready and the view is about to restore its state.
95+
*/
96+
Ready = 2,
97+
98+
/**
99+
* Views, panels and editors have restored. For editors this means, that
100+
* they show their contents fully.
101+
*/
102+
Restored = 3,
103+
104+
/**
105+
* The last phase after views, panels and editors have restored and
106+
* some time has passed (few seconds).
107+
*/
90108
Eventually = 4
91109
}
92110

93111
export function LifecyclePhaseToString(phase: LifecyclePhase) {
94112
switch (phase) {
95113
case LifecyclePhase.Starting: return 'Starting';
96-
case LifecyclePhase.Restoring: return 'Restoring';
97-
case LifecyclePhase.Running: return 'Running';
114+
case LifecyclePhase.Ready: return 'Ready';
115+
case LifecyclePhase.Restored: return 'Restored';
98116
case LifecyclePhase.Eventually: return 'Eventually';
99117
}
100118
}
@@ -142,7 +160,7 @@ export const NullLifecycleService: ILifecycleService = {
142160
_serviceBrand: null,
143161
onWillShutdown: Event.None,
144162
onShutdown: Event.None,
145-
phase: LifecyclePhase.Running,
163+
phase: LifecyclePhase.Restored,
146164
startupKind: StartupKind.NewWindow,
147165
when() { return Promise.resolve(); }
148166
};

src/vs/workbench/browser/parts/activitybar/activitybarPart.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ export class ActivitybarPart extends Part {
188188
// The workaround is to promote the element onto its own drawing layer. We do
189189
// this only after the workbench has loaded because otherwise there is ugly flicker.
190190
if (isMacintosh) {
191-
this.lifecycleService.when(LifecyclePhase.Running).then(() => {
191+
this.lifecycleService.when(LifecyclePhase.Ready).then(() => {
192192
scheduleAtNextAnimationFrame(() => { // another delay...
193193
scheduleAtNextAnimationFrame(() => { // ...to prevent more flickering on startup
194194
registerThemingParticipant((theme, collector) => {

src/vs/workbench/browser/parts/compositePart.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
221221
// Report progress for slow loading composites (but only if we did not create the composites before already)
222222
const progressService = this.mapProgressServiceToComposite[composite.getId()];
223223
if (progressService && !compositeContainer) {
224-
this.mapProgressServiceToComposite[composite.getId()].showWhile(Promise.resolve(), this.partService.isCreated() ? 800 : 3200 /* less ugly initial startup */);
224+
this.mapProgressServiceToComposite[composite.getId()].showWhile(Promise.resolve(), this.partService.isRestored() ? 800 : 3200 /* less ugly initial startup */);
225225
}
226226

227227
// Fill Content and Actions

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ export class EditorControl extends Disposable {
168168

169169
// Show progress while setting input after a certain timeout. If the workbench is opening
170170
// be more relaxed about progress showing by increasing the delay a little bit to reduce flicker.
171-
const operation = this.editorOperation.start(this.partService.isCreated() ? 800 : 3200);
171+
const operation = this.editorOperation.start(this.partService.isRestored() ? 800 : 3200);
172172

173173
// Call into editor control
174174
const editorWillChange = !inputMatches;

src/vs/workbench/browser/parts/notifications/notificationsToasts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export class NotificationsToasts extends Themable {
8282
private registerListeners(): void {
8383

8484
// Wait for the running phase to ensure we can draw notifications properly
85-
this.lifecycleService.when(LifecyclePhase.Running).then(() => {
85+
this.lifecycleService.when(LifecyclePhase.Ready).then(() => {
8686

8787
// Show toast for initial notifications if any
8888
this.model.notifications.forEach(notification => this.addToast(notification));

src/vs/workbench/common/actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Registry.add(Extensions.WorkbenchActions, new class implements IWorkbenchActionR
9696
private triggerAndDisposeAction(instantiationService: IInstantiationService, lifecycleService: ILifecycleService, descriptor: SyncActionDescriptor, args: any): Thenable<void> {
9797

9898
// run action when workbench is created
99-
return lifecycleService.when(LifecyclePhase.Running).then(() => {
99+
return lifecycleService.when(LifecyclePhase.Ready).then(() => {
100100
const actionInstance = instantiationService.createInstance(descriptor.syncDescriptor);
101101
try {
102102
actionInstance.label = descriptor.label || actionInstance.label;

src/vs/workbench/common/contributions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class WorkbenchContributionsRegistry implements IWorkbenchContributionsRegistry
6969
this.instantiationService = instantiationService;
7070
this.lifecycleService = lifecycleService;
7171

72-
[LifecyclePhase.Starting, LifecyclePhase.Restoring, LifecyclePhase.Running, LifecyclePhase.Eventually].forEach(phase => {
72+
[LifecyclePhase.Starting, LifecyclePhase.Ready, LifecyclePhase.Restored, LifecyclePhase.Eventually].forEach(phase => {
7373
this.instantiateByPhase(instantiationService, lifecycleService, phase);
7474
});
7575
}

src/vs/workbench/electron-browser/shell.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ import { ILabelService, LabelService } from 'vs/platform/label/common/label';
100100
import { IDownloadService } from 'vs/platform/download/common/download';
101101
import { DownloadService } from 'vs/platform/download/node/downloadService';
102102
import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc';
103-
import { runWhenIdle } from 'vs/base/common/async';
104103
import { TextResourcePropertiesService } from 'vs/workbench/services/textfile/electron-browser/textResourcePropertiesService';
105104
import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/node/multiExtensionManagement';
106105
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
@@ -189,7 +188,7 @@ export class WorkbenchShell extends Disposable {
189188
this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.');
190189
}, 10000);
191190

192-
this.lifecycleService.when(LifecyclePhase.Running).then(() => {
191+
this.lifecycleService.when(LifecyclePhase.Restored).then(() => {
193192
clearTimeout(timeoutHandle);
194193
});
195194
}
@@ -208,30 +207,16 @@ export class WorkbenchShell extends Disposable {
208207
try {
209208
const workbench = instantiationService.createInstance(Workbench, container, this.configuration, serviceCollection, this.lifecycleService, this.mainProcessClient);
210209

211-
// Set lifecycle phase to `Restoring`
212-
this.lifecycleService.phase = LifecyclePhase.Restoring;
213-
214210
// Startup Workbench
215211
workbench.startup().then(startupInfos => {
216212

217-
// Set lifecycle phase to `Runnning`
218-
this.lifecycleService.phase = LifecyclePhase.Running;
219-
220213
// Startup Telemetry
221214
this.logStartupTelemetry(startupInfos);
222215

223216
// Storage Telemetry (TODO@Ben remove me later, including storage errors)
224217
if (!this.environmentService.extensionTestsPath) {
225218
this.logStorageTelemetry();
226219
}
227-
228-
// Set lifecycle phase to `Runnning For A Bit` after a short delay
229-
let eventuallPhaseTimeoutHandle = runWhenIdle(() => {
230-
eventuallPhaseTimeoutHandle = void 0;
231-
this.lifecycleService.phase = LifecyclePhase.Eventually;
232-
}, 5000);
233-
234-
this._register(eventuallPhaseTimeoutHandle);
235220
}, error => handleStartupError(this.logService, error));
236221

237222
return workbench;
@@ -546,6 +531,9 @@ export class WorkbenchShell extends Disposable {
546531

547532
// Listeners
548533
this.registerListeners();
534+
535+
// Set lifecycle phase to `Ready`
536+
this.lifecycleService.phase = LifecyclePhase.Ready;
549537
}
550538

551539
private registerListeners(): void {

0 commit comments

Comments
 (0)