@@ -8,19 +8,24 @@ import {
8
8
import { fork } from 'child_process' ;
9
9
import { AddressInfo } from 'net' ;
10
10
import { join } from 'path' ;
11
+ import * as fs from 'fs-extra' ;
11
12
import { initSplashScreen } from '../splash/splash-screen' ;
12
13
import { MaybePromise } from '@theia/core/lib/common/types' ;
13
14
import { ElectronSecurityToken } from '@theia/core/lib/electron-common/electron-token' ;
14
15
import { FrontendApplicationConfig } from '@theia/application-package/lib/application-props' ;
15
16
import {
16
17
ElectronMainApplication as TheiaElectronMainApplication ,
18
+ ElectronMainExecutionParams ,
17
19
TheiaBrowserWindowOptions ,
18
20
} from '@theia/core/lib/electron-main/electron-main-application' ;
19
21
import { SplashServiceImpl } from '../splash/splash-service-impl' ;
20
22
import { ipcMain } from '@theia/core/shared/electron' ;
23
+ import { URI } from '@theia/core/shared/vscode-uri' ;
21
24
22
25
app . commandLine . appendSwitch ( 'disable-http-cache' ) ;
23
26
27
+ const WORKSPACES = 'workspaces' ;
28
+
24
29
@injectable ( )
25
30
export class ElectronMainApplication extends TheiaElectronMainApplication {
26
31
protected _windows : BrowserWindow [ ] = [ ] ;
@@ -36,6 +41,24 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
36
41
return super . start ( config ) ;
37
42
}
38
43
44
+ protected async launch ( params : ElectronMainExecutionParams ) : Promise < void > {
45
+ const workspaces : string [ ] | undefined = this . electronStore . get ( WORKSPACES ) ;
46
+ let useDefault = true ;
47
+ if ( workspaces && workspaces . length > 0 ) {
48
+ // Setting `secondInstance=true` allows us to pass workspace URIs to the frontend
49
+ const newParams = Object . assign ( { } , params , { secondInstance : true } ) ;
50
+ for ( const file of workspaces ) {
51
+ if ( await fs . pathExists ( file ) ) {
52
+ useDefault = false ;
53
+ await this . handleMainCommand ( newParams , { file } ) ;
54
+ }
55
+ }
56
+ }
57
+ if ( useDefault ) {
58
+ super . launch ( params ) ;
59
+ }
60
+ }
61
+
39
62
protected getTitleBarStyle ( ) : 'native' | 'custom' {
40
63
return 'native' ;
41
64
}
@@ -148,6 +171,7 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
148
171
}
149
172
}
150
173
} ) ;
174
+ this . attachClosedWorkspace ( electronWindow ) ;
151
175
this . attachReadyToShow ( electronWindow ) ;
152
176
this . attachSaveWindowState ( electronWindow ) ;
153
177
this . attachGlobalShortcuts ( electronWindow ) ;
@@ -218,6 +242,33 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
218
242
}
219
243
}
220
244
245
+ protected closedWorkspaces : { workspace : string , time : number } [ ] = [ ] ;
246
+
247
+ protected attachClosedWorkspace ( window : BrowserWindow ) : void {
248
+ // Since the `before-quit` event is only fired when closing the *last* window
249
+ // We need to keep track of recently closed windows/workspaces manually
250
+ window . on ( 'close' , ( ) => {
251
+ const url = window . webContents . getURL ( ) ;
252
+ const workspace = URI . parse ( url ) . fragment ;
253
+ if ( workspace ) {
254
+ const workspaceUri = URI . file ( workspace ) ;
255
+ this . closedWorkspaces . push ( {
256
+ workspace : workspaceUri . fsPath ,
257
+ time : Date . now ( )
258
+ } )
259
+ }
260
+ } ) ;
261
+ }
262
+
263
+ protected onWillQuit ( event : Electron . Event ) : void {
264
+ // Only add workspaces which were closed within the last second (1000 milliseconds)
265
+ const threshold = Date . now ( ) - 1000 ;
266
+ const workspaces = this . closedWorkspaces . filter ( e => e . time > threshold ) . map ( e => e . workspace ) . sort ( ) ;
267
+ this . electronStore . set ( WORKSPACES , workspaces ) ;
268
+
269
+ super . onWillQuit ( event ) ;
270
+ }
271
+
221
272
get windows ( ) : BrowserWindow [ ] {
222
273
return this . _windows . slice ( ) ;
223
274
}
0 commit comments