diff --git a/src/browser/AccessibilityManager.ts b/src/browser/AccessibilityManager.ts index ed2c12b0..703459f4 100644 --- a/src/browser/AccessibilityManager.ts +++ b/src/browser/AccessibilityManager.ts @@ -7,7 +7,6 @@ import * as Strings from 'browser/LocalizableStrings'; import { ITerminal, IRenderDebouncer } from 'browser/Types'; import { TimeBasedDebouncer } from 'browser/TimeBasedDebouncer'; import { Disposable, toDisposable } from 'common/Lifecycle'; -import { ScreenDprMonitor } from 'browser/ScreenDprMonitor'; import { ICoreBrowserService, IRenderService } from 'browser/services/Services'; import { addDisposableDomListener } from 'browser/Lifecycle'; import { IBuffer } from 'common/buffer/Types'; @@ -30,8 +29,6 @@ export class AccessibilityManager extends Disposable { private _liveRegionLineCount: number = 0; private _liveRegionDebouncer: IRenderDebouncer; - private _screenDprMonitor: ScreenDprMonitor; - private _topBoundaryFocusListener: (e: FocusEvent) => void; private _bottomBoundaryFocusListener: (e: FocusEvent) => void; @@ -97,8 +94,7 @@ export class AccessibilityManager extends Disposable { this.register(this._terminal.onBlur(() => this._clearLiveRegion())); this.register(this._renderService.onDimensionsChange(() => this._refreshRowsDimensions())); - this._screenDprMonitor = this.register(instantiationService.createInstance(ScreenDprMonitor)); - this.register(this._screenDprMonitor.onDprChange(() => this._refreshRowsDimensions())); + this.register(this._coreBrowserService.onDprChange(() => this._refreshRowsDimensions())); // This shouldn't be needed on modern browsers but is present in case the // media query that drives the ScreenDprMonitor isn't supported // TODO: Listen to window change diff --git a/src/browser/ScreenDprMonitor.ts b/src/browser/ScreenDprMonitor.ts index 6ff016e5..1152a55a 100644 --- a/src/browser/ScreenDprMonitor.ts +++ b/src/browser/ScreenDprMonitor.ts @@ -3,7 +3,6 @@ * @license MIT */ -import { ICoreBrowserService } from 'browser/services/Services'; import { EventEmitter } from 'common/EventEmitter'; import { Disposable, toDisposable } from 'common/Lifecycle'; @@ -21,16 +20,13 @@ export class ScreenDprMonitor extends Disposable { private _currentDevicePixelRatio: number; private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined; private _resolutionMediaMatchList: MediaQueryList | undefined; - private _parentWindow: Window; private readonly _onDprChange = this.register(new EventEmitter()); public readonly onDprChange = this._onDprChange.event; - constructor(@ICoreBrowserService coreBrowserService: ICoreBrowserService) { + constructor(private _parentWindow: Window) { super(); - this._parentWindow = coreBrowserService.window; - // Initialize listener and dpr value this._outerListener = () => { if (this._parentWindow.devicePixelRatio !== this._currentDevicePixelRatio) { @@ -41,20 +37,16 @@ export class ScreenDprMonitor extends Disposable { this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio; this._updateDpr(); - // Listen for window changes - this.register(coreBrowserService.onWindowChange(w => { - this._parentWindow = w; - if (this._parentWindow.devicePixelRatio !== this._currentDevicePixelRatio) { - this._onDprChange.fire(this._parentWindow.devicePixelRatio); - } - this._updateDpr(); - })); - // Setup additional disposables this.register(toDisposable(() => this.clearListener())); } - public setListener(): void { + public setWindow(parentWindow: Window): void { + this._parentWindow = parentWindow; + if (this._parentWindow.devicePixelRatio !== this._currentDevicePixelRatio) { + this._onDprChange.fire(this._parentWindow.devicePixelRatio); + } + this._updateDpr(); } private _updateDpr(): void { diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index 1ad5bc76..d557cd98 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -350,6 +350,7 @@ export class MockCompositionHelper implements ICompositionHelper { } export class MockCoreBrowserService implements ICoreBrowserService { + public onDprChange = new EventEmitter().event; public onWindowChange = new EventEmitter().event; public serviceBrand: undefined; public isFocused: boolean = true; diff --git a/src/browser/services/CoreBrowserService.ts b/src/browser/services/CoreBrowserService.ts index 2c598606..8a189315 100644 --- a/src/browser/services/CoreBrowserService.ts +++ b/src/browser/services/CoreBrowserService.ts @@ -5,25 +5,31 @@ import { Disposable } from 'common/Lifecycle'; import { ICoreBrowserService } from './Services'; -import { EventEmitter } from 'common/EventEmitter'; +import { EventEmitter, forwardEvent } from 'common/EventEmitter'; +import { ScreenDprMonitor } from 'browser/ScreenDprMonitor'; export class CoreBrowserService extends Disposable implements ICoreBrowserService { public serviceBrand: undefined; private _isFocused = false; private _cachedIsFocused: boolean | undefined = undefined; + private _screenDprMonitor = new ScreenDprMonitor(this._window); + private readonly _onDprChange = this.register(new EventEmitter()); + public readonly onDprChange = this._onDprChange.event; private readonly _onWindowChange = this.register(new EventEmitter()); public readonly onWindowChange = this._onWindowChange.event; constructor( private _textarea: HTMLTextAreaElement, - // TODO: Add getter and setter and event private _window: Window & typeof globalThis, public readonly mainDocument: Document ) { super(); + this.register(this.onWindowChange(w => this._screenDprMonitor.setWindow(w))); + this.register(forwardEvent(this._screenDprMonitor.onDprChange, this._onDprChange)); + this._textarea.addEventListener('focus', () => this._isFocused = true); this._textarea.addEventListener('blur', () => this._isFocused = false); } diff --git a/src/browser/services/RenderService.ts b/src/browser/services/RenderService.ts index 60c27798..179ddeb2 100644 --- a/src/browser/services/RenderService.ts +++ b/src/browser/services/RenderService.ts @@ -5,7 +5,6 @@ import { addDisposableDomListener } from 'browser/Lifecycle'; import { RenderDebouncer } from 'browser/RenderDebouncer'; -import { ScreenDprMonitor } from 'browser/ScreenDprMonitor'; import { IRenderDebouncerWithCallback } from 'browser/Types'; import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types'; import { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services'; @@ -25,7 +24,6 @@ export class RenderService extends Disposable implements IRenderService { private _renderer: MutableDisposable = this.register(new MutableDisposable()); private _renderDebouncer: IRenderDebouncerWithCallback; - private _screenDprMonitor: ScreenDprMonitor; private _pausedResizeTask = new DebouncedIdleTask(); private _isPaused: boolean = false; @@ -67,8 +65,7 @@ export class RenderService extends Disposable implements IRenderService { this._renderDebouncer = new RenderDebouncer(coreBrowserService.window, (start, end) => this._renderRows(start, end)); this.register(this._renderDebouncer); - this._screenDprMonitor = this.register(instantiationService.createInstance(ScreenDprMonitor)); - this.register(this._screenDprMonitor.onDprChange(() => this.handleDevicePixelRatioChange())); + this.register(coreBrowserService.onDprChange(() => this.handleDevicePixelRatioChange())); this.register(bufferService.onResize(() => this._fullRefresh())); this.register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear())); diff --git a/src/browser/services/Services.ts b/src/browser/services/Services.ts index a1faab3d..5c14fa8a 100644 --- a/src/browser/services/Services.ts +++ b/src/browser/services/Services.ts @@ -29,7 +29,9 @@ export interface ICoreBrowserService { readonly isFocused: boolean; - onWindowChange: IEvent; + readonly onDprChange: IEvent; + readonly onWindowChange: IEvent; + /** * Gets or sets the parent window that the terminal is rendered into. DOM and rendering APIs (e.g. * requestAnimationFrame) should be invoked in the context of this window. This should be set when