Use a more robust solution to changing devicePixelRatio

This commit is contained in:
Daniel Imms
2017-12-29 13:54:01 -08:00
parent ef5beb6706
commit 72d946e089
3 changed files with 67 additions and 5 deletions
+62
View File
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
* @license MIT
*/
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 {
private _currentDevicePixelRatio: number;
private _outerListener: MediaQueryListListener;
private _listener: ScreenDprListener;
private _minMediaMatchList: MediaQueryList;
private _maxMediaMatchList: MediaQueryList;
public setListener(listener: ScreenDprListener): void {
if (this._listener) {
this.clearListener();
}
this._listener = listener;
this._outerListener = () => {
this._listener(window.devicePixelRatio, this._currentDevicePixelRatio);
this._updateDpr();
};
this._updateDpr();
}
private _updateDpr(): void {
// Clear listeners for old DPR
if (this._minMediaMatchList) {
this._minMediaMatchList.removeListener(this._outerListener);
}
if (this._maxMediaMatchList) {
this._maxMediaMatchList.removeListener(this._outerListener);
}
// Add listeners for new DPR
this._currentDevicePixelRatio = window.devicePixelRatio;
this._minMediaMatchList = window.matchMedia(`screen and (-webkit-min-device-pixel-ratio: ${window.devicePixelRatio})`);
this._maxMediaMatchList = window.matchMedia(`screen and (-webkit-max-device-pixel-ratio: ${window.devicePixelRatio})`);
this._minMediaMatchList.addListener(this._outerListener);
this._maxMediaMatchList.addListener(this._outerListener);
}
public clearListener(): void {
if (!this._listener) {
return;
}
this._minMediaMatchList.removeListener(this._outerListener);
this._maxMediaMatchList.removeListener(this._outerListener);
this._listener = null;
this._outerListener = null;
}
}