Closed Bug 1477007 Opened 3 years ago Closed 3 years ago

Using meta viewport user-scalable=0 option can result in being unable to pan around the page.

Categories

(Core :: Layout, defect, P3)

defect

Tracking

()

RESOLVED FIXED
mozilla63
Tracking Status
firefox63 --- fixed

People

(Reporter: twisniewski, Assigned: botond)

References

(Blocks 1 open bug)

Details

(Whiteboard: [webcompat])

Attachments

(2 files)

Attached file test.html
If a page specifies user-scalable=0 in their meta-viewport tag, then users may be unable to pan around to see content that initially is off-screen.

If the content sets an explicit width/height, then it might be possible to pan around, but otherwise it does not (as per the attached test case).

Chrome does allow the user to pan around.

I'm not sure if this has the same underlying cause as bug 1423013.
I find the fact that you can't scroll on this page even though the page is not overflow:hidden, to be very surprising. I will investigate.
Assignee: nobody → botond
The issue goes away when "width=max-device-width" is removed, which suggests that fixing bug 1476995 may fix this.

All the same, I don't think even a completely bogus value in the meta-viewport tag should mess a page up this badly.
(In reply to Botond Ballo [:botond] from comment #2)
> The issue goes away when "width=max-device-width" is removed

It looks like whenever "width" is set to an unrecognized value (any value that's neither a number nor the special value "device-width"), we use a default width of 980px, and a corresponding height that preserves the aspect ratio.

If "width" is empty and "initial-scale" is set to 1, however, we treat "width" as if it were "device-width".

That explains why removing "width=max-deice-width" fixes the problem.

What remains to be investigated, is why the page cannot be scrolled; in the absence of overflow:hidden, it should be scrollable regardless of what viewport width we compute.
(In reply to Botond Ballo [:botond] from comment #3)
> What remains to be investigated, is why the page cannot be scrolled; in the
> absence of overflow:hidden, it should be scrollable regardless of what
> viewport width we compute.

It looks like the ingredients required to trigger this bug are:

  1) A viewport size that's larger than the screen size (at unit zoom).
  2) Page content that overflows the screen size (visual viewport),
     but not the (layout) viewport size.
  3) The page being loaded at unit zoom (due to intial-scale=1).
  4) The page not being zoomable (due to user-scalable=no).

These things seem to conspire to prevent the RCD-RSF from getting a displayport.

The problems start with the RCD-RSF returning false for WantAsyncScroll(). WantAsyncScroll() returns true in two cases:

  a) The scroll frame is zoomable [1]. This is not the case
     due to (4) above.

  b) The scroll frame has a scroll range [2]. However, we use
     the layout viewport ("scroll port") to make this
     determination. Thanks to (2) above, the scroll frame does
     not have a scroll range in this sense.

Since the RCD-RSF doesn't WantAsyncScroll(), it doesn't get a display port on initial page load by the "layerize the first async-scrollable frame we encounter" optimization [3].

I looked at what else might give the RCD-RSF a display port on page load, but came up blank:

  - InitializeRootDisplayport() only applies to the RSF of the
    display root document (the root document in a process),
    which the RCD is not on Fennec.

  - MobileViewportManager sets a displayport on the RCD-RSF,
    but only if it has a resolution [4], which in this case
    it doesn't due to (3) above.

So, no initial displayport ==> no scroll metadata on the RCD's container layer (there's a special-case codepath for setting root scroll metadata [5] but again it only applies to the display root document) ==> no APZC for the RCD-RSF.

You might think that in and of itself that's not a big deal: even if the RCD-RSF doesn't get layerized on page load, it will get layerized once you try to touch-scroll it, right? Unfortunately not: the codepaths that layerize content in response to events like touch events, use GetNearestScrollableFrame() with the ONLY_ASYNC_SCROLLABLE flag to choose what to layerize, and that skips scroll frames that don't WantAsyncScroll() [6]. So, our RCD is stuck without a displayport (and thus without an APZC) for good.

[1] https://searchfox.org/mozilla-central/rev/704612cf4426f0f0510b3e160895578c319a3270/layout/generic/nsGfxScrollFrame.cpp#1355
[2] https://searchfox.org/mozilla-central/rev/704612cf4426f0f0510b3e160895578c319a3270/layout/generic/nsGfxScrollFrame.cpp#1377
[3] https://searchfox.org/mozilla-central/rev/704612cf4426f0f0510b3e160895578c319a3270/layout/base/nsLayoutUtils.cpp#3328
[4] https://searchfox.org/mozilla-central/rev/704612cf4426f0f0510b3e160895578c319a3270/layout/base/MobileViewportManager.cpp#315
[5] https://searchfox.org/mozilla-central/rev/704612cf4426f0f0510b3e160895578c319a3270/layout/painting/nsDisplayList.cpp#2549
[6] https://searchfox.org/mozilla-central/rev/704612cf4426f0f0510b3e160895578c319a3270/layout/base/nsLayoutUtils.cpp#1991
I think the conceptual problem here lies with WantAsyncScroll() returning false. The function is assuming that the visual viewport can only be smaller than the layout viewport if the page is zoomable, but that assumption is wrong: here we can a non-zoomable page whose viewport size and initial zoom level are such that you still need to be able to scroll within the (layout) viewport.
A meta viewport tag can simultaneously specify user-scalable=no, and a
layout viewport size and initial zoom level that make the visual viewport
smaller than the layout viewport.
Comment on attachment 8996478 [details]
Bug 1477007 - Ensure the visual viewport can be scrolled within the layout viewport even if a page is not zoomable. r=kats

Kartikaya Gupta (email:kats@mozilla.com) has approved the revision.

https://phabricator.services.mozilla.com/D2584
Attachment #8996478 - Flags: review+
Priority: -- → P3
Pushed by bballo@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/786d4f456690
Ensure the visual viewport can be scrolled within the layout viewport even if a page is not zoomable. r=kats
https://hg.mozilla.org/mozilla-central/rev/786d4f456690
Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla63
Depends on: 1481423
You need to log in before you can comment on or make changes to this bug.