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/. */
7 #include "CoalescedTouchData.h"
8 #include "BrowserChild.h"
9 #include "mozilla/dom/PointerEventHandler.h"
11 using namespace mozilla
;
12 using namespace mozilla::dom
;
14 static const uint32_t sMaxTouchMoveIdentifiers
= 10;
16 void CoalescedTouchData::CreateCoalescedTouchEvent(
17 const WidgetTouchEvent
& aEvent
) {
18 MOZ_ASSERT(IsEmpty());
19 mCoalescedInputEvent
= MakeUnique
<WidgetTouchEvent
>(aEvent
);
20 for (size_t i
= 0; i
< mCoalescedInputEvent
->mTouches
.Length(); i
++) {
21 const RefPtr
<Touch
>& touch
= mCoalescedInputEvent
->mTouches
[i
];
22 touch
->mCoalescedWidgetEvents
= MakeAndAddRef
<WidgetPointerEventHolder
>();
23 // Add an initial event into coalesced events, so
24 // the relevant pointer event would at least contain one coalesced event.
25 WidgetPointerEvent
* event
=
26 touch
->mCoalescedWidgetEvents
->mEvents
.AppendElement(WidgetPointerEvent(
27 aEvent
.IsTrusted(), ePointerMove
, aEvent
.mWidget
));
28 PointerEventHandler::InitPointerEventFromTouch(*event
, aEvent
, *touch
,
30 event
->mFlags
.mBubbles
= false;
31 event
->mFlags
.mCancelable
= false;
35 void CoalescedTouchData::Coalesce(const WidgetTouchEvent
& aEvent
,
36 const ScrollableLayerGuid
& aGuid
,
37 const uint64_t& aInputBlockId
,
38 const nsEventStatus
& aApzResponse
) {
39 MOZ_ASSERT(aEvent
.mMessage
== eTouchMove
);
41 CreateCoalescedTouchEvent(aEvent
);
43 mInputBlockId
= aInputBlockId
;
44 mApzResponse
= aApzResponse
;
46 MOZ_ASSERT(mGuid
== aGuid
);
47 MOZ_ASSERT(mInputBlockId
== aInputBlockId
);
48 MOZ_ASSERT(mCoalescedInputEvent
->mModifiers
== aEvent
.mModifiers
);
49 MOZ_ASSERT(mCoalescedInputEvent
->mInputSource
== aEvent
.mInputSource
);
51 for (size_t i
= 0; i
< aEvent
.mTouches
.Length(); i
++) {
52 const RefPtr
<Touch
>& touch
= aEvent
.mTouches
[i
];
53 // Get the same touch in the original event
54 RefPtr
<Touch
> sameTouch
= GetTouch(touch
->Identifier());
55 // The checks in CoalescedTouchData::CanCoalesce ensure it should never
57 MOZ_ASSERT(sameTouch
);
58 MOZ_ASSERT(sameTouch
->mCoalescedWidgetEvents
);
59 MOZ_ASSERT(!sameTouch
->mCoalescedWidgetEvents
->mEvents
.IsEmpty());
60 if (!sameTouch
->Equals(touch
)) {
61 sameTouch
->SetSameAs(touch
);
62 WidgetPointerEvent
* event
=
63 sameTouch
->mCoalescedWidgetEvents
->mEvents
.AppendElement(
64 WidgetPointerEvent(aEvent
.IsTrusted(), ePointerMove
,
66 PointerEventHandler::InitPointerEventFromTouch(*event
, aEvent
, *touch
,
68 event
->mFlags
.mBubbles
= false;
69 event
->mFlags
.mCancelable
= false;
73 mCoalescedInputEvent
->mTimeStamp
= aEvent
.mTimeStamp
;
77 bool CoalescedTouchData::CanCoalesce(const WidgetTouchEvent
& aEvent
,
78 const ScrollableLayerGuid
& aGuid
,
79 const uint64_t& aInputBlockId
,
80 const nsEventStatus
& aApzResponse
) {
81 MOZ_ASSERT(!IsEmpty());
82 if (mGuid
!= aGuid
|| mInputBlockId
!= aInputBlockId
||
83 mCoalescedInputEvent
->mModifiers
!= aEvent
.mModifiers
||
84 mCoalescedInputEvent
->mInputSource
!= aEvent
.mInputSource
||
85 aEvent
.mTouches
.Length() > sMaxTouchMoveIdentifiers
) {
89 // Ensures both touchmove events have the same touches
90 if (aEvent
.mTouches
.Length() != mCoalescedInputEvent
->mTouches
.Length()) {
93 for (const RefPtr
<Touch
>& touch
: aEvent
.mTouches
) {
94 if (!GetTouch(touch
->Identifier())) {
99 // If one of them is eIgnore and the other one is eConsumeDoDefault,
100 // we always coalesce them to eConsumeDoDefault.
101 if (mApzResponse
!= aApzResponse
) {
102 if (mApzResponse
== nsEventStatus::nsEventStatus_eIgnore
&&
103 aApzResponse
== nsEventStatus::nsEventStatus_eConsumeDoDefault
) {
104 mApzResponse
= aApzResponse
;
105 } else if (mApzResponse
!= nsEventStatus::nsEventStatus_eConsumeDoDefault
||
106 aApzResponse
!= nsEventStatus::nsEventStatus_eIgnore
) {
114 Touch
* CoalescedTouchData::GetTouch(int32_t aIdentifier
) {
115 for (const RefPtr
<Touch
>& touch
: mCoalescedInputEvent
->mTouches
) {
116 if (touch
->Identifier() == aIdentifier
) {
123 void CoalescedTouchMoveFlusher::WillRefresh(mozilla::TimeStamp aTime
) {
124 MOZ_ASSERT(mRefreshDriver
);
125 mBrowserChild
->ProcessPendingCoalescedTouchData();
128 CoalescedTouchMoveFlusher::CoalescedTouchMoveFlusher(
129 BrowserChild
* aBrowserChild
)
130 : CoalescedInputFlusher(aBrowserChild
) {}
132 CoalescedTouchMoveFlusher::~CoalescedTouchMoveFlusher() { RemoveObserver(); }