提交 fb7991a3 编写于 作者: B Benjamin Pasero

debt - bring back macOS custom title menu

上级 afde7913
......@@ -93,6 +93,7 @@ export const enum MenuId {
SearchContext,
StatusBarWindowIndicatorMenu,
TouchBarContext,
TitleBarContext,
ViewItemContext,
ViewTitle,
CommentThreadTitle,
......
......@@ -4,18 +4,17 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/titlebarpart';
import { dirname, posix } from 'vs/base/common/path';
import * as resources from 'vs/base/common/resources';
import { Part } from 'vs/workbench/browser/part';
import { ITitleService, ITitleProperties } from 'vs/workbench/services/title/common/titleService';
import { getZoomFactor } from 'vs/base/browser/browser';
import { IWindowService, IWindowsService, MenuBarVisibility, getTitleBarStyle } from 'vs/platform/windows/common/windows';
import { IWindowService, MenuBarVisibility, getTitleBarStyle } from 'vs/platform/windows/common/windows';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IAction, Action } from 'vs/base/common/actions';
import { IAction } from 'vs/base/common/actions';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { DisposableStore, dispose } from 'vs/base/common/lifecycle';
import * as nls from 'vs/nls';
import { EditorInput, toResource, Verbosity, SideBySideEditor } from 'vs/workbench/common/editor';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
......@@ -29,7 +28,7 @@ import { trim } from 'vs/base/common/strings';
import { EventType, EventHelper, Dimension, isAncestor, hide, show, removeClass, addClass, append, $, addDisposableListener, runAtThisOrScheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { CustomMenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { template, getBaseLabel } from 'vs/base/common/labels';
import { template } from 'vs/base/common/labels';
import { ILabelService } from 'vs/platform/label/common/label';
import { Event, Emitter } from 'vs/base/common/event';
import { IStorageService } from 'vs/platform/storage/common/storage';
......@@ -37,6 +36,9 @@ import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/bro
import { RunOnceScheduler } from 'vs/base/common/async';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { Schemas } from 'vs/base/common/network';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuService, IMenu, MenuId } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
export class TitlebarPart extends Part implements ITitleService {
......@@ -71,7 +73,6 @@ export class TitlebarPart extends Part implements ITitleService {
private lastLayoutDimensions: Dimension;
private pendingTitle: string;
private representedFileName: string;
private isInactive: boolean;
......@@ -80,11 +81,12 @@ export class TitlebarPart extends Part implements ITitleService {
private titleUpdater: RunOnceScheduler = this._register(new RunOnceScheduler(() => this.doUpdateTitle(), 0));
private contextMenu: IMenu;
constructor(
@IContextMenuService private readonly contextMenuService: IContextMenuService,
@IWindowService private readonly windowService: IWindowService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IWindowsService private readonly windowsService: IWindowsService,
@IEditorService private readonly editorService: IEditorService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
......@@ -92,10 +94,14 @@ export class TitlebarPart extends Part implements ITitleService {
@IThemeService themeService: IThemeService,
@ILabelService private readonly labelService: ILabelService,
@IStorageService storageService: IStorageService,
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@IMenuService menuService: IMenuService,
@IContextKeyService contextKeyService: IContextKeyService
) {
super(Parts.TITLEBAR_PART, { hasTitle: false }, themeService, storageService, layoutService);
this.contextMenu = this._register(menuService.createMenu(MenuId.TitleBarContext, contextKeyService));
this.registerListeners();
}
......@@ -181,9 +187,6 @@ export class TitlebarPart extends Part implements ITitleService {
// Apply to window
this.windowService.setRepresentedFilename(path);
// Keep for context menu
this.representedFileName = path;
}
private doUpdateTitle(): void {
......@@ -502,44 +505,16 @@ export class TitlebarPart extends Part implements ITitleService {
const event = new StandardMouseEvent(e);
const anchor = { x: event.posx, y: event.posy };
// Show menu
const actions = this.getContextMenuActions();
if (actions.length) {
this.contextMenuService.showContextMenu({
getAnchor: () => anchor,
getActions: () => actions,
onHide: () => actions.forEach(a => a.dispose())
});
}
}
private getContextMenuActions(): IAction[] {
// Fill in contributed actions
const actions: IAction[] = [];
const actionsDisposable = createAndFillInContextMenuActions(this.contextMenu, undefined, actions, this.contextMenuService);
if (this.representedFileName) {
const segments = this.representedFileName.split(posix.sep);
for (let i = segments.length; i > 0; i--) {
const isFile = (i === segments.length);
let pathOffset = i;
if (!isFile) {
pathOffset++; // for segments which are not the file name we want to open the folder
}
const path = segments.slice(0, pathOffset).join(posix.sep);
let label: string;
if (!isFile) {
label = getBaseLabel(dirname(path));
} else {
label = getBaseLabel(path);
}
actions.push(new ShowItemInFolderAction(path, label || posix.sep, this.windowsService));
}
}
return actions;
// Show it
this.contextMenuService.showContextMenu({
getAnchor: () => anchor,
getActions: () => actions,
onHide: () => dispose(actionsDisposable)
});
}
private adjustTitleMarginToCenter(): void {
......@@ -604,19 +579,6 @@ export class TitlebarPart extends Part implements ITitleService {
}
}
class ShowItemInFolderAction extends Action {
constructor(private path: string, label: string, private windowsService: IWindowsService) {
super('showItemInFolder.action.id', label);
}
run(): Promise<void> {
if (this.path && this.windowsService) { }
return Promise.resolve();
// return this.windowsService.showItemInFolder(URI.file(this.path));
}
}
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
const titlebarActiveFg = theme.getColor(TITLE_BAR_ACTIVE_FOREGROUND);
if (titlebarActiveFg) {
......
......@@ -19,12 +19,12 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { ITitleService } from 'vs/workbench/services/title/common/titleService';
import { IWorkbenchThemeService, VS_HC_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService';
import * as browser from 'vs/base/browser/browser';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands';
import { IResourceInput } from 'vs/platform/editor/common/editor';
import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/nativeKeymapService';
import { ipcRenderer as ipc, webFrame, crashReporter, Event } from 'electron';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { IMenuService, MenuId, IMenu, MenuItemAction, ICommandAction, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { IMenuService, MenuId, IMenu, MenuItemAction, ICommandAction, SubmenuItemAction, MenuRegistry } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { RunOnceScheduler } from 'vs/base/common/async';
......@@ -56,6 +56,8 @@ import { withNullAsUndefined } from 'vs/base/common/types';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { Schemas } from 'vs/base/common/network';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { posix, dirname } from 'vs/base/common/path';
import { getBaseLabel } from 'vs/base/common/labels';
const TextInputActions: IAction[] = [
new Action('undo', nls.localize('undo', "Undo"), undefined, true, () => Promise.resolve(document.execCommand('undo'))),
......@@ -74,6 +76,8 @@ export class ElectronWindow extends Disposable {
private readonly touchBarDisposables = this._register(new DisposableStore());
private lastInstalledTouchedBar: ICommandAction[][] | undefined;
private customTitleContextMenuDisposable = this._register(new DisposableStore());
private previousConfiguredZoomLevel: number | undefined;
private addFoldersScheduler: RunOnceScheduler;
......@@ -245,6 +249,11 @@ export class ElectronWindow extends Disposable {
this._register(this.trackClosedWaitFiles(waitMarkerFile, resourcesToWaitFor));
}
// macOS custom title menu
if (isMacintosh) {
this._register(this.editorService.onDidActiveEditorChange(() => this.provideCustomTitleContextMenu()));
}
}
private onDidVisibleEditorsChange(): void {
......@@ -308,6 +317,43 @@ export class ElectronWindow extends Disposable {
}
}
private provideCustomTitleContextMenu(): void {
// Clear old menu
this.customTitleContextMenuDisposable.clear();
// Provide new menu if a file is opened and we are on a custom title
const fileResource = toResource(this.editorService.activeEditor, { supportSideBySide: SideBySideEditor.MASTER, filterByScheme: Schemas.file });
if (!fileResource || getTitleBarStyle(this.configurationService, this.environmentService) !== 'custom') {
return;
}
// Split up filepath into segments
const filePath = fileResource.fsPath;
const segments = filePath.split(posix.sep);
for (let i = segments.length; i > 0; i--) {
const isFile = (i === segments.length);
let pathOffset = i;
if (!isFile) {
pathOffset++; // for segments which are not the file name we want to open the folder
}
const path = segments.slice(0, pathOffset).join(posix.sep);
let label: string;
if (!isFile) {
label = getBaseLabel(dirname(path));
} else {
label = getBaseLabel(path);
}
const commandId = `workbench.action.revealPathInFinder${i}`;
this.customTitleContextMenuDisposable.add(CommandsRegistry.registerCommand(commandId, () => this.electronService.showItemInFolder(path)));
this.customTitleContextMenuDisposable.add(MenuRegistry.appendMenuItem(MenuId.TitleBarContext, { command: { id: commandId, title: label || posix.sep }, order: -i }));
}
}
private create(): void {
// Native menu controller
......
......@@ -14,6 +14,7 @@ export interface ITitleProperties {
}
export interface ITitleService {
_serviceBrand: undefined;
/**
......@@ -25,4 +26,4 @@ export interface ITitleService {
* Update some environmental title properties.
*/
updateProperties(properties: ITitleProperties): void;
}
\ No newline at end of file
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册