Skip to content

Commit afd5c6f

Browse files
committed
Merge remote-tracking branch 'origin/main' into msujew/theia-update-1.22
# Conflicts: # arduino-ide-extension/src/electron-main/theia/electron-main-application.ts
2 parents 4775259 + 69ac1f4 commit afd5c6f

File tree

3 files changed

+101
-9
lines changed

3 files changed

+101
-9
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/browser/boards/boards-service-provider.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
230230
)) {
231231
if (
232232
this.latestValidBoardsConfig.selectedBoard.fqbn === board.fqbn &&
233-
this.latestValidBoardsConfig.selectedBoard.name === board.name
233+
this.latestValidBoardsConfig.selectedBoard.name === board.name &&
234+
this.latestValidBoardsConfig.selectedPort.protocol === board.port?.protocol
234235
) {
235236
this.boardsConfig = {
236237
...this.latestValidBoardsConfig,

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

+96
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,40 @@ import { app, BrowserWindow, BrowserWindowConstructorOptions, ipcMain, screen }
33
import { fork } from 'child_process';
44
import { AddressInfo } from 'net';
55
import { join } from 'path';
6+
import * as fs from 'fs-extra';
67
import { initSplashScreen } from '../splash/splash-screen';
78
import { MaybePromise } from '@theia/core/lib/common/types';
89
import { ElectronSecurityToken } from '@theia/core/lib/electron-common/electron-token';
910
import { FrontendApplicationConfig } from '@theia/application-package/lib/application-props';
1011
import {
1112
ElectronMainApplication as TheiaElectronMainApplication,
13+
ElectronMainExecutionParams,
1214
TheiaBrowserWindowOptions,
1315
} from '@theia/core/lib/electron-main/electron-main-application';
1416
import { SplashServiceImpl } from '../splash/splash-service-impl';
17+
import { ipcMain } from '@theia/core/shared/electron';
18+
import { URI } from '@theia/core/shared/vscode-uri';
1519
import * as electronRemoteMain from '@theia/core/electron-shared/@electron/remote/main';
1620

1721
app.commandLine.appendSwitch('disable-http-cache');
1822

23+
interface WorkspaceOptions {
24+
file: string
25+
x: number
26+
y: number
27+
width: number
28+
height: number
29+
isMaximized: boolean
30+
isFullScreen: boolean
31+
time: number
32+
}
33+
34+
const WORKSPACES = 'workspaces';
35+
1936
@injectable()
2037
export class ElectronMainApplication extends TheiaElectronMainApplication {
2138
protected _windows: BrowserWindow[] = [];
39+
protected startup = false;
2240

2341
@inject(SplashServiceImpl)
2442
protected readonly splashService: SplashServiceImpl;
@@ -31,6 +49,45 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
3149
return super.start(config);
3250
}
3351

52+
protected async launch(params: ElectronMainExecutionParams): Promise<void> {
53+
this.startup = true;
54+
const workspaces: WorkspaceOptions[] | undefined = this.electronStore.get(WORKSPACES);
55+
let useDefault = true;
56+
if (workspaces && workspaces.length > 0) {
57+
for (const workspace of workspaces) {
58+
const file = workspace.file;
59+
if (typeof file === 'string' && await fs.pathExists(file)) {
60+
useDefault = false;
61+
await this.openSketch(workspace);
62+
}
63+
}
64+
}
65+
this.startup = false;
66+
if (useDefault) {
67+
super.launch(params);
68+
}
69+
}
70+
71+
protected async openSketch(workspace: WorkspaceOptions): Promise<BrowserWindow> {
72+
const options = await this.getLastWindowOptions();
73+
options.x = workspace.x;
74+
options.y = workspace.y;
75+
options.width = workspace.width;
76+
options.height = workspace.height;
77+
options.isMaximized = workspace.isMaximized;
78+
options.isFullScreen = workspace.isFullScreen;
79+
const [uri, electronWindow] = await Promise.all([this.createWindowUri(), this.createWindow(options)]);
80+
electronWindow.loadURL(uri.withFragment(encodeURI(workspace.file)).toString(true));
81+
return electronWindow;
82+
}
83+
84+
protected avoidOverlap(options: TheiaBrowserWindowOptions): TheiaBrowserWindowOptions {
85+
if (this.startup) {
86+
return options;
87+
}
88+
return super.avoidOverlap(options);
89+
}
90+
3491
protected getTitleBarStyle(): 'native' | 'custom' {
3592
return 'native';
3693
}
@@ -143,6 +200,7 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
143200
}
144201
}
145202
});
203+
this.attachClosedWorkspace(electronWindow);
146204
this.attachReadyToShow(electronWindow);
147205
this.attachSaveWindowState(electronWindow);
148206
this.attachGlobalShortcuts(electronWindow);
@@ -214,6 +272,44 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
214272
}
215273
}
216274

275+
protected closedWorkspaces: WorkspaceOptions[] = [];
276+
277+
protected attachClosedWorkspace(window: BrowserWindow): void {
278+
// Since the `before-quit` event is only fired when closing the *last* window
279+
// We need to keep track of recently closed windows/workspaces manually
280+
window.on('close', () => {
281+
const url = window.webContents.getURL();
282+
const workspace = URI.parse(url).fragment;
283+
if (workspace) {
284+
const workspaceUri = URI.file(workspace);
285+
const bounds = window.getNormalBounds();
286+
this.closedWorkspaces.push({
287+
...bounds,
288+
isMaximized: window.isMaximized(),
289+
isFullScreen: window.isFullScreen(),
290+
file: workspaceUri.fsPath,
291+
time: Date.now()
292+
})
293+
}
294+
});
295+
}
296+
297+
protected onWillQuit(event: Electron.Event): void {
298+
// Only add workspaces which were closed within the last second (1000 milliseconds)
299+
const threshold = Date.now() - 1000;
300+
const visited = new Set<string>();
301+
const workspaces = this.closedWorkspaces.filter(e => {
302+
if (e.time < threshold || visited.has(e.file)) {
303+
return false;
304+
}
305+
visited.add(e.file);
306+
return true;
307+
}).sort((a, b) => a.file.localeCompare(b.file));
308+
this.electronStore.set(WORKSPACES, workspaces);
309+
310+
super.onWillQuit(event);
311+
}
312+
217313
get windows(): BrowserWindow[] {
218314
return this._windows.slice();
219315
}

0 commit comments

Comments
 (0)