diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index b1e7116444dc..97529b6a5543 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -1865,15 +1865,25 @@ nsDOMWindowUtils::ToScreenRectInCSSUnits(float aX, float aY, float aWidth, nsPresContext* presContext = GetPresContext(); MOZ_ASSERT(presContext); - nsRect appUnitsRect = LayoutDeviceRect::ToAppUnits( - ViewAs( - rect, PixelCastJustification::ScreenIsParentLayerForRoot), - presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()); - CSSRect cssUnitsRect = CSSRect::FromAppUnits(appUnitsRect); + auto devRect = ViewAs( + rect, PixelCastJustification::ScreenIsParentLayerForRoot); + // We want to return the screen rect in CSS units of the browser chrome. The + // browser chrome doesn't have any built-in zoom, except for the text scale + // factor. + // + // TODO(emilio): It'd be cleaner to convert callers to use plain toScreenRect, + // and perform the screen -> CSS rect in the parent process instead, probably. + LayoutDeviceToCSSScale scale = [&] { + float auPerDev = + presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom(); + auPerDev /= LookAndFeel::GetTextScaleFactor(); + return LayoutDeviceToCSSScale(auPerDev / AppUnitsPerCSSPixel()); + }(); + + CSSRect cssRect = devRect * scale; RefPtr outRect = new DOMRect(mWindow); - outRect->SetRect(cssUnitsRect.x, cssUnitsRect.y, cssUnitsRect.width, - cssUnitsRect.height); + outRect->SetRect(cssRect.x, cssRect.y, cssRect.width, cssRect.height); outRect.forget(aResult); return NS_OK; } diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index e982a7d0b9f9..170c3ae9ebca 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -929,7 +929,15 @@ void nsPresContext::RecomputeBrowsingContextDependentData() { // matter... Medium also doesn't affect those. return; } - SetFullZoom(browsingContext->FullZoom()); + // NOTE(emilio): We use the OS "text scale factor" as an extra source for full + // zoom, rather than text zoom (which would seem the obvious choice at first). + // is for a variety of reasons: + // * It generally creates more visually consistent results. + // * It has always been the effective behavior on GTK. + // * It matches other browsers as well. + float effectiveFullZoom = + browsingContext->FullZoom() * LookAndFeel::GetTextScaleFactor(); + SetFullZoom(effectiveFullZoom); SetTextZoom(browsingContext->TextZoom()); SetOverrideDPPX(browsingContext->OverrideDPPX()); @@ -1581,6 +1589,9 @@ void nsPresContext::ThemeChangedInternal() { LookAndFeel::HandleGlobalThemeChange(); + // Full zoom might have changed as a result of the text scale factor. + RecomputeBrowsingContextDependentData(); + // Changes to system metrics and other look and feel values can change media // queries on them. // diff --git a/widget/LookAndFeel.h b/widget/LookAndFeel.h index 955c7875160c..2cc2f03b8dab 100644 --- a/widget/LookAndFeel.h +++ b/widget/LookAndFeel.h @@ -445,6 +445,10 @@ class LookAndFeel { return GetColor(aId, aFrame).valueOr(aDefault); } + static float GetTextScaleFactor() { + return GetFloat(FloatID::TextScaleFactor, 1.0f); + } + /** * GetInt() and GetFloat() return a int or float value for aID. The result * might be distance, time, some flags or a int value which has particular diff --git a/widget/ScrollbarDrawingGTK.cpp b/widget/ScrollbarDrawingGTK.cpp index 6877ed0c3b33..15556cad35d7 100644 --- a/widget/ScrollbarDrawingGTK.cpp +++ b/widget/ScrollbarDrawingGTK.cpp @@ -131,16 +131,4 @@ void ScrollbarDrawingGTK::RecomputeScrollbarParams() { defaultSize = overrideSize; } mHorizontalScrollbarHeight = mVerticalScrollbarWidth = defaultSize; - - // On GTK, widgets don't account for text scale factor, but that's included - // in the usual DPI computations, so we undo that here, just like - // GetMonitorScaleFactor does it in nsNativeThemeGTK. - float scale = - LookAndFeel::GetFloat(LookAndFeel::FloatID::TextScaleFactor, 1.0f); - if (scale != 1.0f) { - mVerticalScrollbarWidth = - uint32_t(round(float(mVerticalScrollbarWidth) / scale)); - mHorizontalScrollbarHeight = - uint32_t(round(float(mHorizontalScrollbarHeight) / scale)); - } } diff --git a/widget/gtk/ScreenHelperGTK.cpp b/widget/gtk/ScreenHelperGTK.cpp index 2011face0c93..2989cbf3d76a 100644 --- a/widget/gtk/ScreenHelperGTK.cpp +++ b/widget/gtk/ScreenHelperGTK.cpp @@ -204,8 +204,7 @@ static already_AddRefed MakeScreenGtk(GdkScreen* aScreen, } #endif - CSSToLayoutDeviceScale defaultCssScale(gdkScaleFactor * - gfxPlatformGtk::GetFontScaleFactor()); + CSSToLayoutDeviceScale defaultCssScale(gdkScaleFactor); float dpi = 96.0f; gint heightMM = gdk_screen_get_monitor_height_mm(aScreen, aMonitorNum); @@ -371,8 +370,7 @@ already_AddRefed ScreenGetterWayland::MakeScreenWayland(gint aMonitor) { // Use per-monitor scaling factor in gtk/wayland, or 1.0 otherwise. DesktopToLayoutDeviceScale contentsScale(monitor->scale); - CSSToLayoutDeviceScale defaultCssScale(monitor->scale * - gfxPlatformGtk::GetFontScaleFactor()); + CSSToLayoutDeviceScale defaultCssScale(monitor->scale); float dpi = 96.0f; gint heightMM = monitor->height_mm; diff --git a/widget/gtk/nsNativeThemeGTK.cpp b/widget/gtk/nsNativeThemeGTK.cpp index 0a27e92e11c2..98d65481fe53 100644 --- a/widget/gtk/nsNativeThemeGTK.cpp +++ b/widget/gtk/nsNativeThemeGTK.cpp @@ -66,17 +66,7 @@ static inline gint GetMonitorScaleFactor(nsPresContext* aPresContext) { double scale = StaticPrefs::layout_css_devPixelsPerPx(); if (scale <= 0) { if (nsCOMPtr rootWidget = aPresContext->GetRootWidget()) { - // We need to use GetDefaultScale() despite it returns monitor scale - // factor multiplied by font scale factor because it is the only scale - // updated in nsPuppetWidget. - // Since we don't want to apply font scale factor for UI elements - // (because GTK does not do so) we need to remove that from returned - // value. The computed monitor scale factor needs to be rounded before - // casting to integer to avoid rounding errors which would lead to - // returning 0. - int monitorScale = int( - round(rootWidget->GetDefaultScale().scale / - LookAndFeel::GetFloat(LookAndFeel::FloatID::TextScaleFactor))); + int monitorScale = int(round(rootWidget->GetDefaultScale().scale)); // Monitor scale can be negative if it has not been initialized in the // puppet widget yet. We also make sure that we return positive value. if (monitorScale < 1) { diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 025c37f39aa7..c0300eb50283 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -646,9 +646,7 @@ float nsWindow::GetDPI() { return dpi; } -double nsWindow::GetDefaultScaleInternal() { - return FractionalScaleFactor() * gfxPlatformGtk::GetFontScaleFactor(); -} +double nsWindow::GetDefaultScaleInternal() { return FractionalScaleFactor(); } DesktopToLayoutDeviceScale nsWindow::GetDesktopToDeviceScale() { #ifdef MOZ_WAYLAND diff --git a/widget/windows/nsLookAndFeel.cpp b/widget/windows/nsLookAndFeel.cpp index f9db6770712d..7c3e19a12de7 100644 --- a/widget/windows/nsLookAndFeel.cpp +++ b/widget/windows/nsLookAndFeel.cpp @@ -576,7 +576,8 @@ LookAndFeelFont nsLookAndFeel::GetLookAndFeelFontInternal( result.haveFont() = false; // Get scaling factor from physical to logical pixels - double pixelScale = 1.0 / WinUtils::SystemScaleFactor(); + double pixelScale = + 1.0 / WinUtils::SystemScaleFactor() / LookAndFeel::GetTextScaleFactor(); // The lfHeight is in pixels, and it needs to be adjusted for the // device it will be displayed on.