Skip to content

Commit

Permalink
Merge pull request #206363 from microsoft/rebornix/ltd-platypus
Browse files Browse the repository at this point in the history
Move off  in Webview
  • Loading branch information
rebornix committed Mar 12, 2024
2 parents af3992d + 2010576 commit 19de9d2
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 105 deletions.
7 changes: 0 additions & 7 deletions src/vs/base/browser/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ export function ensureCodeWindow(targetWindow: Window, fallbackWindowId: number)
// eslint-disable-next-line no-restricted-globals
export const mainWindow = window as CodeWindow;

/**
* @deprecated to support multi-window scenarios, use `DOM.mainWindow`
* if you target the main global window or use helpers such as `DOM.getWindow()`
* or `DOM.getActiveWindow()` to obtain the correct window for the context you are in.
*/
export const $window = mainWindow;

export function isAuxiliaryWindow(obj: Window): obj is CodeWindow {
if (obj === mainWindow) {
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/vs/editor/browser/services/editorWorkerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/di
import { ILinesDiffComputerOptions, MovedText } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping, RangeMapping, LineRangeMapping } from 'vs/editor/common/diff/rangeMapping';
import { LineRange } from 'vs/editor/common/core/lineRange';
import { $window } from 'vs/base/browser/window';
import { mainWindow } from 'vs/base/browser/window';
import { WindowIntervalTimer } from 'vs/base/browser/dom';

/**
Expand Down Expand Up @@ -283,7 +283,7 @@ class WorkerManager extends Disposable {
this._lastWorkerUsedTime = (new Date()).getTime();

const stopWorkerInterval = this._register(new WindowIntervalTimer());
stopWorkerInterval.cancelAndSet(() => this._checkStopIdleWorker(), Math.round(STOP_WORKER_DELTA_TIME_MS / 2), $window);
stopWorkerInterval.cancelAndSet(() => this._checkStopIdleWorker(), Math.round(STOP_WORKER_DELTA_TIME_MS / 2), mainWindow);

this._register(this._modelService.onModelRemoved(_ => this._checkStopEmptyWorker()));
}
Expand Down
3 changes: 2 additions & 1 deletion src/vs/workbench/api/browser/mainThreadCodeInsets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { getWindow } from 'vs/base/browser/dom';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { isEqual } from 'vs/base/common/resources';
import { URI, UriComponents } from 'vs/base/common/uri';
Expand Down Expand Up @@ -43,7 +44,7 @@ class EditorWebviewZone implements IViewZone {
this.heightInLines = height;

editor.changeViewZones(accessor => this._id = accessor.addZone(this));
webview.mountTo(this.domNode);
webview.mountTo(this.domNode, getWindow(editor.getDomNode()));
}

dispose(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput {
let capabilities = EditorInputCapabilities.None;

capabilities |= EditorInputCapabilities.CanDropIntoEditor;
capabilities |= EditorInputCapabilities.AuxWindowUnsupported;

if (!this.customEditorService.getCustomEditorCapabilities(this.viewType)?.supportsMultipleEditorsPerDocument) {
capabilities |= EditorInputCapabilities.Singleton;
Expand All @@ -153,6 +152,11 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput {

if (this.resource.scheme === Schemas.untitled) {
capabilities |= EditorInputCapabilities.Untitled;
capabilities |= EditorInputCapabilities.AuxWindowUnsupported;
}

if (this.isDirty()) {
capabilities |= EditorInputCapabilities.AuxWindowUnsupported;
}

return capabilities;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -676,12 +676,12 @@ export class ExtensionEditor extends EditorPane {

webview.initialScrollProgress = this.initialScrollProgress.get(webviewIndex) || 0;

webview.claim(this, this.scopedContextKeyService);
webview.claim(this, this.window, this.scopedContextKeyService);
setParentFlowTo(webview.container, container);
webview.layoutWebviewOverElement(container);

webview.setHtml(body);
webview.claim(this, undefined);
webview.claim(this, this.window, undefined);

this.contentDisposables.add(webview.onDidFocus(() => this._onDidFocus?.fire()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -513,10 +513,10 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
return !!this.webview;
}

createWebview(codeWindow: CodeWindow): Promise<void> {
createWebview(targetWindow: CodeWindow): Promise<void> {
const baseUrl = this.asWebviewUri(this.getNotebookBaseUri(), undefined);
const htmlContent = this.generateContent(baseUrl.toString());
return this._initialize(htmlContent, codeWindow);
return this._initialize(htmlContent, targetWindow);
}

private getNotebookBaseUri() {
Expand Down Expand Up @@ -551,16 +551,16 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
];
}

private _initialize(content: string, codeWindow: CodeWindow): Promise<void> {
private _initialize(content: string, targetWindow: CodeWindow): Promise<void> {
if (!getWindow(this.element).document.body.contains(this.element)) {
throw new Error('Element is already detached from the DOM tree');
}

this.webview = this._createInset(this.webviewService, content, codeWindow);
this.webview.mountTo(this.element);
this.webview = this._createInset(this.webviewService, content);
this.webview.mountTo(this.element, targetWindow);
this._register(this.webview);

this._register(new WebviewWindowDragMonitor(() => this.webview));
this._register(new WebviewWindowDragMonitor(targetWindow, () => this.webview));

const initializePromise = new DeferredPromise<void>();

Expand Down Expand Up @@ -1123,7 +1123,7 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
await this.openerService.open(newFileUri);
}

private _createInset(webviewService: IWebviewService, content: string, codeWindow: CodeWindow) {
private _createInset(webviewService: IWebviewService, content: string) {
this.localResourceRootsCache = this._getResourceRootsCache();
const webview = webviewService.createWebviewElement({
origin: BackLayerWebView.getOriginStore(this.storageService).getOrigin(this.notebookViewType, undefined),
Expand All @@ -1139,8 +1139,7 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
localResourceRoots: this.localResourceRootsCache,
},
extension: undefined,
providedViewType: 'notebook.output',
codeWindow: codeWindow
providedViewType: 'notebook.output'
});

webview.setHtml(content);
Expand Down
27 changes: 21 additions & 6 deletions src/vs/workbench/contrib/webview/browser/overlayWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { Dimension } from 'vs/base/browser/dom';
import { Dimension, getWindowById } from 'vs/base/browser/dom';
import { FastDomNode } from 'vs/base/browser/fastDomNode';
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { CodeWindow, mainWindow } from 'vs/base/browser/window';
import { Emitter } from 'vs/base/common/event';
import { Disposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
Expand Down Expand Up @@ -36,6 +37,9 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {

private _owner: any = undefined;

private _windowId: number | undefined = undefined;
private get window() { return typeof this._windowId === 'number' ? getWindowById(this._windowId)?.window : undefined; }

private readonly _scopedContextKeyService = this._register(new MutableDisposable<IScopedContextKeyService>());
private _findWidgetVisible: IContextKey<boolean> | undefined;
private _findWidgetEnabled: IContextKey<boolean> | undefined;
Expand Down Expand Up @@ -103,21 +107,32 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {

// Webviews cannot be reparented in the dom as it will destroy their contents.
// Mount them to a high level node to avoid this.
this._layoutService.mainContainer.appendChild(node);
this._layoutService.getContainer(this.window ?? mainWindow).appendChild(node);
}

return this._container.domNode;
}

public claim(owner: any, scopedContextKeyService: IContextKeyService | undefined) {
public claim(owner: any, targetWindow: CodeWindow, scopedContextKeyService: IContextKeyService | undefined) {
if (this._isDisposed) {
return;
}

const oldOwner = this._owner;

if (this._windowId !== targetWindow.vscodeWindowId) {
// moving to a new window
this.release(oldOwner);
// since we are moving to a new window, we need to dispose the webview and recreate
this._webview.clear();
this._webviewEvents.clear();
this._container?.domNode.remove();
this._container = undefined;
}

this._owner = owner;
this._show();
this._windowId = targetWindow.vscodeWindowId;
this._show(targetWindow);

if (oldOwner !== owner) {
const contextKeyService = (scopedContextKeyService || this._baseContextKeyService);
Expand Down Expand Up @@ -184,7 +199,7 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {
}
}

private _show() {
private _show(targetWindow: CodeWindow) {
if (this._isDisposed) {
throw new Error('OverlayWebview is disposed');
}
Expand Down Expand Up @@ -215,7 +230,7 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {

this._findWidgetEnabled?.set(!!this.options.enableFindWidget);

webview.mountTo(this.container);
webview.mountTo(this.container, targetWindow);

// Forward events from inner webview to outer listeners
this._webviewEvents.clear();
Expand Down
5 changes: 2 additions & 3 deletions src/vs/workbench/contrib/webview/browser/webview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ export interface WebviewInitInfo {
readonly contentOptions: WebviewContentOptions;

readonly extension: WebviewExtensionDescription | undefined;
readonly codeWindow?: CodeWindow;
}

export const enum WebviewContentPurpose {
Expand Down Expand Up @@ -278,7 +277,7 @@ export interface IWebviewElement extends IWebview {
*
* @param parent Element to append the webview to.
*/
mountTo(parent: HTMLElement): void;
mountTo(parent: HTMLElement, targetWindow: CodeWindow): void;
}

/**
Expand Down Expand Up @@ -308,7 +307,7 @@ export interface IOverlayWebview extends IWebview {
* @param claimant Identifier for the object claiming the webview.
* This must match the `claimant` passed to {@link IOverlayWebview.release}.
*/
claim(claimant: any, scopedContextKeyService: IContextKeyService | undefined): void;
claim(claimant: any, targetWindow: CodeWindow, scopedContextKeyService: IContextKeyService | undefined): void;

/**
* Release ownership of the webview.
Expand Down

0 comments on commit 19de9d2

Please sign in to comment.