tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit b65113ed0849854fbc6833c0c9619e27bd89b890
parent 5e7833fdea31106939bf8f832f8606af5c3945ab
Author: Alexandru Marc <amarc@mozilla.com>
Date:   Tue, 21 Oct 2025 17:36:17 +0300

Revert "Bug 1995498 - Assume per-monitor DPI awareness. r=win-reviewers,gstoll" for causing mass win failures

This reverts commit 47ae5f5f7b18ceeae9cd1b1405ddb1e20c65a9c7.

Diffstat:
Mwidget/windows/ScreenHelperWin.cpp | 7++++++-
Mwidget/windows/WinUtils.cpp | 48++++++++++++++++++++++++++++++++++++++++--------
Mwidget/windows/WinUtils.h | 1+
Mwidget/windows/nsWindow.cpp | 22++++++++++++----------
Mwidget/windows/nsWindow.h | 7+++++++
5 files changed, 66 insertions(+), 19 deletions(-)

diff --git a/widget/windows/ScreenHelperWin.cpp b/widget/windows/ScreenHelperWin.cpp @@ -94,7 +94,12 @@ BOOL CALLBACK CollectMonitors(HMONITOR aMon, HDC, LPRECT, LPARAM ioParam) { } double scale = WinUtils::LogToPhysFactor(aMon); - DesktopToLayoutDeviceScale contentsScaleFactor(1.0); + DesktopToLayoutDeviceScale contentsScaleFactor; + if (WinUtils::IsPerMonitorDPIAware()) { + contentsScaleFactor.scale = 1.0; + } else { + contentsScaleFactor.scale = scale; + } 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 @@ -244,12 +244,39 @@ typedef HRESULT(WINAPI* GETPROCESSDPIAWARENESSPROC)(HANDLE, 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) { - UINT dpiX, dpiY = 96; - sGetDpiForMonitor(aMonitor ? aMonitor : GetPrimaryMonitor(), - MDT_EFFECTIVE_DPI, &dpiX, &dpiY); - return dpiY; + 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(); } /* static */ @@ -290,9 +317,14 @@ WinUtils::GetPrimaryMonitor() { /* static */ HMONITOR WinUtils::MonitorFromRect(const gfx::Rect& rect) { - RECT globalWindowBounds = {NSToIntRound(rect.X()), NSToIntRound(rect.Y()), - NSToIntRound(rect.XMost()), - NSToIntRound(rect.YMost())}; + // 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()))}; return ::MonitorFromRect(&globalWindowBounds, MONITOR_DEFAULTTONEAREST); } @@ -309,7 +341,7 @@ int WinUtils::GetSystemMetricsForDpi(int nIndex, UINT dpi) { if (HasSystemMetricsForDpi()) { return sGetSystemMetricsForDpi(nIndex, dpi); } else { - double scale = dpi / SystemDPI(); + double scale = IsPerMonitorDPIAware() ? dpi / SystemDPI() : 1.0; return NSToIntRound(::GetSystemMetrics(nIndex) * scale); } } diff --git a/widget/windows/WinUtils.h b/widget/windows/WinUtils.h @@ -217,6 +217,7 @@ 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,16 +5518,18 @@ bool nsWindow::ProcessMessageInternal(UINT msg, WPARAM& wParam, LPARAM& lParam, case WM_MOVING: FinishLiveResizing(MOVING); - // 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(); + 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(); + } } break; diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h @@ -196,6 +196,13 @@ 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;