Bug 1889244 - Truncate rather than round inner sizes. r=dholbert

This should allow us to work on bug 1647356 and co again, and prevents
undesired scrollbars like those from bug 1648265. It should also be more
compatible (seems like my comment in
https://github.com/w3c/csswg-drafts/issues/5260 still holds).

Differential Revision: https://phabricator.services.mozilla.com/D206434
This commit is contained in:
Emilio Cobos Álvarez 2024-04-03 10:42:54 +00:00
parent 284b666425
commit 5b3d95fe9f
5 changed files with 52 additions and 39 deletions

View file

@ -3473,9 +3473,17 @@ nsresult nsGlobalWindowOuter::GetInnerSize(CSSSize& aSize) {
aSize = CSSPixel::FromAppUnits(viewportSize); aSize = CSSPixel::FromAppUnits(viewportSize);
if (StaticPrefs::dom_innerSize_rounded()) { switch (StaticPrefs::dom_innerSize_rounding()) {
aSize.width = std::roundf(aSize.width); case 1:
aSize.height = std::roundf(aSize.height); aSize.width = std::roundf(aSize.width);
aSize.height = std::roundf(aSize.height);
break;
case 2:
aSize.width = std::truncf(aSize.width);
aSize.height = std::truncf(aSize.height);
break;
default:
break;
} }
return NS_OK; return NS_OK;

View file

@ -13,7 +13,7 @@ function test_once() {
`${rect.width}x${rect.height}, ${content.innerWidth}x${content.innerHeight}` `${rect.width}x${rect.height}, ${content.innerWidth}x${content.innerHeight}`
); );
is( is(
Math.round(rect.height), Math.trunc(rect.height),
content.innerHeight, content.innerHeight,
"Should fill the viewport and not overflow" "Should fill the viewport and not overflow"
); );

View file

@ -2779,7 +2779,11 @@
value: false value: false
mirror: always mirror: always
# Whether innerWidth / innerHeight return rounded or fractional sizes. # How innerWidth / innerHeight return rounded or fractional sizes.
#
# 0 or others: Do not round at all.
# 1: Round.
# 2: Truncate.
# #
# NOTE(emilio): Fractional sizes are not web-compatible, see the regressions # NOTE(emilio): Fractional sizes are not web-compatible, see the regressions
# from bug 1676843, but we want to expose the fractional sizes (probably in # from bug 1676843, but we want to expose the fractional sizes (probably in
@ -2787,9 +2791,9 @@
# time being. # time being.
# #
# [1]: https://github.com/w3c/csswg-drafts/issues/5260 # [1]: https://github.com/w3c/csswg-drafts/issues/5260
- name: dom.innerSize.rounded - name: dom.innerSize.rounding
type: bool type: uint32_t
value: true value: 2
mirror: always mirror: always
# Whether we conform to Input Events Level 1 or Input Events Level 2. # Whether we conform to Input Events Level 1 or Input Events Level 2.

View file

@ -1,5 +0,0 @@
[window_size_rounding.html]
bug: Different viewport size
[window_size_rounding]
expected:
if os == "android": FAIL

View file

@ -1,35 +1,41 @@
<!doctype html> <!doctype html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src=/resources/testharness.js></script> <script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script> <script src=/resources/testharnessreport.js></script>
<pre> <iframe style="border: 0; padding: 0; width: 100.75px; height: 100.75px" srcdoc="<html style='width: 100vw; height: 100vh'>"></iframe>
<script> <script>
test(function() { onload = function() {
let originalWidth = window.innerWidth; test(() => {
let originalHeight = window.innerHeight; assert_equals(window.devicePixelRatio, 1, `precondition: ${window.innerWidth}x${window.innerHeight}`);
assert_equals(window.devicePixelRatio, 1, `precondition: ${originalWidth}x${originalHeight}`); // So that the 100.75 is fractional css pixel, but whole dev pixels, and representable in app units.
SpecialPowers.setFullZoom(window, 4);
// This precondition holds because of: let win = document.querySelector("iframe").contentWindow;
// https://searchfox.org/mozilla-central/rev/50215d649d4854812837f1343e8f47bd998dacb5/browser/base/content/browser.js#1717 const rounded = 101;
// const truncated = 100;
// But if this test starts failing you can just update the assert and the const raw = 100.75;
// factor below accordingly so that the asserts keep passing.
assert_equals(originalWidth, 1280, "precondition");
// Set a fractional scale factor that guarantees that we get a fractional innerWidth const rect = win.document.documentElement.getBoundingClientRect();
const kFactor = 1.5; assert_equals(rect.height, raw);
const kOneAppUnit = 1 / 60; assert_equals(rect.width, raw);
SpecialPowers.setFullZoom(window, kFactor); switch (SpecialPowers.getIntPref("dom.innerSize.rounding")) {
assert_approx_equals(window.devicePixelRatio, kFactor, kOneAppUnit); case 1:
assert_not_equals(window.innerWidth, originalWidth); assert_equals(win.innerWidth, rounded);
assert_not_equals(window.innerHeight, originalHeight); assert_equals(win.innerHeight, rounded);
if (SpecialPowers.getBoolPref("dom.innerSize.rounded")) { break;
assert_equals(window.innerWidth, Math.round(originalWidth / kFactor)); case 2:
assert_equals(window.innerHeight, Math.round(originalHeight / kFactor)); assert_equals(win.innerWidth, truncated);
} else { assert_equals(win.innerHeight, truncated);
assert_not_equals(window.innerWidth, Math.round(window.innerWidth)); break;
} default:
SpecialPowers.setFullZoom(window, 1); // Restore zoom so results can be seen fine... assert_equals(win.innerWidth, raw);
}); assert_equals(win.innerHeight, raw);
break;
}
SpecialPowers.setFullZoom(window, 1);
})
};
</script> </script>