mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-08 03:46:33 +00:00
fix: restored window.titleBarStyle
Ref: #1733 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
parent
d68bc4abdb
commit
9ffe421fab
@ -100,6 +100,19 @@
|
|||||||
background-color: var(--theia-titleBar-activeBackground);
|
background-color: var(--theia-titleBar-activeBackground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#arduino-toolbar-panel {
|
||||||
|
background: var(--theia-titleBar-activeBackground);
|
||||||
|
color: var(--theia-titleBar-activeForeground);
|
||||||
|
display: flex;
|
||||||
|
min-height: var(--theia-private-menubar-height);
|
||||||
|
border-bottom: 1px solid var(--theia-titleBar-border);
|
||||||
|
}
|
||||||
|
#arduino-toolbar-panel:window-inactive,
|
||||||
|
#arduino-toolbar-panel:-moz-window-inactive {
|
||||||
|
background: var(--theia-titleBar-inactiveBackground);
|
||||||
|
color: var(--theia-titleBar-inactiveForeground);
|
||||||
|
}
|
||||||
|
|
||||||
#arduino-toolbar-container {
|
#arduino-toolbar-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -7,6 +7,8 @@ import {
|
|||||||
SHELL_TABBAR_CONTEXT_MENU,
|
SHELL_TABBAR_CONTEXT_MENU,
|
||||||
TabBar,
|
TabBar,
|
||||||
Widget,
|
Widget,
|
||||||
|
Layout,
|
||||||
|
SplitPanel,
|
||||||
} from '@theia/core/lib/browser';
|
} from '@theia/core/lib/browser';
|
||||||
import {
|
import {
|
||||||
ConnectionStatus,
|
ConnectionStatus,
|
||||||
@ -17,6 +19,11 @@ import { MessageService } from '@theia/core/lib/common/message-service';
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||||
import { ToolbarAwareTabBar } from './tab-bars';
|
import { ToolbarAwareTabBar } from './tab-bars';
|
||||||
|
|
||||||
|
interface WidgetOptions
|
||||||
|
extends Omit<TheiaApplicationShell.WidgetOptions, 'area'> {
|
||||||
|
area?: TheiaApplicationShell.Area | 'toolbar';
|
||||||
|
}
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class ApplicationShell extends TheiaApplicationShell {
|
export class ApplicationShell extends TheiaApplicationShell {
|
||||||
@inject(MessageService)
|
@inject(MessageService)
|
||||||
@ -24,10 +31,11 @@ export class ApplicationShell extends TheiaApplicationShell {
|
|||||||
|
|
||||||
@inject(ConnectionStatusService)
|
@inject(ConnectionStatusService)
|
||||||
private readonly connectionStatusService: ConnectionStatusService;
|
private readonly connectionStatusService: ConnectionStatusService;
|
||||||
|
private toolbarPanel: Panel;
|
||||||
|
|
||||||
override async addWidget(
|
override async addWidget(
|
||||||
widget: Widget,
|
widget: Widget,
|
||||||
options: Readonly<TheiaApplicationShell.WidgetOptions> = {}
|
options: Readonly<WidgetOptions> = {}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// By default, Theia open a widget **next** to the currently active in the target area.
|
// By default, Theia open a widget **next** to the currently active in the target area.
|
||||||
// Instead of this logic, we want to open the new widget after the last of the target area.
|
// 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 {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (options.area === 'toolbar') {
|
||||||
|
this.toolbarPanel.addWidget(widget);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const area = options.area || 'main';
|
||||||
let ref: Widget | undefined = options.ref;
|
let ref: Widget | undefined = options.ref;
|
||||||
const area: TheiaApplicationShell.Area = options.area || 'main';
|
|
||||||
if (!ref && (area === 'main' || area === 'bottom')) {
|
if (!ref && (area === 'main' || area === 'bottom')) {
|
||||||
const tabBar = this.getTabBarFor(area);
|
const tabBar = this.getTabBarFor(area);
|
||||||
if (tabBar) {
|
if (tabBar) {
|
||||||
@ -48,7 +60,10 @@ export class ApplicationShell extends TheiaApplicationShell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return super.addWidget(widget, { ...options, ref });
|
return super.addWidget(widget, {
|
||||||
|
...(<TheiaApplicationShell.WidgetOptions>options),
|
||||||
|
ref,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override handleEvent(): boolean {
|
override handleEvent(): boolean {
|
||||||
@ -56,6 +71,46 @@ export class ApplicationShell extends TheiaApplicationShell {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override initializeShell(): void {
|
||||||
|
this.toolbarPanel = this.createToolbarPanel();
|
||||||
|
super.initializeShell();
|
||||||
|
}
|
||||||
|
|
||||||
|
private createToolbarPanel(): Panel {
|
||||||
|
const toolbarPanel = new Panel();
|
||||||
|
toolbarPanel.id = 'arduino-toolbar-panel';
|
||||||
|
toolbarPanel.show();
|
||||||
|
return toolbarPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override createLayout(): Layout {
|
||||||
|
const bottomSplitLayout = this.createSplitLayout(
|
||||||
|
[this.mainPanel, this.bottomPanel],
|
||||||
|
[1, 0],
|
||||||
|
{ orientation: 'vertical', spacing: 0 }
|
||||||
|
);
|
||||||
|
const panelForBottomArea = new SplitPanel({ layout: bottomSplitLayout });
|
||||||
|
panelForBottomArea.id = 'theia-bottom-split-panel';
|
||||||
|
|
||||||
|
const leftRightSplitLayout = this.createSplitLayout(
|
||||||
|
[
|
||||||
|
this.leftPanelHandler.container,
|
||||||
|
panelForBottomArea,
|
||||||
|
this.rightPanelHandler.container,
|
||||||
|
],
|
||||||
|
[0, 1, 0],
|
||||||
|
{ orientation: 'horizontal', spacing: 0 }
|
||||||
|
);
|
||||||
|
const panelForSideAreas = new SplitPanel({ layout: leftRightSplitLayout });
|
||||||
|
panelForSideAreas.id = 'theia-left-right-split-panel';
|
||||||
|
|
||||||
|
return this.createBoxLayout(
|
||||||
|
[this.topPanel, this.toolbarPanel, panelForSideAreas, this.statusBar],
|
||||||
|
[0, 0, 1, 0],
|
||||||
|
{ direction: 'top-to-bottom', spacing: 0 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid hiding top panel as we use it for arduino toolbar
|
// Avoid hiding top panel as we use it for arduino toolbar
|
||||||
protected override createTopPanel(): Panel {
|
protected override createTopPanel(): Panel {
|
||||||
const topPanel = super.createTopPanel();
|
const topPanel = super.createTopPanel();
|
||||||
|
@ -19,7 +19,8 @@ export class ArduinoToolbarContainer extends Widget {
|
|||||||
this.toolbars = toolbars;
|
this.toolbars = toolbars;
|
||||||
}
|
}
|
||||||
|
|
||||||
override onAfterAttach(msg: Message) {
|
override onAfterAttach(msg: Message): void {
|
||||||
|
super.onAfterAttach(msg);
|
||||||
for (const toolbar of this.toolbars) {
|
for (const toolbar of this.toolbars) {
|
||||||
Widget.attach(toolbar, this.node);
|
Widget.attach(toolbar, this.node);
|
||||||
}
|
}
|
||||||
@ -56,9 +57,11 @@ export class ArduinoToolbarContribution
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onStart(app: FrontendApplication) {
|
onStart(app: FrontendApplication): void {
|
||||||
app.shell.addWidget(this.arduinoToolbarContainer, {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
area: 'top',
|
const options = <any>{
|
||||||
});
|
area: 'toolbar',
|
||||||
|
};
|
||||||
|
app.shell.addWidget(this.arduinoToolbarContainer, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import {
|
|||||||
CommandMenuNode,
|
CommandMenuNode,
|
||||||
CompoundMenuNode,
|
CompoundMenuNode,
|
||||||
CompoundMenuNodeRole,
|
CompoundMenuNodeRole,
|
||||||
MAIN_MENU_BAR,
|
|
||||||
MenuNode,
|
MenuNode,
|
||||||
MenuPath,
|
MenuPath,
|
||||||
} from '@theia/core/lib/common/menu';
|
} from '@theia/core/lib/common/menu';
|
||||||
@ -39,18 +38,9 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override createElectronMenuBar(): Electron.Menu {
|
override createElectronMenuBar(): Electron.Menu | null {
|
||||||
this._toggledCommands.clear(); // https://github.com/eclipse-theia/theia/issues/8977
|
this._toggledCommands.clear(); // https://github.com/eclipse-theia/theia/issues/8977
|
||||||
const menuModel = this.menuProvider.getMenu(MAIN_MENU_BAR);
|
return super.createElectronMenuBar();
|
||||||
const template = this.fillMenuTemplate([], menuModel, [], {
|
|
||||||
rootMenuPath: MAIN_MENU_BAR,
|
|
||||||
});
|
|
||||||
if (isOSX) {
|
|
||||||
template.unshift(this.createOSXMenu());
|
|
||||||
}
|
|
||||||
const menu = remote.Menu.buildFromTemplate(this.escapeAmpersand(template));
|
|
||||||
this._menu = menu;
|
|
||||||
return menu;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override async setMenuBar(): Promise<void> {
|
override async setMenuBar(): Promise<void> {
|
||||||
@ -61,13 +51,7 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
|||||||
this.updateWhenReady = true;
|
this.updateWhenReady = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.preferencesService.ready;
|
return super.setMenuBar();
|
||||||
const createdMenuBar = this.createElectronMenuBar();
|
|
||||||
if (isOSX) {
|
|
||||||
remote.Menu.setApplicationMenu(createdMenuBar);
|
|
||||||
} else {
|
|
||||||
remote.getCurrentWindow().setMenu(createdMenuBar);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override createElectronContextMenu(
|
override createElectronContextMenu(
|
||||||
|
@ -1,53 +1,38 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import {
|
||||||
|
getCurrentWebContents,
|
||||||
|
getCurrentWindow,
|
||||||
|
} from '@theia/core/electron-shared/@electron/remote';
|
||||||
|
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
||||||
|
import { KeybindingRegistry } from '@theia/core/lib/browser/keybinding';
|
||||||
|
import { PreferenceScope } from '@theia/core/lib/browser/preferences/preference-scope';
|
||||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||||
import { KeybindingRegistry } from '@theia/core/lib/browser/keybinding';
|
|
||||||
import {
|
import {
|
||||||
ElectronMenuContribution as TheiaElectronMenuContribution,
|
|
||||||
ElectronCommands,
|
ElectronCommands,
|
||||||
|
ElectronMenuContribution as TheiaElectronMenuContribution,
|
||||||
} from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
|
} from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
|
||||||
import { MainMenuManager } from '../../../common/main-menu-manager';
|
|
||||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
|
||||||
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
|
||||||
import { ZoomLevel } from '@theia/core/lib/electron-browser/window/electron-window-preferences';
|
import { ZoomLevel } from '@theia/core/lib/electron-browser/window/electron-window-preferences';
|
||||||
import { PreferenceScope } from '@theia/core/lib/browser/preferences/preference-scope';
|
import { injectable } from '@theia/core/shared/inversify';
|
||||||
import {
|
import { MainMenuManager } from '../../../common/main-menu-manager';
|
||||||
getCurrentWindow,
|
|
||||||
getCurrentWebContents,
|
|
||||||
} from '@theia/core/electron-shared/@electron/remote';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class ElectronMenuContribution
|
export class ElectronMenuContribution
|
||||||
extends TheiaElectronMenuContribution
|
extends TheiaElectronMenuContribution
|
||||||
implements MainMenuManager
|
implements MainMenuManager
|
||||||
{
|
{
|
||||||
@inject(FrontendApplicationStateService)
|
private app: FrontendApplication;
|
||||||
private readonly appStateService: FrontendApplicationStateService;
|
|
||||||
|
|
||||||
// private appReady = false;
|
|
||||||
// private updateWhenReady = false;
|
|
||||||
|
|
||||||
override onStart(app: FrontendApplication): void {
|
override onStart(app: FrontendApplication): void {
|
||||||
|
this.app = app;
|
||||||
super.onStart(app);
|
super.onStart(app);
|
||||||
this.appStateService.reachedState('ready').then(() => {
|
|
||||||
// this.appReady = true;
|
|
||||||
// if (this.updateWhenReady) {
|
|
||||||
// this.update();
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override hideTopPanel(): void {
|
|
||||||
// NOOP
|
|
||||||
// We reuse the `div` for the Arduino toolbar.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update(): void {
|
update(): void {
|
||||||
// if (this.appReady) {
|
// no menu updates before `onStart`
|
||||||
(this as any).setMenu();
|
if (!this.app) {
|
||||||
// } else {
|
return;
|
||||||
// this.updateWhenReady = true;
|
}
|
||||||
// }
|
this.setMenu(this.app);
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
override registerCommands(registry: CommandRegistry): void {
|
||||||
|
@ -19,8 +19,13 @@ import {
|
|||||||
} from '@theia/core/lib/electron-main/electron-main-application';
|
} from '@theia/core/lib/electron-main/electron-main-application';
|
||||||
import { URI } from '@theia/core/shared/vscode-uri';
|
import { URI } from '@theia/core/shared/vscode-uri';
|
||||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||||
import * as os from '@theia/core/lib/common/os';
|
import { isOSX } from '@theia/core/lib/common/os';
|
||||||
import { Restart } from '@theia/core/lib/electron-common/messaging/electron-messages';
|
import {
|
||||||
|
RequestTitleBarStyle,
|
||||||
|
Restart,
|
||||||
|
TitleBarStyleAtStartup,
|
||||||
|
TitleBarStyleChanged,
|
||||||
|
} from '@theia/core/lib/electron-common/messaging/electron-messages';
|
||||||
import { TheiaBrowserWindowOptions } from '@theia/core/lib/electron-main/theia-electron-window';
|
import { TheiaBrowserWindowOptions } from '@theia/core/lib/electron-main/theia-electron-window';
|
||||||
import { IsTempSketch } from '../../node/is-temp-sketch';
|
import { IsTempSketch } from '../../node/is-temp-sketch';
|
||||||
import {
|
import {
|
||||||
@ -176,7 +181,7 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
|||||||
|
|
||||||
private attachFileAssociations(cwd: string): void {
|
private attachFileAssociations(cwd: string): void {
|
||||||
// OSX: register open-file event
|
// OSX: register open-file event
|
||||||
if (os.isOSX) {
|
if (isOSX) {
|
||||||
app.on('open-file', async (event, path) => {
|
app.on('open-file', async (event, path) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const resolvedPath = await this.resolvePath(path, cwd);
|
const resolvedPath = await this.resolvePath(path, cwd);
|
||||||
@ -330,10 +335,19 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override getTitleBarStyle(
|
protected override getTitleBarStyle(
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
config: FrontendApplicationConfig
|
||||||
_config: FrontendApplicationConfig
|
|
||||||
): 'native' | 'custom' {
|
): 'native' | 'custom' {
|
||||||
return 'native';
|
const storedFrame = this.electronStore.get('windowstate')?.frame;
|
||||||
|
if (storedFrame !== undefined) {
|
||||||
|
return !!storedFrame ? 'native' : 'custom';
|
||||||
|
}
|
||||||
|
if (config.preferences && config.preferences['window.titleBarStyle']) {
|
||||||
|
const titleBarStyle = config.preferences['window.titleBarStyle'];
|
||||||
|
if (titleBarStyle === 'native' || titleBarStyle === 'custom') {
|
||||||
|
return titleBarStyle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'custom';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override hookApplicationEvents(): void {
|
protected override hookApplicationEvents(): void {
|
||||||
@ -351,6 +365,21 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
|||||||
this.delete(sketch);
|
this.delete(sketch);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
ipcMain.on(TitleBarStyleChanged, ({ sender }, titleBarStyle: string) => {
|
||||||
|
this.useNativeWindowFrame = isOSX || titleBarStyle === 'native';
|
||||||
|
const browserWindow = BrowserWindow.fromId(sender.id);
|
||||||
|
if (browserWindow) {
|
||||||
|
this.saveWindowState(browserWindow);
|
||||||
|
} else {
|
||||||
|
console.warn(`no BrowserWindow with id: ${sender.id}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ipcMain.on(RequestTitleBarStyle, ({ sender }) => {
|
||||||
|
sender.send(
|
||||||
|
TitleBarStyleAtStartup,
|
||||||
|
this.didUseNativeWindowFrameOnStart.get(sender.id) ? 'native' : 'custom'
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async onSecondInstance(
|
protected override async onSecondInstance(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user