From a856e60a0cfcc9609f46855062162e8aa4b69c08 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 10 Nov 2020 15:33:09 -0800 Subject: [PATCH] Better support dragging and dropping with webview views Fixes #108953 --- .../browser/webviewWindowDragMonitor.ts | 35 +++++++++++++++++++ .../webviewPanel/browser/webviewEditor.ts | 15 ++------ .../webviewView/browser/webviewViewPane.ts | 8 +++-- 3 files changed, 43 insertions(+), 15 deletions(-) create mode 100644 src/vs/workbench/contrib/webview/browser/webviewWindowDragMonitor.ts diff --git a/src/vs/workbench/contrib/webview/browser/webviewWindowDragMonitor.ts b/src/vs/workbench/contrib/webview/browser/webviewWindowDragMonitor.ts new file mode 100644 index 00000000000..3bbc9e85798 --- /dev/null +++ b/src/vs/workbench/contrib/webview/browser/webviewWindowDragMonitor.ts @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as DOM from 'vs/base/browser/dom'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { Webview } from 'vs/workbench/contrib/webview/browser/webview'; + +/** + * Allows webviews to monitor when an element in the VS Code editor is being dragged/dropped. + * + * This is required since webview end up eating the drag event. VS Code needs to see this + * event so it can handle editor element drag drop. + */ +export class WebviewWindowDragMonitor extends Disposable { + constructor(getWebview: () => Webview | undefined) { + super(); + + this._register(DOM.addDisposableListener(window, DOM.EventType.DRAG_START, () => { + getWebview()?.windowDidDragStart(); + })); + + const onDragEnd = () => { + getWebview()?.windowDidDragEnd(); + }; + + this._register(DOM.addDisposableListener(window, DOM.EventType.DRAG_END, onDragEnd)); + this._register(DOM.addDisposableListener(window, DOM.EventType.MOUSE_MOVE, currentEvent => { + if (currentEvent.buttons === 0) { + onDragEnd(); + } + })); + } +} diff --git a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts index d277dbcbd96..7849aedb38b 100644 --- a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts +++ b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts @@ -15,6 +15,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; import { EditorInput, EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor'; import { WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview'; +import { WebviewWindowDragMonitor } from 'vs/workbench/contrib/webview/browser/webviewWindowDragMonitor'; import { WebviewInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditorInput'; import { IEditorDropService } from 'vs/workbench/services/editor/browser/editorDropService'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -155,19 +156,7 @@ export class WebviewEditor extends EditorPane { containsGroup: (group) => this.group?.id === group.group.id })); - this._webviewVisibleDisposables.add(DOM.addDisposableListener(window, DOM.EventType.DRAG_START, () => { - this.webview?.windowDidDragStart(); - })); - - const onDragEnd = () => { - this.webview?.windowDidDragEnd(); - }; - this._webviewVisibleDisposables.add(DOM.addDisposableListener(window, DOM.EventType.DRAG_END, onDragEnd)); - this._webviewVisibleDisposables.add(DOM.addDisposableListener(window, DOM.EventType.MOUSE_MOVE, currentEvent => { - if (currentEvent.buttons === 0) { - onDragEnd(); - } - })); + this._webviewVisibleDisposables.add(new WebviewWindowDragMonitor(() => this.webview)); this.synchronizeWebviewContainerDimensions(input.webview); this._webviewVisibleDisposables.add(this.trackFocus(input.webview)); diff --git a/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts b/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts index df90ede801c..e2b992d1b32 100644 --- a/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts +++ b/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Dimension } from 'vs/base/browser/dom'; +import * as DOM from 'vs/base/browser/dom'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { Emitter } from 'vs/base/common/event'; import { DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; @@ -24,6 +24,7 @@ import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewl import { Memento, MementoObject } from 'vs/workbench/common/memento'; import { IViewDescriptorService, IViewsService } from 'vs/workbench/common/views'; import { IWebviewService, WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview'; +import { WebviewWindowDragMonitor } from 'vs/workbench/contrib/webview/browser/webviewWindowDragMonitor'; import { IWebviewViewService, WebviewView } from 'vs/workbench/contrib/webviewView/browser/webviewViewService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -139,7 +140,7 @@ export class WebviewViewPane extends ViewPane { } if (this._container) { - this._webview.value.layoutWebviewOverElement(this._container, new Dimension(width, height)); + this._webview.value.layoutWebviewOverElement(this._container, new DOM.Dimension(width, height)); } } @@ -172,6 +173,9 @@ export class WebviewViewPane extends ViewPane { this._webviewDisposables.add(webview.onDidUpdateState(() => { this.viewState[storageKeys.webviewState] = webview.state; })); + + this._webviewDisposables.add(new WebviewWindowDragMonitor(() => this._webview.value)); + const source = this._webviewDisposables.add(new CancellationTokenSource()); this.withProgress(async () => { -- GitLab