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
);
29 event
->mFlags
.mBubbles
= false;
30 event
->mFlags
.mCancelable
= false;
34 void CoalescedTouchData::Coalesce(const WidgetTouchEvent
& aEvent
,
35 const ScrollableLayerGuid
& aGuid
,
36 const uint64_t& aInputBlockId
,
37 const nsEventStatus
& aApzResponse
) {
38 MOZ_ASSERT(aEvent
.mMessage
== eTouchMove
);
40 CreateCoalescedTouchEvent(aEvent
);
42 mInputBlockId
= aInputBlockId
;
43 mApzResponse
= aApzResponse
;
45 MOZ_ASSERT(mGuid
== aGuid
);
46 MOZ_ASSERT(mInputBlockId
== aInputBlockId
);
47 MOZ_ASSERT(mCoalescedInputEvent
->mModifiers
== aEvent
.mModifiers
);
48 MOZ_ASSERT(mCoalescedInputEvent
->mInputSource
== aEvent
.mInputSource
);
50 for (size_t i
= 0; i
< aEvent
.mTouches
.Length(); i
++) {
51 const RefPtr
<Touch
>& touch
= aEvent
.mTouches
[i
];
52 // Get the same touch in the original event
53 RefPtr
<Touch
> sameTouch
= GetTouch(touch
->Identifier());
54 // The checks in CoalescedTouchData::CanCoalesce ensure it should never
56 MOZ_ASSERT(sameTouch
);
57 MOZ_ASSERT(sameTouch
->mCoalescedWidgetEvents
);
58 MOZ_ASSERT(!sameTouch
->mCoalescedWidgetEvents
->mEvents
.IsEmpty());
59 if (!sameTouch
->Equals(touch
)) {
60 sameTouch
->SetSameAs(touch
);
61 WidgetPointerEvent
* event
=
62 sameTouch
->mCoalescedWidgetEvents
->mEvents
.AppendElement(
63 WidgetPointerEvent(aEvent
.IsTrusted(), ePointerMove
,
65 PointerEventHandler::InitPointerEventFromTouch(*event
, aEvent
, *touch
);
66 event
->mFlags
.mBubbles
= false;
67 event
->mFlags
.mCancelable
= false;
71 mCoalescedInputEvent
->mTimeStamp
= aEvent
.mTimeStamp
;
75 bool CoalescedTouchData::CanCoalesce(const WidgetTouchEvent
& aEvent
,
76 const ScrollableLayerGuid
& aGuid
,
77 const uint64_t& aInputBlockId
,
78 const nsEventStatus
& aApzResponse
) {
79 MOZ_ASSERT(!IsEmpty());
80 if (mGuid
!= aGuid
|| mInputBlockId
!= aInputBlockId
||
81 mCoalescedInputEvent
->mModifiers
!= aEvent
.mModifiers
||
82 mCoalescedInputEvent
->mInputSource
!= aEvent
.mInputSource
||
83 aEvent
.mTouches
.Length() > sMaxTouchMoveIdentifiers
) {
87 // Ensures both touchmove events have the same touches
88 if (aEvent
.mTouches
.Length() != mCoalescedInputEvent
->mTouches
.Length()) {
91 for (const RefPtr
<Touch
>& touch
: aEvent
.mTouches
) {
92 if (!GetTouch(touch
->Identifier())) {
97 // If one of them is eIgnore and the other one is eConsumeDoDefault,
98 // we always coalesce them to eConsumeDoDefault.
99 if (mApzResponse
!= aApzResponse
) {
100 if (mApzResponse
== nsEventStatus::nsEventStatus_eIgnore
&&
101 aApzResponse
== nsEventStatus::nsEventStatus_eConsumeDoDefault
) {
102 mApzResponse
= aApzResponse
;
103 } else if (mApzResponse
!= nsEventStatus::nsEventStatus_eConsumeDoDefault
||
104 aApzResponse
!= nsEventStatus::nsEventStatus_eIgnore
) {
112 Touch
* CoalescedTouchData::GetTouch(int32_t aIdentifier
) {
113 for (const RefPtr
<Touch
>& touch
: mCoalescedInputEvent
->mTouches
) {
114 if (touch
->Identifier() == aIdentifier
) {
121 void CoalescedTouchMoveFlusher::WillRefresh(mozilla::TimeStamp aTime
) {
122 MOZ_ASSERT(mRefreshDriver
);
123 mBrowserChild
->ProcessPendingCoalescedTouchData();
126 CoalescedTouchMoveFlusher::CoalescedTouchMoveFlusher(
127 BrowserChild
* aBrowserChild
)
128 : CoalescedInputFlusher(aBrowserChild
) {}
130 CoalescedTouchMoveFlusher::~CoalescedTouchMoveFlusher() { RemoveObserver(); }