diff options
Diffstat (limited to 'Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp')
-rw-r--r-- | Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp | 142 |
1 files changed, 124 insertions, 18 deletions
diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp index 2dc475856..1f222658c 100644 --- a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp +++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2014-2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,6 +33,7 @@ #include "WebPageProxyMessages.h" #include "WebProcess.h" #include <WebCore/Page.h> +#include <WebCore/WheelEventTestTrigger.h> #include <wtf/MainThread.h> #include <wtf/RunLoop.h> @@ -46,13 +47,14 @@ using namespace WebCore; namespace WebKit { -PassRefPtr<EventDispatcher> EventDispatcher::create() +Ref<EventDispatcher> EventDispatcher::create() { - return adoptRef(new EventDispatcher); + return adoptRef(*new EventDispatcher); } EventDispatcher::EventDispatcher() - : m_queue(WorkQueue::create("com.apple.WebKit.EventDispatcher")) + : m_queue(WorkQueue::create("com.apple.WebKit.EventDispatcher", WorkQueue::Type::Serial, WorkQueue::QOS::UserInteractive)) + , m_recentWheelEventDeltaFilter(WheelEventDeltaFilter::create()) { } @@ -63,18 +65,18 @@ EventDispatcher::~EventDispatcher() #if ENABLE(ASYNC_SCROLLING) void EventDispatcher::addScrollingTreeForPage(WebPage* webPage) { - MutexLocker locker(m_scrollingTreesMutex); + LockHolder locker(m_scrollingTreesMutex); ASSERT(webPage->corePage()->scrollingCoordinator()); ASSERT(!m_scrollingTrees.contains(webPage->pageID())); - AsyncScrollingCoordinator* scrollingCoordinator = toAsyncScrollingCoordinator(webPage->corePage()->scrollingCoordinator()); - m_scrollingTrees.set(webPage->pageID(), toThreadedScrollingTree(scrollingCoordinator->scrollingTree())); + AsyncScrollingCoordinator& scrollingCoordinator = downcast<AsyncScrollingCoordinator>(*webPage->corePage()->scrollingCoordinator()); + m_scrollingTrees.set(webPage->pageID(), downcast<ThreadedScrollingTree>(scrollingCoordinator.scrollingTree())); } void EventDispatcher::removeScrollingTreeForPage(WebPage* webPage) { - MutexLocker locker(m_scrollingTreesMutex); + LockHolder locker(m_scrollingTreesMutex); ASSERT(m_scrollingTrees.contains(webPage->pageID())); m_scrollingTrees.remove(webPage->pageID()); @@ -88,19 +90,42 @@ void EventDispatcher::initializeConnection(IPC::Connection* connection) void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent, bool canRubberBandAtLeft, bool canRubberBandAtRight, bool canRubberBandAtTop, bool canRubberBandAtBottom) { -#if ENABLE(ASYNC_SCROLLING) - MutexLocker locker(m_scrollingTreesMutex); - if (ThreadedScrollingTree* scrollingTree = m_scrollingTrees.get(pageID)) { - PlatformWheelEvent platformWheelEvent = platform(wheelEvent); + PlatformWheelEvent platformWheelEvent = platform(wheelEvent); + +#if PLATFORM(COCOA) + switch (wheelEvent.phase()) { + case PlatformWheelEventPhaseBegan: + m_recentWheelEventDeltaFilter->beginFilteringDeltas(); + break; + case PlatformWheelEventPhaseEnded: + m_recentWheelEventDeltaFilter->endFilteringDeltas(); + break; + default: + break; + } + + if (m_recentWheelEventDeltaFilter->isFilteringDeltas()) { + m_recentWheelEventDeltaFilter->updateFromDelta(FloatSize(platformWheelEvent.deltaX(), platformWheelEvent.deltaY())); + FloatSize filteredDelta = m_recentWheelEventDeltaFilter->filteredDelta(); + platformWheelEvent = platformWheelEvent.copyWithDeltasAndVelocity(filteredDelta.width(), filteredDelta.height(), m_recentWheelEventDeltaFilter->filteredVelocity()); + } +#endif +#if ENABLE(ASYNC_SCROLLING) + LockHolder locker(m_scrollingTreesMutex); + if (RefPtr<ThreadedScrollingTree> scrollingTree = m_scrollingTrees.get(pageID)) { // FIXME: It's pretty horrible that we're updating the back/forward state here. // WebCore should always know the current state and know when it changes so the // scrolling tree can be notified. // We only need to do this at the beginning of the gesture. - if (platformWheelEvent.phase() == PlatformWheelEventPhaseBegan) - ScrollingThread::dispatch(bind(&ThreadedScrollingTree::setCanRubberBandState, scrollingTree, canRubberBandAtLeft, canRubberBandAtRight, canRubberBandAtTop, canRubberBandAtBottom)); + if (platformWheelEvent.phase() == PlatformWheelEventPhaseBegan) { + ScrollingThread::dispatch([scrollingTree, canRubberBandAtLeft, canRubberBandAtRight, canRubberBandAtTop, canRubberBandAtBottom] { + scrollingTree->setCanRubberBandState(canRubberBandAtLeft, canRubberBandAtRight, canRubberBandAtTop, canRubberBandAtBottom); + }); + } ScrollingTree::EventResult result = scrollingTree->tryToHandleWheelEvent(platformWheelEvent); + if (result == ScrollingTree::DidHandleEvent || result == ScrollingTree::DidNotHandleEvent) { sendDidReceiveEvent(pageID, wheelEvent, result == ScrollingTree::DidHandleEvent); return; @@ -113,24 +138,105 @@ void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEven UNUSED_PARAM(canRubberBandAtBottom); #endif - RunLoop::main()->dispatch(bind(&EventDispatcher::dispatchWheelEvent, this, pageID, wheelEvent)); + RunLoop::main().dispatch([protectedThis = makeRef(*this), pageID, wheelEvent]() mutable { + protectedThis->dispatchWheelEvent(pageID, wheelEvent); + }); +} + +#if ENABLE(MAC_GESTURE_EVENTS) +void EventDispatcher::gestureEvent(uint64_t pageID, const WebKit::WebGestureEvent& gestureEvent) +{ + RunLoop::main().dispatch([protectedThis = makeRef(*this), pageID, gestureEvent]() mutable { + protectedThis->dispatchGestureEvent(pageID, gestureEvent); + }); +} +#endif + +#if ENABLE(IOS_TOUCH_EVENTS) +void EventDispatcher::clearQueuedTouchEventsForPage(const WebPage& webPage) +{ + LockHolder locker(&m_touchEventsLock); + m_touchEvents.remove(webPage.pageID()); +} + +void EventDispatcher::getQueuedTouchEventsForPage(const WebPage& webPage, TouchEventQueue& destinationQueue) +{ + LockHolder locker(&m_touchEventsLock); + destinationQueue = m_touchEvents.take(webPage.pageID()); +} + +void EventDispatcher::touchEvent(uint64_t pageID, const WebKit::WebTouchEvent& touchEvent) +{ + bool updateListWasEmpty; + { + LockHolder locker(&m_touchEventsLock); + updateListWasEmpty = m_touchEvents.isEmpty(); + auto addResult = m_touchEvents.add(pageID, TouchEventQueue()); + if (addResult.isNewEntry) + addResult.iterator->value.append(touchEvent); + else { + TouchEventQueue& queuedEvents = addResult.iterator->value; + ASSERT(!queuedEvents.isEmpty()); + const WebTouchEvent& lastTouchEvent = queuedEvents.last(); + + // Coalesce touch move events. + if (touchEvent.type() == WebEvent::TouchMove && lastTouchEvent.type() == WebEvent::TouchMove) + queuedEvents.last() = touchEvent; + else + queuedEvents.append(touchEvent); + } + } + + if (updateListWasEmpty) { + RunLoop::main().dispatch([protectedThis = makeRef(*this)]() mutable { + protectedThis->dispatchTouchEvents(); + }); + } +} + +void EventDispatcher::dispatchTouchEvents() +{ + HashMap<uint64_t, TouchEventQueue> localCopy; + { + LockHolder locker(&m_touchEventsLock); + localCopy.swap(m_touchEvents); + } + + for (auto& slot : localCopy) { + if (WebPage* webPage = WebProcess::singleton().webPage(slot.key)) + webPage->dispatchAsynchronousTouchEvents(slot.value); + } } +#endif void EventDispatcher::dispatchWheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent) { - ASSERT(isMainThread()); + ASSERT(RunLoop::isMain()); - WebPage* webPage = WebProcess::shared().webPage(pageID); + WebPage* webPage = WebProcess::singleton().webPage(pageID); if (!webPage) return; webPage->wheelEvent(wheelEvent); } +#if ENABLE(MAC_GESTURE_EVENTS) +void EventDispatcher::dispatchGestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent) +{ + ASSERT(RunLoop::isMain()); + + WebPage* webPage = WebProcess::singleton().webPage(pageID); + if (!webPage) + return; + + webPage->gestureEvent(gestureEvent); +} +#endif + #if ENABLE(ASYNC_SCROLLING) void EventDispatcher::sendDidReceiveEvent(uint64_t pageID, const WebEvent& event, bool didHandleEvent) { - WebProcess::shared().parentProcessConnection()->send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(event.type()), didHandleEvent), pageID); + WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(event.type()), didHandleEvent), pageID); } #endif |