Tweetdeck scrollbar jumps down when clicked on near the top of the column
Categories
(Core :: Panning and Zooming, defect, P2)
Tracking
()
Tracking | Status | |
---|---|---|
firefox92 | --- | fixed |
People
(Reporter: iii_iii, Assigned: botond)
References
Details
Attachments
(7 files)
923 bytes,
text/html
|
Details | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review |
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0
Steps to reproduce:
Sign into twitter. Visit tweetdeck.twitter.com. When the scroll bar grip is at or near the top of a column click on it and try to drag it upward.
Actual results:
The grip jumps downward. The grip seems to be out of sync with the location of the mouse pointer.
Expected results:
Normally dragging upward from the top would reveal a new tweet if there were one, otherwise do nothing.
This applies to all columns. I don't think it is connected with 1712040.
Comment 2•3 years ago
|
||
The Bugbug bot thinks this bug should belong to the 'Core::Panning and Zooming' component, and is moving the bug to that component. Please revert this change in case you think the bot is wrong.
Assignee | ||
Comment 3•3 years ago
|
||
Thanks for the report, I can reproduce. The issue seems to be specific to WebRender.
Assignee | ||
Comment 4•3 years ago
|
||
The bug is reproducible as far back as WebRender is usable, so I'm not able to find a useful regression window.
Assignee | ||
Comment 5•3 years ago
|
||
Finally, the issue does not reproduce with apz.drag.enabled=false
, confirming that it's a bug in the APZ scrollbar dragging codepath.
Assignee | ||
Updated•3 years ago
|
I've noticed a work around of sorts. If you middle click (or click the mouse wheel) somewhere away from the scroll grip and hold it down, the scroll grip jumps under the mouse pointer, and then you can move the scroll grip normally without the bug as long as you hold down the middle mouse button.
Assignee | ||
Comment 7•3 years ago
|
||
(In reply to iii_iii from comment #6)
I've noticed a work around of sorts. If you middle click (or click the mouse wheel) somewhere away from the scroll grip and hold it down, the scroll grip jumps under the mouse pointer, and then you can move the scroll grip normally without the bug as long as you hold down the middle mouse button.
I expect using middle-click here forces us to take the main-thread scrollbar dragging codepath, which doesn't have this problem.
If you're looking for a workaround, a simpler one is to change the pref apz.drag.enabled
to false
in about:config
(which forces us to always use the main-thread scrollbar dragging codepath).
Assignee | ||
Comment 8•3 years ago
|
||
It looks like the scrollable element in question has an incorrect composition bounds origin. The composition bounds origin is one of the quantities APZ relies on to correctly convert the vertical screen coordinate of a mouse event during a scrollbar drag to the corresponding scroll position of the scrollable element.
Assignee | ||
Comment 9•3 years ago
|
||
(In reply to Botond Ballo [:botond] from comment #8)
It looks like the scrollable element in question has an incorrect composition bounds origin.
I take that back. The composition bounds origin is (0,0) both with and without WR. That's not what I expected it to be, but it's also not what's causing the problem here.
The difference between WR and non-WR seems to be the local (ParentLayer) coordinates of the mouse event. I think this suggests there's a scroll node with a transform that's present in the non-WR case but absent in the WR case.
Assignee | ||
Comment 10•3 years ago
|
||
The page also trips up this assertion:
[Parent 4962, WRSceneBuilder#1] ###!!! ASSERTION: Two layers that scroll together have different ancestor transforms: 'false', file /home/botond/dev/projects/mozilla/central/gfx/layers/apz/src/APZCTreeManager.cpp:1419
I believe that's related to the problem. To see how, let's look at a hit-testing tree:
APZCTreeManager (7fe01be58800)
HitTestingTreeNode (7fe01be06850) APZC (7fdffc9d2000) g=({ l=0x100000001, p=1, v=3 }) r=({ }) t=([ I ]) c=([0,0,1280,972])
HitTestingTreeNode (7fe01be08d20) APZC (0) g=(l=0x100000001) r=({ }) t=([ 1 0; 0 1; 0 113; ]) c=(none)
HitTestingTreeNode (7fe01be079c0) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7fe01be07bb0) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7fe01be096d0) APZC (7fe005846000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7fe01be08b30) APZC (7fe005846000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none) scrollbar scrollthumb
HitTestingTreeNode (7fe01be06660) APZC (7fe005846000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7fe01be08f10) APZC (7fdfe92aa000) g=({ l=0x100000002, p=2, v=4 }) r=({ }) t=([ I ]) c=([60,0,1280,843])
HitTestingTreeNode (7fe01be09e90) APZC (7fe005846000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none) scrollbar scrollthumb
HitTestingTreeNode (7fe01be06a40) APZC (7fdfe92aa000) g=({ l=0x100000002, p=2, v=4 }) r=({ }) t=([ I ]) c=([60,0,1280,843]) scrollbar scrollthumb
HitTestingTreeNode (7fe01be07f90) APZC (7fe005846000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ 1 0; 0 1; 382 50; ]) c=(none)
HitTestingTreeNode (7fe01be08750) APZC (7fdfe92aa000) g=({ l=0x100000002, p=2, v=4 }) r=({ }) t=([ I ]) c=([60,0,1280,843])
HitTestingTreeNode (7fe01be094e0) APZC (7fdfe16fe000) g=({ l=0x100000002, p=2, v=7 }) r=({ }) t=([ I ]) c=([0,0,298,793])
HitTestingTreeNode (7fe01be077d0) APZC (7fe005846000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7fe01be09100) APZC (7fdfe92aa000) g=({ l=0x100000002, p=2, v=4 }) r=({ }) t=([ I ]) c=([60,0,1280,843])
HitTestingTreeNode (7fe01be098c0) APZC (7fe005846000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none)
- The APZC whose scrollbar is being dragged is the one with v=7.
- One of the ancestor nodes of this APZC has a translation transform of (382, 50).
- However, this ancestor node is associated with the v=2 APZC.
- The v=2 APZC in turn has several nodes associated with it, and not all of them have this transform.
- This violates an APZ assumption, and APZ warns about this. In such cases, it uses the transform on the first node encountered for v=2 (which is the identity) for all nodes associated with v=2, i.e. the (382, 50) translation is effectively discarded.
Assignee | ||
Comment 11•3 years ago
|
||
I described APZ's requirement on the scroll nodes here incorrectly in the previous comment. The requirement is that, for a given APZC, all scroll nodes associated with that APZC must have the same ancestor transform. That's the transform from each node to their common ancestor, but not including the node's own transform.
So, in the above hit-testing tree, the v=2 APZC is not the one that violates this requirement -- the ancestor transforms for all of its nodes is the identity.
Rather, it's the v=4 APZC which violates this requirement -- it, too has several associated nodes, and one of them has the (382, 50) in its ancestor transform while the others don't.
Now, let's compare to a non-WR hit-testing tree:
APZCTreeManager (7fd597c7b000)
HitTestingTreeNode (7fd597108560) APZC (7fd57e6a0000) g=({ l=0x100000001, p=1, v=3 }) r=({ }) t=([ I ]) c=([0,0,1280,972])
HitTestingTreeNode (7fd597107bb0) APZC (0) g=(l=0x100000001) r=({ Hit=[0,0,1280,972] DispatchToContent=[0,28,1280,72] }) t=([ I ]) c=(none)
HitTestingTreeNode (7fd573c804e0) APZC (0) g=(l=0x100000001) r=({ }) t=([ 1 0; 0 1; 0 113; ]) c=([0,113,1280,972])
HitTestingTreeNode (7fd573c7fd20) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7fd5971096d0) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=([])
HitTestingTreeNode (7fd597108b30) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,1280,859] }) t=([ I ]) c=(none)
HitTestingTreeNode (7fd573c808c0) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fd597107f90) APZC (7fd56de4a000) g=({ l=0x100000002, p=2, v=2 }) r=({ Hit=[0,0,1280,859] DispatchToContent=[60,843,1280,855] }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fd597106090) APZC (7fd56de4a000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([60,843,1280,855]) scrollbar scrollthumb
HitTestingTreeNode (7fd597108180) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,1161,12] DispatchToContent=[0,0,1161,12] }) t=([ 1 0; 0 1; 60 843; ]) c=(none)
HitTestingTreeNode (7fd59710a270) APZC (7fd56de4a000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fd597109e90) APZC (7fd56e84b000) g=({ l=0x100000002, p=2, v=4 }) r=({ Hit=[0,0,1270,843] DispatchToContent=[0,0,1264,843] }) t=([ 1 0; 0 1; 60 0; ]) c=([60,0,1280,843])
HitTestingTreeNode (7fd59710a840) APZC (7fd56de4a000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fd59710a460) APZC (7fd56e84b000) g=({ l=0x100000002, p=2, v=4 }) r=({ }) t=([ 1 0; 0 1; 66 50; ]) c=([66,0,376,843])
HitTestingTreeNode (7fd59710ae10) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,310,793] DispatchToContent=[0,0,310,793] }) t=([ I ]) c=(none)
HitTestingTreeNode (7fd573c802f0) APZC (7fd56de4a000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fd573c7d470) APZC (7fd56e84b000) g=({ l=0x100000002, p=2, v=4 }) r=({ }) t=([ 1 0; 0 1; 382 50; ]) c=([382,0,692,843])
HitTestingTreeNode (7fd59710a650) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,310,793] DispatchToContent=[0,0,310,793] }) t=([ I ]) c=(none)
HitTestingTreeNode (7fd59710ac20) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=([298,0,310,793]) scrollbar scrollthumb
HitTestingTreeNode (7fd59710aa30) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,12,103] DispatchToContent=[0,0,12,103] }) t=([ 1 0; 0 1; 298 0; ]) c=(none)
HitTestingTreeNode (7fd573c7fb30) APZC (7fd569be6000) g=({ l=0x100000002, p=2, v=7 }) r=({ Hit=[0,0,298,5735] DispatchToContent=[0,0,298,5735] }) t=([ I ]) c=([0,0,298,793])
HitTestingTreeNode (7fd573c7e3f0) APZC (7fd56de4a000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fd573c7dc30) APZC (7fd56e84b000) g=({ l=0x100000002, p=2, v=4 }) r=({ }) t=([ 1 0; 0 1; 698 50; ]) c=([698,0,1008,843])
HitTestingTreeNode (7fd573c7d280) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,310,793] DispatchToContent=[0,0,310,793] }) t=([ I ]) c=(none)
HitTestingTreeNode (7fd573c80ca0) APZC (7fd56de4a000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fd59710a080) APZC (7fd56e84b000) g=({ l=0x100000002, p=2, v=4 }) r=({ }) t=([ 1 0; 0 1; 1014 82; ]) c=([1014,0,1280,843])
HitTestingTreeNode (7fd573c7e5e0) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,310,761] DispatchToContent=[0,0,310,761] }) t=([ I ]) c=(none)
HitTestingTreeNode (7fd573c7ff10) APZC (7fd56de4a000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fd597108d20) APZC (7fd56a3a5000) g=({ l=0x100000002, p=2, v=3 }) r=({ Hit=[0,0,60,548] }) t=([ 1 0; 0 1; 0 112; ]) c=([0,112,60,660])
HitTestingTreeNode (7fd597107010) APZC (7fd56de4a000) g=({ l=0x100000002, p=2, v=2 }) r=({ Hit=[0,632,60,751] }) t=([ I ]) c=([0,0,1280,859])
Note a very important difference: the (382, 50) transform is now on a v=4 node, not a v=2 node. So, it's no longer a part of the ancestor transform of the v=4 nodes, and thus the v=4 nodes no longer violate the APZ requirement.
Assignee | ||
Comment 12•3 years ago
|
||
This is the point where continuing to debug the full website starts to get unwieldy (as I need to look at display list dumps which get very long), so my next step here is to try and prepare a reduced testcase.
Assignee | ||
Comment 13•3 years ago
|
||
Updated•3 years ago
|
Assignee | ||
Comment 14•3 years ago
|
||
Posting some new hit-testing trees for the reduced testcase.
WebRender:
APZCTreeManager (7f330f555800)
HitTestingTreeNode (7f330f506470) APZC (7f32f04f1000) g=({ l=0x100000001, p=1, v=3 }) r=({ }) t=([ I ]) c=([0,0,1280,972])
HitTestingTreeNode (7f330f508940) APZC (0) g=(l=0x100000001) r=({ }) t=([ 1 0; 0 1; 0 113; ]) c=(none)
HitTestingTreeNode (7f330f5077d0) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7f330f508750) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7f330f506660) APZC (7f32efe68000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7f330f507da0) APZC (7f32efe68000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none) scrollbar scrollthumb
HitTestingTreeNode (7f330f5094e0) APZC (7f32efe68000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7f330f507f90) APZC (7f330aca5000) g=({ l=0x100000002, p=2, v=3 }) r=({ }) t=([ I ]) c=([0,0,1268,859])
HitTestingTreeNode (7f330f508560) APZC (7f32efe68000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none) scrollbar scrollthumb
HitTestingTreeNode (7f330f5096d0) APZC (7f330aca5000) g=({ l=0x100000002, p=2, v=3 }) r=({ }) t=([ I ]) c=([0,0,1268,859]) scrollbar scrollthumb
HitTestingTreeNode (7f330f5075e0) APZC (7f32efe68000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ 1 0; 0 1; 0 50; ]) c=(none)
HitTestingTreeNode (7f330f508b30) APZC (7f330aca5000) g=({ l=0x100000002, p=2, v=3 }) r=({ }) t=([ I ]) c=([0,0,1268,859])
HitTestingTreeNode (7f330f506e20) APZC (7f32defe8000) g=({ l=0x100000002, p=2, v=4 }) r=({ }) t=([ I ]) c=([0,0,622,859])
HitTestingTreeNode (7f330f506c30) APZC (7f32efe68000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7f330f509ab0) APZC (7f330aca5000) g=({ l=0x100000002, p=2, v=3 }) r=({ }) t=([ I ]) c=([0,0,1268,859])
- scrollframe whose thumb is being dragged is v=4
- enclosing transform (here the amount is (0, 50)) is on a v=2 node, making it part of the ancestor transform for v=3 nodes
- APZ assumption is violated for v=3
non-WebRender:
APZCTreeManager (7fb3a5279000)
HitTestingTreeNode (7fb3a4708b30) APZC (7fb38de8e000) g=({ l=0x100000001, p=1, v=3 }) r=({ }) t=([ I ]) c=([0,0,1280,972])
HitTestingTreeNode (7fb3a47098c0) APZC (0) g=(l=0x100000001) r=({ Hit=[0,0,1280,972] DispatchToContent=[0,28,1280,72] }) t=([ I ]) c=(none)
HitTestingTreeNode (7fb3a4708f10) APZC (0) g=(l=0x100000001) r=({ }) t=([ 1 0; 0 1; 0 113; ]) c=([0,113,1280,972])
HitTestingTreeNode (7fb3a4708d20) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=(none)
HitTestingTreeNode (7fb3a4707bb0) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=([])
HitTestingTreeNode (7fb3a47077d0) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,1280,859] }) t=([ I ]) c=(none)
HitTestingTreeNode (7fb3a4706e20) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fb3a4706c30) APZC (7fb383bb0000) g=({ l=0x100000002, p=2, v=2 }) r=({ Hit=[0,0,1280,859] DispatchToContent=[1268,0,1280,859] }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fb3a4708940) APZC (7fb383bb0000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([1268,0,1280,859]) scrollbar scrollthumb
HitTestingTreeNode (7fb3a4709100) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,12,415] DispatchToContent=[0,0,12,415] }) t=([ 1 0; 0 1; 1268 0; ]) c=(none)
HitTestingTreeNode (7fb3a4708560) APZC (7fb383bb0000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fb3a47096d0) APZC (7fb383bb1000) g=({ l=0x100000002, p=2, v=3 }) r=({ Hit=[0,0,1268,1718] }) t=([ I ]) c=([0,0,1268,859])
HitTestingTreeNode (7fb3a4706090) APZC (7fb383bb0000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fb3a4709ca0) APZC (7fb383bb1000) g=({ l=0x100000002, p=2, v=3 }) r=({ }) t=([ 1 0; 0 1; 0 50; ]) c=([0,0,1268,859])
HitTestingTreeNode (7fb3a4708180) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,634,859] DispatchToContent=[622,0,634,859] }) t=([ I ]) c=(none)
HitTestingTreeNode (7fb3a4708750) APZC (0) g=(l=0x100000002) r=({ }) t=([ I ]) c=([622,0,634,859]) scrollbar scrollthumb
HitTestingTreeNode (7fb3a4708370) APZC (0) g=(l=0x100000002) r=({ Hit=[0,0,12,139] DispatchToContent=[0,0,12,139] }) t=([ 1 0; 0 1; 622 0; ]) c=(none)
HitTestingTreeNode (7fb3a4706660) APZC (7fb3846c1000) g=({ l=0x100000002, p=2, v=4 }) r=({ Hit=[0,0,622,5000] }) t=([ I ]) c=([0,0,622,859])
HitTestingTreeNode (7fb3a4707da0) APZC (7fb383bb0000) g=({ l=0x100000002, p=2, v=2 }) r=({ }) t=([ I ]) c=([0,0,1280,859])
HitTestingTreeNode (7fb3a47094e0) APZC (7fb383bb1000) g=({ l=0x100000002, p=2, v=3 }) r=({ Hit=[0,859,634,1718] }) t=([ I ]) c=([0,0,1268,859])
- scrollframe whose thumb is being dragged is v=4
- enclosing (0, 50) transform is on a v=3 node, no assumption violations
Assignee | ||
Comment 15•3 years ago
•
|
||
Next, some content-side dumps.
For WebRender, a WebRenderLayerScrollData tree:
WebRenderLayerScrollData(0x7f564c310008), descendantCount=8, visible=[]
WebRenderLayerScrollData(0x7f564c310188), descendantCount=7, visible=[]
WebRenderLayerScrollData(0x7f564c310c08), descendantCount=0, metadata0={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [overscroll=auto] [0 scrollupdates] }, visible=[]
WebRenderLayerScrollData(0x7f564c310a88), descendantCount=0, metadata0={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [overscroll=auto] [0 scrollupdates] }, visible=[1268,0,1280,415], scrollbarType=1, scrollbarAnimationId=0x509000000002
WebRenderLayerScrollData(0x7f564c310908), descendantCount=0, metadata0={ [metrics={ [cb=(x=0, y=0, w=1268, h=859)] [sr=(x=0, y=0, w=1268, h=1718)] [s=(0,0)] [dp=(x=0, y=0, w=1268, h=1718)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1268, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 2)] scrollId=3 }] [color=dev_rgba(0, 0, 0, 0.000000)] [scrollParent=2] [overscroll=auto] [0 scrollupdates] }, metadata1={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [overscroll=auto] [0 scrollupdates] }, visible=[]
WebRenderLayerScrollData(0x7f564c310788), descendantCount=0, metadata0={ [metrics={ [cb=(x=0, y=0, w=1268, h=859)] [sr=(x=0, y=0, w=1268, h=1718)] [s=(0,0)] [dp=(x=0, y=0, w=1268, h=1718)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1268, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 2)] scrollId=3 }] [color=dev_rgba(0, 0, 0, 0.000000)] [scrollParent=2] [overscroll=auto] [0 scrollupdates] }, metadata1={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [overscroll=auto] [0 scrollupdates] }, visible=[622,0,634,139], scrollbarType=1, scrollbarAnimationId=0x509000000003
WebRenderLayerScrollData(0x7f564c310488), descendantCount=1, metadata0={ [metrics={ [cb=(x=0, y=0, w=1268, h=859)] [sr=(x=0, y=0, w=1268, h=1718)] [s=(0,0)] [dp=(x=0, y=0, w=1268, h=1718)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1268, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 2)] scrollId=3 }] [color=dev_rgba(0, 0, 0, 0.000000)] [scrollParent=2] [overscroll=auto] [0 scrollupdates] }, metadata1={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [overscroll=auto] [0 scrollupdates] }, ancestorTransform=[ 1 0; 0 1; 0 50; ], visible=[]
WebRenderLayerScrollData(0x7f564c310608), descendantCount=0, metadata0={ [metrics={ [cb=(x=0, y=0, w=622, h=859)] [sr=(x=0, y=0, w=622, h=5000)] [s=(0,0)] [dp=(x=0, y=0, w=622, h=2304)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=622, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 3)] scrollId=4 }] [color=dev_rgba(0, 0, 0, 0.000000)] [scrollParent=3] [overscroll=auto] [1 scrollupdates] }, visible=[]
WebRenderLayerScrollData(0x7f564c310308), descendantCount=0, metadata0={ [metrics={ [cb=(x=0, y=0, w=1268, h=859)] [sr=(x=0, y=0, w=1268, h=1718)] [s=(0,0)] [dp=(x=0, y=0, w=1268, h=1718)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1268, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 2)] scrollId=3 }] [color=dev_rgba(0, 0, 0, 0.000000)] [scrollParent=2] [overscroll=auto] [0 scrollupdates] }, metadata1={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [overscroll=auto] [0 scrollupdates] }, visible=[]
And for non-WebRender, a layer tree:
ClientLayerManager (0x7fca4066e800) --- in content order
ClientContainerLayer (0x7fca3d73a800) [visible=[0,0,1280,859]] [opaqueContent] [presShellResolution=1]
ClientPaintedLayer (0x7fca3d73b800) [clip=(x=0, y=0, w=0, h=0)] [not visible]
ClientColorLayer (0x7fca3d740800) [visible=[0,0,1280,859]] { Hit=[0,0,1280,859] } [opaqueContent] [color=dev_rgba(255, 255, 255, 1.000000)] [bounds=(x=0, y=0, w=1280, h=859)]
ClientContainerLayer (0x7fca3d73b000) [clip=(x=0, y=0, w=1280, h=859)] [visible=[0,0,1280,859]] [asyncZoomContainer scrollId=2] [presShellResolution=1]
ClientPaintedLayer (0x7fca3d73c800) [visible=[0,0,1280,859]] { Hit=[0,0,1280,859] DispatchToContent=[1268,0,1280,859] } [opaqueContent] [metrics0={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [clip=(x=0, y=0, w=1280, h=859)] [overscroll=auto] [0 scrollupdates] }] [valid=[0,0,1280,859]]
ClientContainerLayer (0x7fca3d73c000) [clip=(x=1268, y=0, w=12, h=859)] [visible=[1268,0,1280,415]] [vscrollbar=3] [metrics0={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [clip=(x=0, y=0, w=1280, h=859)] [overscroll=auto] [0 scrollupdates] }] [presShellResolution=1]
ClientPaintedLayer (0x7fca3d73d800) [transform=[ 1 0; 0 1; 1268 0; ]] [effective-transform=[ 1 0; 0 1; 1268 0; ]] [visible=[0,0,12,415]] { Hit=[0,0,12,415] DispatchToContent=[0,0,12,415] } [valid=[0,0,12,415]]
ClientPaintedLayer (0x7fca3d743800) [not visible] { Hit=[0,0,1268,1718] } [opaqueContent] [metrics0={ [metrics={ [cb=(x=0, y=0, w=1268, h=859)] [sr=(x=0, y=0, w=1268, h=1718)] [s=(0,0)] [dp=(x=0, y=0, w=1268, h=1718)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1268, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 2)] scrollId=3 }] [color=dev_rgba(0, 0, 0, 0.000000)] [scrollParent=2] [clip=(x=0, y=0, w=1268, h=859)] [overscroll=auto] [0 scrollupdates] }] [metrics1={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [clip=(x=0, y=0, w=1280, h=859)] [overscroll=auto] [0 scrollupdates] }]
ClientContainerLayer (0x7fca3d73d000) [clip=(x=0, y=0, w=1268, h=1718)] [transform=[ 1 0; 0 1; 0 50; ]] [effective-transform=[ 1 0; 0 1; 0 50; ]] [visible=[0,0,634,859]] [metrics0={ [metrics={ [cb=(x=0, y=0, w=1268, h=859)] [sr=(x=0, y=0, w=1268, h=1718)] [s=(0,0)] [dp=(x=0, y=0, w=1268, h=1718)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1268, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 2)] scrollId=3 }] [color=dev_rgba(0, 0, 0, 0.000000)] [scrollParent=2] [clip=(x=0, y=0, w=1268, h=859)] [overscroll=auto] [0 scrollupdates] }] [metrics1={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [clip=(x=0, y=0, w=1280, h=859)] [overscroll=auto] [0 scrollupdates] }] [presShellResolution=1]
ClientPaintedLayer (0x7fca3d73f800) [effective-transform=[ 1 0; 0 1; 0 50; ]] [visible=[622,0,634,859]] { Hit=[0,0,634,859] DispatchToContent=[622,0,634,859] } [opaqueContent] [valid=[622,0,634,859]]
ClientContainerLayer (0x7fca440cd800) [clip=(x=622, y=0, w=12, h=859)] [effective-transform=[ 1 0; 0 1; 0 50; ]] [visible=[622,0,634,139]] [vscrollbar=4] [presShellResolution=1]
ClientPaintedLayer (0x7fca440d0000) [transform=[ 1 0; 0 1; 622 0; ]] [effective-transform=[ 1 0; 0 1; 622 50; ]] [visible=[0,0,12,139]] { Hit=[0,0,12,139] DispatchToContent=[0,0,12,139] } [valid=[0,0,12,139]]
ClientPaintedLayer (0x7fca440ce800) [effective-transform=[ 1 0; 0 1; 0 50; ]] [visible=[0,0,622,3200]] { Hit=[0,0,622,5000] } [opaqueContent] [metrics0={ [metrics={ [cb=(x=0, y=0, w=622, h=859)] [sr=(x=0, y=0, w=622, h=5000)] [s=(0,0)] [dp=(x=0, y=0, w=622, h=3200)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=622, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 3)] scrollId=4 }] [color=dev_rgba(0, 0, 0, 0.000000)] [scrollParent=3] [clip=(x=0, y=0, w=622, h=859)] [overscroll=auto] [1 scrollupdates] }] [valid=[0,0,622,3200]]
ClientPaintedLayer (0x7fca3d743000) [not visible] { Hit=[0,859,634,1718] } [opaqueContent] [metrics0={ [metrics={ [cb=(x=0, y=0, w=1268, h=859)] [sr=(x=0, y=0, w=1268, h=1718)] [s=(0,0)] [dp=(x=0, y=0, w=1268, h=1718)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1268, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 2)] scrollId=3 }] [color=dev_rgba(0, 0, 0, 0.000000)] [scrollParent=2] [clip=(x=0, y=0, w=1268, h=859)] [overscroll=auto] [0 scrollupdates] }] [metrics1={ [metrics={ [cb=(x=0, y=0, w=1280, h=859)] [sr=(x=0, y=0, w=1280, h=859)] [s=(0,0)] [dp=(x=0, y=0, w=1280, h=859)] [cdp=(x=0, y=0, w=0, h=0)] [rcs=(1280 x 859)] [v=(x=0, y=0, w=1280, h=859)] [z=(ld=1.000 r=1.000 cr=1 z=1 er=1 )] [u=(0 1)] scrollId=2 [rcd] }] [color=dev_rgba(255, 255, 255, 1.000000)] [clip=(x=0, y=0, w=1280, h=859)] [overscroll=auto] [0 scrollupdates] }]
In both cases, the parent (v=3) and grandparent (v=2) of the v=4 hit-testing tree node come from a single node in the above trees. That single node has two metrics (v=2 and v=3), and the (0,50) transform is present on that node (as a property of the node itself, not one of the metrics). However, when the hit-testing tree is created, with WebRender the transform ends up on the v=2 node whereas with non-WR the transform ends up on the v=3 node.
Assignee | ||
Comment 16•3 years ago
•
|
||
It looks like layers have only one transform associated with them, and it gets associated with the bottommost node (here, v=3).
WebRenderLayerScrollData, on the other hand, has both a "transform" and an "ancestor transform"; the former gets associated with the bottommost layer (v=3), while the latter with the topmost layer (v=2), and the (0,50) is in the ancestor transform.
Assignee | ||
Comment 17•3 years ago
•
|
||
I've been reading the WebRender code for creating WebRenderLayerScrollData nodes, and my understanding so far is that the "ancestor transform" is an optimization of sorts. Rather than having every nsDisplayTransform display item create its own WebRenderLayerScrollData node, we try to "defer" some transforms and combine them into other nodes (and possibly also combine them with each other); this is explained in more detail in this comment. When a WebRenderLayerScrollData node is finally emitted, the deferred transforms are stored in the "ancestor transform" field, which gets associated with the topmost metrics during hit-testing tree building.
If I disable this optimization (by commenting out the branches here and here), the bug goes away.
Assignee | ||
Comment 18•3 years ago
|
||
In this case, the transform display item has v=3 as its ASR.
That means we want the transform to end up on a hit-testing tree node with v=3, not on an ancestor of such a node. (Otherwise, the transform will become part of the ancestor transform [here using that term in the APZ sense] of the v=3 node, which may violate APZ's requirement if there are v=3 nodes elsewhere in the tree (which will not have that as part of their ancestor transform).)
Since WebRenderLayerScrollData::mAncestorTransform
is associated with the topmost metrics, that in turn means that if the transform is deferred, it better end up on a WRLSD node whose topmost metrics is v=3.
The metrics that get put on a WRLSD are determined by the aStopAtAsr parameter of WebRenderLayerScrollData::Initialize()
. If we want the topmost metrics to be v=3, we need aStopAtAsr = ancestor(3) = 2.
That's not what happens here. We have aStopAtAsr = nullptr, and the WRLSD ends up with both v=3 and v=2 metrics.
Assignee | ||
Comment 19•3 years ago
•
|
||
Basically, I think the APZ requirement induces a limitation on how aggressively we can collapse WRLSD nodes (i.e. use the "deferred transform" mechanism to stuff more things into a single WRLSD node), which the code to build the WRLSD tree is not respecting.
Assignee | ||
Comment 20•3 years ago
|
||
The codepath that creates the WRLSD item is this one.
item
is a descendant item of the transform, with ASR v=4- the transform item is the current deferred transform item; its ASR is v=3 so we take the enclosing if-branch
- earlier in the branch, we create a WRLSD for the descendant item
- we pass the deferred item's ASR for
aStopAtAsr
, so this WRLSD just gets the v=4 metrics
- we pass the deferred item's ASR for
- then we create the WRLSD for the transform item, with the transform as ancestor transform
- stopAtAsr is nullptr, so this WRLSD gets v=3 and v=2 metrics
I guess, in this case, we need to create a third WRLSD, such that the one for the transform item has the transform's ASR (v=3) as topmost?
A couple of open questions:
- Do we need to handle a similar scenario in the else-branch? (I suspect yes.)
- Should we somehow be handling this earlier instead, at the time we populate the deferred transform?
Assignee | ||
Comment 21•3 years ago
|
||
(In reply to Botond Ballo [:botond] from comment #20)
I guess, in this case, we need to create a third WRLSD, such that the one for the transform item has the transform's ASR (v=3) as topmost?
I realized that this approach is probably not going to work, as creating an additional WRLSD node with v=2 metrics requires as input a display item with v=2 as its ASR, and such a display item may not be available.
So, I'm now thinking of a revised approach:
- Keep the same number of WRLSD nodes as before.
- When setting an ancestor transform on a WRLSD node, annotate it with the transform's ASR (in this case, v=3).
- When generating hit-testing tree nodes based on the WRLSD, instead of placing the transform on the topmost node, place it on the node with the matching scroll id.
Assignee | ||
Comment 22•3 years ago
|
||
I've got a fix based on the approach in comment 21 working locally.
Assignee | ||
Comment 23•3 years ago
|
||
Try push is showing some test failures I need to investigate.
Assignee | ||
Comment 24•3 years ago
|
||
This push is looking better.
Assignee | ||
Comment 25•3 years ago
|
||
Assignee | ||
Comment 26•3 years ago
|
||
Depends on D120564
Assignee | ||
Comment 27•3 years ago
|
||
Depends on D120565
Assignee | ||
Comment 28•3 years ago
|
||
Transforms stored in WebRenderLayerScrollData::mAncestorTransform would
always end up on the topmost hit-testing tree node generated by that
WebRenderLayerScrollData node. That topmost node may not correspond
to the ASR of the transform item(s) which are the source of the
mAncestorTransform. The transform being in the wrong place in the
hit-testing tree can in turn violate APZ's assumptions about different
nodes that scroll together having the same ancestor transform.
To resolve this, this patch stores the transform item's ASR in the
WebRenderLayerScrollData, and applies it to the matching hit-testing
tree node.
Depends on D120566
Assignee | ||
Comment 29•3 years ago
|
||
Maybe<T*> is a redundant representation if there is no semantic
difference between Nothing() and Some(nullptr), and just makes
for cumbersome access syntax.
Reporter | ||
Comment 30•3 years ago
|
||
This bug doesn't seem to be happening in 90.0.2. Did you fix it?
Assignee | ||
Comment 31•3 years ago
|
||
(In reply to iii_iii from comment #30)
This bug doesn't seem to be happening in 90.0.2. Did you fix it?
I can still reproduce the issue in 90.0.2, with WebRender enabled.
Perhaps you have WebRender disabled for some reason? You can check in about:support
, under "Compositing".
Assignee | ||
Comment 32•3 years ago
|
||
(The fix hasn't merged yet and is likely headed for Firefox 92.)
Assignee | ||
Comment 33•3 years ago
|
||
Depends on D120568
Reporter | ||
Comment 34•3 years ago
|
||
This is very odd. The bug came back again earlier today. But now it has gone away again. I haven't changed any settings. Perhaps a website can change the settings?
about:support
Compositing WebRender (Software)
but further down the page:
WEBRENDER
available by default
disabled by env: Not qualified
When the bug comes back I will check this page again.
Reporter | ||
Comment 35•3 years ago
|
||
I see what to do. When in tweetdeck and the bug is present, click on the new tweet button in the panel on the left. This opens a new column and the others shift to the right. Then close the new column clicking the cross, the other columns move to the left again, and now the bug has gone away.
Assignee | ||
Updated•3 years ago
|
Comment 37•3 years ago
|
||
Comment 38•3 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/a822ab0de8d0
https://hg.mozilla.org/mozilla-central/rev/8716a1f06b9a
https://hg.mozilla.org/mozilla-central/rev/1ae004db16d3
https://hg.mozilla.org/mozilla-central/rev/0b9d07ef46cb
https://hg.mozilla.org/mozilla-central/rev/67eef5d179da
https://hg.mozilla.org/mozilla-central/rev/2bffa50c624a
Description
•