Changeset 202408 in webkit


Ignore:
Timestamp:
Jun 23, 2016 7:38:00 PM (8 years ago)
Author:
benjamin@webkit.org
Message:

Specialize synchronous event tracking per event type
https://bugs.webkit.org/show_bug.cgi?id=158826

Reviewed by Simon Fraser.

Source/WebCore:

First, kudos to Rick Byers for all his helps on passive event dispatch.
The specs are pretty damn good and his help reviewing patches is very useful.

This patch change synchronous event dispatch to happen per event
instead of per sequence touchstart->touchend.

The big advantage of this is we can dispatch more events asynchronously.
For example, to handle a tap programmatically, you can limit the active listener
to the touchend event. The touchstart and touchmove are now dispatched asynchronously.

The implementation is a simple extension to EventTrackingRegions.
Instead of a single synchronous region, we have one region per event type.
When processing the events, we only need to send the events synchronously
if that particular event type has a synchronous region.

Note that EventDispatcher's touch event support already supports
mixing synchronous and asynchronous events. The events are always processed
in order even if asynchronous events are pending when a synchronous dispatch
happens.

Tests: fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener.html

fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener.html
fast/events/touch/ios/tap-with-active-touch-end-listener.html
fast/events/touch/ios/tap-with-passive-listener-inside-active-listener.html
fast/events/touch/ios/tap-with-passive-touch-end-listener.html
fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements.html
fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements.html

  • CMakeLists.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • dom/EventTarget.cpp:

(WebCore::EventTarget::hasActiveTouchEventListeners): Deleted.

  • dom/EventTarget.h:
  • page/DebugPageOverlays.cpp:

(WebCore::NonFastScrollableRegionOverlay::updateRegion):

  • page/Page.cpp:

(WebCore::Page::nonFastScrollableRects):

  • page/scrolling/ScrollingCoordinator.cpp:

(WebCore::ScrollingCoordinator::absoluteEventTrackingRegionsForFrame):

  • page/scrolling/ScrollingStateFrameScrollingNode.cpp:

(WebCore::ScrollingStateFrameScrollingNode::dumpProperties):

  • page/scrolling/ScrollingTree.cpp:

(WebCore::ScrollingTree::shouldHandleWheelEventSynchronously):
(WebCore::ScrollingTree::eventTrackingTypeForPoint):

  • page/scrolling/ScrollingTree.h:
  • platform/EventTrackingRegions.cpp: Added.

(WebCore::EventTrackingRegions::trackingTypeForPoint):
(WebCore::EventTrackingRegions::isEmpty):
(WebCore::EventTrackingRegions::translate):
(WebCore::EventTrackingRegions::uniteSynchronousRegion):
(WebCore::EventTrackingRegions::unite):
(WebCore::operator==):

  • platform/EventTrackingRegions.h:

(WebCore::EventTrackingRegions::isEmpty): Deleted.
(WebCore::EventTrackingRegions::trackingTypeForPoint): Deleted.
(WebCore::operator==): Deleted.

Source/WebKit2:

  • Shared/WebCoreArgumentCoders.cpp:

(IPC::ArgumentCoder<EventTrackingRegions>::encode):
(IPC::ArgumentCoder<EventTrackingRegions>::decode):

  • UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:

(WebKit::RemoteScrollingCoordinatorProxy::eventTrackingTypeForPoint):

  • UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
  • UIProcess/WebPageProxy.cpp:

(WebKit::mergeTrackingTypes):
(WebKit::WebPageProxy::updateTouchEventTracking):
(WebKit::WebPageProxy::touchEventTrackingType):
(WebKit::WebPageProxy::handleTouchEventSynchronously):
(WebKit::WebPageProxy::handleTouchEventAsynchronously):
(WebKit::WebPageProxy::handleTouchEvent):
(WebKit::WebPageProxy::resetState):

  • UIProcess/WebPageProxy.h:

(WebKit::WebPageProxy::TouchEventTracking::isTrackingAnything):
(WebKit::WebPageProxy::TouchEventTracking::reset):

LayoutTests:

  • fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener-expected.txt: Added.
  • fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener.html: Added.
  • fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener-expected.txt: Added.
  • fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener.html: Added.
  • fast/events/touch/ios/tap-with-active-touch-end-listener-expected.txt: Added.
  • fast/events/touch/ios/tap-with-active-touch-end-listener.html: Added.
  • fast/events/touch/ios/tap-with-passive-listener-inside-active-listener.html: Added.
  • fast/events/touch/ios/tap-with-passive-touch-end-listener-expected.txt: Added.
  • fast/events/touch/ios/tap-with-passive-touch-end-listener.html: Added.
  • fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements-expected.txt: Added.
  • fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements.html: Added.
  • fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements-expected.txt: Added.
  • fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements.html: Added.
Location:
trunk
Files:
14 added
29 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r202406 r202408  
     12016-06-23  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        Specialize synchronous event tracking per event type
     4        https://bugs.webkit.org/show_bug.cgi?id=158826
     5
     6        Reviewed by Simon Fraser.
     7
     8        * fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener-expected.txt: Added.
     9        * fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener.html: Added.
     10        * fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener-expected.txt: Added.
     11        * fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener.html: Added.
     12        * fast/events/touch/ios/tap-with-active-touch-end-listener-expected.txt: Added.
     13        * fast/events/touch/ios/tap-with-active-touch-end-listener.html: Added.
     14        * fast/events/touch/ios/tap-with-passive-listener-inside-active-listener.html: Added.
     15        * fast/events/touch/ios/tap-with-passive-touch-end-listener-expected.txt: Added.
     16        * fast/events/touch/ios/tap-with-passive-touch-end-listener.html: Added.
     17        * fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements-expected.txt: Added.
     18        * fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements.html: Added.
     19        * fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements-expected.txt: Added.
     20        * fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements.html: Added.
     21
    1222016-06-23  Alexey Proskuryakov  <ap@apple.com>
    223
  • trunk/LayoutTests/tiled-drawing/scrolling/fixed/fixed-in-overflow-expected.txt

    r201958 r202408  
    33  (contents size 785 2213)
    44  (requested scroll position 0 200)
    5   (synchronous event dispatch region
     5  (synchronous event dispatch region for event wheel
    66    at (0,13) size 204x204)
    77  (children 1
  • trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-expected.txt

    r201958 r202408  
    22  (scrollable area size 785 600)
    33  (contents size 785 1016)
    4   (synchronous event dispatch region
     4  (synchronous event dispatch region for event wheel
    55    at (45,47) size 404x304)
    66  (children 1
  • trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-gain-scrolling-ancestor-expected.txt

    r201958 r202408  
    22  (scrollable area size 785 600)
    33  (contents size 785 1016)
    4   (synchronous event dispatch region
     4  (synchronous event dispatch region for event wheel
    55    at (45,47) size 404x304)
    66  (children 1
  • trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-in-fixed-expected.txt

    r201958 r202408  
    22  (scrollable area size 785 600)
    33  (contents size 785 1016)
    4   (synchronous event dispatch region
     4  (synchronous event dispatch region for event wheel
    55    at (45,37) size 404x304)
    66  (children 1
  • trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-lose-scrolling-ancestor-expected.txt

    r201958 r202408  
    22  (scrollable area size 785 600)
    33  (contents size 785 1016)
    4   (synchronous event dispatch region
     4  (synchronous event dispatch region for event wheel
    55    at (45,47) size 404x304)
    66  (children 1
  • trunk/LayoutTests/tiled-drawing/scrolling/frames/frameset-frame-scrollability-expected.txt

    r201958 r202408  
    22  (scrollable area size 800 600)
    33  (contents size 800 600)
    4   (synchronous event dispatch region
     4  (synchronous event dispatch region for event wheel
    55    at (0,0) size 800x594)
    66)
  • trunk/LayoutTests/tiled-drawing/scrolling/frames/frameset-nested-frame-scrollability-expected.txt

    r201958 r202408  
    22  (scrollable area size 800 600)
    33  (contents size 800 600)
    4   (synchronous event dispatch region
     4  (synchronous event dispatch region for event wheel
    55    at (0,166) size 280x434)
    66)
  • trunk/LayoutTests/tiled-drawing/scrolling/frames/scroll-region-after-frame-layout-expected.txt

    r201958 r202408  
    33  (scrollable area size 785 600)
    44  (contents size 785 757)
    5   (synchronous event dispatch region
     5  (synchronous event dispatch region for event wheel
    66    at (68,68) size 300x300)
    77)
  • trunk/Source/WebCore/CMakeLists.txt

    r202383 r202408  
    21152115    platform/DragData.cpp
    21162116    platform/DragImage.cpp
     2117    platform/EventTrackingRegions.cpp
    21172118    platform/FileChooser.cpp
    21182119    platform/FileStream.cpp
  • trunk/Source/WebCore/ChangeLog

    r202407 r202408  
     12016-06-23  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        Specialize synchronous event tracking per event type
     4        https://bugs.webkit.org/show_bug.cgi?id=158826
     5
     6        Reviewed by Simon Fraser.
     7
     8        First, kudos to Rick Byers for all his helps on passive event dispatch.
     9        The specs are pretty damn good and his help reviewing patches is very useful.
     10
     11        This patch change synchronous event dispatch to happen per event
     12        instead of per sequence touchstart->touchend.
     13
     14        The big advantage of this is we can dispatch more events asynchronously.
     15        For example, to handle a tap programmatically, you can limit the active listener
     16        to the touchend event. The touchstart and touchmove are now dispatched asynchronously.
     17
     18        The implementation is a simple extension to EventTrackingRegions.
     19        Instead of a single synchronous region, we have one region per event type.
     20        When processing the events, we only need to send the events synchronously
     21        if that particular event type has a synchronous region.
     22
     23        Note that EventDispatcher's touch event support already supports
     24        mixing synchronous and asynchronous events. The events are always processed
     25        in order even if asynchronous events are pending when a synchronous dispatch
     26        happens.
     27
     28        Tests: fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener.html
     29               fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener.html
     30               fast/events/touch/ios/tap-with-active-touch-end-listener.html
     31               fast/events/touch/ios/tap-with-passive-listener-inside-active-listener.html
     32               fast/events/touch/ios/tap-with-passive-touch-end-listener.html
     33               fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements.html
     34               fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements.html
     35
     36        * CMakeLists.txt:
     37        * WebCore.xcodeproj/project.pbxproj:
     38        * dom/EventTarget.cpp:
     39        (WebCore::EventTarget::hasActiveTouchEventListeners): Deleted.
     40        * dom/EventTarget.h:
     41        * page/DebugPageOverlays.cpp:
     42        (WebCore::NonFastScrollableRegionOverlay::updateRegion):
     43        * page/Page.cpp:
     44        (WebCore::Page::nonFastScrollableRects):
     45        * page/scrolling/ScrollingCoordinator.cpp:
     46        (WebCore::ScrollingCoordinator::absoluteEventTrackingRegionsForFrame):
     47        * page/scrolling/ScrollingStateFrameScrollingNode.cpp:
     48        (WebCore::ScrollingStateFrameScrollingNode::dumpProperties):
     49        * page/scrolling/ScrollingTree.cpp:
     50        (WebCore::ScrollingTree::shouldHandleWheelEventSynchronously):
     51        (WebCore::ScrollingTree::eventTrackingTypeForPoint):
     52        * page/scrolling/ScrollingTree.h:
     53        * platform/EventTrackingRegions.cpp: Added.
     54        (WebCore::EventTrackingRegions::trackingTypeForPoint):
     55        (WebCore::EventTrackingRegions::isEmpty):
     56        (WebCore::EventTrackingRegions::translate):
     57        (WebCore::EventTrackingRegions::uniteSynchronousRegion):
     58        (WebCore::EventTrackingRegions::unite):
     59        (WebCore::operator==):
     60        * platform/EventTrackingRegions.h:
     61        (WebCore::EventTrackingRegions::isEmpty): Deleted.
     62        (WebCore::EventTrackingRegions::trackingTypeForPoint): Deleted.
     63        (WebCore::operator==): Deleted.
     64
    1652016-06-23  Simon Fraser  <simon.fraser@apple.com>
    266
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r202383 r202408  
    10761076                26255F0418878E110006E1FD /* UserAgentMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26255F0218878E110006E1FD /* UserAgentMac.mm */; };
    10771077                262EC41A1D078FB900BA78FC /* EventTrackingRegions.h in Headers */ = {isa = PBXBuildFile; fileRef = 262EC4191D078F3D00BA78FC /* EventTrackingRegions.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1078                262EC41D1D110B9000BA78FC /* EventTrackingRegions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 262EC41C1D110B1F00BA78FC /* EventTrackingRegions.cpp */; };
    10781079                265541391489811C000DFC5D /* KeyEventCodesIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 265541371489811C000DFC5D /* KeyEventCodesIOS.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10791080                2655413A1489811C000DFC5D /* KeyEventIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 265541381489811C000DFC5D /* KeyEventIOS.mm */; };
     
    86118612                26255F0218878E110006E1FD /* UserAgentMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UserAgentMac.mm; sourceTree = "<group>"; };
    86128613                262EC4191D078F3D00BA78FC /* EventTrackingRegions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventTrackingRegions.h; sourceTree = "<group>"; };
     8614                262EC41C1D110B1F00BA78FC /* EventTrackingRegions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventTrackingRegions.cpp; sourceTree = "<group>"; };
    86138615                265541371489811C000DFC5D /* KeyEventCodesIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyEventCodesIOS.h; sourceTree = "<group>"; };
    86148616                265541381489811C000DFC5D /* KeyEventIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyEventIOS.mm; sourceTree = "<group>"; };
     
    2313523137                                A7CFB3D00B7ED10A0070C32D /* DragImage.h */,
    2313623138                                1CA19E150DC255CA0065A994 /* EventLoop.h */,
     23139                                262EC41C1D110B1F00BA78FC /* EventTrackingRegions.cpp */,
    2313723140                                262EC4191D078F3D00BA78FC /* EventTrackingRegions.h */,
    2313823141                                934FE9E40B5CA539003E4A73 /* FileChooser.cpp */,
     
    3067630679                                1AE2AB290A1CE63B00B42B25 /* JSHTMLModElement.cpp in Sources */,
    3067730680                                BC305C790C076BB300CD20F0 /* JSHTMLObjectElement.cpp in Sources */,
     30681                                262EC41D1D110B9000BA78FC /* EventTrackingRegions.cpp in Sources */,
    3067830682                                BC305CA40C0781BB00CD20F0 /* JSHTMLObjectElementCustom.cpp in Sources */,
    3067930683                                1A85B1EA0A1B240500D8C87C /* JSHTMLOListElement.cpp in Sources */,
  • trunk/Source/WebCore/dom/EventTarget.cpp

    r202105 r202408  
    244244}
    245245
    246 bool EventTarget::hasActiveTouchEventListeners() const
    247 {
    248     const EventNames& names = eventNames();
    249     return hasActiveEventListeners(names.touchstartEvent)
    250         || hasActiveEventListeners(names.touchmoveEvent)
    251         || hasActiveEventListeners(names.touchendEvent)
    252         || hasActiveEventListeners(names.touchcancelEvent)
    253         || hasActiveEventListeners(names.touchforcechangeEvent);
    254 }
    255 
    256246void EventTarget::fireEventListeners(Event& event, EventTargetData* d, EventListenerVector& entry)
    257247{
  • trunk/Source/WebCore/dom/EventTarget.h

    r202105 r202408  
    169169    void invalidateJSEventListeners(JSC::JSObject*);
    170170
    171     bool hasActiveTouchEventListeners() const;
    172 
    173171protected:
    174172    virtual ~EventTarget();
  • trunk/Source/WebCore/page/DebugPageOverlays.cpp

    r201958 r202408  
    134134        if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
    135135            EventTrackingRegions eventTrackingRegions = scrollingCoordinator->absoluteEventTrackingRegions();
    136             *region = eventTrackingRegions.synchronousDispatchRegion;
     136            for (const auto& synchronousEventRegion : eventTrackingRegions.eventSpecificSynchronousDispatchRegions)
     137                region->unite(synchronousEventRegion.value);
    137138        }
    138139    }
  • trunk/Source/WebCore/page/Page.cpp

    r202183 r202408  
    373373
    374374    Vector<IntRect> rects;
    375     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    376         rects = scrollingCoordinator->absoluteEventTrackingRegions().synchronousDispatchRegion.rects();
     375    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
     376        const EventTrackingRegions& eventTrackingRegions = scrollingCoordinator->absoluteEventTrackingRegions();
     377        for (const auto& synchronousEventRegion : eventTrackingRegions.eventSpecificSynchronousDispatchRegions)
     378            rects.appendVector(synchronousEventRegion.value.rects());
     379    }
    377380
    378381    Vector<FloatQuad> quads(rects.size());
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp

    r201958 r202408  
    2929
    3030#include "Document.h"
     31#include "EventNames.h"
    3132#include "FrameView.h"
    3233#include "GraphicsLayer.h"
     
    145146   
    146147    // FIXME: if we've already accounted for this subframe as a scrollable area, we can avoid recursing into it here.
     148    EventTrackingRegions eventTrackingRegions;
    147149    for (Frame* subframe = frame.tree().firstChild(); subframe; subframe = subframe->tree().nextSibling()) {
    148150        FrameView* subframeView = subframe->view();
     
    150152            continue;
    151153
    152         Region subframeRegion = absoluteEventTrackingRegionsForFrame(*subframe).synchronousDispatchRegion;
     154        EventTrackingRegions subframeRegion = absoluteEventTrackingRegionsForFrame(*subframe);
    153155        // Map from the frame document to our document.
    154156        IntPoint offset = subframeView->contentsToContainingViewContents(IntPoint());
     
    156158        // FIXME: this translation ignores non-trival transforms on the frame.
    157159        subframeRegion.translate(toIntSize(offset));
    158         nonFastScrollableRegion.unite(subframeRegion);
     160        eventTrackingRegions.unite(subframeRegion);
    159161    }
    160162
     
    170172
    171173    // FIXME: If this is not the main frame, we could clip the region to the frame's bounds.
    172     return EventTrackingRegions { Region(), nonFastScrollableRegion };
     174    eventTrackingRegions.uniteSynchronousRegion(eventNames().wheelEvent, nonFastScrollableRegion);
     175    return eventTrackingRegions;
    173176#endif
    174177}
  • trunk/Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.cpp

    r201958 r202408  
    246246        indent -= 2;
    247247    }
    248     if (!m_eventTrackingRegions.synchronousDispatchRegion.isEmpty()) {
    249         ++indent;
    250         writeIndent(ts, indent);
    251         ts << "(synchronous event dispatch region";
    252         ++indent;
    253         for (auto rect : m_eventTrackingRegions.synchronousDispatchRegion.rects()) {
    254             ts << "\n";
     248    if (!m_eventTrackingRegions.eventSpecificSynchronousDispatchRegions.isEmpty()) {
     249        for (const auto& synchronousEventRegion : m_eventTrackingRegions.eventSpecificSynchronousDispatchRegions) {
     250            ++indent;
    255251            writeIndent(ts, indent);
    256             ts << rect;
     252            ts << "(synchronous event dispatch region for event " << synchronousEventRegion.key;
     253            ++indent;
     254            for (auto rect : synchronousEventRegion.value.rects()) {
     255                ts << "\n";
     256                writeIndent(ts, indent);
     257                ts << rect;
     258            }
     259            ts << ")\n";
     260            indent -= 2;
    257261        }
    258         ts << ")\n";
    259         indent -= 2;
    260262    }
    261263
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp

    r201958 r202408  
    2929#if ENABLE(ASYNC_SCROLLING)
    3030
     31#include "EventNames.h"
    3132#include "Logging.h"
    3233#include "PlatformWheelEvent.h"
     
    6768        position.move(frameScrollingNode.viewToContentsOffset(m_mainFrameScrollPosition));
    6869
    69         bool isSynchronousDispatchRegion = m_eventTrackingRegions.trackingTypeForPoint(roundedIntPoint(position)) == TrackingType::Synchronous;
     70        const EventNames& names = eventNames();
     71        IntPoint roundedPosition = roundedIntPoint(position);
     72        bool isSynchronousDispatchRegion = m_eventTrackingRegions.trackingTypeForPoint(names.wheelEvent, roundedPosition) == TrackingType::Synchronous
     73            || m_eventTrackingRegions.trackingTypeForPoint(names.mousewheelEvent, roundedPosition) == TrackingType::Synchronous;
    7074        LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::shouldHandleWheelEventSynchronously: wheelEvent at " << wheelEvent.position() << " mapped to content point " << position << ", in non-fast region " << isSynchronousDispatchRegion);
    7175
     
    234238}
    235239
    236 TrackingType ScrollingTree::eventTrackingTypeForPoint(IntPoint p)
    237 {
    238     LockHolder lock(m_mutex);
    239    
    240     return m_eventTrackingRegions.trackingTypeForPoint(p);
     240TrackingType ScrollingTree::eventTrackingTypeForPoint(const AtomicString& eventName, IntPoint p)
     241{
     242    LockHolder lock(m_mutex);
     243   
     244    return m_eventTrackingRegions.trackingTypeForPoint(eventName, p);
    241245}
    242246
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.h

    r201958 r202408  
    102102#endif
    103103
    104     WEBCORE_EXPORT TrackingType eventTrackingTypeForPoint(IntPoint);
     104    WEBCORE_EXPORT TrackingType eventTrackingTypeForPoint(const AtomicString& eventName, IntPoint);
    105105   
    106106#if PLATFORM(MAC)
  • trunk/Source/WebCore/platform/EventTrackingRegions.h

    r201958 r202408  
    2727
    2828#include "Region.h"
     29#include <wtf/HashMap.h>
     30#include <wtf/text/StringHash.h>
     31#include <wtf/text/WTFString.h>
    2932
    3033namespace WebCore {
     
    4043    Region asynchronousDispatchRegion;
    4144
    42     // Region for which events must be sent before performing the default behavior.
    43     Region synchronousDispatchRegion;
     45    // Regions for which events must be sent before performing the default behavior.
     46    // The key is the Event Name with an active handler.
     47    HashMap<String, Region> eventSpecificSynchronousDispatchRegions;
    4448
    4549    bool isEmpty() const;
    4650
    47     TrackingType trackingTypeForPoint(const IntPoint&);
     51    void translate(IntSize);
     52    void uniteSynchronousRegion(const String& eventName, const Region&);
     53    void unite(const EventTrackingRegions&);
     54
     55    TrackingType trackingTypeForPoint(const String& eventName, const IntPoint&);
    4856};
    4957
    50 inline bool EventTrackingRegions::isEmpty() const
    51 {
    52     return asynchronousDispatchRegion.isEmpty() && synchronousDispatchRegion.isEmpty();
    53 }
    54 
    55 inline TrackingType EventTrackingRegions::trackingTypeForPoint(const IntPoint& point)
    56 {
    57     if (synchronousDispatchRegion.contains(point))
    58         return TrackingType::Synchronous;
    59     if (asynchronousDispatchRegion.contains(point))
    60         return TrackingType::Asynchronous;
    61     return TrackingType::NotTracking;
    62 }
    63 
    64 inline bool operator==(const EventTrackingRegions& a, const EventTrackingRegions& b)
    65 {
    66     return a.asynchronousDispatchRegion == b.asynchronousDispatchRegion
    67         && a.synchronousDispatchRegion == b.synchronousDispatchRegion;
    68 }
     58bool operator==(const EventTrackingRegions&, const EventTrackingRegions&);
     59inline bool operator!=(const EventTrackingRegions& a, const EventTrackingRegions& b) { return !(a == b); }
    6960
    7061} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/Region.h

    r179861 r202408  
    199199    return a.m_bounds == b.m_bounds && a.m_shape == b.m_shape;
    200200}
     201inline bool operator!=(const Region& a, const Region& b)
     202{
     203    return !(a == b);
     204}
    201205
    202206inline bool operator==(const Region::Shape& a, const Region::Shape& b)
     
    209213    return a.y == b.y && a.segmentIndex == b.segmentIndex;
    210214}
     215inline bool operator!=(const Region::Span& a, const Region::Span& b)
     216{
     217    return !(a == b);
     218}
    211219
    212220} // namespace WebCore
  • trunk/Source/WebKit2/ChangeLog

    r202399 r202408  
     12016-06-23  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        Specialize synchronous event tracking per event type
     4        https://bugs.webkit.org/show_bug.cgi?id=158826
     5
     6        Reviewed by Simon Fraser.
     7
     8        * Shared/WebCoreArgumentCoders.cpp:
     9        (IPC::ArgumentCoder<EventTrackingRegions>::encode):
     10        (IPC::ArgumentCoder<EventTrackingRegions>::decode):
     11        * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:
     12        (WebKit::RemoteScrollingCoordinatorProxy::eventTrackingTypeForPoint):
     13        * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
     14        * UIProcess/WebPageProxy.cpp:
     15        (WebKit::mergeTrackingTypes):
     16        (WebKit::WebPageProxy::updateTouchEventTracking):
     17        (WebKit::WebPageProxy::touchEventTrackingType):
     18        (WebKit::WebPageProxy::handleTouchEventSynchronously):
     19        (WebKit::WebPageProxy::handleTouchEventAsynchronously):
     20        (WebKit::WebPageProxy::handleTouchEvent):
     21        (WebKit::WebPageProxy::resetState):
     22        * UIProcess/WebPageProxy.h:
     23        (WebKit::WebPageProxy::TouchEventTracking::isTrackingAnything):
     24        (WebKit::WebPageProxy::TouchEventTracking::reset):
     25
    1262016-06-23  Said Abou-Hallawa  <sabouhallawa@apple.com>
    227
  • trunk/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp

    r201958 r202408  
    495495            }
    496496        }
    497         {
     497        for (const auto& synchronousEventRegion : node.eventTrackingRegions().eventSpecificSynchronousDispatchRegions) {
    498498            TextStream::GroupScope group(ts);
    499             ts << "synchronous-event-tracking-region";
    500             for (auto rect : node.eventTrackingRegions().synchronousDispatchRegion.rects()) {
     499            ts << "synchronous-event-tracking-region for event " << synchronousEventRegion.key;
     500
     501            for (auto rect : synchronousEventRegion.value.rects()) {
    501502                ts << "\n";
    502503                ts.writeIndent();
  • trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp

    r201958 r202408  
    112112{
    113113    encoder << eventTrackingRegions.asynchronousDispatchRegion;
    114     encoder << eventTrackingRegions.synchronousDispatchRegion;
     114    encoder << eventTrackingRegions.eventSpecificSynchronousDispatchRegions;
    115115}
    116116
     
    120120    if (!decoder.decode(asynchronousDispatchRegion))
    121121        return false;
    122     Region synchronousDispatchRegion;
    123     if (!decoder.decode(synchronousDispatchRegion))
     122    HashMap<String, Region> eventSpecificSynchronousDispatchRegions;
     123    if (!decoder.decode(eventSpecificSynchronousDispatchRegions))
    124124        return false;
    125125    eventTrackingRegions.asynchronousDispatchRegion = WTFMove(asynchronousDispatchRegion);
    126     eventTrackingRegions.synchronousDispatchRegion = WTFMove(synchronousDispatchRegion);
     126    eventTrackingRegions.eventSpecificSynchronousDispatchRegions = WTFMove(eventSpecificSynchronousDispatchRegions);
    127127    return true;
    128128}
  • trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp

    r201958 r202408  
    150150}
    151151
    152 TrackingType RemoteScrollingCoordinatorProxy::eventTrackingTypeForPoint(IntPoint p) const
     152TrackingType RemoteScrollingCoordinatorProxy::eventTrackingTypeForPoint(const AtomicString& eventName, IntPoint p) const
    153153{
    154     return m_scrollingTree->eventTrackingTypeForPoint(p);
     154    return m_scrollingTree->eventTrackingTypeForPoint(eventName, p);
    155155}
    156156
  • trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h

    r201958 r202408  
    5757    void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll);
    5858
    59     WebCore::TrackingType eventTrackingTypeForPoint(WebCore::IntPoint) const;
     59    WebCore::TrackingType eventTrackingTypeForPoint(const AtomicString& eventName, WebCore::IntPoint) const;
    6060
    6161    // Called externally when native views move around.
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r202393 r202408  
    111111#include <WebCore/DragController.h>
    112112#include <WebCore/DragData.h>
     113#include <WebCore/EventNames.h>
    113114#include <WebCore/FloatRect.h>
    114115#include <WebCore/FocusDirection.h>
     
    19561957#if ENABLE(TOUCH_EVENTS)
    19571958
    1958 TrackingType WebPageProxy::touchEventTrackingType(const WebTouchEvent& touchStartEvent) const
     1959static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b)
     1960{
     1961    if (static_cast<uintptr_t>(b) > static_cast<uintptr_t>(a))
     1962        return b;
     1963    return a;
     1964}
     1965
     1966void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent)
    19591967{
    19601968#if ENABLE(ASYNC_SCROLLING)
    1961     TrackingType trackingType = TrackingType::NotTracking;
     1969    const EventNames& names = eventNames();
    19621970    for (auto& touchPoint : touchStartEvent.touchPoints()) {
    1963         TrackingType touchPointTrackingType = m_scrollingCoordinatorProxy->eventTrackingTypeForPoint(touchPoint.location());
    1964         if (touchPointTrackingType == TrackingType::Synchronous)
    1965             return TrackingType::Synchronous;
    1966 
    1967         if (touchPointTrackingType == TrackingType::Asynchronous)
    1968             trackingType = touchPointTrackingType;
    1969     }
    1970 
    1971     return trackingType;
     1971        IntPoint location = touchPoint.location();
     1972        auto updateTrackingType = [this, location](TrackingType& trackingType, const AtomicString& eventName) {
     1973            if (trackingType == TrackingType::Synchronous)
     1974                return;
     1975
     1976            TrackingType trackingTypeForLocation = m_scrollingCoordinatorProxy->eventTrackingTypeForPoint(eventName, location);
     1977
     1978            trackingType = mergeTrackingTypes(trackingType, trackingTypeForLocation);
     1979        };
     1980        updateTrackingType(m_touchEventTracking.touchForceChangedTracking, names.touchforcechangeEvent);
     1981        updateTrackingType(m_touchEventTracking.touchStartTracking, names.touchstartEvent);
     1982        updateTrackingType(m_touchEventTracking.touchMoveTracking, names.touchmoveEvent);
     1983        updateTrackingType(m_touchEventTracking.touchEndTracking, names.touchendEvent);
     1984    }
    19721985#else
    19731986    UNUSED_PARAM(touchStartEvent);
     1987    m_touchEventTracking.touchForceChangedTracking = TrackingType::Synchronous;
     1988    m_touchEventTracking.touchStartTracking = TrackingType::Synchronous;
     1989    m_touchEventTracking.touchMoveTracking = TrackingType::Synchronous;
     1990    m_touchEventTracking.touchEndTracking = TrackingType::Synchronous;
    19741991#endif // ENABLE(ASYNC_SCROLLING)
    1975     return TrackingType::Synchronous;
     1992}
     1993
     1994TrackingType WebPageProxy::touchEventTrackingType(const WebTouchEvent& touchStartEvent) const
     1995{
     1996    // We send all events if any type is needed, we just do it asynchronously for the types that are not tracked.
     1997    //
     1998    // Touch events define a sequence with strong dependencies. For example, we can expect
     1999    // a TouchMove to only appear after a TouchStart, and the ids of the touch points is consistent between
     2000    // the two.
     2001    //
     2002    // WebCore should not have to set up its state correctly after some events were dismissed.
     2003    // For example, we don't want to send a TouchMoved without a TouchPressed.
     2004    // We send everything, WebCore updates its internal state and dispatch what is needed to the page.
     2005    TrackingType globalTrackingType = m_touchEventTracking.isTrackingAnything() ? TrackingType::Asynchronous : TrackingType::NotTracking;
     2006
     2007    globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchForceChangedTracking);
     2008    for (auto& touchPoint : touchStartEvent.touchPoints()) {
     2009        switch (touchPoint.state()) {
     2010        case WebPlatformTouchPoint::TouchReleased:
     2011            globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchEndTracking);
     2012            break;
     2013        case WebPlatformTouchPoint::TouchPressed:
     2014            globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchStartTracking);
     2015            break;
     2016        case WebPlatformTouchPoint::TouchMoved:
     2017        case WebPlatformTouchPoint::TouchStationary:
     2018            globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchMoveTracking);
     2019            break;
     2020        case WebPlatformTouchPoint::TouchCancelled:
     2021            globalTrackingType = mergeTrackingTypes(globalTrackingType, TrackingType::Asynchronous);
     2022            break;
     2023        }
     2024    }
     2025
     2026    return globalTrackingType;
    19762027}
    19772028
     
    19992050
    20002051    if (event.type() == WebEvent::TouchStart) {
    2001         m_touchEventsTrackingType = touchEventTrackingType(event);
     2052        updateTouchEventTracking(event);
    20022053        m_layerTreeTransactionIdAtLastTouchStart = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).lastCommittedLayerTreeTransactionID();
    20032054    }
    20042055
    2005     if (m_touchEventsTrackingType == TrackingType::NotTracking)
    2006         return;
    2007 
    2008     if (m_touchEventsTrackingType == TrackingType::Asynchronous) {
     2056    TrackingType touchEventsTrackingType = touchEventTrackingType(event);
     2057    if (touchEventsTrackingType == TrackingType::NotTracking)
     2058        return;
     2059
     2060    if (touchEventsTrackingType == TrackingType::Asynchronous) {
    20092061        // We can end up here if a native gesture has not started but the event handlers are passive.
    20102062        //
     
    20272079
    20282080    if (event.allTouchPointsAreReleased())
    2029         m_touchEventsTrackingType = TrackingType::NotTracking;
     2081        m_touchEventTracking.reset();
    20302082}
    20312083
     
    20352087        return;
    20362088
    2037     if (m_touchEventsTrackingType == TrackingType::NotTracking)
     2089    TrackingType touchEventsTrackingType = touchEventTrackingType(event);
     2090    if (touchEventsTrackingType == TrackingType::NotTracking)
    20382091        return;
    20392092
     
    20412094
    20422095    if (event.allTouchPointsAreReleased())
    2043         m_touchEventsTrackingType = TrackingType::NotTracking;
     2096        m_touchEventTracking.reset();
    20442097}
    20452098
     
    20512104
    20522105    if (event.type() == WebEvent::TouchStart)
    2053         m_touchEventsTrackingType = touchEventTrackingType(event);
    2054 
    2055     if (m_touchEventsTrackingType == TrackingType::NotTracking)
     2106        updateTouchEventTracking(event);
     2107
     2108    if (touchEventTrackingType(event) == TrackingType::NotTracking)
    20562109        return;
    20572110
     
    20762129
    20772130    if (event.allTouchPointsAreReleased())
    2078         m_touchEventsTrackingType = TrackingType::NotTracking;
     2131        m_touchEventTracking.reset();
    20792132}
    20802133#endif // ENABLE(TOUCH_EVENTS)
     
    50955148
    50965149#if ENABLE(TOUCH_EVENTS)
    5097     m_touchEventsTrackingType = TrackingType::NotTracking;
     5150    m_touchEventTracking.reset();
    50985151#endif
    50995152
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r202347 r202408  
    14691469
    14701470#if ENABLE(TOUCH_EVENTS)
     1471    void updateTouchEventTracking(const WebTouchEvent&);
    14711472    WebCore::TrackingType touchEventTrackingType(const WebTouchEvent&) const;
    14721473#endif
     
    16961697
    16971698#if ENABLE(TOUCH_EVENTS)
    1698     WebCore::TrackingType m_touchEventsTrackingType { WebCore::TrackingType::NotTracking };
     1699    struct TouchEventTracking {
     1700        WebCore::TrackingType touchForceChangedTracking { WebCore::TrackingType::NotTracking };
     1701        WebCore::TrackingType touchStartTracking { WebCore::TrackingType::NotTracking };
     1702        WebCore::TrackingType touchMoveTracking { WebCore::TrackingType::NotTracking };
     1703        WebCore::TrackingType touchEndTracking { WebCore::TrackingType::NotTracking };
     1704
     1705        bool isTrackingAnything() const
     1706        {
     1707            return touchForceChangedTracking != WebCore::TrackingType::NotTracking
     1708                || touchStartTracking != WebCore::TrackingType::NotTracking
     1709                || touchMoveTracking != WebCore::TrackingType::NotTracking
     1710                || touchEndTracking != WebCore::TrackingType::NotTracking;
     1711        }
     1712
     1713        void reset()
     1714        {
     1715            touchForceChangedTracking = WebCore::TrackingType::NotTracking;
     1716            touchStartTracking = WebCore::TrackingType::NotTracking;
     1717            touchMoveTracking = WebCore::TrackingType::NotTracking;
     1718            touchEndTracking = WebCore::TrackingType::NotTracking;
     1719        }
     1720    };
     1721    TouchEventTracking m_touchEventTracking;
    16991722#endif
    17001723#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
Note: See TracChangeset for help on using the changeset viewer.