tor-browser

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

commit ec10c7ec7e6c28249852472f7aea8d1484303e8e
parent f85b6b318c0e4f89bcd3011dc30c9b81867b42ff
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date:   Fri, 17 Oct 2025 00:23:57 +0000

Bug 1994762 - Default to parent widget scale factor for popups. r=mac-reviewers,spohl

What seems to happen is that, when showing widgets on a previous or updated
position, we now have the right rect (because we've sized the popup frame
correctly already). So we create the window with a frame, and get the wrong
scale factor.

If we have a parent window (i.e. if we're a popup) we can pull the scale factor
from our parent if we're not visible. This matches GTK, and nsMenuPopupFrame
doesn't consider having a different DPI (the AppUnitsPerDevPixel is
per-prescontext), so I think it's fine.

Differential Revision: https://phabricator.services.mozilla.com/D268968

Diffstat:
Mwidget/cocoa/nsCocoaWindow.h | 1+
Mwidget/cocoa/nsCocoaWindow.mm | 22+++++++++++-----------
2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h @@ -520,6 +520,7 @@ class nsCocoaWindow final : public nsIWidget { void UpdateBounds(); int32_t GetWorkspaceID(); void MoveVisibleWindowToWorkspace(int32_t workspaceID); + CGFloat ComputeBackingScaleFactor() const; void DoResize(double aX, double aY, double aWidth, double aHeight, bool aRepaint, bool aConstrainToCurrentScreen); diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm @@ -6405,12 +6405,14 @@ LayoutDeviceIntRect nsCocoaWindow::GetScreenBounds() { double nsCocoaWindow::GetDefaultScaleInternal() { return BackingScaleFactor(); } -static CGFloat GetBackingScaleFactor(NSWindow* aWindow) { - NSRect frame = aWindow.frame; +CGFloat nsCocoaWindow::ComputeBackingScaleFactor() const { + if (nsIWidget* parent = GetParent()) { + return parent->GetDesktopToDeviceScale().scale; + } + NSRect frame = mWindow.frame; if (frame.size.width > 0 && frame.size.height > 0) { - return nsCocoaUtils::GetBackingScaleFactor(aWindow); + return nsCocoaUtils::GetBackingScaleFactor(mWindow); } - // For windows with zero width or height, the backingScaleFactor method // is broken - it will always return 2 on a retina macbook, even when // the window position implies it's on a non-hidpi external display @@ -6421,18 +6423,17 @@ static CGFloat GetBackingScaleFactor(NSWindow* aWindow) { // NSBackingPropertyOldScaleFactorKey key when a window on an // external display is resized to/from zero height, even though it hasn't // really changed screens. - + // // This causes us to handle popup window sizing incorrectly when the // popup is resized to zero height (bug 820327) - nsXULPopupManager // becomes (incorrectly) convinced the popup has been explicitly forced // to a non-default size and needs to have size attributes attached. - + // // Workaround: instead of asking the window, we'll find the screen it is on // and ask that for *its* backing scale factor. - + // // (See bug 853252 and additional comments in windowDidChangeScreen: below // for further complications this causes.) - // First, expand the rect so that it actually has a measurable area, // for FindTargetScreenForRect to use. if (frame.size.width == 0) { @@ -6441,7 +6442,6 @@ static CGFloat GetBackingScaleFactor(NSWindow* aWindow) { if (frame.size.height == 0) { frame.size.height = 1; } - // Then identify the screen it belongs to, and return its scale factor. NSScreen* screen = FindTargetScreenForRect(nsCocoaUtils::CocoaRectToGeckoRect(frame)); @@ -6455,12 +6455,12 @@ CGFloat nsCocoaWindow::BackingScaleFactor() const { if (!mWindow) { return 1.0; } - mBackingScaleFactor = GetBackingScaleFactor(mWindow); + mBackingScaleFactor = ComputeBackingScaleFactor(); return mBackingScaleFactor; } void nsCocoaWindow::BackingScaleFactorChanged() { - CGFloat newScale = GetBackingScaleFactor(mWindow); + CGFloat newScale = ComputeBackingScaleFactor(); // Ignore notification if it hasn't really changed if (BackingScaleFactor() == newScale) {