Skip to content

Commit

Permalink
show custom title bar on macos
Browse files Browse the repository at this point in the history
Signed-off-by: Akos Kitta <[email protected]>
  • Loading branch information
Akos Kitta committed Feb 9, 2023
1 parent 479628b commit afbe887
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ import { RenameCloudSketch } from './contributions/rename-cloud-sketch';
import { CreateFeatures } from './create/create-features';
import { NativeImageCache } from './native-image-cache';
import { rebindWindowPreferences } from '../electron-browser/theia/core/electron-window-preferences';
import { rebindCorePreferences } from './theia/core/core-preferences';

export default new ContainerModule((bind, unbind, isBound, rebind) => {
// Commands and toolbar items
Expand Down Expand Up @@ -1022,4 +1023,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(FrontendApplicationContribution).toService(NativeImageCache);
// enable `'window.titleBarStyle'` on all supported OSs
rebindWindowPreferences(bind, rebind);
// enable `'window.menuBarVisibility'` on all supported OSs
rebindCorePreferences(bind, rebind);
});
34 changes: 34 additions & 0 deletions arduino-ide-extension/src/browser/theia/core/core-preferences.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
CorePreferenceContribution,
CorePreferences,
corePreferenceSchema,
createCorePreferences,
} from '@theia/core/lib/browser/core-preferences';
import { PreferenceContribution } from '@theia/core/lib/browser/preferences/preference-contribution';
import { PreferenceService } from '@theia/core/lib/browser/preferences/preference-service';
import { deepClone } from '@theia/core/lib/common/objects';
import { PreferenceSchema } from '@theia/core/lib/common/preferences/preference-schema';
import { interfaces } from '@theia/core/shared/inversify';

const copy = deepClone(corePreferenceSchema);
copy.properties['window.menuBarVisibility'].included = true; // https://github.com/arduino/arduino-ide/issues/1733#issuecomment-1424186676
const corePreferencesSchema: PreferenceSchema = copy;

export function rebindCorePreferences(
bind: interfaces.Bind,
rebind: interfaces.Rebind
): void {
rebind(CorePreferences)
.toDynamicValue((ctx) => {
const preferences =
ctx.container.get<PreferenceService>(PreferenceService);
const contribution = ctx.container.get<PreferenceContribution>(
CorePreferenceContribution
);
return createCorePreferences(preferences, contribution.schema);
})
.inSingletonScope();
rebind(CorePreferenceContribution).toConstantValue({
schema: corePreferencesSchema,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ export class ArduinoToolbarContribution
}

onStart(app: FrontendApplication) {
app.shell.addWidget(this.arduinoToolbarContainer, {
area: 'top',
});
// app.shell.addWidget(this.arduinoToolbarContainer, {
// area: 'top',
// });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
CommandMenuNode,
CompoundMenuNode,
CompoundMenuNodeRole,
MAIN_MENU_BAR,
MenuNode,
MenuPath,
} from '@theia/core/lib/common/menu';
Expand All @@ -28,7 +27,7 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
@inject(FrontendApplicationStateService)
private readonly appStateService: FrontendApplicationStateService;

private appReady = false;
appReady = false;
private updateWhenReady = false;

override postConstruct(): void {
Expand All @@ -41,18 +40,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
const menuModel = this.menuProvider.getMenu(MAIN_MENU_BAR);
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;
return super.createElectronMenuBar();
}

override async setMenuBar(): Promise<void> {
Expand All @@ -63,13 +53,7 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
this.updateWhenReady = true;
return;
}
await this.preferencesService.ready;
const createdMenuBar = this.createElectronMenuBar();
if (isOSX) {
remote.Menu.setApplicationMenu(createdMenuBar);
} else {
remote.getCurrentWindow().setMenu(createdMenuBar);
}
return super.setMenuBar();
}

override createElectronContextMenu(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import { injectable } from '@theia/core/shared/inversify';
import {
getCurrentWebContents,
getCurrentWindow,
Menu,
} from '@theia/core/electron-shared/@electron/remote';
import {
BrowserWindow,
Menu as ElectronMenu,
} from '@theia/core/electron-shared/electron';
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 { MenuModelRegistry } from '@theia/core/lib/common/menu';
import { KeybindingRegistry } from '@theia/core/lib/browser/keybinding';
import { isOSX } from '@theia/core/lib/common/os';
import {
ElectronMenuContribution as TheiaElectronMenuContribution,
ElectronCommands,
ElectronMenuContribution as TheiaElectronMenuContribution,
} from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
import { MainMenuManager } from '../../../common/main-menu-manager';
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
import { ZoomLevel } from '@theia/core/lib/electron-browser/window/electron-window-preferences';
import { PreferenceScope } from '@theia/core/lib/browser/preferences/preference-scope';
import {
getCurrentWindow,
getCurrentWebContents,
} from '@theia/core/electron-shared/@electron/remote';
import { injectable } from '@theia/core/shared/inversify';
import { MainMenuManager } from '../../../common/main-menu-manager';

@injectable()
export class ElectronMenuContribution
Expand All @@ -27,14 +33,28 @@ export class ElectronMenuContribution
super.onStart(app);
}

protected override hideTopPanel(): void {
// NOOP
// IDE2 reuses the `div` for the toolbar.
update(): void {
// no menu updates before `onStart`
if (!this.app) {
return;
}
this.setMenu(this.app);
}

update(): void {
if (this.app) {
this.setMenu(this.app);
protected override setMenu(
app: FrontendApplication,
electronMenu: ElectronMenu | null = this.factory.createElectronMenuBar(),
electronWindow: BrowserWindow = getCurrentWindow()
): void {
this.hideTopPanel(app); // Updates the top panel's visibility on all operating systems.
if (this.titleBarStyle === 'custom' && !this.menuBar) {
this.createCustomTitleBar(app, electronWindow);
}
if (isOSX) {
Menu.setApplicationMenu(electronMenu);
} else {
// Unix/Windows: Set the per-window menus
electronWindow.setMenu(electronMenu);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { interfaces } from '@theia/core/shared/inversify';

const copy = deepClone(theiaElectronWindowPreferencesSchema);
copy.properties['window.titleBarStyle'].included = true; // https://github.com/eclipse-theia/theia/pull/10044#issuecomment-1423841453
copy.properties['window.titleBarStyle'].default = 'custom';
const electronWindowPreferencesSchema: PreferenceSchema = copy;

export function rebindWindowPreferences(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ import {
import { URI } from '@theia/core/shared/vscode-uri';
import { Deferred } from '@theia/core/lib/common/promise-util';
import * as os 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 { IsTempSketch } from '../../node/is-temp-sketch';
import {
Expand Down Expand Up @@ -330,10 +335,19 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
}

protected override getTitleBarStyle(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_config: FrontendApplicationConfig
config: FrontendApplicationConfig
): '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 {
Expand All @@ -351,6 +365,21 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
this.delete(sketch);
}
});
ipcMain.on(TitleBarStyleChanged, ({ sender }, titleBarStyle: string) => {
this.useNativeWindowFrame = titleBarStyle === 'native'; // XXX: No `isOSX || ` check
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(
Expand Down

0 comments on commit afbe887

Please sign in to comment.