commit 71f243cfd9ed706a19f89755e2f40b3be68424b4
parent ae425b2a55b4dd05374fbdcb80e09a19d1caa3e8
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Wed, 22 Oct 2025 11:00:57 +0000
Bug 1995498 - Assume per-monitor DPI awareness. r=win-reviewers,gstoll
This should be fine on Win10+ which is all we support.
Differential Revision: https://phabricator.services.mozilla.com/D269342
Diffstat:
5 files changed, 19 insertions(+), 75 deletions(-)
diff --git a/widget/windows/ScreenHelperWin.cpp b/widget/windows/ScreenHelperWin.cpp
@@ -94,12 +94,7 @@ BOOL CALLBACK CollectMonitors(HMONITOR aMon, HDC, LPRECT, LPARAM ioParam) {
}
double scale = WinUtils::LogToPhysFactor(aMon);
- DesktopToLayoutDeviceScale contentsScaleFactor;
- if (WinUtils::IsPerMonitorDPIAware()) {
- contentsScaleFactor.scale = 1.0;
- } else {
- contentsScaleFactor.scale = scale;
- }
+ DesktopToLayoutDeviceScale contentsScaleFactor(1.0);
CSSToLayoutDeviceScale defaultCssScaleFactor(scale);
LayoutDeviceIntRect rect(info.rcMonitor.left, info.rcMonitor.top,
info.rcMonitor.right - info.rcMonitor.left,
diff --git a/widget/windows/WinUtils.cpp b/widget/windows/WinUtils.cpp
@@ -234,48 +234,12 @@ float WinUtils::SystemDPI() {
// static
double WinUtils::SystemScaleFactor() { return SystemDPI() / 96.0; }
-typedef HRESULT(WINAPI* GETDPIFORMONITORPROC)(HMONITOR, MONITOR_DPI_TYPE, UINT*,
- UINT*);
-
-typedef HRESULT(WINAPI* GETPROCESSDPIAWARENESSPROC)(HANDLE,
- PROCESS_DPI_AWARENESS*);
-
-GETDPIFORMONITORPROC sGetDpiForMonitor;
-GETPROCESSDPIAWARENESSPROC sGetProcessDpiAwareness;
-
-static bool SlowIsPerMonitorDPIAware() {
- // Intentionally leak the handle.
- HMODULE shcore = LoadLibraryEx(L"shcore", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
- if (shcore) {
- sGetDpiForMonitor =
- (GETDPIFORMONITORPROC)GetProcAddress(shcore, "GetDpiForMonitor");
- sGetProcessDpiAwareness = (GETPROCESSDPIAWARENESSPROC)GetProcAddress(
- shcore, "GetProcessDpiAwareness");
- }
- PROCESS_DPI_AWARENESS dpiAwareness;
- return sGetDpiForMonitor && sGetProcessDpiAwareness &&
- SUCCEEDED(
- sGetProcessDpiAwareness(GetCurrentProcess(), &dpiAwareness)) &&
- dpiAwareness == PROCESS_PER_MONITOR_DPI_AWARE;
-}
-
-/* static */
-bool WinUtils::IsPerMonitorDPIAware() {
- static bool perMonitorDPIAware = SlowIsPerMonitorDPIAware();
- return perMonitorDPIAware;
-}
-
/* static */
float WinUtils::MonitorDPI(HMONITOR aMonitor) {
- if (IsPerMonitorDPIAware()) {
- UINT dpiX, dpiY = 96;
- sGetDpiForMonitor(aMonitor ? aMonitor : GetPrimaryMonitor(),
- MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
- return dpiY;
- }
-
- // We're not per-monitor aware, use system DPI instead.
- return SystemDPI();
+ UINT dpiX, dpiY = 96;
+ GetDpiForMonitor(aMonitor ? aMonitor : GetPrimaryMonitor(), MDT_EFFECTIVE_DPI,
+ &dpiX, &dpiY);
+ return dpiY;
}
/* static */
@@ -316,14 +280,9 @@ WinUtils::GetPrimaryMonitor() {
/* static */
HMONITOR
WinUtils::MonitorFromRect(const gfx::Rect& rect) {
- // convert coordinates from desktop to device pixels for MonitorFromRect
- double dpiScale =
- IsPerMonitorDPIAware() ? 1.0 : LogToPhysFactor(GetPrimaryMonitor());
-
- RECT globalWindowBounds = {NSToIntRound(dpiScale * rect.X()),
- NSToIntRound(dpiScale * rect.Y()),
- NSToIntRound(dpiScale * (rect.XMost())),
- NSToIntRound(dpiScale * (rect.YMost()))};
+ RECT globalWindowBounds = {NSToIntRound(rect.X()), NSToIntRound(rect.Y()),
+ NSToIntRound(rect.XMost()),
+ NSToIntRound(rect.YMost())};
return ::MonitorFromRect(&globalWindowBounds, MONITOR_DEFAULTTONEAREST);
}
@@ -340,7 +299,7 @@ int WinUtils::GetSystemMetricsForDpi(int nIndex, UINT dpi) {
if (HasSystemMetricsForDpi()) {
return sGetSystemMetricsForDpi(nIndex, dpi);
} else {
- double scale = IsPerMonitorDPIAware() ? dpi / SystemDPI() : 1.0;
+ double scale = dpi / SystemDPI();
return NSToIntRound(::GetSystemMetrics(nIndex) * scale);
}
}
diff --git a/widget/windows/WinUtils.h b/widget/windows/WinUtils.h
@@ -217,7 +217,6 @@ class WinUtils {
*/
static double SystemScaleFactor();
- static bool IsPerMonitorDPIAware();
/**
* Get the DPI of the given monitor if it's per-monitor DPI aware, otherwise
* return the system DPI.
diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp
@@ -5518,18 +5518,16 @@ bool nsWindow::ProcessMessageInternal(UINT msg, WPARAM& wParam, LPARAM& lParam,
case WM_MOVING:
FinishLiveResizing(MOVING);
- if (WinUtils::IsPerMonitorDPIAware()) {
- // Sometimes, we appear to miss a WM_DPICHANGED message while moving
- // a window around. Therefore, call ChangedDPI and ResetLayout here
- // if it appears that the window's scaling is not what we expect.
- // This causes the prescontext and appshell window management code to
- // check the appUnitsPerDevPixel value and current widget size, and
- // refresh them if necessary. If nothing has changed, these calls will
- // return without actually triggering any extra reflow or painting.
- if (WinUtils::LogToPhysFactor(mWnd) != mDefaultScale) {
- ChangedDPI();
- ResetLayout();
- }
+ // Sometimes, we appear to miss a WM_DPICHANGED message while moving
+ // a window around. Therefore, call ChangedDPI and ResetLayout here
+ // if it appears that the window's scaling is not what we expect.
+ // This causes the prescontext and appshell window management code to
+ // check the appUnitsPerDevPixel value and current widget size, and
+ // refresh them if necessary. If nothing has changed, these calls will
+ // return without actually triggering any extra reflow or painting.
+ if (WinUtils::LogToPhysFactor(mWnd) != mDefaultScale) {
+ ChangedDPI();
+ ResetLayout();
}
break;
diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h
@@ -196,13 +196,6 @@ class nsWindow final : public nsIWidget {
double GetDefaultScaleInternal() override;
void DidClearParent(nsIWidget* aOldParent) override;
int32_t LogToPhys(double aValue);
- mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override {
- if (mozilla::widget::WinUtils::IsPerMonitorDPIAware()) {
- return mozilla::DesktopToLayoutDeviceScale(1.0);
- } else {
- return mozilla::DesktopToLayoutDeviceScale(GetDefaultScaleInternal());
- }
- }
void Show(bool aState) override;
bool IsVisible() const override;