/** * Copyright (c) 2017 The xterm.js authors. All rights reserved. * @license MIT */ import { Disposable } from 'common/Lifecycle'; export type ScreenDprListener = (newDevicePixelRatio?: number, oldDevicePixelRatio?: number) => void; /** * The screen device pixel ratio monitor allows listening for when the * window.devicePixelRatio value changes. This is done not with polling but with * the use of window.matchMedia to watch media queries. When the event fires, * the listener will be reattached using a different media query to ensure that * any further changes will register. * * The listener should fire on both window zoom changes and switching to a * monitor with a different DPI. */ export class ScreenDprMonitor extends Disposable { private _currentDevicePixelRatio: number = window.devicePixelRatio; private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined; private _listener: ScreenDprListener | undefined; private _resolutionMediaMatchList: MediaQueryList | undefined; public setListener(listener: ScreenDprListener): void { if (this._listener) { this.clearListener(); } this._listener = listener; this._outerListener = () => { if (!this._listener) { return; } this._listener(window.devicePixelRatio, this._currentDevicePixelRatio); this._updateDpr(); }; this._updateDpr(); } public dispose(): void { super.dispose(); this.clearListener(); } private _updateDpr(): void { if (!this._outerListener) { return; } // Clear listeners for old DPR this._resolutionMediaMatchList?.removeListener(this._outerListener); // Add listeners for new DPR this._currentDevicePixelRatio = window.devicePixelRatio; this._resolutionMediaMatchList = window.matchMedia(`screen and (resolution: ${window.devicePixelRatio}dppx)`); this._resolutionMediaMatchList.addListener(this._outerListener); } public clearListener(): void { if (!this._resolutionMediaMatchList || !this._listener || !this._outerListener) { return; } this._resolutionMediaMatchList.removeListener(this._outerListener); this._resolutionMediaMatchList = undefined; this._listener = undefined; this._outerListener = undefined; } }