Changeset 200602 in webkit


Ignore:
Timestamp:
May 9, 2016 5:20:27 PM (8 years ago)
Author:
Simon Fraser
Message:

[iOS] visibility:hidden -webkit-overflow-scrolling: touch divs can interfere with page scrolling
https://bugs.webkit.org/show_bug.cgi?id=157496
Source/WebCore:

Reviewed by Tim Horton.

UIScrollViews are constructed in the UI process for visibility:hidden scrollable elements
with -webkit-overflow-scrolling: touch, and these intercept user events when they should not.

Fix by propagating a "contentsHidden" flag from the web process which is used to turn off
user interaction on these views.

Test: fast/scrolling/ios/touch-scroll-visibility-hidden.html

  • platform/graphics/ca/GraphicsLayerCA.cpp:

(WebCore::GraphicsLayerCA::updateContentsVisibility): We have to tell the scrolling layer
if we have visibility:hidden.

  • platform/graphics/ca/PlatformCALayer.h:
  • platform/graphics/ca/cocoa/PlatformCALayerCocoa.h:
  • platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:

(PlatformCALayerCocoa::contentsHidden):
(PlatformCALayerCocoa::setContentsHidden):

  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::updateAfterDescendants):

Source/WebKit2:

rdar://problem/22963278

Reviewed by Tim Horton.

UIScrollViews are constructed in the UI process for visibility:hidden scrollable elements
with -webkit-overflow-scrolling: touch, and these intercept user events when they should not.

Fix by propagating a "contentsHidden" flag from the web process which is used to turn off
user interaction on these views.

  • Shared/mac/RemoteLayerTreePropertyApplier.mm:

(WebKit::RemoteLayerTreePropertyApplier::applyProperties):

  • Shared/mac/RemoteLayerTreeTransaction.h:
  • Shared/mac/RemoteLayerTreeTransaction.mm:

(WebKit::RemoteLayerTreeTransaction::LayerProperties::LayerProperties):
(WebKit::RemoteLayerTreeTransaction::LayerProperties::encode):
(WebKit::RemoteLayerTreeTransaction::LayerProperties::decode):
(WebKit::dumpChangedLayers):

  • UIProcess/ios/RemoteLayerTreeHostIOS.mm:

(-[UIView _recursiveFindDescendantScrollViewAtPoint:withEvent:]): Our custom hit
test needs to take view.isUserInteractionEnabled into account.

  • WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:

(WebKit::PlatformCALayerRemote::setHidden):
(WebKit::PlatformCALayerRemote::contentsHidden):
(WebKit::PlatformCALayerRemote::setContentsHidden):

  • WebProcess/WebPage/mac/PlatformCALayerRemote.h:

Tools:

rdar://problem/22963278

Reviewed by Tim Horton.

Enhance UIScriptController to generate a drag, which is useful for scrolling.

  • WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl:
  • WebKitTestRunner/UIScriptContext/UIScriptController.cpp:

(WTR::UIScriptController::dragFromPointToPoint):

  • WebKitTestRunner/UIScriptContext/UIScriptController.h:
  • WebKitTestRunner/ios/HIDEventGenerator.h:
  • WebKitTestRunner/ios/HIDEventGenerator.mm:

(-[HIDEventGenerator dragWithStartPoint:endPoint:duration:completionBlock:]):

  • WebKitTestRunner/ios/UIScriptControllerIOS.mm:

(WTR::UIScriptController::dragFromPointToPoint):

LayoutTests:

rdar://problem/22963278

Reviewed by Tim Horton.

Add a fast/scrolling/ios directory, disable it everywhere except on iOS.

  • TestExpectations:
  • fast/scrolling/ios/touch-scroll-visibility-hidden-expected.txt: Added.
  • fast/scrolling/ios/touch-scroll-visibility-hidden.html: Added.
  • platform/ios-simulator-wk2/TestExpectations:
Location:
trunk
Files:
3 added
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r200601 r200602  
     12016-05-09  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [iOS] visibility:hidden -webkit-overflow-scrolling: touch divs can interfere with page scrolling
     4        https://bugs.webkit.org/show_bug.cgi?id=157496
     5        rdar://problem/22963278
     6
     7        Reviewed by Tim Horton.
     8       
     9        Add a fast/scrolling/ios directory, disable it everywhere except on iOS.
     10
     11        * TestExpectations:
     12        * fast/scrolling/ios/touch-scroll-visibility-hidden-expected.txt: Added.
     13        * fast/scrolling/ios/touch-scroll-visibility-hidden.html: Added.
     14        * platform/ios-simulator-wk2/TestExpectations:
     15
    1162016-05-09  Myles C. Maxfield  <mmaxfield@apple.com>
    217
  • trunk/LayoutTests/TestExpectations

    r200571 r200602  
    2121fast/events/ios [ Skip ]
    2222fast/events/touch/ios [ Skip ]
     23fast/scrolling/ios [ Skip ]
    2324
    2425fast/forms/attributed-strings.html [ Skip ]
  • trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations

    r200534 r200602  
    1010fast/harness/concurrent-ui-side-scripts.html [ Pass ]
    1111fast/zooming/ios [ Pass ]
     12fast/scrolling/ios [ Pass ]
    1213
    1314#//////////////////////////////////////////////////////////////////////////////////////////
  • trunk/Source/WebCore/ChangeLog

    r200601 r200602  
     12016-05-09  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [iOS] visibility:hidden -webkit-overflow-scrolling: touch divs can interfere with page scrolling
     4        https://bugs.webkit.org/show_bug.cgi?id=157496
     5
     6        Reviewed by Tim Horton.
     7
     8        UIScrollViews are constructed in the UI process for visibility:hidden scrollable elements
     9        with -webkit-overflow-scrolling: touch, and these intercept user events when they should not.
     10
     11        Fix by propagating a "contentsHidden" flag from the web process which is used to turn off
     12        user interaction on these views.
     13
     14        Test: fast/scrolling/ios/touch-scroll-visibility-hidden.html
     15
     16        * platform/graphics/ca/GraphicsLayerCA.cpp:
     17        (WebCore::GraphicsLayerCA::updateContentsVisibility): We have to tell the scrolling layer
     18        if we have visibility:hidden.
     19        * platform/graphics/ca/PlatformCALayer.h:
     20        * platform/graphics/ca/cocoa/PlatformCALayerCocoa.h:
     21        * platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:
     22        (PlatformCALayerCocoa::contentsHidden):
     23        (PlatformCALayerCocoa::setContentsHidden):
     24        * rendering/RenderLayerBacking.cpp:
     25        (WebCore::RenderLayerBacking::updateAfterDescendants):
     26
    1272016-05-09  Myles C. Maxfield  <mmaxfield@apple.com>
    228
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r199862 r200602  
    18781878            m_backdropLayer->setHidden(true);
    18791879    }
     1880
     1881    m_layer->setContentsHidden(!m_contentsVisible);
    18801882}
    18811883
  • trunk/Source/WebCore/platform/graphics/ca/PlatformCALayer.h

    r199862 r200602  
    159159    virtual void setHidden(bool) = 0;
    160160
     161    virtual bool contentsHidden() const = 0;
     162    virtual void setContentsHidden(bool) = 0;
     163
    161164    virtual bool geometryFlipped() const = 0;
    162165    virtual void setGeometryFlipped(bool) = 0;
  • trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.h

    r199862 r200602  
    9090    bool isHidden() const override;
    9191    void setHidden(bool) override;
     92
     93    bool contentsHidden() const override;
     94    void setContentsHidden(bool) override;
    9295
    9396    void setBackingStoreAttached(bool) override;
  • trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm

    r199862 r200602  
    617617}
    618618
     619bool PlatformCALayerCocoa::contentsHidden() const
     620{
     621    // Used to disable user interaction for some platforms.
     622    return true;
     623}
     624
     625void PlatformCALayerCocoa::setContentsHidden(bool)
     626{
     627    // Used to disable user interaction for some platforms.
     628}
     629
    619630void PlatformCALayerCocoa::setBackingStoreAttached(bool)
    620631{
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r199111 r200602  
    10671067
    10681068    m_graphicsLayer->setContentsVisible(m_owningLayer.hasVisibleContent() || isPaintDestinationForDescendantLayers());
     1069    if (m_scrollingLayer)
     1070        m_scrollingLayer->setContentsVisible(renderer().style().visibility() == VISIBLE);
    10691071}
    10701072
  • trunk/Source/WebKit2/ChangeLog

    r200595 r200602  
     12016-05-09  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [iOS] visibility:hidden -webkit-overflow-scrolling: touch divs can interfere with page scrolling
     4        https://bugs.webkit.org/show_bug.cgi?id=157496
     5        rdar://problem/22963278
     6
     7        Reviewed by Tim Horton.
     8
     9        UIScrollViews are constructed in the UI process for visibility:hidden scrollable elements
     10        with -webkit-overflow-scrolling: touch, and these intercept user events when they should not.
     11
     12        Fix by propagating a "contentsHidden" flag from the web process which is used to turn off
     13        user interaction on these views.
     14
     15        * Shared/mac/RemoteLayerTreePropertyApplier.mm:
     16        (WebKit::RemoteLayerTreePropertyApplier::applyProperties):
     17        * Shared/mac/RemoteLayerTreeTransaction.h:
     18        * Shared/mac/RemoteLayerTreeTransaction.mm:
     19        (WebKit::RemoteLayerTreeTransaction::LayerProperties::LayerProperties):
     20        (WebKit::RemoteLayerTreeTransaction::LayerProperties::encode):
     21        (WebKit::RemoteLayerTreeTransaction::LayerProperties::decode):
     22        (WebKit::dumpChangedLayers):
     23        * UIProcess/ios/RemoteLayerTreeHostIOS.mm:
     24        (-[UIView _recursiveFindDescendantScrollViewAtPoint:withEvent:]): Our custom hit
     25        test needs to take view.isUserInteractionEnabled into account.
     26        * WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
     27        (WebKit::PlatformCALayerRemote::setHidden):
     28        (WebKit::PlatformCALayerRemote::contentsHidden):
     29        (WebKit::PlatformCALayerRemote::setContentsHidden):
     30        * WebProcess/WebPage/mac/PlatformCALayerRemote.h:
     31
    1322016-05-09  Ada Chan  <adachan@apple.com>
    233
  • trunk/Source/WebKit2/Shared/mac/RemoteLayerTreePropertyApplier.mm

    r199212 r200602  
    313313
    314314    if (properties.changedProperties & RemoteLayerTreeTransaction::MaskLayerChanged) {
    315 
    316315        CALayer *maskOwnerLayer = view.layer;
    317316
     
    333332        }
    334333    }
     334   
     335    if (properties.changedProperties & RemoteLayerTreeTransaction::ContentsHiddenChanged)
     336        view.userInteractionEnabled = !properties.contentsHidden;
     337
    335338    END_BLOCK_OBJC_EXCEPTIONS;
    336339}
  • trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.h

    r198189 r200602  
    7070        MasksToBoundsChanged            = 1LLU << 15,
    7171        OpaqueChanged                   = 1LLU << 16,
    72         MaskLayerChanged                = 1LLU << 17,
    73         ClonedContentsChanged           = 1LLU << 18,
    74         ContentsRectChanged             = 1LLU << 19,
    75         ContentsScaleChanged            = 1LLU << 20,
    76         CornerRadiusChanged             = 1LLU << 21,
    77         ShapeRoundedRectChanged         = 1LLU << 22,
    78         ShapePathChanged                = 1LLU << 23,
    79         MinificationFilterChanged       = 1LLU << 24,
    80         MagnificationFilterChanged      = 1LLU << 25,
    81         BlendModeChanged                = 1LLU << 26,
    82         WindRuleChanged                 = 1LLU << 27,
    83         SpeedChanged                    = 1LLU << 28,
    84         TimeOffsetChanged               = 1LLU << 29,
    85         BackingStoreChanged             = 1LLU << 30,
    86         BackingStoreAttachmentChanged   = 1LLU << 31,
    87         FiltersChanged                  = 1LLU << 32,
    88         AnimationsChanged               = 1LLU << 33,
    89         EdgeAntialiasingMaskChanged     = 1LLU << 34,
    90         CustomAppearanceChanged         = 1LLU << 35,
     72        ContentsHiddenChanged           = 1LLU << 17,
     73        MaskLayerChanged                = 1LLU << 18,
     74        ClonedContentsChanged           = 1LLU << 19,
     75        ContentsRectChanged             = 1LLU << 20,
     76        ContentsScaleChanged            = 1LLU << 21,
     77        CornerRadiusChanged             = 1LLU << 22,
     78        ShapeRoundedRectChanged         = 1LLU << 23,
     79        ShapePathChanged                = 1LLU << 24,
     80        MinificationFilterChanged       = 1LLU << 25,
     81        MagnificationFilterChanged      = 1LLU << 26,
     82        BlendModeChanged                = 1LLU << 27,
     83        WindRuleChanged                 = 1LLU << 28,
     84        SpeedChanged                    = 1LLU << 29,
     85        TimeOffsetChanged               = 1LLU << 30,
     86        BackingStoreChanged             = 1LLU << 31,
     87        BackingStoreAttachmentChanged   = 1LLU << 32,
     88        FiltersChanged                  = 1LLU << 33,
     89        AnimationsChanged               = 1LLU << 34,
     90        EdgeAntialiasingMaskChanged     = 1LLU << 35,
     91        CustomAppearanceChanged         = 1LLU << 36,
    9192    };
    9293    typedef uint64_t LayerChange;
     
    165166        bool masksToBounds;
    166167        bool opaque;
     168        bool contentsHidden;
    167169    };
    168170
  • trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm

    r198189 r200602  
    104104    , masksToBounds(false)
    105105    , opaque(false)
     106    , contentsHidden(false)
    106107{
    107108}
     
    141142    , masksToBounds(other.masksToBounds)
    142143    , opaque(other.opaque)
     144    , contentsHidden(other.contentsHidden)
    143145{
    144146    // FIXME: LayerProperties should reference backing store by ID, so that two layers can have the same backing store (for clones).
     
    211213    if (changedProperties & OpaqueChanged)
    212214        encoder << opaque;
     215
     216    if (changedProperties & ContentsHiddenChanged)
     217        encoder << contentsHidden;
    213218
    214219    if (changedProperties & MaskLayerChanged)
     
    372377    if (result.changedProperties & OpaqueChanged) {
    373378        if (!decoder.decode(result.opaque))
     379            return false;
     380    }
     381
     382    if (result.changedProperties & ContentsHiddenChanged) {
     383        if (!decoder.decode(result.contentsHidden))
    374384            return false;
    375385    }
     
    742752        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::OpaqueChanged)
    743753            ts.dumpProperty("opaque", layerProperties.opaque);
     754
     755        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::ContentsHiddenChanged)
     756            ts.dumpProperty("contentsHidden", layerProperties.contentsHidden);
    744757
    745758        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::MaskLayerChanged)
  • trunk/Source/WebKit2/UIProcess/ios/RemoteLayerTreeHostIOS.mm

    r180965 r200602  
    6161        CGPoint subviewPoint = [view convertPoint:point fromView:self];
    6262
    63         if ([view pointInside:subviewPoint withEvent:event] && [view isKindOfClass:[UIScrollView class]])
     63        if ([view pointInside:subviewPoint withEvent:event] && [view isKindOfClass:[UIScrollView class]] && view.isUserInteractionEnabled)
    6464            foundView = view;
    6565
  • trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp

    r199862 r200602  
    504504void PlatformCALayerRemote::setHidden(bool value)
    505505{
     506    if (m_properties.hidden == value)
     507        return;
     508
    506509    m_properties.hidden = value;
    507510    m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::HiddenChanged);
     511}
     512
     513bool PlatformCALayerRemote::contentsHidden() const
     514{
     515    return m_properties.contentsHidden;
     516}
     517
     518void PlatformCALayerRemote::setContentsHidden(bool value)
     519{
     520    if (m_properties.contentsHidden == value)
     521        return;
     522
     523    m_properties.contentsHidden = value;
     524    m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::ContentsHiddenChanged);
    508525}
    509526
  • trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h

    r199862 r200602  
    9595    void setHidden(bool) override;
    9696
     97    bool contentsHidden() const override;
     98    void setContentsHidden(bool) override;
     99
    97100    void setBackingStoreAttached(bool) override;
    98101    bool backingStoreAttached() const override;
  • trunk/Tools/ChangeLog

    r200590 r200602  
     12016-05-09  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [iOS] visibility:hidden -webkit-overflow-scrolling: touch divs can interfere with page scrolling
     4        https://bugs.webkit.org/show_bug.cgi?id=157496
     5        rdar://problem/22963278
     6
     7        Reviewed by Tim Horton.
     8
     9        Enhance UIScriptController to generate a drag, which is useful for scrolling.
     10
     11        * WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl:
     12        * WebKitTestRunner/UIScriptContext/UIScriptController.cpp:
     13        (WTR::UIScriptController::dragFromPointToPoint):
     14        * WebKitTestRunner/UIScriptContext/UIScriptController.h:
     15        * WebKitTestRunner/ios/HIDEventGenerator.h:
     16        * WebKitTestRunner/ios/HIDEventGenerator.mm:
     17        (-[HIDEventGenerator dragWithStartPoint:endPoint:duration:completionBlock:]):
     18        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
     19        (WTR::UIScriptController::dragFromPointToPoint):
     20
    1212016-05-09  Simon Fraser  <simon.fraser@apple.com>
    222
  • trunk/Tools/WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl

    r195899 r200602  
    3737    void singleTapAtPoint(long x, long y, object callback);
    3838    void doubleTapAtPoint(long x, long y, object callback);
     39    void dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, object callback);
    3940
    4041    void typeCharacterUsingHardwareKeyboard(DOMString character, object callback);
  • trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.cpp

    r195899 r200602  
    135135}
    136136
     137void UIScriptController::dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback)
     138{
     139}
     140
    137141void UIScriptController::typeCharacterUsingHardwareKeyboard(JSStringRef, JSValueRef)
    138142{
  • trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.h

    r197566 r200602  
    5252    void singleTapAtPoint(long x, long y, JSValueRef callback);
    5353    void doubleTapAtPoint(long x, long y, JSValueRef callback);
     54    void dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback);
    5455   
    5556    void typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback);
  • trunk/Tools/WebKitTestRunner/ios/HIDEventGenerator.h

    r195899 r200602  
    3333
    3434// Touches
    35 - (void)touchDown:(CGPoint)location;
    36 - (void)liftUp:(CGPoint)location;
    37 - (void)moveToPoints:(CGPoint*)locations touchCount:(NSUInteger)count duration:(NSTimeInterval)seconds;
    3835- (void)touchDown:(CGPoint)location touchCount:(NSUInteger)count completionBlock:(void (^)(void))completionBlock;
    3936- (void)liftUp:(CGPoint)location touchCount:(NSUInteger)count completionBlock:(void (^)(void))completionBlock;
  • trunk/Tools/WebKitTestRunner/ios/HIDEventGenerator.mm

    r195899 r200602  
    416416- (void)dragWithStartPoint:(CGPoint)startLocation endPoint:(CGPoint)endLocation duration:(double)seconds completionBlock:(void (^)(void))completionBlock
    417417{
     418    [self touchDown:startLocation touchCount:1];
     419    [self moveToPoints:&endLocation touchCount:1 duration:seconds];
     420    [self liftUp:endLocation];
     421    [self _sendMarkerHIDEventWithCompletionBlock:completionBlock];
    418422}
    419423
  • trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

    r195899 r200602  
    126126}
    127127
     128void UIScriptController::dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback)
     129{
     130    unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
     131
     132    CGPoint startPoint = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), startX, startY);
     133    CGPoint endPoint = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), endX, endY);
     134   
     135    [[HIDEventGenerator sharedHIDEventGenerator] dragWithStartPoint:startPoint endPoint:endPoint duration:durationSeconds completionBlock:^{
     136        if (!m_context)
     137            return;
     138        m_context->asyncTaskComplete(callbackID);
     139    }];
     140}
     141
    128142void UIScriptController::typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback)
    129143{
Note: See TracChangeset for help on using the changeset viewer.