Bug 1773633 - Allow configuring OS zoom behavior. r=tnikkel

This is reasonably straight-forward and should allow us change the
desired behavior on platforms if / when we need.

Also, this adds tests for the feature by using the relevant float pref
(though we can't easily assert the full-zoom behavior because it changes
the size of the reftest window itself).

Differential Revision: https://phabricator.services.mozilla.com/D148902
This commit is contained in:
Emilio Cobos Álvarez 2022-06-13 00:05:00 +00:00
Родитель f35bad6668
Коммит 3514929e87
9 изменённых файлов: 92 добавлений и 17 удалений

Просмотреть файл

@ -1877,7 +1877,7 @@ nsDOMWindowUtils::ToScreenRectInCSSUnits(float aX, float aY, float aWidth,
LayoutDeviceToCSSScale scale = [&] {
float auPerDev =
presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
auPerDev /= LookAndFeel::GetTextScaleFactor();
auPerDev /= LookAndFeel::SystemZoomSettings().mFullZoom;
return LayoutDeviceToCSSScale(auPerDev / AppUnitsPerCSSPixel());
}();

Просмотреть файл

@ -929,16 +929,9 @@ void nsPresContext::RecomputeBrowsingContextDependentData() {
// matter... Medium also doesn't affect those.
return;
}
// 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());
auto systemZoom = LookAndFeel::SystemZoomSettings();
SetFullZoom(browsingContext->FullZoom() * systemZoom.mFullZoom);
SetTextZoom(browsingContext->TextZoom() * systemZoom.mTextZoom);
SetOverrideDPPX(browsingContext->OverrideDPPX());
auto* top = browsingContext->Top();

Просмотреть файл

@ -0,0 +1,10 @@
<!doctype html>
<html reftest-zoom="1.5">
<style>
div {
width: 100px;
height: 100px;
background-color: purple;
}
</style>
<div>Box with text</div>

Просмотреть файл

@ -0,0 +1,10 @@
<!doctype html>
<html reftest-text-zoom="1.5">
<style>
div {
width: 100px;
height: 100px;
background-color: purple;
}
</style>
<div>Box with text</div>

Просмотреть файл

@ -0,0 +1,9 @@
<!doctype html>
<style>
div {
width: 100px;
height: 100px;
background-color: purple;
}
</style>
<div>Box with text</div>

Просмотреть файл

@ -2116,3 +2116,9 @@ pref(image.downscale-during-decode.enabled,true) == 1744468-1.html 1744468-1-ref
== 1747272-1.html 1747272-1-ref.html
== 1750146-1.html 1750146-1-ref.html
== 1735265-1.html 1735265-1-ref.html
test-pref(ui.textScaleFactor,150) test-pref(browser.display.os-zoom-behavior,0) == 1773633.html 1773633.html
test-pref(ui.textScaleFactor,150) test-pref(browser.display.os-zoom-behavior,1) != 1773633.html 1773633.html
test-pref(ui.textScaleFactor,150) test-pref(browser.display.os-zoom-behavior,2) != 1773633.html 1773633.html
# TODO: This doesn't quite work because textScaleFactor also applies to the reftest window itself, ugh.
# test-pref(ui.textScaleFactor,150) test-pref(browser.display.os-zoom-behavior,1) == 1773633.html 1773633-full-zoom.html
test-pref(ui.textScaleFactor,150) test-pref(browser.display.os-zoom-behavior,2) == 1773633.html 1773633-text-zoom.html

Просмотреть файл

@ -1122,6 +1122,20 @@
value: "#FBFBFE"
mirror: never
# Determines the behavior of OS zoom settings.
#
# 0: doesn't affect rendering at all
# 1: affects full zoom (dpi, effectively).
# 2: affects text zoom.
#
# Default is (1): Historical behavior on Linux, matches other browsers on
# Windows, and generally creates more consistent rendering.
- name: browser.display.os-zoom-behavior
type: RelaxedAtomicInt32
value: 1
mirror: always
rust: true
# Whether focus rings are always shown by default.
#
# This is the initial value of nsWindowRoot::mShowFocusRings, but it can be

Просмотреть файл

@ -446,9 +446,20 @@ class LookAndFeel {
}
static float GetTextScaleFactor() {
return GetFloat(FloatID::TextScaleFactor, 1.0f);
float f = GetFloat(FloatID::TextScaleFactor, 1.0f);
if (MOZ_UNLIKELY(f <= 0.0f)) {
return 1.0f;
}
return f;
}
struct ZoomSettings {
float mFullZoom = 1.0f;
float mTextZoom = 1.0f;
};
static ZoomSettings SystemZoomSettings();
/**
* 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

Просмотреть файл

@ -322,6 +322,22 @@ bool nsXPLookAndFeel::sInitialized = false;
nsXPLookAndFeel* nsXPLookAndFeel::sInstance = nullptr;
bool nsXPLookAndFeel::sShutdown = false;
auto LookAndFeel::SystemZoomSettings() -> ZoomSettings {
ZoomSettings settings;
switch (StaticPrefs::browser_display_os_zoom_behavior()) {
case 0:
default:
break;
case 1:
settings.mFullZoom = GetTextScaleFactor();
break;
case 2:
settings.mTextZoom = GetTextScaleFactor();
break;
}
return settings;
}
// static
nsXPLookAndFeel* nsXPLookAndFeel::GetInstance() {
if (sInstance) {
@ -385,10 +401,13 @@ static void IntPrefChanged(const nsACString& aPref) {
LookAndFeel::NotifyChangedAllWindows(changeKind);
}
static void FloatPrefChanged() {
// Float prefs can't change our system colors or fonts.
LookAndFeel::NotifyChangedAllWindows(
widget::ThemeChangeKind::MediaQueriesOnly);
static void FloatPrefChanged(const nsACString& aPref) {
// Most float prefs can't change our system colors or fonts, but
// textScaleFactor affects layout.
auto changeKind = aPref.EqualsLiteral("ui.textScaleFactor")
? widget::ThemeChangeKind::StyleAndLayout
: widget::ThemeChangeKind::MediaQueriesOnly;
LookAndFeel::NotifyChangedAllWindows(changeKind);
}
static void ColorPrefChanged() {
@ -408,7 +427,7 @@ void nsXPLookAndFeel::OnPrefChanged(const char* aPref, void* aClosure) {
for (const char* pref : sFloatPrefs) {
if (prefName.Equals(pref)) {
FloatPrefChanged();
FloatPrefChanged(prefName);
return;
}
}
@ -434,6 +453,9 @@ static constexpr struct {
// Affects media queries and scrollbar sizes, so gotta relayout.
{"widget.gtk.overlay-scrollbars.enabled"_ns,
widget::ThemeChangeKind::StyleAndLayout},
// Affects zoom settings which includes text and full zoom.
{"browser.display.os-zoom-behavior"_ns,
widget::ThemeChangeKind::StyleAndLayout},
// This affects not only the media query, but also the native theme, so we
// need to re-layout.
{"browser.theme.toolbar-theme"_ns, widget::ThemeChangeKind::AllBits},