55
66import { app , BrowserWindow , dialog , protocol , session , Session , systemPreferences , WebFrameMain } from 'electron' ;
77import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain' ;
8- import { statSync } from 'fs' ;
98import { hostname , release } from 'os' ;
109import { VSBuffer } from 'vs/base/common/buffer' ;
1110import { toErrorMessage } from 'vs/base/common/errorMessage' ;
@@ -109,8 +108,7 @@ import { ExtensionsProfileScannerService, IExtensionsProfileScannerService } fro
109108import { IExtensionsScannerService } from 'vs/platform/extensionManagement/common/extensionsScannerService' ;
110109import { ExtensionsScannerService } from 'vs/platform/extensionManagement/node/extensionsScannerService' ;
111110import { UserDataTransientProfilesHandler } from 'vs/platform/userDataProfile/electron-main/userDataTransientProfilesHandler' ;
112- import { RunOnceScheduler , runWhenIdle } from 'vs/base/common/async' ;
113- import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile' ;
111+ import { Promises , RunOnceScheduler , runWhenIdle } from 'vs/base/common/async' ;
114112
115113/**
116114 * The main VS Code application. There will only ever be one instance,
@@ -327,12 +325,12 @@ export class CodeApplication extends Disposable {
327325 } ) ;
328326
329327 // macOS dock activate
330- app . on ( 'activate' , ( event , hasVisibleWindows ) => {
328+ app . on ( 'activate' , async ( event , hasVisibleWindows ) => {
331329 this . logService . trace ( 'app#activate' ) ;
332330
333331 // Mac only event: open new window when we get activated
334332 if ( ! hasVisibleWindows ) {
335- this . windowsMainService ?. openEmptyWindow ( { context : OpenContext . DOCK } ) ;
333+ await this . windowsMainService ?. openEmptyWindow ( { context : OpenContext . DOCK } ) ;
336334 }
337335 } ) ;
338336
@@ -364,7 +362,7 @@ export class CodeApplication extends Disposable {
364362 event . preventDefault ( ) ;
365363
366364 // Keep in array because more might come!
367- macOpenFileURIs . push ( this . getWindowOpenableFromPathSync ( path ) ) ;
365+ macOpenFileURIs . push ( hasWorkspaceFileExtension ( path ) ? { workspaceUri : URI . file ( path ) } : { fileUri : URI . file ( path ) } ) ;
368366
369367 // Clear previous handler if any
370368 if ( runningTimeout !== undefined ) {
@@ -373,8 +371,8 @@ export class CodeApplication extends Disposable {
373371 }
374372
375373 // Handle paths delayed in case more are coming!
376- runningTimeout = setTimeout ( ( ) => {
377- this . windowsMainService ?. open ( {
374+ runningTimeout = setTimeout ( async ( ) => {
375+ await this . windowsMainService ?. open ( {
378376 context : OpenContext . DOCK /* can also be opening from finder while app is running */ ,
379377 cli : this . environmentMainService . args ,
380378 urisToOpen : macOpenFileURIs ,
@@ -387,8 +385,8 @@ export class CodeApplication extends Disposable {
387385 } , 100 ) ;
388386 } ) ;
389387
390- app . on ( 'new-window-for-tab' , ( ) => {
391- this . windowsMainService ?. openEmptyWindow ( { context : OpenContext . DESKTOP } ) ; //macOS native tab "+" button
388+ app . on ( 'new-window-for-tab' , async ( ) => {
389+ await this . windowsMainService ?. openEmptyWindow ( { context : OpenContext . DESKTOP } ) ; //macOS native tab "+" button
392390 } ) ;
393391
394392 //#region Bootstrap IPC Handlers
@@ -538,15 +536,11 @@ export class CodeApplication extends Disposable {
538536 // Setup Handlers
539537 this . setUpHandlers ( appInstantiationService ) ;
540538
541- // Ensure profile exists when passed in from CLI
542- const profilePromise = this . userDataProfilesMainService . checkAndCreateProfileFromCli ( this . environmentMainService . args ) ;
543- const profile = profilePromise ? await profilePromise : undefined ;
544-
545539 // Init Channels
546540 appInstantiationService . invokeFunction ( accessor => this . initChannels ( accessor , mainProcessElectronServer , sharedProcessClient ) ) ;
547541
548542 // Open Windows
549- appInstantiationService . invokeFunction ( accessor => this . openFirstWindow ( accessor , profile , mainProcessElectronServer ) ) ;
543+ await appInstantiationService . invokeFunction ( accessor => this . openFirstWindow ( accessor , mainProcessElectronServer ) ) ;
550544
551545 // Post Open Windows Tasks
552546 appInstantiationService . invokeFunction ( accessor => this . afterWindowOpen ( accessor , sharedProcess ) ) ;
@@ -632,7 +626,8 @@ export class CodeApplication extends Disposable {
632626 services . set ( IWindowsMainService , new SyncDescriptor ( WindowsMainService , [ machineId , this . userEnv ] , false ) ) ;
633627
634628 // Dialogs
635- services . set ( IDialogMainService , new SyncDescriptor ( DialogMainService , undefined , true ) ) ;
629+ const dialogMainService = new DialogMainService ( this . logService ) ;
630+ services . set ( IDialogMainService , dialogMainService ) ;
636631
637632 // Launch
638633 services . set ( ILaunchMainService , new SyncDescriptor ( LaunchMainService , undefined , false /* proxied to other processes */ ) ) ;
@@ -659,10 +654,6 @@ export class CodeApplication extends Disposable {
659654 // Webview Manager
660655 services . set ( IWebviewManagerService , new SyncDescriptor ( WebviewMainService ) ) ;
661656
662- // Workspaces
663- services . set ( IWorkspacesService , new SyncDescriptor ( WorkspacesMainService , undefined , false /* proxied to other processes */ ) ) ;
664- services . set ( IWorkspacesManagementMainService , new SyncDescriptor ( WorkspacesManagementMainService , undefined , true ) ) ;
665- services . set ( IWorkspacesHistoryMainService , new SyncDescriptor ( WorkspacesHistoryMainService , undefined , false ) ) ;
666657
667658 // Menubar
668659 services . set ( IMenubarMainService , new SyncDescriptor ( MenubarMainService ) ) ;
@@ -690,6 +681,12 @@ export class CodeApplication extends Disposable {
690681 const backupMainService = new BackupMainService ( this . environmentMainService , this . configurationService , this . logService , this . stateMainService ) ;
691682 services . set ( IBackupMainService , backupMainService ) ;
692683
684+ // Workspaces
685+ const workspacesManagementMainService = new WorkspacesManagementMainService ( this . environmentMainService , this . logService , this . userDataProfilesMainService , backupMainService , dialogMainService , this . productService ) ;
686+ services . set ( IWorkspacesManagementMainService , workspacesManagementMainService ) ;
687+ services . set ( IWorkspacesService , new SyncDescriptor ( WorkspacesMainService , undefined , false /* proxied to other processes */ ) ) ;
688+ services . set ( IWorkspacesHistoryMainService , new SyncDescriptor ( WorkspacesHistoryMainService , undefined , false ) ) ;
689+
693690 // URL handling
694691 services . set ( IURLService , new SyncDescriptor ( NativeURLService , undefined , false /* proxied to other processes */ ) ) ;
695692
@@ -712,7 +709,10 @@ export class CodeApplication extends Disposable {
712709 services . set ( IExtensionsScannerService , new SyncDescriptor ( ExtensionsScannerService , undefined , true ) ) ;
713710
714711 // Init services that require it
715- await backupMainService . initialize ( ) ;
712+ await Promises . settled ( [
713+ backupMainService . initialize ( ) ,
714+ workspacesManagementMainService . initialize ( )
715+ ] ) ;
716716
717717 return this . mainInstantiationService . createChild ( services ) ;
718718 }
@@ -829,7 +829,7 @@ export class CodeApplication extends Disposable {
829829 mainProcessElectronServer . registerChannel ( ipcExtensionHostStarterChannelName , extensionHostStarterChannel ) ;
830830 }
831831
832- private openFirstWindow ( accessor : ServicesAccessor , profile : IUserDataProfile | undefined , mainProcessElectronServer : ElectronIPCServer ) : ICodeWindow [ ] {
832+ private async openFirstWindow ( accessor : ServicesAccessor , mainProcessElectronServer : ElectronIPCServer ) : Promise < ICodeWindow [ ] > {
833833 const windowsMainService = this . windowsMainService = accessor . get ( IWindowsMainService ) ;
834834 const urlService = accessor . get ( IURLService ) ;
835835 const nativeHostMainService = accessor . get ( INativeHostMainService ) ;
@@ -917,7 +917,7 @@ export class CodeApplication extends Disposable {
917917 const windowOpenableFromProtocolLink = app . getWindowOpenableFromProtocolLink ( uri ) ;
918918 logService . trace ( 'app#handleURL: windowOpenableFromProtocolLink = ' , windowOpenableFromProtocolLink ) ;
919919 if ( windowOpenableFromProtocolLink ) {
920- const [ window ] = windowsMainService . open ( {
920+ const [ window ] = await windowsMainService . open ( {
921921 context : OpenContext . API ,
922922 cli : { ...environmentService . args } ,
923923 urisToOpen : [ windowOpenableFromProtocolLink ] ,
@@ -932,7 +932,7 @@ export class CodeApplication extends Disposable {
932932 }
933933
934934 if ( shouldOpenInNewWindow ) {
935- const [ window ] = windowsMainService . open ( {
935+ const [ window ] = await windowsMainService . open ( {
936936 context : OpenContext . API ,
937937 cli : { ...environmentService . args } ,
938938 forceNewWindow : true ,
@@ -989,6 +989,9 @@ export class CodeApplication extends Disposable {
989989 } ) ;
990990 }
991991
992+ // Ensure profile exists when passed in from CLI
993+ const profile = await this . userDataProfilesMainService . checkAndCreateProfileFromCli ( this . environmentMainService . args ) ;
994+
992995 // Start without file/folder arguments
993996 if ( ! hasCliArgs && ! hasFolderURIs && ! hasFileURIs ) {
994997
@@ -1012,7 +1015,7 @@ export class CodeApplication extends Disposable {
10121015 return windowsMainService . open ( {
10131016 context : OpenContext . DOCK ,
10141017 cli : args ,
1015- urisToOpen : macOpenFiles . map ( file => this . getWindowOpenableFromPathSync ( file ) ) ,
1018+ urisToOpen : macOpenFiles . map ( path => ( hasWorkspaceFileExtension ( path ) ? { workspaceUri : URI . file ( path ) } : { fileUri : URI . file ( path ) } ) ) ,
10161019 noRecentEntry,
10171020 waitMarkerFileURI,
10181021 initialStartup : true ,
@@ -1104,23 +1107,6 @@ export class CodeApplication extends Disposable {
11041107 return undefined ;
11051108 }
11061109
1107- private getWindowOpenableFromPathSync ( path : string ) : IWindowOpenable {
1108- try {
1109- const fileStat = statSync ( path ) ;
1110- if ( fileStat . isDirectory ( ) ) {
1111- return { folderUri : URI . file ( path ) } ;
1112- }
1113-
1114- if ( hasWorkspaceFileExtension ( path ) ) {
1115- return { workspaceUri : URI . file ( path ) } ;
1116- }
1117- } catch ( error ) {
1118- // ignore errors
1119- }
1120-
1121- return { fileUri : URI . file ( path ) } ;
1122- }
1123-
11241110 private afterWindowOpen ( accessor : ServicesAccessor , sharedProcess : SharedProcess ) : void {
11251111 const telemetryService = accessor . get ( ITelemetryService ) ;
11261112 const updateService = accessor . get ( IUpdateService ) ;
0 commit comments