Bumping gaia.json for 1 gaia revision(s) a=gaia-bump
[gecko.git] / widget / shared / WidgetEventImpl.cpp
blob0639205670d7f63bb0d7e1863222eb8a27d7c6e9
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/BasicEvents.h"
7 #include "mozilla/ContentEvents.h"
8 #include "mozilla/InternalMutationEvent.h"
9 #include "mozilla/MiscEvents.h"
10 #include "mozilla/MouseEvents.h"
11 #include "mozilla/Preferences.h"
12 #include "mozilla/TextEvents.h"
13 #include "mozilla/TouchEvents.h"
15 namespace mozilla {
17 /******************************************************************************
18 * As*Event() implementation
19 ******************************************************************************/
21 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
22 #define NS_EVENT_CLASS(aPrefix, aName) \
23 aPrefix##aName* \
24 WidgetEvent::As##aName() \
25 { \
26 return nullptr; \
27 } \
29 const aPrefix##aName* \
30 WidgetEvent::As##aName() const \
31 { \
32 return const_cast<WidgetEvent*>(this)->As##aName(); \
35 #include "mozilla/EventClassList.h"
37 #undef NS_EVENT_CLASS
38 #undef NS_ROOT_EVENT_CLASS
40 /******************************************************************************
41 * mozilla::WidgetEvent
43 * Event struct type checking methods.
44 ******************************************************************************/
46 bool
47 WidgetEvent::IsQueryContentEvent() const
49 return mClass == eQueryContentEventClass;
52 bool
53 WidgetEvent::IsSelectionEvent() const
55 return mClass == eSelectionEventClass;
58 bool
59 WidgetEvent::IsContentCommandEvent() const
61 return mClass == eContentCommandEventClass;
64 bool
65 WidgetEvent::IsNativeEventDelivererForPlugin() const
67 return mClass == ePluginEventClass;
71 /******************************************************************************
72 * mozilla::WidgetEvent
74 * Event message checking methods.
75 ******************************************************************************/
77 bool
78 WidgetEvent::HasMouseEventMessage() const
80 switch (message) {
81 case NS_MOUSE_BUTTON_DOWN:
82 case NS_MOUSE_BUTTON_UP:
83 case NS_MOUSE_CLICK:
84 case NS_MOUSE_DOUBLECLICK:
85 case NS_MOUSE_ENTER:
86 case NS_MOUSE_EXIT:
87 case NS_MOUSE_ACTIVATE:
88 case NS_MOUSE_ENTER_SYNTH:
89 case NS_MOUSE_EXIT_SYNTH:
90 case NS_MOUSE_MOZHITTEST:
91 case NS_MOUSE_MOVE:
92 return true;
93 default:
94 return false;
98 bool
99 WidgetEvent::HasDragEventMessage() const
101 switch (message) {
102 case NS_DRAGDROP_ENTER:
103 case NS_DRAGDROP_OVER:
104 case NS_DRAGDROP_EXIT:
105 case NS_DRAGDROP_DRAGDROP:
106 case NS_DRAGDROP_GESTURE:
107 case NS_DRAGDROP_DRAG:
108 case NS_DRAGDROP_END:
109 case NS_DRAGDROP_START:
110 case NS_DRAGDROP_DROP:
111 case NS_DRAGDROP_LEAVE_SYNTH:
112 return true;
113 default:
114 return false;
118 bool
119 WidgetEvent::HasKeyEventMessage() const
121 switch (message) {
122 case NS_KEY_DOWN:
123 case NS_KEY_PRESS:
124 case NS_KEY_UP:
125 return true;
126 default:
127 return false;
131 bool
132 WidgetEvent::HasIMEEventMessage() const
134 switch (message) {
135 case NS_TEXT_TEXT:
136 case NS_COMPOSITION_START:
137 case NS_COMPOSITION_END:
138 case NS_COMPOSITION_UPDATE:
139 return true;
140 default:
141 return false;
145 bool
146 WidgetEvent::HasPluginActivationEventMessage() const
148 return message == NS_PLUGIN_ACTIVATE ||
149 message == NS_PLUGIN_FOCUS;
152 /******************************************************************************
153 * mozilla::WidgetEvent
155 * Specific event checking methods.
156 ******************************************************************************/
158 bool
159 WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const
161 const WidgetPluginEvent* pluginEvent = AsPluginEvent();
162 return pluginEvent && pluginEvent->retargetToFocusedDocument;
165 bool
166 WidgetEvent::IsNonRetargetedNativeEventDelivererForPlugin() const
168 const WidgetPluginEvent* pluginEvent = AsPluginEvent();
169 return pluginEvent && !pluginEvent->retargetToFocusedDocument;
172 bool
173 WidgetEvent::IsIMERelatedEvent() const
175 return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent();
178 bool
179 WidgetEvent::IsUsingCoordinates() const
181 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
182 if (mouseEvent) {
183 return !mouseEvent->IsContextMenuKeyEvent();
185 return !HasKeyEventMessage() && !IsIMERelatedEvent() &&
186 !HasPluginActivationEventMessage() &&
187 !IsNativeEventDelivererForPlugin() &&
188 !IsContentCommandEvent() &&
189 message != NS_PLUGIN_RESOLUTION_CHANGED;
192 bool
193 WidgetEvent::IsTargetedAtFocusedWindow() const
195 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
196 if (mouseEvent) {
197 return mouseEvent->IsContextMenuKeyEvent();
199 return HasKeyEventMessage() || IsIMERelatedEvent() ||
200 IsContentCommandEvent() ||
201 IsRetargetedNativeEventDelivererForPlugin();
204 bool
205 WidgetEvent::IsTargetedAtFocusedContent() const
207 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
208 if (mouseEvent) {
209 return mouseEvent->IsContextMenuKeyEvent();
211 return HasKeyEventMessage() || IsIMERelatedEvent() ||
212 IsRetargetedNativeEventDelivererForPlugin();
215 bool
216 WidgetEvent::IsAllowedToDispatchDOMEvent() const
218 switch (mClass) {
219 case eMouseEventClass:
220 case ePointerEventClass:
221 // We want synthesized mouse moves to cause mouseover and mouseout
222 // DOM events (EventStateManager::PreHandleEvent), but not mousemove
223 // DOM events.
224 // Synthesized button up events also do not cause DOM events because they
225 // do not have a reliable refPoint.
226 return AsMouseEvent()->reason == WidgetMouseEvent::eReal;
228 case eWheelEventClass: {
229 // wheel event whose all delta values are zero by user pref applied, it
230 // shouldn't cause a DOM event.
231 const WidgetWheelEvent* wheelEvent = AsWheelEvent();
232 return wheelEvent->deltaX != 0.0 || wheelEvent->deltaY != 0.0 ||
233 wheelEvent->deltaZ != 0.0;
236 // Following events are handled in EventStateManager, so, we don't need to
237 // dispatch DOM event for them into the DOM tree.
238 case eQueryContentEventClass:
239 case eSelectionEventClass:
240 case eContentCommandEventClass:
241 return false;
243 default:
244 return true;
248 /******************************************************************************
249 * mozilla::WidgetInputEvent
250 ******************************************************************************/
252 /* static */
253 Modifier
254 WidgetInputEvent::AccelModifier()
256 static Modifier sAccelModifier = MODIFIER_NONE;
257 if (sAccelModifier == MODIFIER_NONE) {
258 switch (Preferences::GetInt("ui.key.accelKey", 0)) {
259 case nsIDOMKeyEvent::DOM_VK_META:
260 sAccelModifier = MODIFIER_META;
261 break;
262 case nsIDOMKeyEvent::DOM_VK_WIN:
263 sAccelModifier = MODIFIER_OS;
264 break;
265 case nsIDOMKeyEvent::DOM_VK_ALT:
266 sAccelModifier = MODIFIER_ALT;
267 break;
268 case nsIDOMKeyEvent::DOM_VK_CONTROL:
269 sAccelModifier = MODIFIER_CONTROL;
270 break;
271 default:
272 #ifdef XP_MACOSX
273 sAccelModifier = MODIFIER_META;
274 #else
275 sAccelModifier = MODIFIER_CONTROL;
276 #endif
277 break;
280 return sAccelModifier;
283 /******************************************************************************
284 * mozilla::WidgetKeyboardEvent (TextEvents.h)
285 ******************************************************************************/
287 /*static*/ void
288 WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex,
289 nsAString& aKeyName)
291 // The expected way to implement this function would be to use a
292 // switch statement. By using a table-based implementation, below, we
293 // ensure that this function executes in constant time in cases where
294 // compilers wouldn't be able to convert the switch statement to a
295 // jump table. This table-based implementation also minimizes the
296 // space required by the code and data.
297 #define KEY_STR_NUM_INTERNAL(line) key##line
298 #define KEY_STR_NUM(line) KEY_STR_NUM_INTERNAL(line)
300 // Catch non-ASCII DOM key names in our key name list.
301 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
302 static_assert(sizeof(aDOMKeyName) == MOZ_ARRAY_LENGTH(aDOMKeyName), \
303 "Invalid DOM key name");
304 #include "mozilla/KeyNameList.h"
305 #undef NS_DEFINE_KEYNAME
307 struct KeyNameTable
309 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
310 char16_t KEY_STR_NUM(__LINE__)[sizeof(aDOMKeyName)];
311 #include "mozilla/KeyNameList.h"
312 #undef NS_DEFINE_KEYNAME
315 static const KeyNameTable kKeyNameTable = {
316 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) MOZ_UTF16(aDOMKeyName),
317 #include "mozilla/KeyNameList.h"
318 #undef NS_DEFINE_KEYNAME
321 static const uint16_t kKeyNameOffsets[] = {
322 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
323 offsetof(struct KeyNameTable, KEY_STR_NUM(__LINE__)) / sizeof(char16_t),
324 #include "mozilla/KeyNameList.h"
325 #undef NS_DEFINE_KEYNAME
326 // Include this entry so we can compute lengths easily.
327 sizeof(kKeyNameTable)
330 // Use the sizeof trick rather than MOZ_ARRAY_LENGTH to avoid problems
331 // with constexpr functions called inside static_assert with some
332 // compilers.
333 static_assert(KEY_NAME_INDEX_USE_STRING ==
334 (sizeof(kKeyNameOffsets)/sizeof(kKeyNameOffsets[0])) - 1,
335 "Invalid enumeration values!");
337 if (aKeyNameIndex >= KEY_NAME_INDEX_USE_STRING) {
338 aKeyName.Truncate();
339 return;
342 uint16_t offset = kKeyNameOffsets[aKeyNameIndex];
343 uint16_t nextOffset = kKeyNameOffsets[aKeyNameIndex + 1];
344 const char16_t* table = reinterpret_cast<const char16_t*>(&kKeyNameTable);
346 // Subtract off 1 for the null terminator.
347 aKeyName.Assign(table + offset, nextOffset - offset - 1);
349 #undef KEY_STR_NUM
350 #undef KEY_STR_NUM_INTERNAL
353 /*static*/ void
354 WidgetKeyboardEvent::GetDOMCodeName(CodeNameIndex aCodeNameIndex,
355 nsAString& aCodeName)
357 if (aCodeNameIndex >= CODE_NAME_INDEX_USE_STRING) {
358 aCodeName.Truncate();
359 return;
362 #define NS_DEFINE_PHYSICAL_KEY_CODE_NAME(aCPPName, aDOMCodeName) \
363 MOZ_UTF16(aDOMCodeName),
364 static const char16_t* kCodeNames[] = {
365 #include "mozilla/PhysicalKeyCodeNameList.h"
366 MOZ_UTF16("")
368 #undef NS_DEFINE_PHYSICAL_KEY_CODE_NAME
370 MOZ_RELEASE_ASSERT(static_cast<size_t>(aCodeNameIndex) <
371 ArrayLength(kCodeNames),
372 "Illegal physical code enumeration value");
373 aCodeName = kCodeNames[aCodeNameIndex];
376 /* static */ const char*
377 WidgetKeyboardEvent::GetCommandStr(Command aCommand)
379 #define NS_DEFINE_COMMAND(aName, aCommandStr) , #aCommandStr
380 static const char* kCommands[] = {
381 "" // CommandDoNothing
382 #include "mozilla/CommandList.h"
384 #undef NS_DEFINE_COMMAND
386 MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand) < ArrayLength(kCommands),
387 "Illegal command enumeration value");
388 return kCommands[aCommand];
391 } // namespace mozilla