mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 17:19:48 +01:00
fix #58186
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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<void>());
|
||||
get onDidContextMenu(): Event<void> { return this._onDidContextMenu.event; }
|
||||
|
||||
private contextMenuHandler: ContextMenuHandler;
|
||||
private _onDidContextMenu = new Emitter<void>();
|
||||
|
||||
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<void> {
|
||||
return this._onDidContextMenu.event;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,16 +12,20 @@ import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
|
||||
export const IContextViewService = createDecorator<IContextViewService>('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<IContextMenuService>('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<void>;
|
||||
onDidContextMenu: Event<void>; // TODO@isidor these event should be removed once we get async context menus
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -152,8 +152,7 @@ export class SidebarPart extends CompositePart<Viewlet> {
|
||||
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()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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] : []
|
||||
|
||||
Reference in New Issue
Block a user