Changeset 170783 in webkit


Ignore:
Timestamp:
Jul 3, 2014 5:48:14 PM (10 years ago)
Author:
Simon Fraser
Message:

[iOS WK2] Compositing layers draw outside page bounds
https://bugs.webkit.org/show_bug.cgi?id=134619
<rdar://problem/16953222>

Reviewed by Benjamin Poulain.

With the new rubber-banding behavior, we no longer have the root content layer clipping all
the web layers, but this resulted in web layers which were moved outside the viewport by CSS
transforms not being clipped.

Fix by adding a clipping layer inside the scroll view, above _rootContentView. This layer
normally has the same bounds as the content, but when rubber-banding or pinching,
it takes the union of the content bounds and the rect used for fixed positioning.
To make scrolling work as expected in this scenario, when it has non-zero offset, it
has to compensate by setting its bounds origin.

The bounds of the clipping layer are updated on scrolling/zooming, and when the
layer commit tells us that the content size changed.

  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView _updateScrollViewBackground]):

  • UIProcess/ios/WKContentView.mm:

(-[WKContentView initWithFrame:context:configuration:webView:]):
(-[WKContentView updateFixedClippingView:]):
(-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:]):
(-[WKContentView _didCommitLayerTree:]):

Location:
trunk/Source/WebKit2
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r170782 r170783  
     12014-07-03  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [iOS WK2] Compositing layers draw outside page bounds
     4        https://bugs.webkit.org/show_bug.cgi?id=134619
     5        <rdar://problem/16953222>
     6
     7        Reviewed by Benjamin Poulain.
     8       
     9        With the new rubber-banding behavior, we no longer have the root content layer clipping all
     10        the web layers, but this resulted in web layers which were moved outside the viewport by CSS
     11        transforms not being clipped.
     12       
     13        Fix by adding a clipping layer inside the scroll view, above _rootContentView. This layer
     14        normally has the same bounds as the content, but when rubber-banding or pinching,
     15        it takes the union of the content bounds and the rect used for fixed positioning.
     16        To make scrolling work as expected in this scenario, when it has non-zero offset, it
     17        has to compensate by setting its bounds origin.
     18
     19        The bounds of the clipping layer are updated on scrolling/zooming, and when the
     20        layer commit tells us that the content size changed.
     21
     22        * UIProcess/API/Cocoa/WKWebView.mm:
     23        (-[WKWebView _updateScrollViewBackground]):
     24        * UIProcess/ios/WKContentView.mm:
     25        (-[WKContentView initWithFrame:context:configuration:webView:]):
     26        (-[WKContentView updateFixedClippingView:]):
     27        (-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:]):
     28        (-[WKContentView _didCommitLayerTree:]):
     29
    1302014-07-03  Brady Eidson  <beidson@apple.com>
    231
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm

    r170776 r170783  
    665665    else
    666666        color = _page->pageExtendedBackgroundColor();
     667
    667668    CGFloat zoomScale = contentZoomScale(self);
    668669    CGFloat minimumZoomScale = [_scrollView minimumZoomScale];
  • trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm

    r170774 r170783  
    418418
    419419    RetainPtr<UIView> _rootContentView;
     420    RetainPtr<UIView> _fixedClippingView;
    420421    RetainPtr<WKInspectorIndicationView> _inspectorIndicationView;
    421422    RetainPtr<WKInspectorHighlightView> _inspectorHighlightView;
     
    445446    _rootContentView = adoptNS([[UIView alloc] init]);
    446447    [_rootContentView layer].masksToBounds = NO;
    447 
    448     [self addSubview:_rootContentView.get()];
     448   
     449    _fixedClippingView = adoptNS([[UIView alloc] init]);
     450    [_fixedClippingView layer].masksToBounds = YES;
     451    [_fixedClippingView layer].anchorPoint = CGPointZero;
     452#ifndef NDEBUG
     453    [[_fixedClippingView layer] setName:@"Fixed clipping"];
     454#endif
     455
     456    [self addSubview:_fixedClippingView.get()];
     457    [_fixedClippingView addSubview:_rootContentView.get()];
    449458
    450459    [self setupInteraction];
     
    554563}
    555564
     565- (void)updateFixedClippingView:(FloatRect)fixedPositionRectForUI
     566{
     567    FloatRect clippingBounds = [self bounds];
     568    clippingBounds.unite(fixedPositionRectForUI);
     569
     570    [_fixedClippingView setCenter:clippingBounds.location()]; // Not really the center since we set an anchor point.
     571    [_fixedClippingView setBounds:clippingBounds];
     572}
     573
    556574- (void)didUpdateVisibleRect:(CGRect)visibleRect unobscuredRect:(CGRect)unobscuredRect unobscuredRectInScrollViewCoordinates:(CGRect)unobscuredRectInScrollViewCoordinates
    557575    scale:(CGFloat)zoomScale minimumScale:(CGFloat)minimumScale inStableState:(BOOL)isStableState isChangingObscuredInsetsInteractively:(BOOL)isChangingObscuredInsetsInteractively
     
    571589
    572590    RemoteScrollingCoordinatorProxy* scrollingCoordinator = _page->scrollingCoordinatorProxy();
    573     scrollingCoordinator->viewportChangedViaDelegatedScrolling(scrollingCoordinator->rootScrollingNodeID(), _page->computeCustomFixedPositionRect(_page->unobscuredContentRect(), zoomScale), zoomScale);
     591    FloatRect fixedPositionRect = _page->computeCustomFixedPositionRect(_page->unobscuredContentRect(), zoomScale);
     592    scrollingCoordinator->viewportChangedViaDelegatedScrolling(scrollingCoordinator->rootScrollingNodeID(), fixedPositionRect, zoomScale);
    574593
    575594    if (auto drawingArea = _page->drawingArea())
     
    578597    if (!withinEpsilon(oldDisplayedContentScale, zoomScale))
    579598        [self _updateUnscaledView];
     599       
     600    [self updateFixedClippingView:fixedPositionRect];
    580601}
    581602
     
    668689{
    669690    CGSize contentsSize = layerTreeTransaction.contentsSize();
    670 
    671     [self setBounds:{CGPointZero, contentsSize}];
    672     [_rootContentView setFrame:CGRectMake(0, 0, contentsSize.width, contentsSize.height)];
    673     [_inspectorIndicationView setFrame:[self bounds]];
     691    CGRect contentBounds = { CGPointZero, contentsSize };
     692    CGRect oldBounds = [self bounds];
     693
     694    BOOL boundsChanged = !CGRectEqualToRect(oldBounds, contentBounds);
     695    if (boundsChanged) {
     696        [self setBounds:contentBounds];
     697        [_rootContentView setFrame:contentBounds];
     698        [_inspectorIndicationView setFrame:contentBounds];
     699    }
    674700
    675701    [_webView _didCommitLayerTree:layerTreeTransaction];
     702   
     703    if (boundsChanged) {
     704        FloatRect fixedPositionRect = _page->computeCustomFixedPositionRect(_page->unobscuredContentRect(), [[_webView scrollView] zoomScale]);
     705        [self updateFixedClippingView:fixedPositionRect];
     706    }
     707   
    676708    [self _updateChangedSelection];
    677709}
Note: See TracChangeset for help on using the changeset viewer.