Skip to content

Commit

Permalink
Fix #9779: add support for window.menuBarVisibility
Browse files Browse the repository at this point in the history
Signed-off-by: Esther Perelman <[email protected]>
  • Loading branch information
EstherPerelman authored and ChayaLau committed Aug 11, 2021
1 parent dece352 commit aa33d1a
Show file tree
Hide file tree
Showing 16 changed files with 227 additions and 72 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
- [debug] `DebugSession` and `PluginDebugSession` constructors accept a `parentSession` of type `DebugSession | undefined` as their 3rd parameter, offsetting every subsequent parameter by one [#9613](https://github.com/eclipse-theia/theia/pull/9613)
- [monaco] upgraded to monaco 0.23.0 including replacement of `quickOpen` API (0.20.x) with `quickInput` API (0.23.x) [#9154](https://github.com/eclipse-theia/theia/pull/9154)
- [workspace] `WorkspaceCommandContribution.addFolderToWorkspace` no longer accepts `undefined`. `WorkspaceService.addRoot` now accepts a `URI` or a `URI[]` [#9684](https://github.com/eclipse-theia/theia/pull/9684)
-[core] `SidePanelHandler.addMenu` and `SidePanelHandler.removeMenu` no longer exists, instead added `addBottomMenu` and `addTopMenu` for adding menu, `removeTopMenu` and `removeBottomMenu` for removing menu.
`SidebarBottomMenu` interface is renamed `SidebarMenu` and handles not only bottom menu's.
`packages/core/src/browser/shell/sidebar-bottom-menu-widget.tsx` file is renamed `packages/core/src/browser/shell/sidebar-menu-widget.tsx`. `SidebarBottomMenuWidget` class is renamed `SidebarMenuWidget`. changed style class name from `theia-sidebar-bottom-menu` to `theia-sidebar-menu`
[#9830](https://github.com/eclipse-theia/theia/pull/9830)

## v1.15.0 - 6/30/2021

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class ElectronMenuUpdater {
this.setMenu();
}

private setMenu(menu: Menu = this.factory.createMenuBar(), electronWindow: BrowserWindow = remote.getCurrentWindow()): void {
private setMenu(menu: Menu | null = this.factory.createMenuBar(), electronWindow: BrowserWindow = remote.getCurrentWindow()): void {
if (isOSX) {
remote.Menu.setApplicationMenu(menu);
} else {
Expand Down
48 changes: 36 additions & 12 deletions packages/core/src/browser/common-frontend-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ import { environment } from '@theia/application-package/lib/environment';
import { IconThemeService } from './icon-theme-service';
import { ColorContribution } from './color-application-contribution';
import { ColorRegistry, Color } from './color-registry';
import { CorePreferences } from './core-preferences';
import { CoreConfiguration, CorePreferences } from './core-preferences';
import { ThemeService } from './theming';
import { PreferenceService, PreferenceScope } from './preferences';
import { PreferenceService, PreferenceScope, PreferenceChangeEvent } from './preferences';
import { ClipboardService } from './clipboard-service';
import { EncodingRegistry } from './encoding-registry';
import { UTF8 } from '../common/encodings';
Expand Down Expand Up @@ -353,17 +353,11 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
this.updateStyles();
this.updateThemeFromPreference('workbench.colorTheme');
this.updateThemeFromPreference('workbench.iconTheme');
this.preferences.onPreferenceChanged(e => {
if (e.preferenceName === 'workbench.editor.highlightModifiedTabs') {
this.updateStyles();
} else if (e.preferenceName === 'workbench.colorTheme' || e.preferenceName === 'workbench.iconTheme') {
this.updateThemeFromPreference(e.preferenceName);
}
});
this.preferences.onPreferenceChanged(e => this.handlePreferenceChange(e, app));
this.themeService.onDidColorThemeChange(() => this.updateThemePreference('workbench.colorTheme'));
this.iconThemes.onDidChangeCurrent(() => this.updateThemePreference('workbench.iconTheme'));

app.shell.leftPanelHandler.addMenu({
app.shell.leftPanelHandler.addBottomMenu({
id: 'settings-menu',
iconClass: 'codicon codicon-settings-gear',
title: 'Settings',
Expand All @@ -378,11 +372,11 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
order: 1,
};
this.authenticationService.onDidRegisterAuthenticationProvider(() => {
app.shell.leftPanelHandler.addMenu(accountsMenu);
app.shell.leftPanelHandler.addBottomMenu(accountsMenu);
});
this.authenticationService.onDidUnregisterAuthenticationProvider(() => {
if (this.authenticationService.getProviderIds().length === 0) {
app.shell.leftPanelHandler.removeMenu(accountsMenu.id);
app.shell.leftPanelHandler.removeBottomMenu(accountsMenu.id);
}
});
}
Expand Down Expand Up @@ -420,6 +414,36 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
}
}

protected handlePreferenceChange(e: PreferenceChangeEvent<CoreConfiguration>, app: FrontendApplication): void {
switch (e.preferenceName) {
case 'workbench.editor.highlightModifiedTabs': {
this.updateStyles();
break;
}
case 'workbench.colorTheme':
case 'workbench.iconTheme': {
this.updateThemeFromPreference(e.preferenceName);
break;
}
case 'window.menuBarVisibility': {
const { newValue } = e;
const mainMenuId = 'main-menu';
if (newValue === 'compact') {
app.shell.leftPanelHandler.addTopMenu({
id: mainMenuId,
iconClass: 'codicon codicon-menu',
title: 'Application Menu',
menuPath: ['menubar'],
order: 0,
});
} else {
app.shell.leftPanelHandler.removeTopMenu(mainMenuId);
}
break;
}
}
}

onStart(): void {
this.storageService.getData<{ recent: Command[] }>(RECENT_COMMANDS_STORAGE_KEY, { recent: [] })
.then(tasks => this.commandRegistry.recent = tasks.recent);
Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/browser/core-preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { interfaces } from 'inversify';
import { createPreferenceProxy, PreferenceProxy, PreferenceService, PreferenceContribution, PreferenceSchema } from './preferences';
import { SUPPORTED_ENCODINGS } from './supported-encodings';
import { FrontendApplicationConfigProvider } from './frontend-application-config-provider';
import { isOSX } from '../common/os';

export const corePreferenceSchema: PreferenceSchema = {
'type': 'object',
Expand Down Expand Up @@ -97,6 +98,21 @@ export const corePreferenceSchema: PreferenceSchema = {
default: 'code',
description: 'Whether to interpret keypresses by the `code` of the physical key, or by the `keyCode` provided by the OS.'
},
'window.menuBarVisibility': {
type: 'string',
enum: ['classic', 'visible', 'hidden', 'compact'],
markdownEnumDescriptions: [
'Menu is displayed at the top of the window and only hidden in full screen mode.',
'Menu is always visible at the top of the window even in full screen mode.',
'Menu is always hidden.',
'Menu is displayed as a compact button in the sidebar.'
],
default: 'classic',
scope: 'application',
markdownDescription: `Control the visibility of the menu bar.
A setting of 'compact' will move the menu into the sidebar.`,
included: !isOSX
},
}
};

Expand All @@ -112,6 +128,7 @@ export interface CoreConfiguration {
'workbench.silentNotifications': boolean;
'files.encoding': string
'workbench.tree.renderIndentGuides': 'onHover' | 'none' | 'always';
'window.menuBarVisibility': 'classic' | 'visible' | 'hidden' | 'compact';
}

export const CorePreferences = Symbol('CorePreferences');
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/browser/frontend-application-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import {
ApplicationShell, ApplicationShellOptions, DockPanelRenderer, TabBarRenderer,
TabBarRendererFactory, ShellLayoutRestorer,
SidePanelHandler, SidePanelHandlerFactory,
SidebarBottomMenuWidget, SidebarBottomMenuWidgetFactory,
SidebarMenuWidget, SidebarMenuWidgetFactory,
SplitPositionHandler, DockPanelRendererFactory, ApplicationShellLayoutMigration, ApplicationShellLayoutMigrationError
} from './shell';
import { StatusBar, StatusBarImpl } from './status-bar/status-bar';
Expand Down Expand Up @@ -131,8 +131,8 @@ export const frontendApplicationModule = new ContainerModule((bind, unbind, isBo
bind(ApplicationShell).toSelf().inSingletonScope();
bind(SidePanelHandlerFactory).toAutoFactory(SidePanelHandler);
bind(SidePanelHandler).toSelf();
bind(SidebarBottomMenuWidgetFactory).toAutoFactory(SidebarBottomMenuWidget);
bind(SidebarBottomMenuWidget).toSelf();
bind(SidebarMenuWidgetFactory).toAutoFactory(SidebarMenuWidget);
bind(SidebarMenuWidget).toSelf();
bind(SplitPositionHandler).toSelf().inSingletonScope();

bindContributionProvider(bind, TabBarToolbarContribution);
Expand Down
30 changes: 25 additions & 5 deletions packages/core/src/browser/menu/browser-menu-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { ContextKeyService } from '../context-key-service';
import { ContextMenuContext } from './context-menu-context';
import { waitForRevealed } from '../widgets';
import { ApplicationShell } from '../shell';
import { CorePreferences } from '../core-preferences';

export abstract class MenuBarWidget extends MenuBar {
abstract activateMenu(label: string, ...labels: string[]): Promise<MenuWidget>;
Expand All @@ -45,6 +46,9 @@ export class BrowserMainMenuFactory implements MenuWidgetFactory {
@inject(CommandRegistry)
protected readonly commandRegistry: CommandRegistry;

@inject(CorePreferences)
protected readonly corePreferences: CorePreferences;

@inject(KeybindingRegistry)
protected readonly keybindingRegistry: KeybindingRegistry;

Expand All @@ -54,15 +58,31 @@ export class BrowserMainMenuFactory implements MenuWidgetFactory {
createMenuBar(): MenuBarWidget {
const menuBar = new DynamicMenuBarWidget();
menuBar.id = 'theia:menubar';
this.fillMenuBar(menuBar);
const listener = this.keybindingRegistry.onKeybindingsChanged(() => {
menuBar.clearMenus();
this.fillMenuBar(menuBar);
const preferenceListener = this.corePreferences.onPreferenceChanged(preference => {
if (preference.preferenceName === 'window.menuBarVisibility') {
this.showMenuBar(menuBar, preference.newValue);
}
});
const keybindingListener = this.keybindingRegistry.onKeybindingsChanged(() => {
const preference = this.corePreferences['window.menuBarVisibility'];
this.showMenuBar(menuBar, preference);
});
menuBar.disposed.connect(() => {
preferenceListener.dispose();
keybindingListener.dispose();
});
menuBar.disposed.connect(() => listener.dispose());
return menuBar;
}

protected showMenuBar(menuBar: DynamicMenuBarWidget, preference: string | undefined): void {
if (preference && ['classic', 'visible'].includes(preference)) {
menuBar.clearMenus();
this.fillMenuBar(menuBar);
} else {
menuBar.clearMenus();
}
}

protected fillMenuBar(menuBar: MenuBarWidget): void {
const menuModel = this.menuProvider.getMenu(MAIN_MENU_BAR);
const menuCommandRegistry = this.createMenuCommandRegistry(menuModel);
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/browser/shell/application-shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { TabBarToolbarRegistry, TabBarToolbarFactory, TabBarToolbar } from './ta
import { ContextKeyService } from '../context-key-service';
import { Emitter } from '../../common/event';
import { waitForRevealed, waitForClosed } from '../widgets';
import { CorePreferences } from '../core-preferences';

/** The class name added to ApplicationShell instances. */
const APPLICATION_SHELL_CLASS = 'theia-ApplicationShell';
Expand Down Expand Up @@ -204,7 +205,8 @@ export class ApplicationShell extends Widget {
@inject(SidePanelHandlerFactory) sidePanelHandlerFactory: () => SidePanelHandler,
@inject(SplitPositionHandler) protected splitPositionHandler: SplitPositionHandler,
@inject(FrontendApplicationStateService) protected readonly applicationStateService: FrontendApplicationStateService,
@inject(ApplicationShellOptions) @optional() options: RecursivePartial<ApplicationShell.Options> = {}
@inject(ApplicationShellOptions) @optional() options: RecursivePartial<ApplicationShell.Options> = {},
@inject(CorePreferences) protected readonly corePreferences: CorePreferences
) {
super(options as Widget.IOptions);
this.addClass(APPLICATION_SHELL_CLASS);
Expand Down Expand Up @@ -448,7 +450,7 @@ export class ApplicationShell extends Widget {
mode: 'multiple-document',
renderer,
spacing: 0
});
}, this.corePreferences);
dockPanel.id = MAIN_AREA_ID;
dockPanel.widgetAdded.connect((_, widget) => this.fireDidAddWidget(widget));
dockPanel.widgetRemoved.connect((_, widget) => this.fireDidRemoveWidget(widget));
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/browser/shell/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
export * from './application-shell';
export * from './shell-layout-restorer';
export * from './side-panel-handler';
export * from './sidebar-bottom-menu-widget';
export * from './sidebar-menu-widget';
export * from './split-panels';
export * from './tab-bars';
export * from './view-contribution';
44 changes: 35 additions & 9 deletions packages/core/src/browser/shell/side-panel-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { MimeData } from '@phosphor/coreutils';
import { Drag } from '@phosphor/dragdrop';
import { AttachedProperty } from '@phosphor/properties';
import { TabBarRendererFactory, TabBarRenderer, SHELL_TABBAR_CONTEXT_MENU, SideTabBar } from './tab-bars';
import { SidebarBottomMenuWidget, SidebarBottomMenuWidgetFactory, SidebarBottomMenu } from './sidebar-bottom-menu-widget';
import { SidebarMenuWidget, SidebarMenuWidgetFactory, SidebarMenu } from './sidebar-menu-widget';
import { SplitPositionHandler, SplitPositionOptions } from './split-panels';
import { animationFrame } from '../browser';
import { FrontendApplicationStateService } from '../frontend-application-state';
Expand Down Expand Up @@ -65,12 +65,18 @@ export class SidePanelHandler {
* tab bar itself remains visible as long as there is at least one widget.
*/
tabBar: SideTabBar;
/**
* The menu placed on the sidebar top.
* Displayed as icons.
* Open menus when on clicks.
*/
topMenu: SidebarMenuWidget;
/**
* The menu placed on the sidebar bottom.
* Displayed as icons.
* Open menus when on clicks.
*/
bottomMenu: SidebarBottomMenuWidget;
bottomMenu: SidebarMenuWidget;
/**
* A tool bar, which displays a title and widget specific command buttons.
*/
Expand Down Expand Up @@ -107,7 +113,7 @@ export class SidePanelHandler {
@inject(TabBarToolbarRegistry) protected tabBarToolBarRegistry: TabBarToolbarRegistry;
@inject(TabBarToolbarFactory) protected tabBarToolBarFactory: () => TabBarToolbar;
@inject(TabBarRendererFactory) protected tabBarRendererFactory: () => TabBarRenderer;
@inject(SidebarBottomMenuWidgetFactory) protected sidebarBottomWidgetFactory: () => SidebarBottomMenuWidget;
@inject(SidebarMenuWidgetFactory) protected sidebarWidgetFactory: () => SidebarMenuWidget;
@inject(SplitPositionHandler) protected splitPositionHandler: SplitPositionHandler;
@inject(FrontendApplicationStateService) protected readonly applicationStateService: FrontendApplicationStateService;

Expand All @@ -120,8 +126,9 @@ export class SidePanelHandler {
create(side: 'left' | 'right', options: SidePanel.Options): void {
this.side = side;
this.options = options;
this.topMenu = this.createSidebarMenu();
this.tabBar = this.createSideBar();
this.bottomMenu = this.createSidebarBottomMenu();
this.bottomMenu = this.createSidebarMenu();
this.toolBar = this.createToolbar();
this.dockPanel = this.createSidePanel();
this.container = this.createContainer();
Expand Down Expand Up @@ -187,9 +194,9 @@ export class SidePanelHandler {
return toolbar;
}

protected createSidebarBottomMenu(): SidebarBottomMenuWidget {
const bottomMenu = this.sidebarBottomWidgetFactory();
bottomMenu.addClass('theia-sidebar-bottom-menu');
protected createSidebarMenu(): SidebarMenuWidget {
const bottomMenu = this.sidebarWidgetFactory();
bottomMenu.addClass('theia-sidebar-menu');
return bottomMenu;
}

Expand Down Expand Up @@ -232,6 +239,7 @@ export class SidePanelHandler {
const sidebarContainerLayout = new PanelLayout();
const sidebarContainer = new Panel({ layout: sidebarContainerLayout });
sidebarContainer.addClass('theia-app-sidebar-container');
sidebarContainerLayout.addWidget(this.topMenu);
sidebarContainerLayout.addWidget(this.tabBar);
sidebarContainerLayout.addWidget(this.bottomMenu);

Expand Down Expand Up @@ -385,12 +393,30 @@ export class SidePanelHandler {
this.dockPanel.addWidget(widget);
}

/**
* Add a menu to the sidebar top.
*
* If the menu is already added, it will be ignored.
*/
addTopMenu(menu: SidebarMenu): void {
this.topMenu.addMenu(menu);
}

/**
* Remove a menu from the sidebar top.
*
* @param menuId id of the menu to remove
*/
removeTopMenu(menuId: string): void {
this.topMenu.removeMenu(menuId);
}

/**
* Add a menu to the sidebar bottom.
*
* If the menu is already added, it will be ignored.
*/
addMenu(menu: SidebarBottomMenu): void {
addBottomMenu(menu: SidebarMenu): void {
this.bottomMenu.addMenu(menu);
}

Expand All @@ -399,7 +425,7 @@ export class SidePanelHandler {
*
* @param menuId id of the menu to remove
*/
removeMenu(menuId: string): void {
removeBottomMenu(menuId: string): void {
this.bottomMenu.removeMenu(menuId);
}

Expand Down
Loading

0 comments on commit aa33d1a

Please sign in to comment.