70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
/**
|
|
* 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;
|
|
}
|
|
}
|