Merge pull request #162491 from microsoft/joh/contextmenu-menu

Simplify context menu usage from menus
This commit is contained in:
Johannes Rieken 2022-10-03 15:58:48 +02:00 committed by GitHub
commit 3eb08720f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 166 additions and 184 deletions

View file

@ -948,9 +948,11 @@ class StandaloneContextMenuService extends ContextMenuService {
@INotificationService notificationService: INotificationService,
@IContextViewService contextViewService: IContextViewService,
@IKeybindingService keybindingService: IKeybindingService,
@IThemeService themeService: IThemeService
@IThemeService themeService: IThemeService,
@IMenuService menuService: IMenuService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
super(telemetryService, notificationService, contextViewService, keybindingService, themeService);
super(telemetryService, notificationService, contextViewService, keybindingService, themeService, menuService, contextKeyService);
this.configure({ blockMouse: false }); // we do not want that in the standalone editor
}
}

View file

@ -10,7 +10,7 @@ import { coalesceInPlace } from 'vs/base/common/arrays';
import { BugIndicatingError } from 'vs/base/common/errors';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { localize } from 'vs/nls';
import { createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuActionOptions, IMenuService, MenuId, MenuItemAction, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
@ -182,23 +182,15 @@ export class WorkbenchToolBar extends ToolBar {
}));
}
// add context menu actions (iff appicable)
if (this._options?.contextMenu) {
const menu = this._menuService.createMenu(this._options.contextMenu, this._contextKeyService);
const contextMenuActions: IAction[] = [];
createAndFillInContextMenuActions(menu, { ...this._options?.menuOptions, renderShortTitle: true, }, contextMenuActions);
menu.dispose();
if (contextMenuActions.length > 0) {
actions = [...actions, new Separator(), ...contextMenuActions];
}
}
// this.getElement().classList.toggle('config', true);
this._contextMenuService.showContextMenu({
getAnchor: () => e,
getActions: () => actions,
// add context menu actions (iff appicable)
menuId: this._options?.contextMenu,
menuActionOptions: { renderShortTitle: true, ...this._options?.menuOptions },
contextKeyService: this._contextKeyService,
onHide: () => this.getElement().classList.toggle('config', false),
});
}));

View file

@ -5,14 +5,18 @@
import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
import { ModifierKeyEmitter } from 'vs/base/browser/dom';
import { IAction, Separator } from 'vs/base/common/actions';
import { Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { ContextMenuHandler, IContextMenuHandlerOptions } from './contextMenuHandler';
import { IContextMenuService, IContextViewService } from './contextView';
import { IContextMenuMenuDelegate, IContextMenuService, IContextViewService } from './contextView';
export class ContextMenuService extends Disposable implements IContextMenuService {
@ -27,10 +31,10 @@ export class ContextMenuService extends Disposable implements IContextMenuServic
return this._contextMenuHandler;
}
private readonly _onDidShowContextMenu = new Emitter<void>();
private readonly _onDidShowContextMenu = this._store.add(new Emitter<void>());
readonly onDidShowContextMenu = this._onDidShowContextMenu.event;
private readonly _onDidHideContextMenu = new Emitter<void>();
private readonly _onDidHideContextMenu = this._store.add(new Emitter<void>());
readonly onDidHideContextMenu = this._onDidHideContextMenu.event;
constructor(
@ -38,7 +42,9 @@ export class ContextMenuService extends Disposable implements IContextMenuServic
@INotificationService private readonly notificationService: INotificationService,
@IContextViewService private readonly contextViewService: IContextViewService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@IThemeService private readonly themeService: IThemeService
@IThemeService private readonly themeService: IThemeService,
@IMenuService private readonly menuService: IMenuService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
) {
super();
}
@ -49,7 +55,10 @@ export class ContextMenuService extends Disposable implements IContextMenuServic
// ContextMenu
showContextMenu(delegate: IContextMenuDelegate): void {
showContextMenu(delegate: IContextMenuDelegate | IContextMenuMenuDelegate): void {
delegate = ContextMenuMenuDelegate.transform(delegate, this.menuService, this.contextKeyService);
this.contextMenuHandler.showContextMenu({
...delegate,
onHide: (didCancel) => {
@ -62,3 +71,33 @@ export class ContextMenuService extends Disposable implements IContextMenuServic
this._onDidShowContextMenu.fire();
}
}
export namespace ContextMenuMenuDelegate {
function is(thing: IContextMenuDelegate | IContextMenuMenuDelegate): thing is IContextMenuMenuDelegate {
return thing && (<IContextMenuMenuDelegate>thing).menuId instanceof MenuId;
}
export function transform(delegate: IContextMenuDelegate | IContextMenuMenuDelegate, menuService: IMenuService, globalContextKeyService: IContextKeyService): IContextMenuDelegate {
if (!is(delegate)) {
return delegate;
}
const { menuId, menuActionOptions, contextKeyService } = delegate;
return {
...delegate,
getActions: () => {
const target: IAction[] = [];
if (menuId) {
const menu = menuService.createMenu(menuId, contextKeyService ?? globalContextKeyService);
createAndFillInContextMenuActions(menu, menuActionOptions, target);
menu.dispose();
}
if (!delegate.getActions) {
return target;
} else {
return Separator.join(delegate.getActions(), target);
}
}
};
}
}

View file

@ -5,8 +5,11 @@
import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
import { AnchorAlignment, AnchorAxisAlignment, IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { IAction } from 'vs/base/common/actions';
import { Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IMenuActionOptions, MenuId } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const IContextViewService = createDecorator<IContextViewService>('contextViewService');
@ -44,5 +47,25 @@ export interface IContextMenuService {
readonly onDidShowContextMenu: Event<void>;
readonly onDidHideContextMenu: Event<void>;
showContextMenu(delegate: IContextMenuDelegate): void;
showContextMenu(delegate: IContextMenuDelegate | IContextMenuMenuDelegate): void;
}
export type IContextMenuMenuDelegate = {
/**
* The MenuId that should be used to populate the context menu.
*/
menuId?: MenuId;
/**
* Optional options how menu actions are invoked
*/
menuActionOptions?: IMenuActionOptions;
/**
* Optional context key service which drives the given menu
*/
contextKeyService?: IContextKeyService;
/**
* Optional getter for extra actions. They will be prepended to the menu actions.
*/
getActions?(): IAction[];
} & Omit<IContextMenuDelegate, 'getActions'>;

View file

@ -36,9 +36,9 @@ import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IAction } from 'vs/base/common/actions';
import { NoTabsTitleControl } from 'vs/workbench/browser/parts/editor/noTabsTitleControl';
import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { hash } from 'vs/base/common/hash';
@ -364,13 +364,11 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
}
private createContainerContextMenu(): void {
const menu = this._register(this.menuService.createMenu(MenuId.EmptyEditorGroupContext, this.contextKeyService));
this._register(addDisposableListener(this.element, EventType.CONTEXT_MENU, e => this.onShowContainerContextMenu(menu, e)));
this._register(addDisposableListener(this.element, TouchEventType.Contextmenu, () => this.onShowContainerContextMenu(menu)));
this._register(addDisposableListener(this.element, EventType.CONTEXT_MENU, e => this.onShowContainerContextMenu(e)));
this._register(addDisposableListener(this.element, TouchEventType.Contextmenu, () => this.onShowContainerContextMenu()));
}
private onShowContainerContextMenu(menu: IMenu, e?: MouseEvent): void {
private onShowContainerContextMenu(e?: MouseEvent): void {
if (!this.isEmpty) {
return; // only for empty editor groups
}
@ -382,14 +380,11 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
anchor = { x: event.posx, y: event.posy };
}
// Fill in contributed actions
const actions: IAction[] = [];
createAndFillInContextMenuActions(menu, undefined, actions);
// Show it
this.contextMenuService.showContextMenu({
menuId: MenuId.EmptyEditorGroupContext,
contextKeyService: this.contextKeyService,
getAnchor: () => anchor,
getActions: () => actions,
onHide: () => {
this.focus();
}

View file

@ -12,8 +12,8 @@ import { ActionsOrientation, IActionViewItem, prepareActions } from 'vs/base/bro
import { IAction, SubmenuAction, ActionRunner } from 'vs/base/common/actions';
import { ResolvedKeybinding } from 'vs/base/common/keybindings';
import { dispose, DisposableStore } from 'vs/base/common/lifecycle';
import { createActionViewItem, createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenu, IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { createActionViewItem, createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
@ -108,7 +108,6 @@ export abstract class TitleControl extends Themable {
private readonly editorToolBarMenuDisposables = this._register(new DisposableStore());
private contextMenu: IMenu;
private renderDropdownAsChildElement: boolean;
constructor(
@ -140,7 +139,6 @@ export abstract class TitleControl extends Themable {
this.groupLockedContext = ActiveEditorGroupLockedContext.bindTo(contextKeyService);
this.contextMenu = this._register(this.menuService.createMenu(MenuId.EditorTitleContext, this.contextKeyService));
this.renderDropdownAsChildElement = false;
this.create(parent);
@ -374,14 +372,12 @@ export abstract class TitleControl extends Themable {
anchor = { x: event.posx, y: event.posy };
}
// Fill in contributed actions
const actions: IAction[] = [];
createAndFillInContextMenuActions(this.contextMenu, { shouldForwardArgs: true, arg: this.resourceContext.get() }, actions);
// Show it
this.contextMenuService.showContextMenu({
getAnchor: () => anchor,
getActions: () => actions,
menuId: MenuId.EditorTitleContext,
menuActionOptions: { shouldForwardArgs: true, arg: this.resourceContext.get() },
contextKeyService: this.contextKeyService,
getActionsContext: () => ({ groupId: this.group.id, editorIndex: this.group.getIndexOfEditor(editor) }),
getKeyBinding: action => this.getKeybinding(action),
onHide: () => {

View file

@ -11,7 +11,6 @@ import { getZoomFactor } from 'vs/base/browser/browser';
import { MenuBarVisibility, getTitleBarStyle, getMenuBarVisibility } from 'vs/platform/window/common/window';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IAction } from 'vs/base/common/actions';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
@ -25,8 +24,8 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati
import { Emitter, Event } from 'vs/base/common/event';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { createActionViewItem, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { Action2, IMenuService, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { Codicon } from 'vs/base/common/codicons';
@ -92,7 +91,6 @@ export class TitlebarPart extends Part implements ITitleService {
@IThemeService themeService: IThemeService,
@IStorageService storageService: IStorageService,
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@IMenuService private readonly menuService: IMenuService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IHostService private readonly hostService: IHostService,
@IHoverService hoverService: IHoverService,
@ -382,16 +380,11 @@ export class TitlebarPart extends Part implements ITitleService {
const event = new StandardMouseEvent(e);
const anchor = { x: event.posx, y: event.posy };
// Fill in contributed actions
const menu = this.menuService.createMenu(menuId, this.contextKeyService);
const actions: IAction[] = [];
createAndFillInContextMenuActions(menu, undefined, actions);
menu.dispose();
// Show it
this.contextMenuService.showContextMenu({
getAnchor: () => anchor,
getActions: () => actions,
menuId,
contextKeyService: this.contextKeyService,
domForShadowRoot: isMacintosh && isNative ? event.target : undefined
});
}

View file

@ -26,9 +26,7 @@ import { ResourceLabels, IResourceLabelsContainer } from 'vs/workbench/browser/l
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import Severity from 'vs/base/common/severity';
import { basename, dirname } from 'vs/base/common/resources';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { IAction } from 'vs/base/common/actions';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { MenuId } from 'vs/platform/actions/common/actions';
import { ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
@ -78,10 +76,9 @@ export class BulkEditPane extends ViewPane {
@ILabelService private readonly _labelService: ILabelService,
@ITextModelService private readonly _textModelService: ITextModelService,
@IDialogService private readonly _dialogService: IDialogService,
@IMenuService private readonly _menuService: IMenuService,
@IContextMenuService private readonly _contextMenuService: IContextMenuService,
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
@IStorageService private readonly _storageService: IStorageService,
@IContextKeyService contextKeyService: IContextKeyService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService,
@ -92,13 +89,13 @@ export class BulkEditPane extends ViewPane {
) {
super(
{ ...options, titleMenuId: MenuId.BulkEditTitle },
keybindingService, contextMenuService, configurationService, _contextKeyService, viewDescriptorService, _instaService, openerService, themeService, telemetryService
keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, _instaService, openerService, themeService, telemetryService
);
this.element.classList.add('bulk-edit-panel', 'show-file-icons');
this._ctxHasCategories = BulkEditPane.ctxHasCategories.bindTo(_contextKeyService);
this._ctxGroupByFile = BulkEditPane.ctxGroupByFile.bindTo(_contextKeyService);
this._ctxHasCheckedChanges = BulkEditPane.ctxHasCheckedChanges.bindTo(_contextKeyService);
this._ctxHasCategories = BulkEditPane.ctxHasCategories.bindTo(contextKeyService);
this._ctxGroupByFile = BulkEditPane.ctxGroupByFile.bindTo(contextKeyService);
this._ctxHasCheckedChanges = BulkEditPane.ctxHasCheckedChanges.bindTo(contextKeyService);
}
override dispose(): void {
@ -380,16 +377,11 @@ export class BulkEditPane extends ViewPane {
}
private _onContextMenu(e: ITreeContextMenuEvent<any>): void {
const menu = this._menuService.createMenu(MenuId.BulkEditContext, this._contextKeyService);
const actions: IAction[] = [];
createAndFillInContextMenuActions(menu, undefined, actions);
this._contextMenuService.showContextMenu({
getActions: () => actions,
getAnchor: () => e.anchor,
onHide: () => {
menu.dispose();
}
menuId: MenuId.BulkEditContext,
contextKeyService: this.contextKeyService,
getAnchor: () => e.anchor
});
}
}

View file

@ -35,10 +35,6 @@ export class CommentMenus implements IDisposable {
return this.getMenu(MenuId.CommentThreadTitleContext, contextKeyService);
}
getCommentThreadCommentContextActions(contextKeyService: IContextKeyService): IMenu {
return this.getMenu(MenuId.CommentThreadCommentContext, contextKeyService);
}
private getMenu(menuId: MenuId, contextKeyService: IContextKeyService): IMenu {
const menu = this.menuService.createMenu(menuId, contextKeyService);

View file

@ -26,7 +26,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { ToggleReactionsAction, ReactionAction, ReactionActionViewItem } from './reactionsAction';
import { ICommentThreadWidget } from 'vs/workbench/contrib/comments/common/commentThreadWidget';
import { MenuItemAction, SubmenuItemAction, IMenu } from 'vs/platform/actions/common/actions';
import { MenuItemAction, SubmenuItemAction, IMenu, MenuId } from 'vs/platform/actions/common/actions';
import { MenuEntryActionViewItem, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { CommentFormActions } from 'vs/workbench/contrib/comments/browser/commentFormActions';
@ -574,13 +574,11 @@ export class CommentNode<T extends IRange | ICellRange> extends Disposable {
private onContextMenu(e: MouseEvent) {
const actions = this._commentMenus.getCommentThreadCommentContextActions(this._contextKeyService).getActions({ shouldForwardArgs: true }).map((value) => value[1]).flat();
if (!actions.length) {
return;
}
this.contextMenuService.showContextMenu({
getAnchor: () => e,
getActions: () => actions,
menuId: MenuId.CommentThreadCommentContext,
menuActionOptions: { shouldForwardArgs: true },
contextKeyService: this._contextKeyService,
actionRunner: new ActionRunner(),
getActionsContext: () => {
return this.commentNodeContext;

View file

@ -6,7 +6,7 @@
import * as nls from 'vs/nls';
import { URI } from 'vs/base/common/uri';
import * as perf from 'vs/base/common/performance';
import { IAction, WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions';
import { WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions';
import { memoize } from 'vs/base/common/decorators';
import { IFilesConfiguration, ExplorerFolderContext, FilesExplorerFocusedContext, ExplorerFocusedContext, ExplorerRootContext, ExplorerResourceReadonlyContext, ExplorerResourceCut, ExplorerResourceMoveableToTrash, ExplorerCompressedFocusContext, ExplorerCompressedFirstFocusContext, ExplorerCompressedLastFocusContext, ExplorerResourceAvailableEditorIdsContext, VIEW_ID, VIEWLET_ID, ExplorerResourceNotReadonlyContext, ViewHasSomeCollapsibleRootItemContext } from 'vs/workbench/contrib/files/common/files';
import { FileCopiedContext, NEW_FILE_COMMAND_ID, NEW_FOLDER_COMMAND_ID } from 'vs/workbench/contrib/files/browser/fileActions';
@ -31,8 +31,7 @@ import { ExplorerDelegate, ExplorerDataSource, FilesRenderer, ICompressedNavigat
import { IThemeService, IFileIconTheme } from 'vs/platform/theme/common/themeService';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { ITreeContextMenuEvent, TreeVisibility } from 'vs/base/browser/ui/tree/tree';
import { IMenuService, MenuId, IMenu, Action2, registerAction2 } from 'vs/platform/actions/common/actions';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { MenuId, Action2, registerAction2 } from 'vs/platform/actions/common/actions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ExplorerItem, NewExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel';
import { ResourceLabels } from 'vs/workbench/browser/labels';
@ -202,7 +201,6 @@ export class ExplorerView extends ViewPane implements IExplorerView {
@IDecorationsService private readonly decorationService: IDecorationsService,
@ILabelService private readonly labelService: ILabelService,
@IThemeService themeService: IWorkbenchThemeService,
@IMenuService private readonly menuService: IMenuService,
@ITelemetryService telemetryService: ITelemetryService,
@IExplorerService private readonly explorerService: IExplorerService,
@IStorageService private readonly storageService: IStorageService,
@ -242,13 +240,6 @@ export class ExplorerView extends ViewPane implements IExplorerView {
// noop
}
// Memoized locals
@memoize private get contributedContextMenu(): IMenu {
const contributedContextMenu = this.menuService.createMenu(MenuId.ExplorerContext, this.tree.contextKeyService);
this._register(contributedContextMenu);
return contributedContextMenu;
}
@memoize private get fileCopiedContextKey(): IContextKey<boolean> {
return FileCopiedContext.bindTo(this.contextKeyService);
}
@ -582,7 +573,6 @@ export class ExplorerView extends ViewPane implements IExplorerView {
const selection = this.tree.getSelection();
const actions: IAction[] = [];
const roots = this.explorerService.roots; // If the click is outside of the elements pass the root resource if there is only one root. If there are multiple roots pass empty object.
let arg: URI | {};
if (stat instanceof ExplorerItem) {
@ -591,11 +581,12 @@ export class ExplorerView extends ViewPane implements IExplorerView {
} else {
arg = roots.length === 1 ? roots[0].resource : {};
}
createAndFillInContextMenuActions(this.contributedContextMenu, { arg, shouldForwardArgs: true }, actions);
this.contextMenuService.showContextMenu({
menuId: MenuId.ExplorerContext,
menuActionOptions: { arg, shouldForwardArgs: true },
contextKeyService: this.tree.contextKeyService,
getAnchor: () => anchor,
getActions: () => actions,
onHide: (wasCancelled?: boolean) => {
if (wasCancelled) {
this.tree.domFocus();

View file

@ -28,8 +28,7 @@ import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuService, MenuId, IMenu, Action2, registerAction2, MenuRegistry } from 'vs/platform/actions/common/actions';
import { MenuId, Action2, registerAction2, MenuRegistry } from 'vs/platform/actions/common/actions';
import { OpenEditorsDirtyEditorContext, OpenEditorsGroupContext, OpenEditorsReadonlyEditorContext, SAVE_ALL_LABEL, SAVE_ALL_COMMAND_ID, NEW_UNTITLED_FILE_COMMAND_ID } from 'vs/workbench/contrib/files/browser/fileConstants';
import { ResourceContextKey } from 'vs/workbench/common/contextkeys';
import { CodeDataTransfers, containsDragType } from 'vs/platform/dnd/browser/dnd';
@ -69,7 +68,6 @@ export class OpenEditorsView extends ViewPane {
private structuralRefreshDelay: number;
private list!: WorkbenchList<OpenEditor | IEditorGroup>;
private listLabels: ResourceLabels | undefined;
private contributedContextMenu!: IMenu;
private needsRefresh = false;
private elements: (OpenEditor | IEditorGroup)[] = [];
private sortOrder: 'editorOrder' | 'alphabetical' | 'fullPath';
@ -89,7 +87,6 @@ export class OpenEditorsView extends ViewPane {
@IContextKeyService contextKeyService: IContextKeyService,
@IThemeService themeService: IThemeService,
@ITelemetryService telemetryService: ITelemetryService,
@IMenuService private readonly menuService: IMenuService,
@IWorkingCopyService private readonly workingCopyService: IWorkingCopyService,
@IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService,
@IOpenerService openerService: IOpenerService,
@ -243,9 +240,6 @@ export class OpenEditorsView extends ViewPane {
this._register(this.list);
this._register(this.listLabels);
this.contributedContextMenu = this.menuService.createMenu(MenuId.OpenEditorsContext, this.list.contextKeyService);
this._register(this.contributedContextMenu);
this.updateSize();
// Bind context keys
@ -396,12 +390,12 @@ export class OpenEditorsView extends ViewPane {
}
const element = e.element;
const actions: IAction[] = [];
createAndFillInContextMenuActions(this.contributedContextMenu, { shouldForwardArgs: true, arg: element instanceof OpenEditor ? EditorResourceAccessor.getOriginalUri(element.editor) : {} }, actions);
this.contextMenuService.showContextMenu({
menuId: MenuId.OpenEditorsContext,
menuActionOptions: { shouldForwardArgs: true, arg: element instanceof OpenEditor ? EditorResourceAccessor.getOriginalUri(element.editor) : {} },
contextKeyService: this.list.contextKeyService,
getAnchor: () => e.anchor,
getActions: () => actions,
getActionsContext: () => element instanceof OpenEditor ? { groupId: element.groupId, editorIndex: element.group.getIndexOfEditor(element.editor) } : { groupId: element.id }
});
}

View file

@ -32,7 +32,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { FilterData, Filter, VirtualDelegate, ResourceMarkersRenderer, MarkerRenderer, RelatedInformationRenderer, MarkersWidgetAccessibilityProvider, MarkersViewModel } from 'vs/workbench/contrib/markers/browser/markersTreeViewer';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { ActionBar, IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { MenuId } from 'vs/platform/actions/common/actions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { ResourceLabels } from 'vs/workbench/browser/labels';
@ -53,7 +53,6 @@ import { groupBy } from 'vs/base/common/arrays';
import { ResourceMap } from 'vs/base/common/map';
import { EditorResourceAccessor, SideBySideEditor } from 'vs/workbench/common/editor';
import { IMarkersView } from 'vs/workbench/contrib/markers/browser/markers';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { ResourceListDnDHandler } from 'vs/workbench/browser/dnd';
import { ITableContextMenuEvent, ITableEvent } from 'vs/base/browser/ui/table/table';
import { MarkersTable } from 'vs/workbench/contrib/markers/browser/markersTable';
@ -148,7 +147,6 @@ export class MarkersView extends ViewPane implements IMarkersView {
@IContextKeyService contextKeyService: IContextKeyService,
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
@IContextMenuService contextMenuService: IContextMenuService,
@IMenuService private readonly menuService: IMenuService,
@IUriIdentityService private readonly uriIdentityService: IUriIdentityService,
@IKeybindingService keybindingService: IKeybindingService,
@IStorageService storageService: IStorageService,
@ -803,6 +801,7 @@ export class MarkersView extends ViewPane implements IMarkersView {
this.contextMenuService.showContextMenu({
getAnchor: () => e.anchor!,
menuId: MenuId.ProblemsPanelContext,
getActions: () => this.getMenuActions(element),
getActionViewItem: (action) => {
const keybinding = this.keybindingService.lookupKeybinding(action.id);
@ -833,9 +832,6 @@ export class MarkersView extends ViewPane implements IMarkersView {
}
}
const menu = this.menuService.createMenu(MenuId.ProblemsPanelContext, this.widget.contextKeyService);
createAndFillInContextMenuActions(menu, undefined, result);
menu.dispose();
return result;
}

View file

@ -14,7 +14,6 @@ import * as DOM from 'vs/base/browser/dom';
import { IMouseWheelEvent, StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import * as aria from 'vs/base/browser/ui/aria/aria';
import { IListContextMenuEvent } from 'vs/base/browser/ui/list/list';
import { IAction } from 'vs/base/common/actions';
import { DeferredPromise, runWhenIdle, SequencerByKey } from 'vs/base/common/async';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Color, RGBA } from 'vs/base/common/color';
@ -33,8 +32,7 @@ import { Range } from 'vs/editor/common/core/range';
import { IEditor } from 'vs/editor/common/editorCommon';
import { SuggestController } from 'vs/editor/contrib/suggest/browser/suggestController';
import * as nls from 'vs/nls';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { MenuId } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
@ -252,7 +250,6 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
@IContextKeyService contextKeyService: IContextKeyService,
@ILayoutService private readonly layoutService: ILayoutService,
@IContextMenuService private readonly contextMenuService: IContextMenuService,
@IMenuService private readonly menuService: IMenuService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@INotebookExecutionService private readonly notebookExecutionService: INotebookExecutionService,
@INotebookExecutionStateService notebookExecutionStateService: INotebookExecutionStateService,
@ -953,13 +950,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
private showListContextMenu(e: IListContextMenuEvent<CellViewModel>) {
this.contextMenuService.showContextMenu({
getActions: () => {
const result: IAction[] = [];
const menu = this.menuService.createMenu(MenuId.NotebookCellTitle, this.scopedContextKeyService);
createAndFillInContextMenuActions(menu, undefined, result);
menu.dispose();
return result;
},
menuId: MenuId.NotebookCellTitle,
contextKeyService: this.scopedContextKeyService,
getAnchor: () => e.anchor
});
}

View file

@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { IAction } from 'vs/base/common/actions';
import { coalesce } from 'vs/base/common/arrays';
import { decodeBase64 } from 'vs/base/common/buffer';
import { Emitter, Event } from 'vs/base/common/event';
@ -21,8 +20,7 @@ import { ILanguageService } from 'vs/editor/common/languages/language';
import { generateTokensCSSForColorMap } from 'vs/editor/common/languages/supports/tokenization';
import { tokenizeToString } from 'vs/editor/common/languages/textToHtmlTokenizer';
import * as nls from 'vs/nls';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { MenuId } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
@ -130,7 +128,6 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Disposable {
@IFileDialogService private readonly fileDialogService: IFileDialogService,
@IFileService private readonly fileService: IFileService,
@IContextMenuService private readonly contextMenuService: IContextMenuService,
@IMenuService private readonly menuService: IMenuService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IWorkspaceTrustManagementService private readonly workspaceTrustManagementService: IWorkspaceTrustManagementService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@ -766,13 +763,8 @@ var requirejs = (function() {
// Then show the context menu
const webviewRect = this.element.getBoundingClientRect();
this.contextMenuService.showContextMenu({
getActions: () => {
const result: IAction[] = [];
const menu = this.menuService.createMenu(MenuId.NotebookCellTitle, this.contextKeyService);
createAndFillInContextMenuActions(menu, undefined, result);
menu.dispose();
return result;
},
menuId: MenuId.NotebookCellTitle,
contextKeyService: this.contextKeyService,
getAnchor: () => ({
x: webviewRect.x + data.clientX,
y: webviewRect.y + data.clientY
@ -1529,4 +1521,3 @@ function getTokenizationCss() {
const tokenizationCss = colorMap ? generateTokensCSSForColorMap(colorMap) : '';
return tokenizationCss;
}

View file

@ -23,7 +23,7 @@ import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel';
import { ActionRunner, IAction } from 'vs/base/common/actions';
import { IMenuService, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
import { ILocalizedString } from 'vs/platform/action/common/action';
import { createAndFillInContextMenuActions, createAndFillInActionBarActions, createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { createAndFillInActionBarActions, createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IRemoteExplorerService, TunnelModel, makeAddress, TunnelType, ITunnelItem, Tunnel, TUNNEL_VIEW_ID, parseAddress, CandidatePort, TunnelEditId, mapHasAddressLocalhostOrAllInterfaces, Attributes, TunnelSource } from 'vs/workbench/services/remote/common/remoteExplorerService';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
@ -1023,14 +1023,11 @@ export class TunnelPanel extends ViewPane {
this.portChangableContextKey.set(false);
}
const menu = this.menuService.createMenu(MenuId.TunnelContext, this.table.contextKeyService);
const actions: IAction[] = [];
createAndFillInContextMenuActions(menu, { shouldForwardArgs: true }, actions);
menu.dispose();
this.contextMenuService.showContextMenu({
menuId: MenuId.TunnelContext,
menuActionOptions: { shouldForwardArgs: true },
contextKeyService: this.table.contextKeyService,
getAnchor: () => event.anchor,
getActions: () => actions,
getActionViewItem: (action) => {
const keybinding = this.keybindingService.lookupKeybinding(action.id);
if (keybinding) {

View file

@ -10,7 +10,6 @@ import { MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
import { IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { ICompressedTreeElement } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
import { ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
import { IAction } from 'vs/base/common/actions';
import { Delayer } from 'vs/base/common/async';
import { Color, RGBA } from 'vs/base/common/color';
import * as errors from 'vs/base/common/errors';
@ -33,8 +32,7 @@ import { CommonFindController } from 'vs/editor/contrib/find/browser/findControl
import { MultiCursorSelectionController } from 'vs/editor/contrib/multicursor/browser/multicursor';
import * as nls from 'vs/nls';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenu, IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { MenuId } from 'vs/platform/actions/common/actions';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
@ -122,8 +120,6 @@ export class SearchView extends ViewPane {
private hasFilePatternKey: IContextKey<boolean>;
private hasSomeCollapsibleResultKey: IContextKey<boolean>;
private contextMenu: IMenu | null = null;
private tree!: WorkbenchCompressibleObjectTree<RenderableMatch>;
private treeLabels!: ResourceLabels;
private viewletState: MementoObject;
@ -179,7 +175,6 @@ export class SearchView extends ViewPane {
@IThemeService themeService: IThemeService,
@ISearchHistoryService private readonly searchHistoryService: ISearchHistoryService,
@IContextMenuService contextMenuService: IContextMenuService,
@IMenuService private readonly menuService: IMenuService,
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
@IKeybindingService keybindingService: IKeybindingService,
@IStorageService storageService: IStorageService,
@ -824,19 +819,15 @@ export class SearchView extends ViewPane {
}
private onContextMenu(e: ITreeContextMenuEvent<RenderableMatch | null>): void {
if (!this.contextMenu) {
this.contextMenu = this._register(this.menuService.createMenu(MenuId.SearchContext, this.contextKeyService));
}
e.browserEvent.preventDefault();
e.browserEvent.stopPropagation();
const actions: IAction[] = [];
createAndFillInContextMenuActions(this.contextMenu, { shouldForwardArgs: true }, actions);
this.contextMenuService.showContextMenu({
menuId: MenuId.SearchContext,
menuActionOptions: { shouldForwardArgs: true },
contextKeyService: this.contextKeyService,
getAnchor: () => e.anchor,
getActions: () => actions,
getActionsContext: () => e.element,
});
}

View file

@ -6,7 +6,6 @@
import { isFirefox } from 'vs/base/browser/browser';
import { addDisposableListener, EventType } from 'vs/base/browser/dom';
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { IAction } from 'vs/base/common/actions';
import { ThrottledDelayer } from 'vs/base/common/async';
import { streamToBuffer, VSBufferReadableStream } from 'vs/base/common/buffer';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
@ -17,7 +16,6 @@ import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import { localize } from 'vs/nls';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
@ -340,19 +338,14 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
return;
}
const elementBox = this.element.getBoundingClientRect();
const contextKeyService = this._contextKeyService!.createOverlay([
...Object.entries(data.context),
[webviewIdContext, this.providedViewType],
]);
contextMenuService.showContextMenu({
getActions: () => {
const contextKeyService = this._contextKeyService!.createOverlay([
...Object.entries(data.context),
[webviewIdContext, this.providedViewType],
]);
const result: IAction[] = [];
const menu = menuService.createMenu(MenuId.WebviewContext, contextKeyService);
createAndFillInContextMenuActions(menu, { shouldForwardArgs: true }, result);
menu.dispose();
return result;
},
menuId: MenuId.WebviewContext,
menuActionOptions: { shouldForwardArgs: true },
contextKeyService,
getActionsContext: (): WebviewActionContext => ({ ...data.context, webview: this.providedViewType }),
getAnchor: () => ({
x: elementBox.x + data.clientX,

View file

@ -11,7 +11,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { isMacintosh, isWindows, isLinux, isNative } from 'vs/base/common/platform';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { MenuId } from 'vs/platform/actions/common/actions';
import { TitlebarPart as BrowserTitleBarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IThemeService } from 'vs/platform/theme/common/themeService';
@ -62,13 +62,12 @@ export class TitlebarPart extends BrowserTitleBarPart {
@IThemeService themeService: IThemeService,
@IStorageService storageService: IStorageService,
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@IMenuService menuService: IMenuService,
@IContextKeyService contextKeyService: IContextKeyService,
@IHostService hostService: IHostService,
@INativeHostService private readonly nativeHostService: INativeHostService,
@IHoverService hoverService: IHoverService,
) {
super(contextMenuService, configurationService, environmentService, instantiationService, themeService, storageService, layoutService, menuService, contextKeyService, hostService, hoverService);
super(contextMenuService, configurationService, environmentService, instantiationService, themeService, storageService, layoutService, contextKeyService, hostService, hoverService);
this.environmentService = environmentService;
}

View file

@ -5,7 +5,7 @@
import { IAction, IActionRunner, ActionRunner, WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification, Separator, SubmenuAction } from 'vs/base/common/actions';
import * as dom from 'vs/base/browser/dom';
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IContextMenuMenuDelegate, IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { getZoomFactor } from 'vs/base/browser/browser';
@ -13,25 +13,27 @@ import { unmnemonicLabel } from 'vs/base/common/labels';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IContextMenuDelegate, IContextMenuEvent } from 'vs/base/browser/contextmenu';
import { once } from 'vs/base/common/functional';
import { Disposable } from 'vs/base/common/lifecycle';
import { IContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu';
import { popup } from 'vs/base/parts/contextmenu/electron-sandbox/contextmenu';
import { getTitleBarStyle } from 'vs/platform/window/common/window';
import { isMacintosh, isWindows } from 'vs/base/common/platform';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ContextMenuService as HTMLContextMenuService } from 'vs/platform/contextview/browser/contextMenuService';
import { ContextMenuMenuDelegate, ContextMenuService as HTMLContextMenuService } from 'vs/platform/contextview/browser/contextMenuService';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { stripIcons } from 'vs/base/common/iconLabels';
import { coalesce } from 'vs/base/common/arrays';
import { Event, Emitter } from 'vs/base/common/event';
import { AnchorAlignment, AnchorAxisAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { IMenuService } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { Disposable } from 'vs/base/common/lifecycle';
export class ContextMenuService extends Disposable implements IContextMenuService {
export class ContextMenuService implements IContextMenuService {
declare readonly _serviceBrand: undefined;
private impl: IContextMenuService;
private impl: HTMLContextMenuService | NativeContextMenuService;
get onDidShowContextMenu(): Event<void> { return this.impl.onDidShowContextMenu; }
get onDidHideContextMenu(): Event<void> { return this.impl.onDidHideContextMenu; }
@ -42,22 +44,27 @@ export class ContextMenuService extends Disposable implements IContextMenuServic
@IKeybindingService keybindingService: IKeybindingService,
@IConfigurationService configurationService: IConfigurationService,
@IContextViewService contextViewService: IContextViewService,
@IThemeService themeService: IThemeService
@IThemeService themeService: IThemeService,
@IMenuService menuService: IMenuService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
super();
// Custom context menu: Linux/Windows if custom title is enabled
if (!isMacintosh && getTitleBarStyle(configurationService) === 'custom') {
this.impl = new HTMLContextMenuService(telemetryService, notificationService, contextViewService, keybindingService, themeService);
this.impl = new HTMLContextMenuService(telemetryService, notificationService, contextViewService, keybindingService, themeService, menuService, contextKeyService);
}
// Native context menu: otherwise
else {
this.impl = new NativeContextMenuService(notificationService, telemetryService, keybindingService);
this.impl = new NativeContextMenuService(notificationService, telemetryService, keybindingService, menuService, contextKeyService);
}
}
showContextMenu(delegate: IContextMenuDelegate): void {
dispose(): void {
this.impl.dispose();
}
showContextMenu(delegate: IContextMenuDelegate | IContextMenuMenuDelegate): void {
this.impl.showContextMenu(delegate);
}
}
@ -66,21 +73,26 @@ class NativeContextMenuService extends Disposable implements IContextMenuService
declare readonly _serviceBrand: undefined;
private readonly _onDidShowContextMenu = new Emitter<void>();
private readonly _onDidShowContextMenu = this._store.add(new Emitter<void>());
readonly onDidShowContextMenu = this._onDidShowContextMenu.event;
private readonly _onDidHideContextMenu = new Emitter<void>();
private readonly _onDidHideContextMenu = this._store.add(new Emitter<void>());
readonly onDidHideContextMenu = this._onDidHideContextMenu.event;
constructor(
@INotificationService private readonly notificationService: INotificationService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IKeybindingService private readonly keybindingService: IKeybindingService
@IKeybindingService private readonly keybindingService: IKeybindingService,
@IMenuService private readonly menuService: IMenuService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
) {
super();
}
showContextMenu(delegate: IContextMenuDelegate): void {
showContextMenu(delegate: IContextMenuDelegate | IContextMenuMenuDelegate): void {
delegate = ContextMenuMenuDelegate.transform(delegate, this.menuService, this.contextKeyService);
const actions = delegate.getActions();
if (actions.length) {
const onHide = once(() => {