Bug 101425 - Correct absolute rect calculation for scaled fixed position elements
Summary: Correct absolute rect calculation for scaled fixed position elements
Status: RESOLVED WORKSFORME
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-11-06 20:49 PST by Tien-Ren Chen
Modified: 2013-01-30 14:56 PST (History)
6 users (show)

See Also:


Attachments
Patch (6.83 KB, patch)
2012-11-06 20:56 PST, Tien-Ren Chen
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tien-Ren Chen 2012-11-06 20:49:41 PST
Correct absolute rect calculation for scaled fixed position elements
Comment 1 Tien-Ren Chen 2012-11-06 20:56:06 PST
Created attachment 172709 [details]
Patch
Comment 2 Simon Fraser (smfr) 2012-11-07 16:30:07 PST
Comment on attachment 172709 [details]
Patch

Is this the same as bug 100912?
Comment 3 Tien-Ren Chen 2012-11-07 17:01:02 PST
(In reply to comment #2)
> (From update of attachment 172709 [details])
> Is this the same as bug 100912?

Nope. This patch fixes a bug with absoluteRect on scaled fixed position elements. We had this fix in downstream for a while but only drew my attention until 100912.

My understanding is that we use RenderView::scrollOffsetForFixedPosition() to adjust the in-document position of them. When pageScaleFactor == 1.0 scrollOffsetForFixedPosition() equals to scrollPosition() most of the time (except clamped to the scroll range, for the over scroll effect on iOS).

When pageScaleFactor != 1.0, scrollOffsetForFixedPosition() is measured in CSS pixels, while scrollPosition() is in physical pixels. It is understandable that scrollPosition() needs to be in physical pixel for pixel-smooth scrolling. However when we layout the fixed position elements it needs to be snapped to integral CSS pixels, probably because the layout engine couldn't handle fractional offsets until we changed to FractionalLayoutUnit recently.

The bug is that the position adjustment is applied too late. Logically it should be that the fixed position is located at (topLeft + scrollOffsetForFixedPosition) in the RenderView, then we magnify the RenderView, so: absoluteCoords = (topLeft + scrollOffsetForFixedPosition) * transform
In the original code it was: absoluteCoords = topLeft * transform + scrollOffsetForFixedPosition

It is debatable whether we should switch to physical pixel scrollOffsetForFixedPosition, so we can avoid the juddering effect due to pixel rounding. For a short term solution, I think it is safer to keep the old approach but make it correct.

A layout test is included to demonstrate the buggy absoluteRect. Without the patch, getBoundingClientRect() returns bogus value on fixed position element when page is scaled+scrolled.
Comment 4 Tien-Ren Chen 2013-01-30 14:56:13 PST
As we moved to the applyPageScaleFactorInTheCompositor()==true mode, this patch doesn't matter anymore.

If anyone is still using frameScaleFactor (CSS transformation-based scaling), feel free to re-open the bug.