CoalescedMouseData.cpp (4216B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #include "CoalescedMouseData.h" 7 8 #include "BrowserChild.h" 9 #include "base/basictypes.h" 10 #include "mozilla/PresShell.h" 11 #include "mozilla/StaticPrefs_dom.h" 12 #include "nsRefreshDriver.h" 13 14 using namespace mozilla; 15 using namespace mozilla::dom; 16 17 void CoalescedMouseData::Coalesce(const WidgetMouseEvent& aEvent, 18 const ScrollableLayerGuid& aGuid, 19 const uint64_t& aInputBlockId) { 20 if (IsEmpty()) { 21 mCoalescedInputEvent = MakeUnique<WidgetMouseEvent>(aEvent); 22 mCoalescedInputEvent->mCallbackId = std::move(aEvent.mCallbackId); 23 mGuid = aGuid; 24 mInputBlockId = aInputBlockId; 25 MOZ_ASSERT(!mCoalescedInputEvent->mCoalescedWidgetEvents); 26 } else { 27 MOZ_ASSERT(aEvent.mCallbackId.isNothing()); 28 MOZ_ASSERT(mGuid == aGuid); 29 MOZ_ASSERT(mInputBlockId == aInputBlockId); 30 MOZ_ASSERT(mCoalescedInputEvent->mModifiers == aEvent.mModifiers); 31 MOZ_ASSERT(mCoalescedInputEvent->mReason == aEvent.mReason); 32 MOZ_ASSERT(mCoalescedInputEvent->mInputSource == aEvent.mInputSource); 33 MOZ_ASSERT(mCoalescedInputEvent->mButton == aEvent.mButton); 34 MOZ_ASSERT(mCoalescedInputEvent->mButtons == aEvent.mButtons); 35 mCoalescedInputEvent->mTimeStamp = aEvent.mTimeStamp; 36 mCoalescedInputEvent->mRefPoint = aEvent.mRefPoint; 37 mCoalescedInputEvent->mPressure = aEvent.mPressure; 38 mCoalescedInputEvent->AssignPointerHelperData(aEvent); 39 } 40 41 if (aEvent.mMessage == eMouseMove) { 42 // PointerEvent::getCoalescedEvents is only applied to pointermove events. 43 if (!mCoalescedInputEvent->mCoalescedWidgetEvents) { 44 mCoalescedInputEvent->mCoalescedWidgetEvents = 45 new WidgetPointerEventHolder(); 46 } 47 // Append current event in mCoalescedWidgetEvents. We use them to generate 48 // DOM events when content calls PointerEvent::getCoalescedEvents. 49 WidgetPointerEvent* event = 50 mCoalescedInputEvent->mCoalescedWidgetEvents->mEvents.AppendElement( 51 aEvent); 52 53 event->mMessage = ePointerMove; 54 event->mButton = MouseButton::eNotPressed; 55 event->mPressure = aEvent.ComputeMouseButtonPressure(); 56 event->mFlags.mBubbles = false; 57 event->mFlags.mCancelable = false; 58 } 59 } 60 61 bool CoalescedMouseData::CanCoalesce(const WidgetMouseEvent& aEvent, 62 const ScrollableLayerGuid& aGuid, 63 const uint64_t& aInputBlockId, 64 const nsRefreshDriver* aRefreshDriver) { 65 MOZ_ASSERT(aEvent.mMessage == eMouseMove); 66 if (!mCoalescedInputEvent) { 67 return true; 68 } 69 if (mCoalescedInputEvent->mFlags.mIsSynthesizedForTests != 70 aEvent.mFlags.mIsSynthesizedForTests || 71 mCoalescedInputEvent->mModifiers != aEvent.mModifiers || 72 mCoalescedInputEvent->mInputSource != aEvent.mInputSource || 73 mCoalescedInputEvent->pointerId != aEvent.pointerId || 74 mCoalescedInputEvent->mButton != aEvent.mButton || 75 mCoalescedInputEvent->mButtons != aEvent.mButtons || mGuid != aGuid || 76 mInputBlockId != aInputBlockId) { 77 return false; 78 } 79 // Basically, tests do not want to coalesces the consecutive mouse events. 80 // However, if the test calls nsIDOMWindowUtils::AdvanceTimeAndRefresh(0), 81 // they must try to check coalesced mouse move events. 82 if (!aEvent.mFlags.mIsSynthesizedForTests) { 83 return true; 84 } 85 return aRefreshDriver && aRefreshDriver->IsTestControllingRefreshesEnabled(); 86 } 87 88 CoalescedMouseMoveFlusher::CoalescedMouseMoveFlusher( 89 BrowserChild* aBrowserChild) 90 : CoalescedInputFlusher(aBrowserChild) {} 91 92 void CoalescedMouseMoveFlusher::WillRefresh(mozilla::TimeStamp aTime) { 93 MOZ_ASSERT(mRefreshDriver); 94 mBrowserChild->FlushAllCoalescedMouseData(); 95 mBrowserChild->ProcessPendingCoalescedMouseDataAndDispatchEvents(); 96 } 97 98 CoalescedMouseMoveFlusher::~CoalescedMouseMoveFlusher() { RemoveObserver(); }