Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/browser/pixelRatio.ts
3292 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { getWindowId, onDidUnregisterWindow } from './dom.js';
7
import { Emitter, Event } from '../common/event.js';
8
import { Disposable, markAsSingleton } from '../common/lifecycle.js';
9
10
/**
11
* See https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes
12
*/
13
class DevicePixelRatioMonitor extends Disposable {
14
15
private readonly _onDidChange = this._register(new Emitter<void>());
16
readonly onDidChange = this._onDidChange.event;
17
18
private readonly _listener: () => void;
19
private _mediaQueryList: MediaQueryList | null;
20
21
constructor(targetWindow: Window) {
22
super();
23
24
this._listener = () => this._handleChange(targetWindow, true);
25
this._mediaQueryList = null;
26
this._handleChange(targetWindow, false);
27
}
28
29
private _handleChange(targetWindow: Window, fireEvent: boolean): void {
30
this._mediaQueryList?.removeEventListener('change', this._listener);
31
32
this._mediaQueryList = targetWindow.matchMedia(`(resolution: ${targetWindow.devicePixelRatio}dppx)`);
33
this._mediaQueryList.addEventListener('change', this._listener);
34
35
if (fireEvent) {
36
this._onDidChange.fire();
37
}
38
}
39
}
40
41
export interface IPixelRatioMonitor {
42
readonly value: number;
43
readonly onDidChange: Event<number>;
44
}
45
46
class PixelRatioMonitorImpl extends Disposable implements IPixelRatioMonitor {
47
48
private readonly _onDidChange = this._register(new Emitter<number>());
49
readonly onDidChange = this._onDidChange.event;
50
51
private _value: number;
52
53
get value(): number {
54
return this._value;
55
}
56
57
constructor(targetWindow: Window) {
58
super();
59
60
this._value = this._getPixelRatio(targetWindow);
61
62
const dprMonitor = this._register(new DevicePixelRatioMonitor(targetWindow));
63
this._register(dprMonitor.onDidChange(() => {
64
this._value = this._getPixelRatio(targetWindow);
65
this._onDidChange.fire(this._value);
66
}));
67
}
68
69
private _getPixelRatio(targetWindow: Window): number {
70
const ctx: any = document.createElement('canvas').getContext('2d');
71
const dpr = targetWindow.devicePixelRatio || 1;
72
const bsr = ctx.webkitBackingStorePixelRatio ||
73
ctx.mozBackingStorePixelRatio ||
74
ctx.msBackingStorePixelRatio ||
75
ctx.oBackingStorePixelRatio ||
76
ctx.backingStorePixelRatio || 1;
77
return dpr / bsr;
78
}
79
}
80
81
class PixelRatioMonitorFacade {
82
83
private readonly mapWindowIdToPixelRatioMonitor = new Map<number, PixelRatioMonitorImpl>();
84
85
private _getOrCreatePixelRatioMonitor(targetWindow: Window): PixelRatioMonitorImpl {
86
const targetWindowId = getWindowId(targetWindow);
87
let pixelRatioMonitor = this.mapWindowIdToPixelRatioMonitor.get(targetWindowId);
88
if (!pixelRatioMonitor) {
89
pixelRatioMonitor = markAsSingleton(new PixelRatioMonitorImpl(targetWindow));
90
this.mapWindowIdToPixelRatioMonitor.set(targetWindowId, pixelRatioMonitor);
91
92
markAsSingleton(Event.once(onDidUnregisterWindow)(({ vscodeWindowId }) => {
93
if (vscodeWindowId === targetWindowId) {
94
pixelRatioMonitor?.dispose();
95
this.mapWindowIdToPixelRatioMonitor.delete(targetWindowId);
96
}
97
}));
98
}
99
return pixelRatioMonitor;
100
}
101
102
getInstance(targetWindow: Window): IPixelRatioMonitor {
103
return this._getOrCreatePixelRatioMonitor(targetWindow);
104
}
105
}
106
107
/**
108
* Returns the pixel ratio.
109
*
110
* This is useful for rendering <canvas> elements at native screen resolution or for being used as
111
* a cache key when storing font measurements. Fonts might render differently depending on resolution
112
* and any measurements need to be discarded for example when a window is moved from a monitor to another.
113
*/
114
export const PixelRatio = new PixelRatioMonitorFacade();
115
116