Skip to content

Commit fb6a07b

Browse files
author
Akos Kitta
committed
Avoid deleting the workspace when it's still in use.
- From now on, NSFW service disposes after last reference is removed. No more 10sec delay. - Moved the temp workspace deletion to a startup task. - Can set initial task for the window from electron-main. - Removed the `browser-app`. Closes arduino#39 Signed-off-by: Akos Kitta <[email protected]>
1 parent dcc0c0a commit fb6a07b

39 files changed

+570
-567
lines changed

Diff for: .vscode/launch.json

+2-34
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
".",
1515
"--log-level=debug",
1616
"--hostname=localhost",
17-
"--no-cluster",
1817
"--app-project-path=${workspaceRoot}/electron-app",
1918
"--remote-debugging-port=9222",
2019
"--no-app-auto-install",
2120
"--plugins=local-dir:../plugins",
2221
"--hosted-plugin-inspect=9339",
2322
"--content-trace",
24-
"--open-devtools"
23+
"--open-devtools",
24+
"--nsfw-watcher-verbose"
2525
],
2626
"env": {
2727
"NODE_ENV": "development"
@@ -51,7 +51,6 @@
5151
".",
5252
"--log-level=debug",
5353
"--hostname=localhost",
54-
"--no-cluster",
5554
"--app-project-path=${workspaceRoot}/electron-app",
5655
"--remote-debugging-port=9222",
5756
"--no-app-auto-install",
@@ -80,37 +79,6 @@
8079
"port": 9222,
8180
"webRoot": "${workspaceFolder}/electron-app"
8281
},
83-
{
84-
"type": "node",
85-
"request": "launch",
86-
"name": "App (Browser)",
87-
"program": "${workspaceRoot}/browser-app/src-gen/backend/main.js",
88-
"args": [
89-
"--hostname=0.0.0.0",
90-
"--port=3000",
91-
"--no-cluster",
92-
"--no-app-auto-install",
93-
"--plugins=local-dir:plugins"
94-
],
95-
"windows": {
96-
"env": {
97-
"NODE_ENV": "development",
98-
"NODE_PRESERVE_SYMLINKS": "1"
99-
}
100-
},
101-
"env": {
102-
"NODE_ENV": "development"
103-
},
104-
"sourceMaps": true,
105-
"outFiles": [
106-
"${workspaceRoot}/browser-app/src-gen/backend/*.js",
107-
"${workspaceRoot}/browser-app/lib/**/*.js",
108-
"${workspaceRoot}/arduino-ide-extension/lib/**/*.js"
109-
],
110-
"smartStep": true,
111-
"internalConsoleOptions": "openOnSessionStart",
112-
"outputCapture": "std"
113-
},
11482
{
11583
"type": "node",
11684
"request": "launch",

Diff for: .vscode/tasks.json

-30
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,6 @@
1212
"clear": false
1313
}
1414
},
15-
{
16-
"label": "Arduino IDE - Start Browser App",
17-
"type": "shell",
18-
"command": "yarn --cwd ./browser-app start",
19-
"group": "build",
20-
"presentation": {
21-
"reveal": "always",
22-
"panel": "new",
23-
"clear": true
24-
}
25-
},
2615
{
2716
"label": "Arduino IDE - Watch IDE Extension",
2817
"type": "shell",
@@ -34,17 +23,6 @@
3423
"clear": false
3524
}
3625
},
37-
{
38-
"label": "Arduino IDE - Watch Browser App",
39-
"type": "shell",
40-
"command": "yarn --cwd ./browser-app watch",
41-
"group": "build",
42-
"presentation": {
43-
"reveal": "always",
44-
"panel": "new",
45-
"clear": false
46-
}
47-
},
4826
{
4927
"label": "Arduino IDE - Watch Electron App",
5028
"type": "shell",
@@ -56,14 +34,6 @@
5634
"clear": false
5735
}
5836
},
59-
{
60-
"label": "Arduino IDE - Watch All [Browser]",
61-
"type": "shell",
62-
"dependsOn": [
63-
"Arduino IDE - Watch IDE Extension",
64-
"Arduino IDE - Watch Browser App"
65-
]
66-
},
6737
{
6838
"label": "Arduino IDE - Watch All [Electron]",
6939
"type": "shell",

Diff for: arduino-ide-extension/package.json

-2
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,9 @@
147147
"frontend": "lib/browser/arduino-ide-frontend-module"
148148
},
149149
{
150-
"frontend": "lib/browser/theia/core/browser-menu-module",
151150
"frontendElectron": "lib/electron-browser/theia/core/electron-menu-module"
152151
},
153152
{
154-
"frontend": "lib/browser/theia/core/browser-window-module",
155153
"frontendElectron": "lib/electron-browser/theia/core/electron-window-module"
156154
},
157155
{

Diff for: arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ import {
105105
} from '@theia/core/lib/browser/connection-status-service';
106106
import { BoardsDataMenuUpdater } from './boards/boards-data-menu-updater';
107107
import { BoardsDataStore } from './boards/boards-data-store';
108-
import { ILogger } from '@theia/core';
108+
import { ILogger } from '@theia/core/lib/common/logger';
109+
import { bindContributionProvider } from '@theia/core/lib/common/contribution-provider';
109110
import {
110111
FileSystemExt,
111112
FileSystemExtPath,
@@ -308,7 +309,7 @@ import { CoreErrorHandler } from './contributions/core-error-handler';
308309
import { CompilerErrors } from './contributions/compiler-errors';
309310
import { WidgetManager } from './theia/core/widget-manager';
310311
import { WidgetManager as TheiaWidgetManager } from '@theia/core/lib/browser/widget-manager';
311-
import { StartupTasks } from './widgets/sketchbook/startup-task';
312+
import { StartupTasks } from './contributions/startup-task';
312313
import { IndexesUpdateProgress } from './contributions/indexes-update-progress';
313314
import { Daemon } from './contributions/daemon';
314315
import { FirstStartupInstaller } from './contributions/first-startup-installer';
@@ -334,6 +335,8 @@ import {
334335
} from './widgets/component-list/filter-renderer';
335336
import { CheckForUpdates } from './contributions/check-for-updates';
336337
import { OutputEditorFactory } from './theia/output/output-editor-factory';
338+
import { StartupTaskProvider } from '../electron-common/startup-task';
339+
import { DeleteSketch } from './contributions/delete-sketch';
337340

338341
const registerArduinoThemes = () => {
339342
const themes: MonacoThemeJson[] = [
@@ -757,6 +760,10 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
757760
Contribution.configure(bind, OpenBoardsConfig);
758761
Contribution.configure(bind, SketchFilesTracker);
759762
Contribution.configure(bind, CheckForUpdates);
763+
Contribution.configure(bind, DeleteSketch);
764+
765+
bindContributionProvider(bind, StartupTaskProvider);
766+
bind(StartupTaskProvider).toService(BoardsServiceProvider); // to reuse the boards config in another window
760767

761768
// Disabled the quick-pick customization from Theia when multiple formatters are available.
762769
// Use the default VS Code behavior, and pick the first one. In the IDE2, clang-format has `exclusive` selectors.

Diff for: arduino-ide-extension/src/browser/boards/boards-config.tsx

-48
Original file line numberDiff line numberDiff line change
@@ -413,53 +413,5 @@ export namespace BoardsConfig {
413413
const { name } = selectedBoard;
414414
return `${name}${port ? ` at ${port.address}` : ''}`;
415415
}
416-
417-
export function setConfig(
418-
config: Config | undefined,
419-
urlToAttachTo: URL
420-
): URL {
421-
const copy = new URL(urlToAttachTo.toString());
422-
if (!config) {
423-
copy.searchParams.delete('boards-config');
424-
return copy;
425-
}
426-
427-
const selectedBoard = config.selectedBoard
428-
? {
429-
name: config.selectedBoard.name,
430-
fqbn: config.selectedBoard.fqbn,
431-
}
432-
: undefined;
433-
const selectedPort = config.selectedPort
434-
? {
435-
protocol: config.selectedPort.protocol,
436-
address: config.selectedPort.address,
437-
}
438-
: undefined;
439-
const jsonConfig = JSON.stringify({ selectedBoard, selectedPort });
440-
copy.searchParams.set('boards-config', encodeURIComponent(jsonConfig));
441-
return copy;
442-
}
443-
444-
export function getConfig(url: URL): Config | undefined {
445-
const encoded = url.searchParams.get('boards-config');
446-
if (!encoded) {
447-
return undefined;
448-
}
449-
try {
450-
const raw = decodeURIComponent(encoded);
451-
const candidate = JSON.parse(raw);
452-
if (typeof candidate === 'object') {
453-
return candidate;
454-
}
455-
console.warn(
456-
`Expected candidate to be an object. It was ${typeof candidate}. URL was: ${url}`
457-
);
458-
return undefined;
459-
} catch (e) {
460-
console.log(`Could not get board config from URL: ${url}.`, e);
461-
return undefined;
462-
}
463-
}
464416
}
465417
}

Diff for: arduino-ide-extension/src/browser/boards/boards-service-provider.ts

+34-5
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,15 @@ import { nls } from '@theia/core/lib/common';
2323
import { Deferred } from '@theia/core/lib/common/promise-util';
2424
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
2525
import { Unknown } from '../../common/nls';
26+
import {
27+
StartupTask,
28+
StartupTaskProvider,
29+
} from '../../electron-common/startup-task';
2630

2731
@injectable()
28-
export class BoardsServiceProvider implements FrontendApplicationContribution {
32+
export class BoardsServiceProvider
33+
implements FrontendApplicationContribution, StartupTaskProvider
34+
{
2935
@inject(ILogger)
3036
protected logger: ILogger;
3137

@@ -652,14 +658,15 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
652658
}
653659
} else {
654660
// If we could not restore the latest valid config, try to restore something, the board at least.
655-
let storedLatestBoardsConfig = await this.getData<
661+
const storedLatestBoardsConfig = await this.getData<
656662
BoardsConfig.Config | undefined
657663
>('latest-boards-config');
658664
// Try to get from the URL if it was not persisted.
659665
if (!storedLatestBoardsConfig) {
660-
storedLatestBoardsConfig = BoardsConfig.Config.getConfig(
661-
new URL(window.location.href)
662-
);
666+
console.warn('TODO: restore this');
667+
// storedLatestBoardsConfig = BoardsConfig.Config.getConfig(
668+
// new URL(window.location.href)
669+
// );
663670
}
664671
if (storedLatestBoardsConfig) {
665672
this.latestBoardsConfig = storedLatestBoardsConfig;
@@ -682,6 +689,28 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
682689
key
683690
);
684691
}
692+
693+
tasks(): StartupTask[] {
694+
const { selectedBoard: currentBoard, selectedPort: currentPort } =
695+
this.boardsConfig;
696+
const selectedBoard = currentBoard && {
697+
name: currentBoard.name,
698+
fqbn: currentBoard.fqbn,
699+
};
700+
const selectedPort = currentPort && {
701+
protocol: currentPort.protocol,
702+
address: currentPort.address,
703+
};
704+
if (!selectedBoard && !selectedPort) {
705+
return [];
706+
}
707+
return [
708+
{
709+
command: 'arduino-select-board',
710+
args: [{ selectedBoard, selectedPort }],
711+
},
712+
];
713+
}
685714
}
686715

687716
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { injectable } from '@theia/core/shared/inversify';
2+
import { SketchesError } from '../../common/protocol';
3+
import {
4+
Command,
5+
CommandRegistry,
6+
SketchContribution,
7+
Sketch,
8+
} from './contribution';
9+
10+
@injectable()
11+
export class DeleteSketch extends SketchContribution {
12+
override registerCommands(registry: CommandRegistry): void {
13+
registry.registerCommand(DeleteSketch.Commands.DELETE_SKETCH, {
14+
execute: (uri: string) => this.deleteSketch(uri),
15+
});
16+
}
17+
private async deleteSketch(uri: string): Promise<void> {
18+
const sketch = await this.loadSketch(uri);
19+
if (!sketch) {
20+
console.info(`Sketch not found at ${uri}. Skipping deletion.`);
21+
return;
22+
}
23+
return this.sketchService.deleteSketch(sketch);
24+
}
25+
private async loadSketch(uri: string): Promise<Sketch | undefined> {
26+
try {
27+
const sketch = await this.sketchService.loadSketch(uri);
28+
return sketch;
29+
} catch (err) {
30+
if (SketchesError.NotFound.is(err)) {
31+
return undefined;
32+
}
33+
throw err;
34+
}
35+
}
36+
}
37+
export namespace DeleteSketch {
38+
export namespace Commands {
39+
export const DELETE_SKETCH: Command = {
40+
id: 'arduino-delete-sketch',
41+
};
42+
}
43+
}

Diff for: arduino-ide-extension/src/browser/contributions/save-as-sketch.ts

+14-18
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,19 @@ import {
1212
} from './contribution';
1313
import { nls } from '@theia/core/lib/common';
1414
import { ApplicationShell, NavigatableWidget, Saveable } from '@theia/core/lib/browser';
15-
import { EditorManager } from '@theia/editor/lib/browser';
1615
import { WindowService } from '@theia/core/lib/browser/window/window-service';
1716
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
17+
import { WorkspaceInput } from '@theia/workspace/lib/browser';
18+
import { StartupTask } from '../../electron-common/startup-task';
19+
import { DeleteSketch } from './delete-sketch';
1820

1921
@injectable()
2022
export class SaveAsSketch extends SketchContribution {
21-
2223
@inject(ApplicationShell)
23-
protected readonly applicationShell: ApplicationShell;
24-
25-
@inject(EditorManager)
26-
protected override readonly editorManager: EditorManager;
24+
private readonly applicationShell: ApplicationShell;
2725

2826
@inject(WindowService)
29-
protected readonly windowService: WindowService;
27+
private readonly windowService: WindowService;
3028

3129
override registerCommands(registry: CommandRegistry): void {
3230
registry.registerCommand(SaveAsSketch.Commands.SAVE_AS_SKETCH, {
@@ -107,21 +105,19 @@ export class SaveAsSketch extends SketchContribution {
107105
this.sketchService.markAsRecentlyOpened(workspaceUri);
108106
}
109107
}
108+
const options: WorkspaceInput & { tasks: StartupTask[] } = {
109+
preserveWindow: true,
110+
tasks: [],
111+
};
110112
if (workspaceUri && openAfterMove) {
111113
this.windowService.setSafeToShutDown();
112114
if (wipeOriginal || (openAfterMove && execOnlyIfTemp)) {
113-
// This window will navigate away.
114-
// Explicitly stop the contribution to dispose the file watcher before deleting the temp sketch.
115-
// Otherwise, users might see irrelevant _Unable to watch for file changes in this large workspace._ notification.
116-
// https://github.com/arduino/arduino-ide/issues/39.
117-
this.sketchServiceClient.onStop();
118-
// TODO: consider implementing the temp sketch deletion the following way:
119-
// Open the other sketch with a `delete the temp sketch` startup-task.
120-
this.sketchService.notifyDeleteSketch(sketch); // This is a notification and will execute on the backend.
115+
options.tasks.push({
116+
command: DeleteSketch.Commands.DELETE_SKETCH.id,
117+
args: [sketch.uri],
118+
});
121119
}
122-
this.workspaceService.open(new URI(workspaceUri), {
123-
preserveWindow: true,
124-
});
120+
this.workspaceService.open(new URI(workspaceUri), options);
125121
}
126122
return !!workspaceUri;
127123
}

0 commit comments

Comments
 (0)