Skip to content

Commit d9a937c

Browse files
committed
Open all closed workspaces on startup
1 parent 1d88263 commit d9a937c

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

Diff for: arduino-ide-extension/src/browser/arduino-workspace-resolver.ts

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { toUnix } from 'upath';
2-
import URI from '@theia/core/lib/common/uri';
1+
import { URI } from '@theia/core/shared/vscode-uri';
32
import { isWindows } from '@theia/core/lib/common/os';
43
import { notEmpty } from '@theia/core/lib/common/objects';
54
import { MaybePromise } from '@theia/core/lib/common/types';
@@ -61,12 +60,8 @@ export class ArduinoWorkspaceRootResolver {
6160
// - https://github.com/eclipse-theia/theia/blob/8196e9dcf9c8de8ea0910efeb5334a974f426966/packages/workspace/src/browser/workspace-service.ts#L423
6261
protected hashToUri(hash: string | undefined): string | undefined {
6362
if (hash && hash.length > 1 && hash.startsWith('#')) {
64-
const path = hash.slice(1); // Trim the leading `#`.
65-
return new URI(
66-
toUnix(path.slice(isWindows && hash.startsWith('/') ? 1 : 0))
67-
)
68-
.withScheme('file')
69-
.toString();
63+
const path = decodeURI(hash.slice(1)).replace(/\\/g, '/'); // Trim the leading `#`, decode the URI and replace Windows separators
64+
return URI.file(path.slice(isWindows && hash.startsWith('/') ? 1 : 0)).toString();
7065
}
7166
return undefined;
7267
}

Diff for: arduino-ide-extension/src/electron-main/theia/electron-main-application.ts

+51
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,24 @@ import {
88
import { fork } from 'child_process';
99
import { AddressInfo } from 'net';
1010
import { join } from 'path';
11+
import * as fs from 'fs-extra';
1112
import { initSplashScreen } from '../splash/splash-screen';
1213
import { MaybePromise } from '@theia/core/lib/common/types';
1314
import { ElectronSecurityToken } from '@theia/core/lib/electron-common/electron-token';
1415
import { FrontendApplicationConfig } from '@theia/application-package/lib/application-props';
1516
import {
1617
ElectronMainApplication as TheiaElectronMainApplication,
18+
ElectronMainExecutionParams,
1719
TheiaBrowserWindowOptions,
1820
} from '@theia/core/lib/electron-main/electron-main-application';
1921
import { SplashServiceImpl } from '../splash/splash-service-impl';
2022
import { ipcMain } from '@theia/core/shared/electron';
23+
import { URI } from '@theia/core/shared/vscode-uri';
2124

2225
app.commandLine.appendSwitch('disable-http-cache');
2326

27+
const WORKSPACES = 'workspaces';
28+
2429
@injectable()
2530
export class ElectronMainApplication extends TheiaElectronMainApplication {
2631
protected _windows: BrowserWindow[] = [];
@@ -36,6 +41,24 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
3641
return super.start(config);
3742
}
3843

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+
3962
protected getTitleBarStyle(): 'native' | 'custom' {
4063
return 'native';
4164
}
@@ -148,6 +171,7 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
148171
}
149172
}
150173
});
174+
this.attachClosedWorkspace(electronWindow);
151175
this.attachReadyToShow(electronWindow);
152176
this.attachSaveWindowState(electronWindow);
153177
this.attachGlobalShortcuts(electronWindow);
@@ -218,6 +242,33 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
218242
}
219243
}
220244

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+
221272
get windows(): BrowserWindow[] {
222273
return this._windows.slice();
223274
}

0 commit comments

Comments
 (0)