Skip to content

Commit ab09f1e

Browse files
author
Akos Kitta
committed
defer all menu updates before app is ready.
Signed-off-by: Akos Kitta <[email protected]>
1 parent 6282883 commit ab09f1e

File tree

4 files changed

+72
-5
lines changed

4 files changed

+72
-5
lines changed

arduino-ide-extension/src/electron-browser/theia/core/electron-main-menu-factory.ts

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { injectable } from '@theia/core/shared/inversify';
1+
import { inject, injectable } from '@theia/core/shared/inversify';
22
import * as remote from '@theia/core/electron-shared/@electron/remote';
33
import { isOSX } from '@theia/core/lib/common/os';
44
import {
@@ -14,9 +14,26 @@ import {
1414
ArduinoMenus,
1515
PlaceholderMenuNode,
1616
} from '../../../browser/menu/arduino-menus';
17+
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
1718

1819
@injectable()
1920
export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
21+
@inject(FrontendApplicationStateService)
22+
private readonly appStateService: FrontendApplicationStateService;
23+
24+
private appReady = false;
25+
private updateWhenReady = false;
26+
27+
override postConstruct(): void {
28+
super.postConstruct();
29+
this.appStateService.reachedState('ready').then(() => {
30+
this.appReady = true;
31+
if (this.updateWhenReady) {
32+
this.setMenuBar();
33+
}
34+
});
35+
}
36+
2037
override createElectronMenuBar(): Electron.Menu {
2138
this._toggledCommands.clear(); // https://github.com/eclipse-theia/theia/issues/8977
2239
const menuModel = this.menuProvider.getMenu(MAIN_MENU_BAR);
@@ -30,6 +47,13 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
3047
}
3148

3249
override async setMenuBar(): Promise<void> {
50+
// Avoid updating menu items when the app is not ready.
51+
// Getting the current electron window is not free and synchronous.
52+
// Here, we defer all menu update requests, and fire one when the app is ready.
53+
if (!this.appReady) {
54+
this.updateWhenReady = true;
55+
return;
56+
}
3357
await this.preferencesService.ready;
3458
const createdMenuBar = this.createElectronMenuBar();
3559
if (isOSX) {
@@ -39,7 +63,10 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
3963
}
4064
}
4165

42-
override createElectronContextMenu(menuPath: MenuPath, args?: any[]): Electron.Menu {
66+
override createElectronContextMenu(
67+
menuPath: MenuPath,
68+
args?: any[]
69+
): Electron.Menu {
4370
const menuModel = this.menuProvider.getMenu(menuPath);
4471
const template = this.fillMenuTemplate([], menuModel, args, {
4572
showDisabled: false,

arduino-ide-extension/src/electron-browser/theia/core/electron-menu-contribution.ts

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { injectable } from '@theia/core/shared/inversify';
1+
import { inject, injectable } from '@theia/core/shared/inversify';
22
import { CommandRegistry } from '@theia/core/lib/common/command';
33
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
44
import { KeybindingRegistry } from '@theia/core/lib/browser/keybinding';
@@ -7,19 +7,41 @@ import {
77
ElectronCommands,
88
} from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
99
import { MainMenuManager } from '../../../common/main-menu-manager';
10+
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
11+
import { FrontendApplication } from '@theia/core/lib/browser';
1012

1113
@injectable()
1214
export class ElectronMenuContribution
1315
extends TheiaElectronMenuContribution
1416
implements MainMenuManager
1517
{
18+
@inject(FrontendApplicationStateService)
19+
private readonly appStateService: FrontendApplicationStateService;
20+
21+
private appReady = false;
22+
private updateWhenReady = false;
23+
24+
override onStart(app: FrontendApplication): void {
25+
super.onStart(app);
26+
this.appStateService.reachedState('ready').then(() => {
27+
this.appReady = true;
28+
if (this.updateWhenReady) {
29+
this.update();
30+
}
31+
});
32+
}
33+
1634
protected override hideTopPanel(): void {
1735
// NOOP
1836
// We reuse the `div` for the Arduino toolbar.
1937
}
2038

2139
update(): void {
22-
(this as any).setMenu();
40+
if (this.appReady) {
41+
(this as any).setMenu();
42+
} else {
43+
this.updateWhenReady = true;
44+
}
2345
}
2446

2547
override registerCommands(registry: CommandRegistry): void {

arduino-ide-extension/src/electron-browser/theia/core/electron-menu-module.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
1616
bind(ElectronMenuContribution).toSelf().inSingletonScope();
1717
bind(MainMenuManager).toService(ElectronMenuContribution);
1818
rebind(TheiaElectronMenuContribution).to(ElectronMenuContribution);
19-
bind(ElectronMainMenuFactory).toSelf().inRequestScope();
19+
bind(ElectronMainMenuFactory).toSelf().inSingletonScope();
2020
rebind(TheiaElectronMainMenuFactory).toService(ElectronMainMenuFactory);
2121
bind(ElectronWindowService).toSelf().inSingletonScope();
2222
rebind(WindowService).toService(ElectronWindowService);

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

+18
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ const WORKSPACES = 'workspaces';
4242
const APP_STARTED_WITH_NOSPLASH =
4343
typeof process !== 'undefined' && process.argv.indexOf('--nosplash') !== -1;
4444

45+
/**
46+
* If the app is started with `--open-devtools` argument, the `Dev Tools` will be opened.
47+
*/
48+
const APP_STARTED_WITH_DEV_TOOLS =
49+
typeof process !== 'undefined' && process.argv.indexOf('--open-devtools') !== -1;
50+
4551
@injectable()
4652
export class ElectronMainApplication extends TheiaElectronMainApplication {
4753
protected startup = false;
@@ -243,10 +249,22 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
243249
options: TheiaBrowserWindowOptions
244250
): Promise<BrowserWindow> {
245251
const electronWindow = await super.createWindow(options);
252+
if (APP_STARTED_WITH_DEV_TOOLS) {
253+
electronWindow.webContents.openDevTools({ mode: 'undocked' });
254+
}
246255
this.attachListenersToWindow(electronWindow);
247256
return electronWindow;
248257
}
249258

259+
protected override getDefaultOptions(): TheiaBrowserWindowOptions {
260+
const options = super.getDefaultOptions();
261+
if (!options.webPreferences) {
262+
options.webPreferences = {};
263+
}
264+
options.webPreferences.v8CacheOptions = 'bypassHeatCheck'; // TODO: verify this. VS Code use this V8 option.
265+
return options;
266+
}
267+
250268
private attachListenersToWindow(electronWindow: BrowserWindow) {
251269
electronWindow.webContents.on(
252270
'new-window',

0 commit comments

Comments
 (0)