1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/events/event.h"
8 #include <X11/extensions/XInput2.h>
15 #include "base/metrics/histogram.h"
16 #include "base/strings/stringprintf.h"
17 #include "ui/events/event_utils.h"
18 #include "ui/events/keycodes/keyboard_code_conversion.h"
19 #include "ui/gfx/point3_f.h"
20 #include "ui/gfx/point_conversions.h"
21 #include "ui/gfx/transform.h"
22 #include "ui/gfx/transform_util.h"
25 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
26 #elif defined(USE_OZONE)
27 #include "ui/events/keycodes/keyboard_code_conversion.h"
32 std::string
EventTypeName(ui::EventType type
) {
33 #define RETURN_IF_TYPE(t) if (type == ui::t) return #t
34 #define CASE_TYPE(t) case ui::t: return #t
36 CASE_TYPE(ET_UNKNOWN
);
37 CASE_TYPE(ET_MOUSE_PRESSED
);
38 CASE_TYPE(ET_MOUSE_DRAGGED
);
39 CASE_TYPE(ET_MOUSE_RELEASED
);
40 CASE_TYPE(ET_MOUSE_MOVED
);
41 CASE_TYPE(ET_MOUSE_ENTERED
);
42 CASE_TYPE(ET_MOUSE_EXITED
);
43 CASE_TYPE(ET_KEY_PRESSED
);
44 CASE_TYPE(ET_KEY_RELEASED
);
45 CASE_TYPE(ET_MOUSEWHEEL
);
46 CASE_TYPE(ET_MOUSE_CAPTURE_CHANGED
);
47 CASE_TYPE(ET_TOUCH_RELEASED
);
48 CASE_TYPE(ET_TOUCH_PRESSED
);
49 CASE_TYPE(ET_TOUCH_MOVED
);
50 CASE_TYPE(ET_TOUCH_CANCELLED
);
51 CASE_TYPE(ET_DROP_TARGET_EVENT
);
52 CASE_TYPE(ET_TRANSLATED_KEY_PRESS
);
53 CASE_TYPE(ET_TRANSLATED_KEY_RELEASE
);
54 CASE_TYPE(ET_GESTURE_SCROLL_BEGIN
);
55 CASE_TYPE(ET_GESTURE_SCROLL_END
);
56 CASE_TYPE(ET_GESTURE_SCROLL_UPDATE
);
57 CASE_TYPE(ET_GESTURE_SHOW_PRESS
);
58 CASE_TYPE(ET_GESTURE_WIN8_EDGE_SWIPE
);
59 CASE_TYPE(ET_GESTURE_TAP
);
60 CASE_TYPE(ET_GESTURE_TAP_DOWN
);
61 CASE_TYPE(ET_GESTURE_TAP_CANCEL
);
62 CASE_TYPE(ET_GESTURE_BEGIN
);
63 CASE_TYPE(ET_GESTURE_END
);
64 CASE_TYPE(ET_GESTURE_TWO_FINGER_TAP
);
65 CASE_TYPE(ET_GESTURE_PINCH_BEGIN
);
66 CASE_TYPE(ET_GESTURE_PINCH_END
);
67 CASE_TYPE(ET_GESTURE_PINCH_UPDATE
);
68 CASE_TYPE(ET_GESTURE_LONG_PRESS
);
69 CASE_TYPE(ET_GESTURE_LONG_TAP
);
70 CASE_TYPE(ET_GESTURE_SWIPE
);
71 CASE_TYPE(ET_GESTURE_TAP_UNCONFIRMED
);
72 CASE_TYPE(ET_GESTURE_DOUBLE_TAP
);
74 CASE_TYPE(ET_SCROLL_FLING_START
);
75 CASE_TYPE(ET_SCROLL_FLING_CANCEL
);
76 CASE_TYPE(ET_CANCEL_MODE
);
77 CASE_TYPE(ET_UMA_DATA
);
78 case ui::ET_LAST
: NOTREACHED(); return std::string();
79 // Don't include default, so that we get an error when new type is added.
87 bool IsX11SendEventTrue(const base::NativeEvent
& event
) {
89 return event
&& event
->xany
.send_event
;
95 bool X11EventHasNonStandardState(const base::NativeEvent
& event
) {
97 const unsigned int kAllStateMask
=
98 Button1Mask
| Button2Mask
| Button3Mask
| Button4Mask
| Button5Mask
|
99 Mod1Mask
| Mod2Mask
| Mod3Mask
| Mod4Mask
| Mod5Mask
| ShiftMask
|
100 LockMask
| ControlMask
| AnyModifier
;
101 return event
&& (event
->xkey
.state
& ~kAllStateMask
) != 0;
111 ////////////////////////////////////////////////////////////////////////////////
115 if (delete_native_event_
)
116 ReleaseCopiedNativeEvent(native_event_
);
119 GestureEvent
* Event::AsGestureEvent() {
120 CHECK(IsGestureEvent());
121 return static_cast<GestureEvent
*>(this);
124 const GestureEvent
* Event::AsGestureEvent() const {
125 CHECK(IsGestureEvent());
126 return static_cast<const GestureEvent
*>(this);
129 bool Event::HasNativeEvent() const {
130 base::NativeEvent null_event
;
131 std::memset(&null_event
, 0, sizeof(null_event
));
132 return !!std::memcmp(&native_event_
, &null_event
, sizeof(null_event
));
135 void Event::StopPropagation() {
136 // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch
138 // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH);
140 result_
= static_cast<EventResult
>(result_
| ER_CONSUMED
);
143 void Event::SetHandled() {
144 // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch
146 // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH);
148 result_
= static_cast<EventResult
>(result_
| ER_HANDLED
);
151 Event::Event(EventType type
, base::TimeDelta time_stamp
, int flags
)
153 time_stamp_(time_stamp
),
155 native_event_(base::NativeEvent()),
156 delete_native_event_(false),
159 phase_(EP_PREDISPATCH
),
160 result_(ER_UNHANDLED
),
161 source_device_id_(ED_UNKNOWN_DEVICE
) {
163 name_
= EventTypeName(type_
);
166 Event::Event(const base::NativeEvent
& native_event
,
170 time_stamp_(EventTimeFromNative(native_event
)),
172 native_event_(native_event
),
173 delete_native_event_(false),
176 phase_(EP_PREDISPATCH
),
177 result_(ER_UNHANDLED
),
178 source_device_id_(ED_UNKNOWN_DEVICE
) {
179 base::TimeDelta delta
= EventTimeForNow() - time_stamp_
;
181 name_
= EventTypeName(type_
);
182 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser",
183 delta
.InMicroseconds(), 1, 1000000, 100);
184 std::string name_for_event
=
185 base::StringPrintf("Event.Latency.Browser.%s", name_
.c_str());
186 base::HistogramBase
* counter_for_type
=
187 base::Histogram::FactoryGet(
192 base::HistogramBase::kUmaTargetedHistogramFlag
);
193 counter_for_type
->Add(delta
.InMicroseconds());
196 if (native_event
->type
== GenericEvent
) {
197 XIDeviceEvent
* xiev
=
198 static_cast<XIDeviceEvent
*>(native_event
->xcookie
.data
);
199 source_device_id_
= xiev
->deviceid
;
204 Event::Event(const Event
& copy
)
206 time_stamp_(copy
.time_stamp_
),
207 latency_(copy
.latency_
),
209 native_event_(CopyNativeEvent(copy
.native_event_
)),
210 delete_native_event_(true),
213 phase_(EP_PREDISPATCH
),
214 result_(ER_UNHANDLED
),
215 source_device_id_(copy
.source_device_id_
) {
217 name_
= EventTypeName(type_
);
220 void Event::SetType(EventType type
) {
222 name_
= std::string();
225 name_
= EventTypeName(type_
);
228 ////////////////////////////////////////////////////////////////////////////////
231 CancelModeEvent::CancelModeEvent()
232 : Event(ET_CANCEL_MODE
, base::TimeDelta(), 0) {
233 set_cancelable(false);
236 CancelModeEvent::~CancelModeEvent() {
239 ////////////////////////////////////////////////////////////////////////////////
242 LocatedEvent::~LocatedEvent() {
245 LocatedEvent::LocatedEvent(const base::NativeEvent
& native_event
)
246 : Event(native_event
,
247 EventTypeFromNative(native_event
),
248 EventFlagsFromNative(native_event
)),
249 location_(EventLocationFromNative(native_event
)),
250 root_location_(location_
) {
253 LocatedEvent::LocatedEvent(EventType type
,
254 const gfx::PointF
& location
,
255 const gfx::PointF
& root_location
,
256 base::TimeDelta time_stamp
,
258 : Event(type
, time_stamp
, flags
),
260 root_location_(root_location
) {
263 void LocatedEvent::UpdateForRootTransform(
264 const gfx::Transform
& reversed_root_transform
) {
265 // Transform has to be done at root level.
266 gfx::Point3F
p(location_
);
267 reversed_root_transform
.TransformPoint(&p
);
268 location_
= p
.AsPointF();
269 root_location_
= location_
;
272 ////////////////////////////////////////////////////////////////////////////////
275 MouseEvent::MouseEvent(const base::NativeEvent
& native_event
)
276 : LocatedEvent(native_event
),
277 changed_button_flags_(
278 GetChangedMouseButtonFlagsFromNative(native_event
)) {
279 if (type() == ET_MOUSE_PRESSED
|| type() == ET_MOUSE_RELEASED
)
280 SetClickCount(GetRepeatCount(*this));
283 MouseEvent::MouseEvent(EventType type
,
284 const gfx::PointF
& location
,
285 const gfx::PointF
& root_location
,
287 int changed_button_flags
)
288 : LocatedEvent(type
, location
, root_location
, EventTimeForNow(), flags
),
289 changed_button_flags_(changed_button_flags
) {
290 if (this->type() == ET_MOUSE_MOVED
&& IsAnyButton())
291 SetType(ET_MOUSE_DRAGGED
);
295 bool MouseEvent::IsRepeatedClickEvent(
296 const MouseEvent
& event1
,
297 const MouseEvent
& event2
) {
298 // These values match the Windows defaults.
299 static const int kDoubleClickTimeMS
= 500;
300 static const int kDoubleClickWidth
= 4;
301 static const int kDoubleClickHeight
= 4;
303 if (event1
.type() != ET_MOUSE_PRESSED
||
304 event2
.type() != ET_MOUSE_PRESSED
)
307 // Compare flags, but ignore EF_IS_DOUBLE_CLICK to allow triple clicks.
308 if ((event1
.flags() & ~EF_IS_DOUBLE_CLICK
) !=
309 (event2
.flags() & ~EF_IS_DOUBLE_CLICK
))
312 base::TimeDelta time_difference
= event2
.time_stamp() - event1
.time_stamp();
314 if (time_difference
.InMilliseconds() > kDoubleClickTimeMS
)
317 if (std::abs(event2
.x() - event1
.x()) > kDoubleClickWidth
/ 2)
320 if (std::abs(event2
.y() - event1
.y()) > kDoubleClickHeight
/ 2)
327 int MouseEvent::GetRepeatCount(const MouseEvent
& event
) {
329 if (last_click_event_
) {
330 if (event
.type() == ui::ET_MOUSE_RELEASED
) {
331 if (event
.changed_button_flags() ==
332 last_click_event_
->changed_button_flags()) {
333 last_click_complete_
= true;
334 return last_click_event_
->GetClickCount();
336 // If last_click_event_ has changed since this button was pressed
337 // return a click count of 1.
341 if (event
.time_stamp() != last_click_event_
->time_stamp())
342 last_click_complete_
= true;
343 if (!last_click_complete_
||
344 IsX11SendEventTrue(event
.native_event())) {
345 click_count
= last_click_event_
->GetClickCount();
346 } else if (IsRepeatedClickEvent(*last_click_event_
, event
)) {
347 click_count
= last_click_event_
->GetClickCount() + 1;
349 delete last_click_event_
;
351 last_click_event_
= new MouseEvent(event
);
352 last_click_complete_
= false;
355 last_click_event_
->SetClickCount(click_count
);
359 void MouseEvent::ResetLastClickForTest() {
360 if (last_click_event_
) {
361 delete last_click_event_
;
362 last_click_event_
= NULL
;
363 last_click_complete_
= false;
368 MouseEvent
* MouseEvent::last_click_event_
= NULL
;
369 bool MouseEvent::last_click_complete_
= false;
371 int MouseEvent::GetClickCount() const {
372 if (type() != ET_MOUSE_PRESSED
&& type() != ET_MOUSE_RELEASED
)
375 if (flags() & EF_IS_TRIPLE_CLICK
)
377 else if (flags() & EF_IS_DOUBLE_CLICK
)
383 void MouseEvent::SetClickCount(int click_count
) {
384 if (type() != ET_MOUSE_PRESSED
&& type() != ET_MOUSE_RELEASED
)
387 DCHECK(click_count
> 0);
388 DCHECK(click_count
<= 3);
391 switch (click_count
) {
393 f
&= ~EF_IS_DOUBLE_CLICK
;
394 f
&= ~EF_IS_TRIPLE_CLICK
;
397 f
|= EF_IS_DOUBLE_CLICK
;
398 f
&= ~EF_IS_TRIPLE_CLICK
;
401 f
&= ~EF_IS_DOUBLE_CLICK
;
402 f
|= EF_IS_TRIPLE_CLICK
;
408 ////////////////////////////////////////////////////////////////////////////////
411 MouseWheelEvent::MouseWheelEvent(const base::NativeEvent
& native_event
)
412 : MouseEvent(native_event
),
413 offset_(GetMouseWheelOffset(native_event
)) {
416 MouseWheelEvent::MouseWheelEvent(const ScrollEvent
& scroll_event
)
417 : MouseEvent(scroll_event
),
418 offset_(scroll_event
.x_offset(), scroll_event
.y_offset()){
419 SetType(ET_MOUSEWHEEL
);
422 MouseWheelEvent::MouseWheelEvent(const MouseEvent
& mouse_event
,
425 : MouseEvent(mouse_event
), offset_(x_offset
, y_offset
) {
426 DCHECK(type() == ET_MOUSEWHEEL
);
429 MouseWheelEvent::MouseWheelEvent(const MouseWheelEvent
& mouse_wheel_event
)
430 : MouseEvent(mouse_wheel_event
),
431 offset_(mouse_wheel_event
.offset()) {
432 DCHECK(type() == ET_MOUSEWHEEL
);
435 MouseWheelEvent::MouseWheelEvent(const gfx::Vector2d
& offset
,
436 const gfx::PointF
& location
,
437 const gfx::PointF
& root_location
,
439 int changed_button_flags
)
440 : MouseEvent(ui::ET_MOUSEWHEEL
, location
, root_location
, flags
,
441 changed_button_flags
),
446 // This value matches windows WHEEL_DELTA.
448 const int MouseWheelEvent::kWheelDelta
= 120;
450 // This value matches GTK+ wheel scroll amount.
451 const int MouseWheelEvent::kWheelDelta
= 53;
454 void MouseWheelEvent::UpdateForRootTransform(
455 const gfx::Transform
& inverted_root_transform
) {
456 LocatedEvent::UpdateForRootTransform(inverted_root_transform
);
457 gfx::DecomposedTransform decomp
;
458 bool success
= gfx::DecomposeTransform(&decomp
, inverted_root_transform
);
461 offset_
.set_x(offset_
.x() * decomp
.scale
[0]);
463 offset_
.set_y(offset_
.y() * decomp
.scale
[1]);
466 ////////////////////////////////////////////////////////////////////////////////
469 TouchEvent::TouchEvent(const base::NativeEvent
& native_event
)
470 : LocatedEvent(native_event
),
471 touch_id_(GetTouchId(native_event
)),
472 radius_x_(GetTouchRadiusX(native_event
)),
473 radius_y_(GetTouchRadiusY(native_event
)),
474 rotation_angle_(GetTouchAngle(native_event
)),
475 force_(GetTouchForce(native_event
)) {
476 latency()->AddLatencyNumberWithTimestamp(
477 INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT
,
480 base::TimeTicks::FromInternalValue(time_stamp().ToInternalValue()),
483 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT
, 0, 0);
485 if (type() == ET_TOUCH_PRESSED
)
486 IncrementTouchIdRefCount(native_event
);
489 TouchEvent::TouchEvent(EventType type
,
490 const gfx::PointF
& location
,
492 base::TimeDelta time_stamp
)
493 : LocatedEvent(type
, location
, location
, time_stamp
, 0),
497 rotation_angle_(0.0f
),
499 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT
, 0, 0);
502 TouchEvent::TouchEvent(EventType type
,
503 const gfx::PointF
& location
,
506 base::TimeDelta time_stamp
,
511 : LocatedEvent(type
, location
, location
, time_stamp
, flags
),
515 rotation_angle_(angle
),
517 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT
, 0, 0);
520 TouchEvent::~TouchEvent() {
521 // In ctor TouchEvent(native_event) we call GetTouchId() which in X11
522 // platform setups the tracking_id to slot mapping. So in dtor here,
523 // if this touch event is a release event, we clear the mapping accordingly.
524 if (HasNativeEvent())
525 ClearTouchIdIfReleased(native_event());
528 void TouchEvent::UpdateForRootTransform(
529 const gfx::Transform
& inverted_root_transform
) {
530 LocatedEvent::UpdateForRootTransform(inverted_root_transform
);
531 gfx::DecomposedTransform decomp
;
532 bool success
= gfx::DecomposeTransform(&decomp
, inverted_root_transform
);
535 radius_x_
*= decomp
.scale
[0];
537 radius_y_
*= decomp
.scale
[1];
540 ////////////////////////////////////////////////////////////////////////////////
544 KeyEvent
* KeyEvent::last_key_event_
= NULL
;
547 bool KeyEvent::IsRepeated(const KeyEvent
& event
) {
548 // A safe guard in case if there were continous key pressed events that are
550 const int kMaxAutoRepeatTimeMs
= 2000;
551 // Ignore key events that have non standard state masks as it may be
552 // reposted by an IME. IBUS-GTK uses this field to detect the
553 // re-posted event for example. crbug.com/385873.
554 if (X11EventHasNonStandardState(event
.native_event()))
558 if (event
.type() == ui::ET_KEY_RELEASED
) {
559 delete last_key_event_
;
560 last_key_event_
= NULL
;
563 CHECK_EQ(ui::ET_KEY_PRESSED
, event
.type());
564 if (!last_key_event_
) {
565 last_key_event_
= new KeyEvent(event
);
568 if (event
.key_code() == last_key_event_
->key_code() &&
569 event
.flags() == last_key_event_
->flags() &&
570 (event
.time_stamp() - last_key_event_
->time_stamp()).InMilliseconds() <
571 kMaxAutoRepeatTimeMs
) {
574 delete last_key_event_
;
575 last_key_event_
= new KeyEvent(event
);
579 KeyEvent::KeyEvent(const base::NativeEvent
& native_event
)
580 : Event(native_event
,
581 EventTypeFromNative(native_event
),
582 EventFlagsFromNative(native_event
)),
583 key_code_(KeyboardCodeFromNative(native_event
)),
584 code_(CodeFromNative(native_event
)),
585 is_char_(IsCharFromNative(native_event
)),
586 platform_keycode_(PlatformKeycodeFromNative(native_event
)),
588 if (IsRepeated(*this))
589 set_flags(flags() | ui::EF_IS_REPEAT
);
596 KeyEvent::KeyEvent(EventType type
,
597 KeyboardCode key_code
,
599 : Event(type
, EventTimeForNow(), flags
),
602 platform_keycode_(0),
603 character_(GetCharacterFromKeyCode(key_code
, flags
)) {
606 KeyEvent::KeyEvent(EventType type
,
607 KeyboardCode key_code
,
608 const std::string
& code
,
610 : Event(type
, EventTimeForNow(), flags
),
614 platform_keycode_(0),
615 character_(GetCharacterFromKeyCode(key_code
, flags
)) {
618 KeyEvent::KeyEvent(base::char16 character
, KeyboardCode key_code
, int flags
)
619 : Event(ET_KEY_PRESSED
, EventTimeForNow(), flags
),
623 platform_keycode_(0),
624 character_(character
) {
627 KeyEvent::KeyEvent(const KeyEvent
& rhs
)
629 key_code_(rhs
.key_code_
),
631 is_char_(rhs
.is_char_
),
632 platform_keycode_(rhs
.platform_keycode_
),
633 character_(rhs
.character_
) {
634 if (rhs
.extended_key_event_data_
)
635 extended_key_event_data_
.reset(rhs
.extended_key_event_data_
->Clone());
638 KeyEvent
& KeyEvent::operator=(const KeyEvent
& rhs
) {
640 Event::operator=(rhs
);
641 key_code_
= rhs
.key_code_
;
643 is_char_
= rhs
.is_char_
;
644 platform_keycode_
= rhs
.platform_keycode_
;
645 character_
= rhs
.character_
;
647 if (rhs
.extended_key_event_data_
)
648 extended_key_event_data_
.reset(rhs
.extended_key_event_data_
->Clone());
653 KeyEvent::~KeyEvent() {}
655 void KeyEvent::SetExtendedKeyEventData(scoped_ptr
<ExtendedKeyEventData
> data
) {
656 extended_key_event_data_
= data
.Pass();
659 base::char16
KeyEvent::GetCharacter() const {
664 return (native_event().message
== WM_CHAR
) ? key_code_
:
665 GetCharacterFromKeyCode(key_code_
, flags());
666 #elif defined(USE_X11)
668 return GetCharacterFromKeyCode(key_code_
, flags());
670 DCHECK(native_event()->type
== KeyPress
||
671 native_event()->type
== KeyRelease
||
672 (native_event()->type
== GenericEvent
&&
673 (native_event()->xgeneric
.evtype
== XI_KeyPress
||
674 native_event()->xgeneric
.evtype
== XI_KeyRelease
)));
676 // When a control key is held, prefer ASCII characters to non ASCII
677 // characters in order to use it for shortcut keys. GetCharacterFromKeyCode
678 // returns 'a' for VKEY_A even if the key is actually bound to 'à' in X11.
679 // GetCharacterFromXEvent returns 'à' in that case.
680 return IsControlDown() ?
681 GetCharacterFromKeyCode(key_code_
, flags()) :
682 GetCharacterFromXEvent(native_event());
684 if (native_event()) {
685 DCHECK(EventTypeFromNative(native_event()) == ET_KEY_PRESSED
||
686 EventTypeFromNative(native_event()) == ET_KEY_RELEASED
);
689 return GetCharacterFromKeyCode(key_code_
, flags());
693 bool KeyEvent::IsUnicodeKeyCode() const {
697 const int key
= key_code();
698 if (key
>= VKEY_NUMPAD0
&& key
<= VKEY_NUMPAD9
)
700 // Check whether the user is using the numeric keypad with num-lock off.
701 // In that case, EF_EXTENDED will not be set; if it is set, the key event
702 // originated from the relevant non-numpad dedicated key, e.g. [Insert].
703 return (!(flags() & EF_EXTENDED
) &&
704 (key
== VKEY_INSERT
|| key
== VKEY_END
|| key
== VKEY_DOWN
||
705 key
== VKEY_NEXT
|| key
== VKEY_LEFT
|| key
== VKEY_CLEAR
||
706 key
== VKEY_RIGHT
|| key
== VKEY_HOME
|| key
== VKEY_UP
||
713 void KeyEvent::NormalizeFlags() {
715 switch (key_code()) {
717 mask
= EF_CONTROL_DOWN
;
720 mask
= EF_SHIFT_DOWN
;
726 mask
= EF_CAPS_LOCK_DOWN
;
731 if (type() == ET_KEY_PRESSED
)
732 set_flags(flags() | mask
);
734 set_flags(flags() & ~mask
);
737 bool KeyEvent::IsTranslated() const {
740 case ET_KEY_RELEASED
:
742 case ET_TRANSLATED_KEY_PRESS
:
743 case ET_TRANSLATED_KEY_RELEASE
:
751 void KeyEvent::SetTranslated(bool translated
) {
754 case ET_TRANSLATED_KEY_PRESS
:
755 SetType(translated
? ET_TRANSLATED_KEY_PRESS
: ET_KEY_PRESSED
);
757 case ET_KEY_RELEASED
:
758 case ET_TRANSLATED_KEY_RELEASE
:
759 SetType(translated
? ET_TRANSLATED_KEY_RELEASE
: ET_KEY_RELEASED
);
766 ////////////////////////////////////////////////////////////////////////////////
769 ScrollEvent::ScrollEvent(const base::NativeEvent
& native_event
)
770 : MouseEvent(native_event
) {
771 if (type() == ET_SCROLL
) {
772 GetScrollOffsets(native_event
,
773 &x_offset_
, &y_offset_
,
774 &x_offset_ordinal_
, &y_offset_ordinal_
,
776 } else if (type() == ET_SCROLL_FLING_START
||
777 type() == ET_SCROLL_FLING_CANCEL
) {
778 GetFlingData(native_event
,
779 &x_offset_
, &y_offset_
,
780 &x_offset_ordinal_
, &y_offset_ordinal_
,
783 NOTREACHED() << "Unexpected event type " << type()
784 << " when constructing a ScrollEvent.";
788 ScrollEvent::ScrollEvent(EventType type
,
789 const gfx::PointF
& location
,
790 base::TimeDelta time_stamp
,
794 float x_offset_ordinal
,
795 float y_offset_ordinal
,
797 : MouseEvent(type
, location
, location
, flags
, 0),
800 x_offset_ordinal_(x_offset_ordinal
),
801 y_offset_ordinal_(y_offset_ordinal
),
802 finger_count_(finger_count
) {
803 set_time_stamp(time_stamp
);
804 CHECK(IsScrollEvent());
807 void ScrollEvent::Scale(const float factor
) {
810 x_offset_ordinal_
*= factor
;
811 y_offset_ordinal_
*= factor
;
814 ////////////////////////////////////////////////////////////////////////////////
817 GestureEvent::GestureEvent(float x
,
820 base::TimeDelta time_stamp
,
821 const GestureEventDetails
& details
)
822 : LocatedEvent(details
.type(),
826 flags
| EF_FROM_TOUCH
),
830 GestureEvent::~GestureEvent() {