1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_layers_APZInputBridge_h
#define mozilla_layers_APZInputBridge_h
#include "mozilla/EventForwards.h" // for WidgetInputEvent, nsEventStatus
#include "mozilla/layers/APZPublicUtils.h" // for APZWheelAction
#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid
#include "Units.h" // for LayoutDeviceIntPoint
namespace mozilla {
class InputData;
namespace layers {
class APZInputBridgeParent;
struct ScrollableLayerGuid;
enum class APZHandledResult : uint8_t {
Unhandled = 0, // we know for sure that the event will not be handled
// by either the root APZC or others
HandledByRoot = 1, // we know for sure that the event will be handled
// by the root content APZC
HandledByContent = 2, // we know for sure it will be handled by a non-root
// APZC or by an event listener using preventDefault()
// in a document
Invalid = 3,
Last = Invalid
};
/**
* Represents the outcome of APZ receiving and processing an input event.
* This is returned from APZInputBridge::ReceiveInputEvent() and related APIs.
*/
struct APZEventResult {
/**
* Creates a default result with a status of eIgnore, no block ID, and empty
* target guid.
*/
APZEventResult();
/**
* A status flag indicated how APZ handled the event.
* The interpretation of each value is as follows:
*
* nsEventStatus_eConsumeNoDefault is returned to indicate the
* APZ is consuming this event and the caller should discard the event with
* extreme prejudice. The exact scenarios under which this is returned is
* implementation-dependent and may vary.
* nsEventStatus_eIgnore is returned to indicate that the APZ code didn't
* use this event. This might be because it was directed at a point on
* the screen where there was no APZ, or because the thing the user was
* trying to do was not allowed. (For example, attempting to pan a
* non-pannable document).
* nsEventStatus_eConsumeDoDefault is returned to indicate that the APZ
* code may have used this event to do some user-visible thing. Note that
* in some cases CONSUMED is returned even if the event was NOT used. This
* is because we cannot always know at the time of event delivery whether
* the event will be used or not. So we err on the side of sending
* CONSUMED when we are uncertain.
*/
nsEventStatus mStatus;
/**
* The guid of the APZC initially targeted by this event.
* This will usually be the APZC that handles the event, but in cases
* where the event is dispatched to content, it may end up being
* handled by a different APZC.
*/
ScrollableLayerGuid mTargetGuid;
/**
* This is:
* - set to HandledByRoot if we know for sure that the event will be handled
* by the root content APZC;
* - set to HandledByContent if we know for sure it will not be;
* - left empty if we are unsure.
*/
Maybe<APZHandledResult> mHandledResult;
/**
* If this event started or was added to an input block, the id of that
* input block, otherwise InputBlockState::NO_BLOCK_ID.
*/
uint64_t mInputBlockId;
};
/**
* This class lives in the main process, and is accessed via the controller
* thread (which is the process main thread for desktop, and the Java UI
* thread for Android). This class exposes a synchronous API to deliver
* incoming input events to APZ and modify them in-place to unapply the APZ
* async transform. If there is a GPU process, then this class does sync IPC
* calls over to the GPU process in order to accomplish this. Otherwise,
* APZCTreeManager overrides and implements these methods directly.
*/
class APZInputBridge {
public:
/**
* General handler for incoming input events. Manipulates the frame metrics
* based on what type of input it is. For example, a PinchGestureEvent will
* cause scaling. This should only be called externally to this class, and
* must be called on the controller thread.
*
* This function transforms |aEvent| to have its coordinates in DOM space.
* This is so that the event can be passed through the DOM and content can
* handle them. The event may need to be converted to a WidgetInputEvent
* by the caller if it wants to do this.
*
* @param aEvent input event object; is modified in-place
* @return The result of processing the event. Refer to the documentation of
* APZEventResult and its field.
*/
virtual APZEventResult ReceiveInputEvent(InputData& aEvent) = 0;
/**
* WidgetInputEvent handler. Transforms |aEvent| (which is assumed to be an
* already-existing instance of an WidgetInputEvent which may be an
* WidgetTouchEvent) to have its coordinates in DOM space. This is so that the
* event can be passed through the DOM and content can handle them.
*
* NOTE: Be careful of invoking the WidgetInputEvent variant. This can only be
* called on the main thread. See widget/InputData.h for more information on
* why we have InputData and WidgetInputEvent separated. If this function is
* used, the controller thread must be the main thread, or undefined behaviour
* may occur.
* NOTE: On unix, mouse events are treated as touch and are forwarded
* to the appropriate apz as such.
*
* See documentation for other ReceiveInputEvent above.
*/
APZEventResult ReceiveInputEvent(WidgetInputEvent& aEvent);
// Returns the kind of wheel event action, if any, that will be (or was)
// performed by APZ. If this returns true, the event must not perform a
// synchronous scroll.
//
// Even if this returns Nothing(), all wheel events in APZ-aware widgets must
// be sent through APZ so they are transformed correctly for BrowserParent.
static Maybe<APZWheelAction> ActionForWheelEvent(WidgetWheelEvent* aEvent);
protected:
friend class APZInputBridgeParent;
// Methods to help process WidgetInputEvents (or manage conversion to/from
// InputData)
virtual void ProcessUnhandledEvent(LayoutDeviceIntPoint* aRefPoint,
ScrollableLayerGuid* aOutTargetGuid,
uint64_t* aOutFocusSequenceNumber,
LayersId* aOutLayersId) = 0;
virtual void UpdateWheelTransaction(LayoutDeviceIntPoint aRefPoint,
EventMessage aEventMessage) = 0;
virtual ~APZInputBridge() = default;
};
std::ostream& operator<<(std::ostream& aOut,
const APZHandledResult& aHandledResult);
} // namespace layers
} // namespace mozilla
#endif // mozilla_layers_APZInputBridge_h
|