diff --git a/src/vs/base/browser/ui/dropdown/dropdown.ts b/src/vs/base/browser/ui/dropdown/dropdown.ts index b04f5355e9f..62e7849db09 100644 --- a/src/vs/base/browser/ui/dropdown/dropdown.ts +++ b/src/vs/base/browser/ui/dropdown/dropdown.ts @@ -246,8 +246,8 @@ export class DropdownMenu extends BaseDropdown { getAnchor: () => this.element, getActions: () => TPromise.as(this.actions), getActionsContext: () => this.menuOptions ? this.menuOptions.context : null, - getActionItem: (action) => this.menuOptions && this.menuOptions.actionItemProvider ? this.menuOptions.actionItemProvider(action) : null, - getKeyBinding: (action: IAction) => this.menuOptions && this.menuOptions.getKeyBinding ? this.menuOptions.getKeyBinding(action) : null, + getActionItem: action => this.menuOptions && this.menuOptions.actionItemProvider ? this.menuOptions.actionItemProvider(action) : null, + getKeyBinding: action => this.menuOptions && this.menuOptions.getKeyBinding ? this.menuOptions.getKeyBinding(action) : null, getMenuClassName: () => this.menuClassName, onHide: () => this.onHide(), actionRunner: this.menuOptions ? this.menuOptions.actionRunner : null diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index c6ca31a3c08..1893f450847 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -184,11 +184,11 @@ export class DynamicStandaloneServices extends Disposable { let commandService = ensure(ICommandService, () => new StandaloneCommandService(this._instantiationService)); - ensure(IKeybindingService, () => this._register(new StandaloneKeybindingService(contextKeyService, commandService, telemetryService, notificationService, domElement))); + let keybindingService = ensure(IKeybindingService, () => this._register(new StandaloneKeybindingService(contextKeyService, commandService, telemetryService, notificationService, domElement))); let contextViewService = ensure(IContextViewService, () => this._register(new ContextViewService(domElement, telemetryService, new NullLogService()))); - ensure(IContextMenuService, () => this._register(new ContextMenuService(domElement, telemetryService, notificationService, contextViewService))); + ensure(IContextMenuService, () => this._register(new ContextMenuService(domElement, telemetryService, notificationService, contextViewService, keybindingService))); ensure(IMenuService, () => new SimpleMenuService(commandService)); diff --git a/src/vs/platform/contextview/browser/contextMenuHandler.ts b/src/vs/platform/contextview/browser/contextMenuHandler.ts index 0ae68867b5c..e85bc404deb 100644 --- a/src/vs/platform/contextview/browser/contextMenuHandler.ts +++ b/src/vs/platform/contextview/browser/contextMenuHandler.ts @@ -6,6 +6,7 @@ 'use strict'; import 'vs/css!./contextMenuHandler'; + import { combinedDisposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { ActionRunner, IAction, IRunEvent } from 'vs/base/common/actions'; @@ -15,41 +16,38 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IContextMenuDelegate } from 'vs/base/browser/contextmenu'; -import { addDisposableListener } from 'vs/base/browser/dom'; +import { addDisposableListener, EventType } from 'vs/base/browser/dom'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; export class ContextMenuHandler { - - private contextViewService: IContextViewService; - private notificationService: INotificationService; - private telemetryService: ITelemetryService; - private element: HTMLElement; private elementDisposable: IDisposable; private menuContainerElement: HTMLElement; private focusToReturn: HTMLElement; - constructor(element: HTMLElement, contextViewService: IContextViewService, telemetryService: ITelemetryService, notificationService: INotificationService) { + constructor( + element: HTMLElement, + private contextViewService: IContextViewService, + private telemetryService: ITelemetryService, + private notificationService: INotificationService, + private keybindingService: IKeybindingService + ) { this.setContainer(element); - - this.contextViewService = contextViewService; - this.telemetryService = telemetryService; - this.notificationService = notificationService; - - this.menuContainerElement = null; } - public setContainer(container: HTMLElement): void { + setContainer(container: HTMLElement): void { if (this.element) { this.elementDisposable = dispose(this.elementDisposable); this.element = null; } + if (container) { this.element = container; - this.elementDisposable = addDisposableListener(this.element, 'mousedown', (e) => this.onMouseDown(e as MouseEvent)); + this.elementDisposable = addDisposableListener(this.element, EventType.MOUSE_DOWN, (e) => this.onMouseDown(e as MouseEvent)); } } - public showContextMenu(delegate: IContextMenuDelegate): void { + showContextMenu(delegate: IContextMenuDelegate): void { delegate.getActions().then((actions: IAction[]) => { if (!actions.length) { return; // Don't render an empty context menu @@ -80,7 +78,7 @@ export class ContextMenuHandler { actionItemProvider: delegate.getActionItem, context: delegate.getActionsContext ? delegate.getActionsContext() : null, actionRunner, - getKeyBinding: delegate.getKeyBinding + getKeyBinding: delegate.getKeyBinding ? delegate.getKeyBinding : action => this.keybindingService.lookupKeybinding(action.id) }); menu.onDidCancel(() => this.contextViewService.hideContextView(true), null, menuDisposables); @@ -146,7 +144,7 @@ export class ContextMenuHandler { this.contextViewService.hideContextView(); } - public dispose(): void { + dispose(): void { this.setContainer(null); } } \ No newline at end of file diff --git a/src/vs/platform/contextview/browser/contextMenuService.ts b/src/vs/platform/contextview/browser/contextMenuService.ts index 3c6207c6e0d..bca68061137 100644 --- a/src/vs/platform/contextview/browser/contextMenuService.ts +++ b/src/vs/platform/contextview/browser/contextMenuService.ts @@ -10,34 +10,41 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { Event, Emitter } from 'vs/base/common/event'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IContextMenuDelegate } from 'vs/base/browser/contextmenu'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { Disposable } from 'vs/base/common/lifecycle'; +export class ContextMenuService extends Disposable implements IContextMenuService { + _serviceBrand: any; -export class ContextMenuService implements IContextMenuService { - public _serviceBrand: any; + private _onDidContextMenu = this._register(new Emitter()); + get onDidContextMenu(): Event { return this._onDidContextMenu.event; } private contextMenuHandler: ContextMenuHandler; - private _onDidContextMenu = new Emitter(); - constructor(container: HTMLElement, telemetryService: ITelemetryService, notificationService: INotificationService, contextViewService: IContextViewService) { - this.contextMenuHandler = new ContextMenuHandler(container, contextViewService, telemetryService, notificationService); + constructor( + container: HTMLElement, + @ITelemetryService telemetryService: ITelemetryService, + @INotificationService notificationService: INotificationService, + @IContextViewService contextViewService: IContextViewService, + @IKeybindingService keybindingService: IKeybindingService + ) { + super(); + + this.contextMenuHandler = this._register(new ContextMenuHandler(container, contextViewService, telemetryService, notificationService, keybindingService)); } - public dispose(): void { + dispose(): void { this.contextMenuHandler.dispose(); } - public setContainer(container: HTMLElement): void { + setContainer(container: HTMLElement): void { this.contextMenuHandler.setContainer(container); } // ContextMenu - public showContextMenu(delegate: IContextMenuDelegate): void { + showContextMenu(delegate: IContextMenuDelegate): void { this.contextMenuHandler.showContextMenu(delegate); this._onDidContextMenu.fire(); } - - public get onDidContextMenu(): Event { - return this._onDidContextMenu.event; - } } diff --git a/src/vs/platform/contextview/browser/contextView.ts b/src/vs/platform/contextview/browser/contextView.ts index e99dea545f4..b67f748a760 100644 --- a/src/vs/platform/contextview/browser/contextView.ts +++ b/src/vs/platform/contextview/browser/contextView.ts @@ -12,16 +12,20 @@ import { IContextMenuDelegate } from 'vs/base/browser/contextmenu'; export const IContextViewService = createDecorator('contextViewService'); export interface IContextViewService { + _serviceBrand: any; + showContextView(delegate: IContextViewDelegate): void; hideContextView(data?: any): void; layout(): void; } export interface IContextViewDelegate { + + canRelayout?: boolean; // Default: true + getAnchor(): HTMLElement | { x: number; y: number; }; render(container: HTMLElement): IDisposable; - canRelayout?: boolean; // Default: true onDOMEvent?(e: any, activeElement: HTMLElement): void; onHide?(data?: any): void; } @@ -29,8 +33,9 @@ export interface IContextViewDelegate { export const IContextMenuService = createDecorator('contextMenuService'); export interface IContextMenuService { + _serviceBrand: any; + showContextMenu(delegate: IContextMenuDelegate): void; - // TODO@isidor these event should be removed once we get async context menus - onDidContextMenu: Event; + onDidContextMenu: Event; // TODO@isidor these event should be removed once we get async context menus } \ No newline at end of file diff --git a/src/vs/platform/contextview/browser/contextViewService.ts b/src/vs/platform/contextview/browser/contextViewService.ts index 871a806c7e9..5dc3233bfd3 100644 --- a/src/vs/platform/contextview/browser/contextViewService.ts +++ b/src/vs/platform/contextview/browser/contextViewService.ts @@ -8,9 +8,10 @@ import { IContextViewService, IContextViewDelegate } from './contextView'; import { ContextView } from 'vs/base/browser/ui/contextview/contextview'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ILogService } from 'vs/platform/log/common/log'; +import { Disposable } from 'vs/base/common/lifecycle'; -export class ContextViewService implements IContextViewService { - public _serviceBrand: any; +export class ContextViewService extends Disposable implements IContextViewService { + _serviceBrand: any; private contextView: ContextView; @@ -19,30 +20,28 @@ export class ContextViewService implements IContextViewService { @ITelemetryService telemetryService: ITelemetryService, @ILogService private logService: ILogService ) { - this.contextView = new ContextView(container); - } + super(); - public dispose(): void { - this.contextView.dispose(); + this.contextView = this._register(new ContextView(container)); } // ContextView - public setContainer(container: HTMLElement): void { + setContainer(container: HTMLElement): void { this.logService.trace('ContextViewService#setContainer'); this.contextView.setContainer(container); } - public showContextView(delegate: IContextViewDelegate): void { + showContextView(delegate: IContextViewDelegate): void { this.logService.trace('ContextViewService#showContextView'); this.contextView.show(delegate); } - public layout(): void { + layout(): void { this.contextView.layout(); } - public hideContextView(data?: any): void { + hideContextView(data?: any): void { this.logService.trace('ContextViewService#hideContextView'); this.contextView.hide(data); } diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 3d7d84cc022..f79762a1648 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -309,7 +309,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this.contextMenuService.showContextMenu({ getAnchor: () => anchor, getActions: () => TPromise.as(actions), - getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id), onHide: () => this.focus() }); } diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index 297bac18a96..d87e49955bf 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -318,7 +318,7 @@ export abstract class TitleControl extends Themable { }); } - protected getKeybinding(action: IAction): ResolvedKeybinding { + private getKeybinding(action: IAction): ResolvedKeybinding { return this.keybindingService.lookupKeybinding(action.id); } diff --git a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts index 556cdfd222e..10b9cc1645a 100644 --- a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts +++ b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts @@ -152,8 +152,7 @@ export class SidebarPart extends CompositePart { getAnchor: () => anchor, getActions: () => TPromise.as(contextMenuActions), getActionItem: action => this.actionItemProvider(action as Action), - actionRunner: activeViewlet.getActionRunner(), - getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id) + actionRunner: activeViewlet.getActionRunner() }); } } diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 980ae76e762..068f13be0ee 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -112,8 +112,6 @@ import { IEditorGroupsService, GroupDirection, preferredSideBySideGroupDirection import { EditorService } from 'vs/workbench/services/editor/browser/editorService'; import { IExtensionUrlHandler, ExtensionUrlHandler } from 'vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler'; import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { LabelService, ILabelService } from 'vs/platform/label/common/label'; @@ -246,8 +244,7 @@ export class Workbench extends Disposable implements IPartService { @IWorkbenchThemeService private themeService: WorkbenchThemeService, @IEnvironmentService private environmentService: IEnvironmentService, @IWindowService private windowService: IWindowService, - @INotificationService private notificationService: NotificationService, - @ITelemetryService private telemetryService: TelemetryService + @INotificationService private notificationService: NotificationService ) { super(); @@ -364,7 +361,7 @@ export class Workbench extends Disposable implements IPartService { // Use themable context menus when custom titlebar is enabled to match custom menubar if (!isMacintosh && this.getCustomTitleBarStyle() === 'custom') { - serviceCollection.set(IContextMenuService, new SyncDescriptor(HTMLContextMenuService, null, this.telemetryService, this.notificationService, this.contextViewService)); + serviceCollection.set(IContextMenuService, new SyncDescriptor(HTMLContextMenuService)); } else { serviceCollection.set(IContextMenuService, new SyncDescriptor(NativeContextMenuService)); } diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts index 7368ff7e693..f64cf9a3031 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts @@ -56,7 +56,6 @@ import { IDialogService, IConfirmationResult, IConfirmation, getConfirmMessage } import { INotificationService } from 'vs/platform/notification/common/notification'; import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; export class FileDataSource implements IDataSource { constructor( @@ -408,7 +407,6 @@ export class FileController extends WorkbenchTreeController implements IDisposab @IMenuService private menuService: IMenuService, @IContextKeyService contextKeyService: IContextKeyService, @IClipboardService private clipboardService: IClipboardService, - @IKeybindingService private keybindingService: IKeybindingService, @IConfigurationService configurationService: IConfigurationService ) { super({ clickBehavior: ClickBehavior.ON_MOUSE_UP /* do not change to not break DND */ }, configurationService); @@ -541,9 +539,6 @@ export class FileController extends WorkbenchTreeController implements IDisposab tree.domFocus(); } }, - getKeyBinding: (action) => { - return this.keybindingService.lookupKeybinding(action.id); - }, getActionsContext: () => selection && selection.indexOf(stat) >= 0 ? selection.map((fs: ExplorerItem) => fs.resource) : stat instanceof ExplorerItem ? [stat.resource] : []