Skip to content

Commit 9ffe421

Browse files
author
Akos Kitta
committed
fix: restored window.titleBarStyle
Ref: #1733 Signed-off-by: Akos Kitta <[email protected]>
1 parent d68bc4a commit 9ffe421

File tree

6 files changed

+134
-65
lines changed

6 files changed

+134
-65
lines changed

arduino-ide-extension/src/browser/style/main.css

+13
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@
100100
background-color: var(--theia-titleBar-activeBackground);
101101
}
102102

103+
#arduino-toolbar-panel {
104+
background: var(--theia-titleBar-activeBackground);
105+
color: var(--theia-titleBar-activeForeground);
106+
display: flex;
107+
min-height: var(--theia-private-menubar-height);
108+
border-bottom: 1px solid var(--theia-titleBar-border);
109+
}
110+
#arduino-toolbar-panel:window-inactive,
111+
#arduino-toolbar-panel:-moz-window-inactive {
112+
background: var(--theia-titleBar-inactiveBackground);
113+
color: var(--theia-titleBar-inactiveForeground);
114+
}
115+
103116
#arduino-toolbar-container {
104117
display: flex;
105118
width: 100%;

arduino-ide-extension/src/browser/theia/core/application-shell.ts

+58-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
SHELL_TABBAR_CONTEXT_MENU,
88
TabBar,
99
Widget,
10+
Layout,
11+
SplitPanel,
1012
} from '@theia/core/lib/browser';
1113
import {
1214
ConnectionStatus,
@@ -17,17 +19,23 @@ import { MessageService } from '@theia/core/lib/common/message-service';
1719
import { inject, injectable } from '@theia/core/shared/inversify';
1820
import { ToolbarAwareTabBar } from './tab-bars';
1921

22+
interface WidgetOptions
23+
extends Omit<TheiaApplicationShell.WidgetOptions, 'area'> {
24+
area?: TheiaApplicationShell.Area | 'toolbar';
25+
}
26+
2027
@injectable()
2128
export class ApplicationShell extends TheiaApplicationShell {
2229
@inject(MessageService)
2330
private readonly messageService: MessageService;
2431

2532
@inject(ConnectionStatusService)
2633
private readonly connectionStatusService: ConnectionStatusService;
34+
private toolbarPanel: Panel;
2735

2836
override async addWidget(
2937
widget: Widget,
30-
options: Readonly<TheiaApplicationShell.WidgetOptions> = {}
38+
options: Readonly<WidgetOptions> = {}
3139
): Promise<void> {
3240
// By default, Theia open a widget **next** to the currently active in the target area.
3341
// Instead of this logic, we want to open the new widget after the last of the target area.
@@ -37,8 +45,12 @@ export class ApplicationShell extends TheiaApplicationShell {
3745
);
3846
return;
3947
}
48+
if (options.area === 'toolbar') {
49+
this.toolbarPanel.addWidget(widget);
50+
return;
51+
}
52+
const area = options.area || 'main';
4053
let ref: Widget | undefined = options.ref;
41-
const area: TheiaApplicationShell.Area = options.area || 'main';
4254
if (!ref && (area === 'main' || area === 'bottom')) {
4355
const tabBar = this.getTabBarFor(area);
4456
if (tabBar) {
@@ -48,14 +60,57 @@ export class ApplicationShell extends TheiaApplicationShell {
4860
}
4961
}
5062
}
51-
return super.addWidget(widget, { ...options, ref });
63+
return super.addWidget(widget, {
64+
...(<TheiaApplicationShell.WidgetOptions>options),
65+
ref,
66+
});
5267
}
5368

5469
override handleEvent(): boolean {
5570
// NOOP, dragging has been disabled
5671
return false;
5772
}
5873

74+
protected override initializeShell(): void {
75+
this.toolbarPanel = this.createToolbarPanel();
76+
super.initializeShell();
77+
}
78+
79+
private createToolbarPanel(): Panel {
80+
const toolbarPanel = new Panel();
81+
toolbarPanel.id = 'arduino-toolbar-panel';
82+
toolbarPanel.show();
83+
return toolbarPanel;
84+
}
85+
86+
protected override createLayout(): Layout {
87+
const bottomSplitLayout = this.createSplitLayout(
88+
[this.mainPanel, this.bottomPanel],
89+
[1, 0],
90+
{ orientation: 'vertical', spacing: 0 }
91+
);
92+
const panelForBottomArea = new SplitPanel({ layout: bottomSplitLayout });
93+
panelForBottomArea.id = 'theia-bottom-split-panel';
94+
95+
const leftRightSplitLayout = this.createSplitLayout(
96+
[
97+
this.leftPanelHandler.container,
98+
panelForBottomArea,
99+
this.rightPanelHandler.container,
100+
],
101+
[0, 1, 0],
102+
{ orientation: 'horizontal', spacing: 0 }
103+
);
104+
const panelForSideAreas = new SplitPanel({ layout: leftRightSplitLayout });
105+
panelForSideAreas.id = 'theia-left-right-split-panel';
106+
107+
return this.createBoxLayout(
108+
[this.topPanel, this.toolbarPanel, panelForSideAreas, this.statusBar],
109+
[0, 0, 1, 0],
110+
{ direction: 'top-to-bottom', spacing: 0 }
111+
);
112+
}
113+
59114
// Avoid hiding top panel as we use it for arduino toolbar
60115
protected override createTopPanel(): Panel {
61116
const topPanel = super.createTopPanel();

arduino-ide-extension/src/browser/toolbar/arduino-toolbar-contribution.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ export class ArduinoToolbarContainer extends Widget {
1919
this.toolbars = toolbars;
2020
}
2121

22-
override onAfterAttach(msg: Message) {
22+
override onAfterAttach(msg: Message): void {
23+
super.onAfterAttach(msg);
2324
for (const toolbar of this.toolbars) {
2425
Widget.attach(toolbar, this.node);
2526
}
@@ -56,9 +57,11 @@ export class ArduinoToolbarContribution
5657
);
5758
}
5859

59-
onStart(app: FrontendApplication) {
60-
app.shell.addWidget(this.arduinoToolbarContainer, {
61-
area: 'top',
62-
});
60+
onStart(app: FrontendApplication): void {
61+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
62+
const options = <any>{
63+
area: 'toolbar',
64+
};
65+
app.shell.addWidget(this.arduinoToolbarContainer, options);
6366
}
6467
}

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

+3-19
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
CommandMenuNode,
66
CompoundMenuNode,
77
CompoundMenuNodeRole,
8-
MAIN_MENU_BAR,
98
MenuNode,
109
MenuPath,
1110
} from '@theia/core/lib/common/menu';
@@ -39,18 +38,9 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
3938
});
4039
}
4140

42-
override createElectronMenuBar(): Electron.Menu {
41+
override createElectronMenuBar(): Electron.Menu | null {
4342
this._toggledCommands.clear(); // https://github.com/eclipse-theia/theia/issues/8977
44-
const menuModel = this.menuProvider.getMenu(MAIN_MENU_BAR);
45-
const template = this.fillMenuTemplate([], menuModel, [], {
46-
rootMenuPath: MAIN_MENU_BAR,
47-
});
48-
if (isOSX) {
49-
template.unshift(this.createOSXMenu());
50-
}
51-
const menu = remote.Menu.buildFromTemplate(this.escapeAmpersand(template));
52-
this._menu = menu;
53-
return menu;
43+
return super.createElectronMenuBar();
5444
}
5545

5646
override async setMenuBar(): Promise<void> {
@@ -61,13 +51,7 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
6151
this.updateWhenReady = true;
6252
return;
6353
}
64-
await this.preferencesService.ready;
65-
const createdMenuBar = this.createElectronMenuBar();
66-
if (isOSX) {
67-
remote.Menu.setApplicationMenu(createdMenuBar);
68-
} else {
69-
remote.getCurrentWindow().setMenu(createdMenuBar);
70-
}
54+
return super.setMenuBar();
7155
}
7256

7357
override createElectronContextMenu(

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

+17-32
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,38 @@
1-
import { inject, injectable } from '@theia/core/shared/inversify';
1+
import {
2+
getCurrentWebContents,
3+
getCurrentWindow,
4+
} from '@theia/core/electron-shared/@electron/remote';
5+
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
6+
import { KeybindingRegistry } from '@theia/core/lib/browser/keybinding';
7+
import { PreferenceScope } from '@theia/core/lib/browser/preferences/preference-scope';
28
import { CommandRegistry } from '@theia/core/lib/common/command';
39
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
4-
import { KeybindingRegistry } from '@theia/core/lib/browser/keybinding';
510
import {
6-
ElectronMenuContribution as TheiaElectronMenuContribution,
711
ElectronCommands,
12+
ElectronMenuContribution as TheiaElectronMenuContribution,
813
} from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
9-
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/frontend-application';
1214
import { ZoomLevel } from '@theia/core/lib/electron-browser/window/electron-window-preferences';
13-
import { PreferenceScope } from '@theia/core/lib/browser/preferences/preference-scope';
14-
import {
15-
getCurrentWindow,
16-
getCurrentWebContents,
17-
} from '@theia/core/electron-shared/@electron/remote';
15+
import { injectable } from '@theia/core/shared/inversify';
16+
import { MainMenuManager } from '../../../common/main-menu-manager';
1817

1918
@injectable()
2019
export class ElectronMenuContribution
2120
extends TheiaElectronMenuContribution
2221
implements MainMenuManager
2322
{
24-
@inject(FrontendApplicationStateService)
25-
private readonly appStateService: FrontendApplicationStateService;
26-
27-
// private appReady = false;
28-
// private updateWhenReady = false;
23+
private app: FrontendApplication;
2924

3025
override onStart(app: FrontendApplication): void {
26+
this.app = app;
3127
super.onStart(app);
32-
this.appStateService.reachedState('ready').then(() => {
33-
// this.appReady = true;
34-
// if (this.updateWhenReady) {
35-
// this.update();
36-
// }
37-
});
38-
}
39-
40-
protected override hideTopPanel(): void {
41-
// NOOP
42-
// We reuse the `div` for the Arduino toolbar.
4328
}
4429

4530
update(): void {
46-
// if (this.appReady) {
47-
(this as any).setMenu();
48-
// } else {
49-
// this.updateWhenReady = true;
50-
// }
31+
// no menu updates before `onStart`
32+
if (!this.app) {
33+
return;
34+
}
35+
this.setMenu(this.app);
5136
}
5237

5338
override registerCommands(registry: CommandRegistry): void {

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

+35-6
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,13 @@ import {
1919
} from '@theia/core/lib/electron-main/electron-main-application';
2020
import { URI } from '@theia/core/shared/vscode-uri';
2121
import { Deferred } from '@theia/core/lib/common/promise-util';
22-
import * as os from '@theia/core/lib/common/os';
23-
import { Restart } from '@theia/core/lib/electron-common/messaging/electron-messages';
22+
import { isOSX } from '@theia/core/lib/common/os';
23+
import {
24+
RequestTitleBarStyle,
25+
Restart,
26+
TitleBarStyleAtStartup,
27+
TitleBarStyleChanged,
28+
} from '@theia/core/lib/electron-common/messaging/electron-messages';
2429
import { TheiaBrowserWindowOptions } from '@theia/core/lib/electron-main/theia-electron-window';
2530
import { IsTempSketch } from '../../node/is-temp-sketch';
2631
import {
@@ -176,7 +181,7 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
176181

177182
private attachFileAssociations(cwd: string): void {
178183
// OSX: register open-file event
179-
if (os.isOSX) {
184+
if (isOSX) {
180185
app.on('open-file', async (event, path) => {
181186
event.preventDefault();
182187
const resolvedPath = await this.resolvePath(path, cwd);
@@ -330,10 +335,19 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
330335
}
331336

332337
protected override getTitleBarStyle(
333-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
334-
_config: FrontendApplicationConfig
338+
config: FrontendApplicationConfig
335339
): 'native' | 'custom' {
336-
return 'native';
340+
const storedFrame = this.electronStore.get('windowstate')?.frame;
341+
if (storedFrame !== undefined) {
342+
return !!storedFrame ? 'native' : 'custom';
343+
}
344+
if (config.preferences && config.preferences['window.titleBarStyle']) {
345+
const titleBarStyle = config.preferences['window.titleBarStyle'];
346+
if (titleBarStyle === 'native' || titleBarStyle === 'custom') {
347+
return titleBarStyle;
348+
}
349+
}
350+
return 'custom';
337351
}
338352

339353
protected override hookApplicationEvents(): void {
@@ -351,6 +365,21 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
351365
this.delete(sketch);
352366
}
353367
});
368+
ipcMain.on(TitleBarStyleChanged, ({ sender }, titleBarStyle: string) => {
369+
this.useNativeWindowFrame = isOSX || titleBarStyle === 'native';
370+
const browserWindow = BrowserWindow.fromId(sender.id);
371+
if (browserWindow) {
372+
this.saveWindowState(browserWindow);
373+
} else {
374+
console.warn(`no BrowserWindow with id: ${sender.id}`);
375+
}
376+
});
377+
ipcMain.on(RequestTitleBarStyle, ({ sender }) => {
378+
sender.send(
379+
TitleBarStyleAtStartup,
380+
this.didUseNativeWindowFrameOnStart.get(sender.id) ? 'native' : 'custom'
381+
);
382+
});
354383
}
355384

356385
protected override async onSecondInstance(

0 commit comments

Comments
 (0)