Skip to content

Commit

Permalink
Bug 1773633 - Allow configuring OS zoom behavior. r=tnikkel
Browse files Browse the repository at this point in the history
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
  • Loading branch information
emilio committed Jun 13, 2022
1 parent f35bad6 commit 3514929
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 17 deletions.
2 changes: 1 addition & 1 deletion dom/base/nsDOMWindowUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}();

Expand Down
13 changes: 3 additions & 10 deletions layout/base/nsPresContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
10 changes: 10 additions & 0 deletions layout/reftests/bugs/1773633-full-zoom.html
Original file line number Diff line number Diff line change
@@ -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>
10 changes: 10 additions & 0 deletions layout/reftests/bugs/1773633-text-zoom.html
Original file line number Diff line number Diff line change
@@ -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>
9 changes: 9 additions & 0 deletions layout/reftests/bugs/1773633.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!doctype html>
<style>
div {
width: 100px;
height: 100px;
background-color: purple;
}
</style>
<div>Box with text</div>
6 changes: 6 additions & 0 deletions layout/reftests/bugs/reftest.list
Original file line number Diff line number Diff line change
Expand Up @@ -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
14 changes: 14 additions & 0 deletions modules/libpref/init/StaticPrefList.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 12 additions & 1 deletion widget/LookAndFeel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 27 additions & 5 deletions widget/nsXPLookAndFeel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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() {
Expand All @@ -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;
}
}
Expand All @@ -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},
Expand Down

0 comments on commit 3514929

Please sign in to comment.