Support drag and drop from terminal inline tab

Fixes #126492
This commit is contained in:
Daniel Imms
2021-06-28 07:26:00 -07:00
parent eea7d0005f
commit cfb8c268d4
11 changed files with 32 additions and 16 deletions
@@ -49,7 +49,7 @@ export class SuggestWidgetStatus {
this.element = dom.append(container, dom.$('.suggest-status-bar'));
const actionViewItemProvider = <IActionViewItemProvider>(action => {
return action instanceof MenuItemAction ? instantiationService.createInstance(StatusBarViewItem, action) : undefined;
return action instanceof MenuItemAction ? instantiationService.createInstance(StatusBarViewItem, action, undefined) : undefined;
});
this._leftActions = new ActionBar(this.element, { actionViewItemProvider });
this._rightActions = new ActionBar(this.element, { actionViewItemProvider });
@@ -36,7 +36,7 @@ export class DropdownWithPrimaryActionViewItem extends BaseActionViewItem {
@INotificationService _notificationService: INotificationService
) {
super(null, primaryAction);
this._primaryAction = new MenuEntryActionViewItem(primaryAction, _keybindingService, _notificationService);
this._primaryAction = new MenuEntryActionViewItem(primaryAction, undefined, _keybindingService, _notificationService);
this._dropdown = new DropdownMenuActionViewItem(dropdownAction, dropdownMenuActions, this._contextMenuProvider, {
menuAsChild: true,
classNames: ['codicon', 'codicon-chevron-down']
@@ -115,6 +115,10 @@ function fillInActions(
}
}
export interface IMenuEntryActionViewItemOptions {
draggable?: boolean;
}
export class MenuEntryActionViewItem extends ActionViewItem {
private _wantsAltCommand: boolean = false;
@@ -123,10 +127,11 @@ export class MenuEntryActionViewItem extends ActionViewItem {
constructor(
_action: MenuItemAction,
options: IMenuEntryActionViewItemOptions | undefined,
@IKeybindingService protected readonly _keybindingService: IKeybindingService,
@INotificationService protected _notificationService: INotificationService
) {
super(undefined, _action, { icon: !!(_action.class || _action.item.icon), label: !_action.class && !_action.item.icon });
super(undefined, _action, { icon: !!(_action.class || _action.item.icon), label: !_action.class && !_action.item.icon, draggable: options?.draggable });
this._altKey = ModifierKeyEmitter.getInstance();
}
@@ -302,7 +307,7 @@ export class SubmenuEntryActionViewItem extends DropdownMenuActionViewItem {
*/
export function createActionViewItem(instaService: IInstantiationService, action: IAction): undefined | MenuEntryActionViewItem | SubmenuEntryActionViewItem {
if (action instanceof MenuItemAction) {
return instaService.createInstance(MenuEntryActionViewItem, action);
return instaService.createInstance(MenuEntryActionViewItem, action, undefined);
} else if (action instanceof SubmenuItemAction) {
return instaService.createInstance(SubmenuEntryActionViewItem, action);
} else {
@@ -221,7 +221,7 @@ export class CommentNode extends Disposable {
let item = new ReactionActionViewItem(action);
return item;
} else if (action instanceof MenuItemAction) {
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
return this.instantiationService.createInstance(MenuEntryActionViewItem, action, undefined);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
} else {
@@ -517,7 +517,7 @@ class SessionsRenderer implements ICompressibleTreeRenderer<IDebugSession, Fuzzy
const actionBar = new ActionBar(session, {
actionViewItemProvider: action => {
if (action instanceof MenuItemAction) {
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
return this.instantiationService.createInstance(MenuEntryActionViewItem, action, undefined);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
}
@@ -16,7 +16,7 @@ export class CodiconActionViewItem extends MenuEntryActionViewItem {
keybindingService: IKeybindingService,
notificationService: INotificationService,
) {
super(_action, keybindingService, notificationService);
super(_action, undefined, keybindingService, notificationService);
}
override updateLabel(): void {
if (this.options.label && this.label) {
@@ -33,7 +33,7 @@ export class ActionViewWithLabel extends MenuEntryActionViewItem {
keybindingService: IKeybindingService,
notificationService: INotificationService,
) {
super(_action, keybindingService, notificationService);
super(_action, undefined, keybindingService, notificationService);
}
override render(container: HTMLElement): void {
@@ -116,7 +116,7 @@ abstract class AbstractCellRenderer {
if (notebookOptions.getLayoutConfiguration().insertToolbarAlignment === 'center') {
return new CodiconActionViewItem(action, this.keybindingService, this.notificationService);
} else {
return new MenuEntryActionViewItem(action, this.keybindingService, this.notificationService);
return new MenuEntryActionViewItem(action, undefined, this.keybindingService, this.notificationService);
}
}
@@ -232,7 +232,7 @@ class TerminalTabsRenderer implements IListRenderer<ITerminalInstance, ITerminal
const actionBar = new ActionBar(actionsContainer, {
actionViewItemProvider: action =>
action instanceof MenuItemAction
? this._instantiationService.createInstance(MenuEntryActionViewItem, action)
? this._instantiationService.createInstance(MenuEntryActionViewItem, action, undefined)
: undefined
});
@@ -44,6 +44,7 @@ import { ColorScheme } from 'vs/platform/theme/common/theme';
import { getColorClass, getUriClasses } from 'vs/workbench/contrib/terminal/browser/terminalIcon';
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
import { withNullAsUndefined } from 'vs/base/common/types';
import { DataTransfers } from 'vs/base/browser/dnd';
export class TerminalViewPane extends ViewPane {
private _actions: IAction[] | undefined;
@@ -426,7 +427,9 @@ class SingleTerminalTabActionViewItem extends MenuEntryActionViewItem {
undefined,
contextKeyService,
_commandService
), keybindingService, notificationService);
), {
draggable: true
}, keybindingService, notificationService);
// Register listeners to update the tab
this._register(this._terminalService.onInstancePrimaryStatusChanged(e => this.updateLabel(e)));
@@ -457,21 +460,29 @@ class SingleTerminalTabActionViewItem extends MenuEntryActionViewItem {
return;
}
if (this._elementDisposables.length === 0) {
if (this._elementDisposables.length === 0 && this.element && this.label) {
// Right click opens context menu
this._elementDisposables.push(dom.addDisposableListener(this.element!, dom.EventType.CONTEXT_MENU, e => {
this._elementDisposables.push(dom.addDisposableListener(this.element, dom.EventType.CONTEXT_MENU, e => {
if (e.button === 2) {
this._openContextMenu();
e.preventDefault();
}
}));
// Middle click kills
this._elementDisposables.push(dom.addDisposableListener(this.element!, dom.EventType.AUXCLICK, e => {
this._elementDisposables.push(dom.addDisposableListener(this.element, dom.EventType.AUXCLICK, e => {
if (e.button === 1) {
this._terminalService.activeInstance?.dispose();
e.preventDefault();
}
}));
// Drag and drop
this._elementDisposables.push(dom.addDisposableListener(this.element, dom.EventType.DRAG_START, e => {
const instance = this._terminalGroupService.activeInstance;
if (e.dataTransfer && instance) {
e.dataTransfer.setData(DataTransfers.RESOURCES, JSON.stringify([instance.resource.toString()]));
e.dataTransfer.setData(DataTransfers.TERMINALS, JSON.stringify([instance.instanceId]));
}
}));
}
if (this.label) {
const label = this.label;
@@ -914,7 +914,7 @@ abstract class ActionableItemTemplateData<T extends TestItemTreeElement> extends
actionRunner: this.actionRunner,
actionViewItemProvider: action =>
action instanceof MenuItemAction
? this.instantiationService.createInstance(MenuEntryActionViewItem, action)
? this.instantiationService.createInstance(MenuEntryActionViewItem, action, undefined)
: undefined
});
@@ -1223,7 +1223,7 @@ class TestRunElementRenderer implements ICompressibleTreeRenderer<ITreeElement,
const actionBar = new ActionBar(wrapper, {
actionViewItemProvider: action =>
action instanceof MenuItemAction
? this.instantiationService.createInstance(MenuEntryActionViewItem, action)
? this.instantiationService.createInstance(MenuEntryActionViewItem, action, undefined)
: undefined
});