diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 1949053395a..0fd241f3313 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -176,14 +176,14 @@ export function addDisposableGenericMouseUpListener(node: EventTarget, handler: * If currently in an animation frame, `runner` will be executed immediately. * @return token that can be used to cancel the scheduled runner (only if `runner` was not executed immediately). */ -export let runAtThisOrScheduleAtNextAnimationFrame: (runner: () => void, priority?: number) => IDisposable; +export let runAtThisOrScheduleAtNextAnimationFrame: (runner: () => void, targetWindow: Window, priority?: number) => IDisposable; /** * Schedule a callback to be run at the next animation frame. * This allows multiple parties to register callbacks that should run at the next animation frame. * If currently in an animation frame, `runner` will be executed at the next animation frame. * @return token that can be used to cancel the scheduled runner. */ -export let scheduleAtNextAnimationFrame: (runner: () => void, priority?: number) => IDisposable; +export let scheduleAtNextAnimationFrame: (runner: () => void, targetWindow: Window, priority?: number) => IDisposable; class AnimationFrameQueueItem implements IDisposable { @@ -252,35 +252,35 @@ class AnimationFrameQueueItem implements IDisposable { inAnimationFrameRunner = false; }; - scheduleAtNextAnimationFrame = (runner: () => void, priority: number = 0) => { + scheduleAtNextAnimationFrame = (runner: () => void, targetWindow: Window, priority: number = 0) => { const item = new AnimationFrameQueueItem(runner, priority); NEXT_QUEUE.push(item); if (!animFrameRequested) { animFrameRequested = true; - requestAnimationFrame(animationFrameRunner); + targetWindow.requestAnimationFrame(animationFrameRunner); } return item; }; - runAtThisOrScheduleAtNextAnimationFrame = (runner: () => void, priority?: number) => { + runAtThisOrScheduleAtNextAnimationFrame = (runner: () => void, targetWindow: Window, priority?: number) => { if (inAnimationFrameRunner) { const item = new AnimationFrameQueueItem(runner, priority); CURRENT_QUEUE!.push(item); return item; } else { - return scheduleAtNextAnimationFrame(runner, priority); + return scheduleAtNextAnimationFrame(runner, targetWindow, priority); } }; })(); -export function measure(callback: () => void): IDisposable { - return scheduleAtNextAnimationFrame(callback, 10000 /* must be early */); +export function measure(callback: () => void, targetWindow: Window): IDisposable { + return scheduleAtNextAnimationFrame(callback, targetWindow, 10000 /* must be early */); } -export function modify(callback: () => void): IDisposable { - return scheduleAtNextAnimationFrame(callback, -10000 /* must be late */); +export function modify(callback: () => void, targetWindow: Window): IDisposable { + return scheduleAtNextAnimationFrame(callback, targetWindow, -10000 /* must be late */); } /** @@ -780,16 +780,15 @@ export function getActiveWindow(): WindowGlobal { return document.defaultView?.window ?? window; } -export function getWindow(element: Node): WindowGlobal; -export function getWindow(event: UIEvent): WindowGlobal; -export function getWindow(obj: unknown): WindowGlobal; +export function getWindow(element: Node | undefined | null): WindowGlobal; +export function getWindow(event: UIEvent | undefined | null): WindowGlobal; export function getWindow(e: unknown): WindowGlobal { - const candidateNode = e as Node | undefined; + const candidateNode = e as Node | undefined | null; if (candidateNode?.ownerDocument?.defaultView) { return candidateNode.ownerDocument.defaultView.window; } - const candidateEvent = e as UIEvent | undefined; + const candidateEvent = e as UIEvent | undefined | null; if (candidateEvent?.view) { return candidateEvent.view.window; } @@ -996,22 +995,22 @@ function isCSSStyleRule(rule: CSSRule): rule is CSSStyleRule { export function isMouseEvent(e: unknown): e is MouseEvent { // eslint-disable-next-line no-restricted-syntax - return e instanceof MouseEvent || e instanceof getWindow(e).MouseEvent; + return e instanceof MouseEvent || e instanceof getWindow(e as UIEvent).MouseEvent; } export function isKeyboardEvent(e: unknown): e is KeyboardEvent { // eslint-disable-next-line no-restricted-syntax - return e instanceof KeyboardEvent || e instanceof getWindow(e).KeyboardEvent; + return e instanceof KeyboardEvent || e instanceof getWindow(e as UIEvent).KeyboardEvent; } export function isPointerEvent(e: unknown): e is PointerEvent { // eslint-disable-next-line no-restricted-syntax - return e instanceof PointerEvent || e instanceof getWindow(e).PointerEvent; + return e instanceof PointerEvent || e instanceof getWindow(e as UIEvent).PointerEvent; } export function isDragEvent(e: unknown): e is DragEvent { // eslint-disable-next-line no-restricted-syntax - return e instanceof DragEvent || e instanceof getWindow(e).DragEvent; + return e instanceof DragEvent || e instanceof getWindow(e as UIEvent).DragEvent; } export const EventType = { @@ -1463,13 +1462,13 @@ export function windowOpenWithSuccess(url: string, noOpener = true): boolean { return false; } -export function animate(fn: () => void): IDisposable { +export function animate(fn: () => void, targetWindow: Window): IDisposable { const step = () => { fn(); - stepDisposable = scheduleAtNextAnimationFrame(step); + stepDisposable = scheduleAtNextAnimationFrame(step, targetWindow); }; - let stepDisposable = scheduleAtNextAnimationFrame(step); + let stepDisposable = scheduleAtNextAnimationFrame(step, targetWindow); return toDisposable(() => stepDisposable.dispose()); } diff --git a/src/vs/base/browser/touch.ts b/src/vs/base/browser/touch.ts index dd74dca3eb4..23607237cd2 100644 --- a/src/vs/base/browser/touch.ts +++ b/src/vs/base/browser/touch.ts @@ -93,7 +93,7 @@ export class Gesture extends Disposable { this._register(EventUtils.runAndSubscribe(DomUtils.onDidRegisterWindow, ({ window, disposables }) => { disposables.add(DomUtils.addDisposableListener(window.document, 'touchstart', (e: TouchEvent) => this.onTouchStart(e), { passive: false })); - disposables.add(DomUtils.addDisposableListener(window.document, 'touchend', (e: TouchEvent) => this.onTouchEnd(e))); + disposables.add(DomUtils.addDisposableListener(window.document, 'touchend', (e: TouchEvent) => this.onTouchEnd(window, e))); disposables.add(DomUtils.addDisposableListener(window.document, 'touchmove', (e: TouchEvent) => this.onTouchMove(e), { passive: false })); }, { window, disposables: this._store })); } @@ -173,7 +173,7 @@ export class Gesture extends Disposable { } } - private onTouchEnd(e: TouchEvent): void { + private onTouchEnd(targetWindow: Window, e: TouchEvent): void { const timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based. const activeTouchCount = Object.keys(this.activeTouches).length; @@ -218,13 +218,13 @@ export class Gesture extends Disposable { // We need to get all the dispatch targets on the start of the inertia event const dispatchTo = [...this.targets].filter(t => data.initialTarget instanceof Node && t.contains(data.initialTarget)); - this.inertia(dispatchTo, timestamp, // time now - Math.abs(deltaX) / deltaT, // speed - deltaX > 0 ? 1 : -1, // x direction - finalX, // x now - Math.abs(deltaY) / deltaT, // y speed - deltaY > 0 ? 1 : -1, // y direction - finalY // y now + this.inertia(targetWindow, dispatchTo, timestamp, // time now + Math.abs(deltaX) / deltaT, // speed + deltaX > 0 ? 1 : -1, // x direction + finalX, // x now + Math.abs(deltaY) / deltaT, // y speed + deltaY > 0 ? 1 : -1, // y direction + finalY // y now ); } @@ -282,7 +282,7 @@ export class Gesture extends Disposable { } } - private inertia(dispatchTo: readonly EventTarget[], t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void { + private inertia(targetWindow: Window, dispatchTo: readonly EventTarget[], t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void { this.handle = DomUtils.scheduleAtNextAnimationFrame(() => { const now = Date.now(); @@ -311,9 +311,9 @@ export class Gesture extends Disposable { dispatchTo.forEach(d => d.dispatchEvent(evt)); if (!stopped) { - this.inertia(dispatchTo, now, vX, dirX, x + delta_pos_x, vY, dirY, y + delta_pos_y); + this.inertia(targetWindow, dispatchTo, now, vX, dirX, x + delta_pos_x, vY, dirY, y + delta_pos_y); } - }); + }, targetWindow); } private onTouchMove(e: TouchEvent): void { diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index 3775611c73a..6c4edfef56d 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -128,7 +128,7 @@ export class BreadcrumbsWidget { this._domNode.style.width = `${dim.width}px`; this._domNode.style.height = `${dim.height}px`; disposables.add(this._updateScrollbar()); - })); + }, dom.getWindow(this._domNode))); return disposables; } @@ -138,8 +138,8 @@ export class BreadcrumbsWidget { this._scrollable.setRevealOnScroll(false); this._scrollable.scanDomNode(); this._scrollable.setRevealOnScroll(true); - }); - }); + }, dom.getWindow(this._domNode)); + }, dom.getWindow(this._domNode)); } private _style(styleElement: HTMLStyleElement, style: IBreadcrumbsWidgetStyles): void { diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index 9090f95fa79..24af99d7e50 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd'; -import { $, addDisposableListener, animate, Dimension, getContentHeight, getContentWidth, getTopLeftOffset, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; +import { $, addDisposableListener, animate, Dimension, getContentHeight, getContentWidth, getTopLeftOffset, getWindow, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; import { EventType as TouchEventType, Gesture, GestureEvent } from 'vs/base/browser/touch'; @@ -407,7 +407,7 @@ export class ListView implements IListView { this.scrollable = this.disposables.add(new Scrollable({ forceIntegerValues: true, smoothScrollDuration: (options.smoothScrolling ?? false) ? 125 : 0, - scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(cb) + scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(cb, getWindow(this.domNode)) })); this.scrollableElement = this.disposables.add(new SmoothScrollableElement(this.rowsContainer, { alwaysConsumeMouseWheel: options.alwaysConsumeMouseWheel ?? DefaultOptions.alwaysConsumeMouseWheel, @@ -684,7 +684,7 @@ export class ListView implements IListView { this.scrollableElement.setScrollDimensions({ scrollHeight: this.scrollHeight }); this.updateScrollWidth(); this.scrollableElementUpdateDisposable = null; - }); + }, getWindow(this.domNode)); } } @@ -1291,7 +1291,7 @@ export class ListView implements IListView { private setupDragAndDropScrollTopAnimation(event: DragEvent): void { if (!this.dragOverAnimationDisposable) { const viewTop = getTopLeftOffset(this.domNode).top; - this.dragOverAnimationDisposable = animate(this.animateDragAndDropScrollTop.bind(this, viewTop)); + this.dragOverAnimationDisposable = animate(this.animateDragAndDropScrollTop.bind(this, viewTop), getWindow(this.domNode)); } this.dragOverAnimationStopDisposable.dispose(); diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index ce52caea6f1..58b3f29af0f 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -630,7 +630,7 @@ export class MenuBar extends Disposable { this.overflowLayoutScheduled = DOM.scheduleAtNextAnimationFrame(() => { this.updateOverflowAction(); this.overflowLayoutScheduled = undefined; - }); + }, DOM.getWindow(this.container)); } this.setUnfocusedState(); diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index 6cb673170c8..ac02cd0c567 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -576,7 +576,7 @@ export class ScrollableElement extends AbstractScrollableElement { const scrollable = new Scrollable({ forceIntegerValues: true, smoothScrollDuration: 0, - scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(callback) + scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(callback, dom.getWindow(element)) }); super(element, options, scrollable); this._register(scrollable); @@ -621,7 +621,7 @@ export class DomScrollableElement extends AbstractScrollableElement { const scrollable = new Scrollable({ forceIntegerValues: false, // See https://github.com/microsoft/vscode/issues/139877 smoothScrollDuration: 0, - scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(callback) + scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(callback, dom.getWindow(element)) }); super(element, options, scrollable); this._register(scrollable); diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 8f63b6039a1..e88947b044e 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { $, addDisposableListener, append, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; +import { $, addDisposableListener, append, getWindow, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { ISashEvent as IBaseSashEvent, Orientation, Sash, SashState } from 'vs/base/browser/ui/sash/sash'; import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; @@ -584,7 +584,7 @@ export class SplitView scheduleAtNextAnimationFrame(callback, getWindow(this.el)), })); this.scrollableElement = this._register(new SmoothScrollableElement(this.viewContainer, { vertical: this.orientation === Orientation.VERTICAL ? (options.scrollbarVisibility ?? ScrollbarVisibility.Auto) : ScrollbarVisibility.Hidden, diff --git a/src/vs/editor/browser/config/elementSizeObserver.ts b/src/vs/editor/browser/config/elementSizeObserver.ts index f6b344f1872..a7da5f289ed 100644 --- a/src/vs/editor/browser/config/elementSizeObserver.ts +++ b/src/vs/editor/browser/config/elementSizeObserver.ts @@ -6,6 +6,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IDimension } from 'vs/editor/common/core/dimension'; import { Emitter, Event } from 'vs/base/common/event'; +import { getWindow, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; export class ElementSizeObserver extends Disposable { @@ -65,10 +66,10 @@ export class ElementSizeObserver extends Disposable { alreadyObservedThisAnimationFrame = true; observeNow(); } finally { - requestAnimationFrame(() => { + scheduleAtNextAnimationFrame(() => { alreadyObservedThisAnimationFrame = false; update(); - }); + }, getWindow(this._referenceDomElement)); } } }; diff --git a/src/vs/editor/browser/controller/mouseHandler.ts b/src/vs/editor/browser/controller/mouseHandler.ts index cc23b026471..6796378114d 100644 --- a/src/vs/editor/browser/controller/mouseHandler.ts +++ b/src/vs/editor/browser/controller/mouseHandler.ts @@ -682,7 +682,7 @@ class TopBottomDragScrollingOperation extends Disposable { this._position = position; this._mouseEvent = mouseEvent; this._lastTime = Date.now(); - this._animationFrameDisposable = dom.scheduleAtNextAnimationFrame(() => this._execute()); + this._animationFrameDisposable = dom.scheduleAtNextAnimationFrame(() => this._execute(), dom.getWindow(mouseEvent.browserEvent)); } public override dispose(): void { @@ -752,7 +752,7 @@ class TopBottomDragScrollingOperation extends Disposable { } this._dispatchMouse(mouseTarget, true, NavigationCommandRevealType.None); - this._animationFrameDisposable = dom.scheduleAtNextAnimationFrame(() => this._execute()); + this._animationFrameDisposable = dom.scheduleAtNextAnimationFrame(() => this._execute(), dom.getWindow(mouseTarget.element)); } } diff --git a/src/vs/editor/browser/view.ts b/src/vs/editor/browser/view.ts index ff4b7514f27..700b1d55b1d 100644 --- a/src/vs/editor/browser/view.ts +++ b/src/vs/editor/browser/view.ts @@ -432,7 +432,7 @@ export class View extends ViewEventHandler { private _scheduleRender(): void { if (this._renderAnimationFrame === null) { - this._renderAnimationFrame = dom.runAtThisOrScheduleAtNextAnimationFrame(this._onRenderScheduled.bind(this), 100); + this._renderAnimationFrame = dom.runAtThisOrScheduleAtNextAnimationFrame(this._onRenderScheduled.bind(this), dom.getWindow(this.domNode.domNode), 100); } } diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index a09df64b633..36506e9fed0 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -146,7 +146,7 @@ export class ViewCursor { return null; } - const window = dom.getWindow(this._domNode); + const window = dom.getWindow(this._domNode.domNode); let width: number; if (this._cursorStyle === TextEditorCursorStyle.Line) { width = dom.computeScreenAwareSize(window, this._lineCursorWidth > 0 ? this._lineCursorWidth : 2); diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index c1ea768376a..93407998bc0 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1648,7 +1648,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE model, DOMLineBreaksComputerFactory.create(), MonospaceLineBreaksComputerFactory.create(this._configuration.options), - (callback) => dom.scheduleAtNextAnimationFrame(callback), + (callback) => dom.scheduleAtNextAnimationFrame(callback, dom.getWindow(this._domElement)), this.languageConfigurationService, this._themeService, attachedView, diff --git a/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts index b125fb00c01..1a4a07758c5 100644 --- a/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { $, h } from 'vs/base/browser/dom'; +import { $, getWindow, h } from 'vs/base/browser/dom'; import { IBoundarySashes } from 'vs/base/browser/ui/sash/sash'; import { findLast } from 'vs/base/common/arraysFind'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -178,6 +178,7 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor { /** @description ViewZoneManager */ store.add(this._instantiationService.createInstance( readHotReloadableExport(ViewZoneManager, reader), + getWindow(this._domElement), this._editors, this._diffModel, this._options, diff --git a/src/vs/editor/browser/widget/diffEditor/lineAlignment.ts b/src/vs/editor/browser/widget/diffEditor/lineAlignment.ts index 893e4000c93..698734aeba0 100644 --- a/src/vs/editor/browser/widget/diffEditor/lineAlignment.ts +++ b/src/vs/editor/browser/widget/diffEditor/lineAlignment.ts @@ -42,14 +42,15 @@ export class ViewZoneManager extends Disposable { private readonly _originalTopPadding = observableValue(this, 0); private readonly _originalScrollTop: IObservable; private readonly _originalScrollOffset = observableValue(this, 0); - private readonly _originalScrollOffsetAnimated = animatedObservable(this._originalScrollOffset, this._store); + private readonly _originalScrollOffsetAnimated = animatedObservable(this._targetWindow, this._originalScrollOffset, this._store); private readonly _modifiedTopPadding = observableValue(this, 0); private readonly _modifiedScrollTop: IObservable; private readonly _modifiedScrollOffset = observableValue(this, 0); - private readonly _modifiedScrollOffsetAnimated = animatedObservable(this._modifiedScrollOffset, this._store); + private readonly _modifiedScrollOffsetAnimated = animatedObservable(this._targetWindow, this._modifiedScrollOffset, this._store); constructor( + private readonly _targetWindow: Window, private readonly _editors: DiffEditorEditors, private readonly _diffModel: IObservable, private readonly _options: DiffEditorOptions, diff --git a/src/vs/editor/browser/widget/diffEditor/utils.ts b/src/vs/editor/browser/widget/diffEditor/utils.ts index 352ff672edc..81b00083ac7 100644 --- a/src/vs/editor/browser/widget/diffEditor/utils.ts +++ b/src/vs/editor/browser/widget/diffEditor/utils.ts @@ -123,7 +123,7 @@ export class ObservableElementSizeObserver extends Disposable { } } -export function animatedObservable(base: IObservable, store: DisposableStore): IObservable { +export function animatedObservable(targetWindow: Window, base: IObservable, store: DisposableStore): IObservable { let targetVal = base.get(); let startVal = targetVal; let curVal = targetVal; @@ -160,7 +160,7 @@ export function animatedObservable(base: IObservable, store: Di curVal = Math.floor(easeOutExpo(passedMs, startVal, targetVal - startVal, durationMs)); if (passedMs < durationMs) { - animationFrame = requestAnimationFrame(update); + animationFrame = targetWindow.requestAnimationFrame(update); } else { curVal = targetVal; } diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index b86e2fd94ef..aa78d74936a 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -571,7 +571,7 @@ export class SuggestWidget implements IDisposable { this._layout(this.element.size); // Reset focus border this._details.widget.domNode.classList.remove('focused'); - }); + }, dom.getWindow(this.element.domNode)); } focusSelected(): void { @@ -721,7 +721,7 @@ export class SuggestWidget implements IDisposable { this._positionDetails(); this.editor.focus(); this.element.domNode.classList.add('shows-details'); - }); + }, dom.getWindow(this.element.domNode)); } toggleExplainMode(): void { diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 4a1b22ae99f..d019690429b 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -315,7 +315,6 @@ const nlsMultiSelection = localize('multiSelection', "{0} selections"); const nlsEOLLF = localize('endOfLineLineFeed', "LF"); const nlsEOLCRLF = localize('endOfLineCarriageReturnLineFeed', "CRLF"); - export class EditorStatus extends Disposable implements IWorkbenchContribution { private readonly tabFocusModeElement = this._register(new MutableDisposable()); @@ -335,6 +334,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { private toRender: StateChange | undefined = undefined; private editorService: IEditorService; + private targetWindow = window; constructor( @IEditorService editorService: IEditorService, @@ -570,7 +570,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { if (toRender) { this.doRenderNow(); } - }); + }, this.targetWindow); } else { this.toRender.combine(changed); } diff --git a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts index 0acabfac24d..5e40698cef7 100644 --- a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts @@ -1039,7 +1039,7 @@ export class MultiEditorTabsControl extends EditorTabsControl { // Fixes https://github.com/microsoft/vscode/issues/18733 tab.classList.add('dragged'); - scheduleAtNextAnimationFrame(() => tab.classList.remove('dragged')); + scheduleAtNextAnimationFrame(() => tab.classList.remove('dragged'), getWindow(tab)); })); // Drop support @@ -1610,16 +1610,25 @@ export class MultiEditorTabsControl extends EditorTabsControl { Object.assign(this.dimensions, dimensions); if (this.visible) { - // The layout of tabs can be an expensive operation because we access DOM properties - // that can result in the browser doing a full page layout to validate them. To buffer - // this a little bit we try at least to schedule this work on the next animation frame - // when we have restored or when idle otherwise. if (!this.layoutScheduler.value) { - const scheduledLayout = (this.lifecycleService.phase >= LifecyclePhase.Restored ? scheduleAtNextAnimationFrame : runWhenIdle)(() => { + + // The layout of tabs can be an expensive operation because we access DOM properties + // that can result in the browser doing a full page layout to validate them. To buffer + // this a little bit we try at least to schedule this work on the next animation frame + // when we have restored or when idle otherwise. + + const layoutFunction = () => { this.doLayout(this.dimensions, this.layoutScheduler.value?.options /* ensure to pick up latest options */); this.layoutScheduler.clear(); - }); + }; + + let scheduledLayout: IDisposable; + if (this.lifecycleService.phase >= LifecyclePhase.Restored) { + scheduledLayout = scheduleAtNextAnimationFrame(layoutFunction, getWindow(this.tabsContainer)); + } else { + scheduledLayout = runWhenIdle(layoutFunction); + } this.layoutScheduler.value = { options, dispose: () => scheduledLayout.dispose() }; } diff --git a/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts b/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts index c3f0490bedd..fb0f7f5d318 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts @@ -7,7 +7,7 @@ import 'vs/css!./media/notificationsToasts'; import { localize } from 'vs/nls'; import { INotificationsModel, NotificationChangeType, INotificationChangeEvent, INotificationViewItem, NotificationViewItemContentChangeKind } from 'vs/workbench/common/notifications'; import { IDisposable, dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { addDisposableListener, EventType, Dimension, scheduleAtNextAnimationFrame, isAncestorOfActiveElement } from 'vs/base/browser/dom'; +import { addDisposableListener, EventType, Dimension, scheduleAtNextAnimationFrame, isAncestorOfActiveElement, getWindow } from 'vs/base/browser/dom'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { NotificationsList } from 'vs/workbench/browser/parts/notifications/notificationsList'; import { Event, Emitter } from 'vs/base/common/event'; @@ -150,7 +150,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast // (see also https://github.com/microsoft/vscode/issues/107935) const itemDisposables = new DisposableStore(); this.mapNotificationToDisposable.set(item, itemDisposables); - itemDisposables.add(scheduleAtNextAnimationFrame(() => this.doAddToast(item, itemDisposables))); + itemDisposables.add(scheduleAtNextAnimationFrame(() => this.doAddToast(item, itemDisposables), getWindow(this.container))); } private doAddToast(item: INotificationViewItem, itemDisposables: DisposableStore): void { diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index 82c067d6b1a..c7f1c97fd14 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -458,7 +458,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer { disposable.dispose(); this._onDidChangeItemHeight.fire({ element, height: newHeight }); - })); + }, dom.getWindow(templateData.value))); } } @@ -496,7 +496,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer { disposable.dispose(); this._onDidChangeItemHeight.fire({ element, height: newHeight }); - })); + }, dom.getWindow(templateData.value))); } } diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index d7526a49c87..c6f79e430df 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -407,7 +407,7 @@ export class ChatWidget extends Disposable implements IChatWidget { dom.scheduleAtNextAnimationFrame(() => { // Can't set scrollTop during this event listener, the list might overwrite the change revealLastElement(this.tree); - }, 0); + }, dom.getWindow(this.listContainer), 0); } } @@ -640,7 +640,7 @@ export class ChatWidget extends Disposable implements IChatWidget { const inputPartHeight = this.inputPart.layout(possibleMaxHeight, width); const newHeight = Math.min(renderHeight + diff, possibleMaxHeight - inputPartHeight); this.layout(newHeight + inputPartHeight, width); - }); + }, dom.getWindow(this.listContainer)); })); } diff --git a/src/vs/workbench/contrib/comments/browser/commentNode.ts b/src/vs/workbench/contrib/comments/browser/commentNode.ts index d015ba6761b..65ad313fff7 100644 --- a/src/vs/workbench/contrib/comments/browser/commentNode.ts +++ b/src/vs/workbench/contrib/comments/browser/commentNode.ts @@ -170,7 +170,7 @@ export class CommentNode extends Disposable { this._scrollable = new Scrollable({ forceIntegerValues: true, smoothScrollDuration: 125, - scheduleAtNextAnimationFrame: cb => dom.scheduleAtNextAnimationFrame(cb) + scheduleAtNextAnimationFrame: cb => dom.scheduleAtNextAnimationFrame(cb, dom.getWindow(container)) }); this._scrollableElement = this._register(new SmoothScrollableElement(body, { horizontal: ScrollbarVisibility.Visible, @@ -489,7 +489,7 @@ export class CommentNode extends Disposable { dom.scheduleAtNextAnimationFrame(() => { this._commentEditor!.layout({ width: container.clientWidth - 14, height: this._editorHeight }); this._commentEditor!.focus(); - }); + }, dom.getWindow(editContainer)); const lastLine = this._commentEditorModel.getLineCount(); const lastColumn = this._commentEditorModel.getLineLength(lastLine) + 1; diff --git a/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts b/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts index f405b53b5e0..92327e752c6 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts @@ -998,7 +998,7 @@ export class DeletedElement extends SingleSideDiffElement { } this.layoutNotebookCell(); - }); + }, DOM.getWindow(this._diffEditorContainer)); } _buildOutputRendererContainer() { @@ -1201,7 +1201,7 @@ export class InsertElement extends SingleSideDiffElement { if (this._diagonalFill) { this._diagonalFill.style.height = `${this.cell.layoutInfo.editorHeight + this.cell.layoutInfo.editorMargin + this.cell.layoutInfo.metadataStatusHeight + this.cell.layoutInfo.metadataHeight + this.cell.layoutInfo.outputTotalHeight + this.cell.layoutInfo.outputStatusHeight}px`; } - }); + }, DOM.getWindow(this._diffEditorContainer)); } override dispose() { @@ -1626,7 +1626,7 @@ export class ModifiedElement extends AbstractElementRenderer { } this.layoutNotebookCell(); - }); + }, DOM.getWindow(this._diffEditorContainer)); } override dispose() { diff --git a/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.ts b/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.ts index 2d6eb9ea124..35c1e3cf692 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.ts @@ -463,7 +463,7 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD return diffElement.original; }, DiffSide.Original); } - }); + }, DOM.getWindow(this._listViewContainer)); }; this._localStore.add(this._list.onDidChangeContentHeight(() => { @@ -763,7 +763,7 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD DOM.scheduleAtNextAnimationFrame(() => { webview?.ackHeight([{ cellId: cellInfo.cellId, outputId, height }]); - }, 10); + }, DOM.getWindow(this._listViewContainer), 10); } private pendingLayouts = new WeakMap(); @@ -784,7 +784,7 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD relayout(cell, height); r(); - }); + }, DOM.getWindow(this._listViewContainer)); this.pendingLayouts.set(cell, toDisposable(() => { layoutDisposable.dispose(); diff --git a/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffOverviewRuler.ts b/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffOverviewRuler.ts index 1d39891624f..57938e24695 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffOverviewRuler.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffOverviewRuler.ts @@ -114,7 +114,7 @@ export class NotebookDiffOverviewRuler extends Themable { private _scheduleRender(): void { if (this._renderAnimationFrame === null) { - this._renderAnimationFrame = DOM.runAtThisOrScheduleAtNextAnimationFrame(this._onRenderScheduled.bind(this), 16); + this._renderAnimationFrame = DOM.runAtThisOrScheduleAtNextAnimationFrame(this._onRenderScheduled.bind(this), DOM.getWindow(this._domNode.domNode), 16); } } diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index e2cceb4b1ec..e391c3c2d56 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -1454,7 +1454,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD this._localStore.add(DOM.scheduleAtNextAnimationFrame(() => { hasPendingChangeContentHeight = false; this._updateScrollHeight(); - }, 100)); + }, DOM.getWindow(this._body), 100)); })); this._localStore.add(this._list.onDidRemoveOutputs(outputs => { @@ -2259,7 +2259,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD }; if (this._list.inRenderingTransaction) { - const layoutDisposable = DOM.scheduleAtNextAnimationFrame(doLayout); + const layoutDisposable = DOM.scheduleAtNextAnimationFrame(doLayout, DOM.getWindow(this._body)); this._pendingLayouts?.set(cell, toDisposable(() => { layoutDisposable.dispose(); @@ -2973,7 +2973,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD this._webview?.ackHeight([...this._pendingOutputHeightAcks.values()]); this._pendingOutputHeightAcks.clear(); - }, -1); // -1 priority because this depends on calls to layoutNotebookCell, and that may be called multiple times before this runs + }, DOM.getWindow(this._body), -1); // -1 priority because this depends on calls to layoutNotebookCell, and that may be called multiple times before this runs } } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellPart.ts b/src/vs/workbench/contrib/notebook/browser/view/cellPart.ts index ac1396b310f..32dc2032748 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellPart.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellPart.ts @@ -128,18 +128,19 @@ export class CellPartsCollection extends Disposable { private _scheduledOverlayUpdateExecutionState = this._register(new MutableDisposable()); constructor( + private readonly targetWindow: Window, private readonly contentParts: readonly CellContentPart[], private readonly overlayParts: readonly CellOverlayPart[] ) { super(); } - concatContentPart(other: readonly CellContentPart[]): CellPartsCollection { - return new CellPartsCollection(this.contentParts.concat(other), this.overlayParts); + concatContentPart(other: readonly CellContentPart[], targetWindow: Window): CellPartsCollection { + return new CellPartsCollection(targetWindow, this.contentParts.concat(other), this.overlayParts); } - concatOverlayPart(other: readonly CellOverlayPart[]): CellPartsCollection { - return new CellPartsCollection(this.contentParts, this.overlayParts.concat(other)); + concatOverlayPart(other: readonly CellOverlayPart[], targetWindow: Window): CellPartsCollection { + return new CellPartsCollection(targetWindow, this.contentParts, this.overlayParts.concat(other)); } scheduleRenderCell(element: ICellViewModel): void { @@ -161,7 +162,7 @@ export class CellPartsCollection extends Disposable { for (const part of this.overlayParts) { part.renderCell(element); } - }); + }, this.targetWindow); } unrenderCell(element: ICellViewModel): void { @@ -203,7 +204,7 @@ export class CellPartsCollection extends Disposable { for (const part of this.overlayParts) { part.updateState(viewCell, e); } - }); + }, this.targetWindow); } updateForExecutionState(viewCell: ICellViewModel, e: ICellExecutionStateChangedEvent) { @@ -215,6 +216,6 @@ export class CellPartsCollection extends Disposable { for (const part of this.overlayParts) { part.updateForExecutionState(viewCell, e); } - }); + }, this.targetWindow); } } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts index 501569e9984..9f727ebfe88 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts @@ -58,7 +58,7 @@ export class CodeCell extends Disposable { const cellEditorOptions = this._register(new CellEditorOptions(this.notebookEditor.getBaseCellEditorOptions(viewCell.language), this.notebookEditor.notebookOptions, this.configurationService)); this._outputContainerRenderer = this.instantiationService.createInstance(CellOutputContainer, notebookEditor, viewCell, templateData, { limit: outputDisplayLimit }); - this.cellParts = this._register(templateData.cellParts.concatContentPart([cellEditorOptions, this._outputContainerRenderer])); + this.cellParts = this._register(templateData.cellParts.concatContentPart([cellEditorOptions, this._outputContainerRenderer], DOM.getWindow(notebookEditor.getDomNode()))); // this.viewCell.layoutInfo.editorHeight or estimation when this.viewCell.layoutInfo.editorHeight === 0 const editorHeight = this.calculateInitEditorHeight(); @@ -146,7 +146,7 @@ export class CodeCell extends Disposable { this._pendingLayout?.dispose(); this._pendingLayout = DOM.modify(() => { this.cellParts.updateInternalLayoutNow(this.viewCell); - }); + }, DOM.getWindow(this.templateData.container)); } private updateForOutputHover() { diff --git a/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts b/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts index f54d78ac851..04f3c12567f 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts @@ -289,7 +289,7 @@ export class NotebookCellList extends WorkbenchList implements ID if (this._isInLayout) { DOM.scheduleAtNextAnimationFrame(() => { updateVisibleRanges(); - }); + }, DOM.getWindow(container)); } updateVisibleRanges(); })); @@ -297,7 +297,7 @@ export class NotebookCellList extends WorkbenchList implements ID if (this._isInLayout) { DOM.scheduleAtNextAnimationFrame(() => { updateVisibleRanges(); - }); + }, DOM.getWindow(container)); } updateVisibleRanges(); })); @@ -369,7 +369,7 @@ export class NotebookCellList extends WorkbenchList implements ID } this._updateElementsInWebview(viewDiffs); - })); + }, DOM.getWindow(this.rowsContainer))); } })); diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts index d9c13b6094e..f6f8aa92455 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -162,7 +162,7 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen this.notebookEditor)); const focusIndicatorBottom = new FastDomNode(DOM.append(container, $('.cell-focus-indicator.cell-focus-indicator-bottom'))); - const cellParts = new CellPartsCollection([ + const cellParts = new CellPartsCollection(DOM.getWindow(rootContainer), [ templateDisposables.add(scopedInstaService.createInstance(CellEditorStatusBar, this.notebookEditor, container, editorPart, undefined)), templateDisposables.add(new CellFocusIndicator(this.notebookEditor, titleToolbar, focusIndicatorTop, focusIndicatorLeft, focusIndicatorRight, focusIndicatorBottom)), templateDisposables.add(new FoldedCellHint(this.notebookEditor, DOM.append(container, $('.notebook-folded-hint')))), @@ -306,7 +306,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende this.notebookEditor)); const focusIndicatorPart = templateDisposables.add(new CellFocusIndicator(this.notebookEditor, titleToolbar, focusIndicatorTop, focusIndicatorLeft, focusIndicatorRight, focusIndicatorBottom)); - const cellParts = new CellPartsCollection([ + const cellParts = new CellPartsCollection(DOM.getWindow(rootContainer), [ focusIndicatorPart, templateDisposables.add(scopedInstaService.createInstance(CellEditorStatusBar, this.notebookEditor, container, editorPart, editor)), templateDisposables.add(scopedInstaService.createInstance(CellProgressBar, editorPart, cellInputCollapsedContainer)), diff --git a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts index c7b0471d676..390ed06f677 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts @@ -115,7 +115,7 @@ export class NotebookEditorContextKeys { layoutDisposable.add(DOM.scheduleAtNextAnimationFrame(() => { recomputeOutputsExistence(); - })); + }, DOM.getWindow(this._editor.getDomNode()))); }); }; diff --git a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts index ade1e1091e3..072fa071e36 100644 --- a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts +++ b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts @@ -1534,7 +1534,7 @@ class TerminalMessagePeek extends Disposable implements IPeekOutputRenderer { private attachTerminalToDom(terminal: IDetachedTerminalInstance) { terminal.xterm.write('\x1b[?25l'); // hide cursor - requestAnimationFrame(() => this.layoutTerminal(terminal)); + dom.scheduleAtNextAnimationFrame(() => this.layoutTerminal(terminal), dom.getWindow(this.container)); terminal.attachToElement(this.container, { enableGpu: false }); } diff --git a/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts b/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts index a3b261ccaa1..aeec64376e7 100644 --- a/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts +++ b/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts @@ -15,7 +15,7 @@ import { NativeHostService } from 'vs/platform/native/electron-sandbox/nativeHos import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService'; import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService'; import { isAuxiliaryWindow } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService'; -import { getActiveDocument, getWindowsCount, onDidRegisterWindow, trackFocus } from 'vs/base/browser/dom'; +import { getActiveDocument, getWindowsCount, onDidRegisterWindow, scheduleAtNextAnimationFrame, trackFocus } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { memoize } from 'vs/base/common/decorators'; @@ -62,11 +62,11 @@ class WorkbenchHostService extends Disposable implements IHostService { // Workaround: the window does not immediately seem to have focus when // opening, so we schedule a check for focus on the next animation frame - window.requestAnimationFrame(() => { + scheduleAtNextAnimationFrame(() => { if (window.document.hasFocus()) { emitter.fire(true); } - }); + }, window); })); return emitter.event; diff --git a/src/vs/workbench/services/suggest/browser/simpleSuggestWidget.ts b/src/vs/workbench/services/suggest/browser/simpleSuggestWidget.ts index 7df145abc38..f3e8d1c542c 100644 --- a/src/vs/workbench/services/suggest/browser/simpleSuggestWidget.ts +++ b/src/vs/workbench/services/suggest/browser/simpleSuggestWidget.ts @@ -256,7 +256,7 @@ export class SimpleSuggestWidget implements IDisposable { this._layout(this.element.size); // Reset focus border // this._details.widget.domNode.classList.remove('focused'); - }); + }, dom.getWindow(this.element.domNode)); } setLineContext(lineContext: LineContext): void {