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 #ifndef UI_EVENTS_EVENT_H_
6 #define UI_EVENTS_EVENT_H_
8 #include "base/basictypes.h"
9 #include "base/compiler_specific.h"
10 #include "base/event_types.h"
11 #include "base/gtest_prod_util.h"
12 #include "base/logging.h"
13 #include "base/time/time.h"
14 #include "ui/events/event_constants.h"
15 #include "ui/events/gesture_event_details.h"
16 #include "ui/events/gestures/gesture_types.h"
17 #include "ui/events/keycodes/keyboard_codes.h"
18 #include "ui/events/latency_info.h"
19 #include "ui/gfx/point.h"
20 #include "ui/gfx/point_conversions.h"
29 class EVENTS_EXPORT Event {
35 explicit DispatcherApi(Event* event) : event_(event) {}
37 void set_target(EventTarget* target) {
38 event_->target_ = target;
41 void set_phase(EventPhase phase) { event_->phase_ = phase; }
42 void set_result(int result) {
43 event_->result_ = static_cast<EventResult>(result);
50 DISALLOW_COPY_AND_ASSIGN(DispatcherApi);
53 const base::NativeEvent& native_event() const { return native_event_; }
54 EventType type() const { return type_; }
55 const std::string& name() const { return name_; }
56 // time_stamp represents time since machine was booted.
57 const base::TimeDelta& time_stamp() const { return time_stamp_; }
58 int flags() const { return flags_; }
60 // This is only intended to be used externally by classes that are modifying
61 // events in EventFilter::PreHandleKeyEvent().
62 void set_flags(int flags) { flags_ = flags; }
64 EventTarget* target() const { return target_; }
65 EventPhase phase() const { return phase_; }
66 EventResult result() const { return result_; }
68 LatencyInfo* latency() { return &latency_; }
69 const LatencyInfo* latency() const { return &latency_; }
70 void set_latency(const LatencyInfo& latency) { latency_ = latency; }
72 // By default, events are "cancelable", this means any default processing that
73 // the containing abstraction layer may perform can be prevented by calling
74 // SetHandled(). SetHandled() or StopPropagation() must not be called for
75 // events that are not cancelable.
76 bool cancelable() const { return cancelable_; }
78 // The following methods return true if the respective keys were pressed at
79 // the time the event was created.
80 bool IsShiftDown() const { return (flags_ & EF_SHIFT_DOWN) != 0; }
81 bool IsControlDown() const { return (flags_ & EF_CONTROL_DOWN) != 0; }
82 bool IsCapsLockDown() const { return (flags_ & EF_CAPS_LOCK_DOWN) != 0; }
83 bool IsAltDown() const { return (flags_ & EF_ALT_DOWN) != 0; }
84 bool IsAltGrDown() const { return (flags_ & EF_ALTGR_DOWN) != 0; }
85 bool IsRepeat() const { return (flags_ & EF_IS_REPEAT) != 0; }
87 bool IsKeyEvent() const {
88 return type_ == ET_KEY_PRESSED ||
89 type_ == ET_KEY_RELEASED ||
90 type_ == ET_TRANSLATED_KEY_PRESS ||
91 type_ == ET_TRANSLATED_KEY_RELEASE;
94 bool IsMouseEvent() const {
95 return type_ == ET_MOUSE_PRESSED ||
96 type_ == ET_MOUSE_DRAGGED ||
97 type_ == ET_MOUSE_RELEASED ||
98 type_ == ET_MOUSE_MOVED ||
99 type_ == ET_MOUSE_ENTERED ||
100 type_ == ET_MOUSE_EXITED ||
101 type_ == ET_MOUSEWHEEL ||
102 type_ == ET_MOUSE_CAPTURE_CHANGED;
105 bool IsTouchEvent() const {
106 return type_ == ET_TOUCH_RELEASED ||
107 type_ == ET_TOUCH_PRESSED ||
108 type_ == ET_TOUCH_MOVED ||
109 type_ == ET_TOUCH_CANCELLED;
112 bool IsGestureEvent() const {
114 case ET_GESTURE_SCROLL_BEGIN:
115 case ET_GESTURE_SCROLL_END:
116 case ET_GESTURE_SCROLL_UPDATE:
118 case ET_GESTURE_TAP_CANCEL:
119 case ET_GESTURE_TAP_DOWN:
120 case ET_GESTURE_BEGIN:
122 case ET_GESTURE_TWO_FINGER_TAP:
123 case ET_GESTURE_PINCH_BEGIN:
124 case ET_GESTURE_PINCH_END:
125 case ET_GESTURE_PINCH_UPDATE:
126 case ET_GESTURE_LONG_PRESS:
127 case ET_GESTURE_LONG_TAP:
128 case ET_GESTURE_SWIPE:
129 case ET_GESTURE_SHOW_PRESS:
130 case ET_GESTURE_WIN8_EDGE_SWIPE:
131 // When adding a gesture event which is paired with an event which
132 // occurs earlier, add the event to |IsEndingEvent|.
135 case ET_SCROLL_FLING_CANCEL:
136 case ET_SCROLL_FLING_START:
137 // These can be ScrollEvents too. EF_FROM_TOUCH determines if they're
138 // Gesture or Scroll events.
139 return (flags_ & EF_FROM_TOUCH) == EF_FROM_TOUCH;
147 // An ending event is paired with the event which started it. Setting capture
148 // should not prevent ending events from getting to their initial target.
149 bool IsEndingEvent() const {
151 case ui::ET_TOUCH_CANCELLED:
152 case ui::ET_GESTURE_TAP_CANCEL:
153 case ui::ET_GESTURE_END:
154 case ui::ET_GESTURE_SCROLL_END:
155 case ui::ET_GESTURE_PINCH_END:
162 bool IsScrollEvent() const {
163 // Flings can be GestureEvents too. EF_FROM_TOUCH determins if they're
164 // Gesture or Scroll events.
165 return type_ == ET_SCROLL ||
166 ((type_ == ET_SCROLL_FLING_START ||
167 type_ == ET_SCROLL_FLING_CANCEL) &&
168 !(flags() & EF_FROM_TOUCH));
171 bool IsScrollGestureEvent() const {
172 return type_ == ET_GESTURE_SCROLL_BEGIN ||
173 type_ == ET_GESTURE_SCROLL_UPDATE ||
174 type_ == ET_GESTURE_SCROLL_END;
177 bool IsFlingScrollEvent() const {
178 return type_ == ET_SCROLL_FLING_CANCEL ||
179 type_ == ET_SCROLL_FLING_START;
182 bool IsMouseWheelEvent() const {
183 return type_ == ET_MOUSEWHEEL;
186 // Returns true if the event has a valid |native_event_|.
187 bool HasNativeEvent() const;
189 // Immediately stops the propagation of the event. This must be called only
190 // from an EventHandler during an event-dispatch. Any event handler that may
191 // be in the list will not receive the event after this is called.
192 // Note that StopPropagation() can be called only for cancelable events.
193 void StopPropagation();
194 bool stopped_propagation() const { return !!(result_ & ER_CONSUMED); }
196 // Marks the event as having been handled. A handled event does not reach the
197 // next event phase. For example, if an event is handled during the pre-target
198 // phase, then the event is dispatched to all pre-target handlers, but not to
199 // the target or post-target handlers.
200 // Note that SetHandled() can be called only for cancelable events.
202 bool handled() const { return result_ != ER_UNHANDLED; }
205 Event(EventType type, base::TimeDelta time_stamp, int flags);
206 Event(const base::NativeEvent& native_event, EventType type, int flags);
207 Event(const Event& copy);
208 void SetType(EventType type);
209 void set_delete_native_event(bool delete_native_event) {
210 delete_native_event_ = delete_native_event;
212 void set_cancelable(bool cancelable) { cancelable_ = cancelable; }
214 void set_time_stamp(const base::TimeDelta& time_stamp) {
215 time_stamp_ = time_stamp;
218 void set_name(const std::string& name) { name_ = name; }
221 friend class EventTestApi;
225 base::TimeDelta time_stamp_;
226 LatencyInfo latency_;
228 base::NativeEvent native_event_;
229 bool delete_native_event_;
231 EventTarget* target_;
236 class EVENTS_EXPORT CancelModeEvent : public Event {
239 virtual ~CancelModeEvent();
242 class EVENTS_EXPORT LocatedEvent : public Event {
244 virtual ~LocatedEvent();
246 float x() const { return location_.x(); }
247 float y() const { return location_.y(); }
248 void set_location(const gfx::PointF& location) { location_ = location; }
249 // TODO(tdresser): Always return floating point location. See
251 gfx::Point location() const { return gfx::ToFlooredPoint(location_); }
252 const gfx::PointF& location_f() const { return location_; }
253 void set_root_location(const gfx::PointF& root_location) {
254 root_location_ = root_location;
256 gfx::Point root_location() const {
257 return gfx::ToFlooredPoint(root_location_);
259 const gfx::PointF& root_location_f() const {
260 return root_location_;
263 // Transform the locations using |inverted_root_transform|.
264 // This is applied to both |location_| and |root_location_|.
265 virtual void UpdateForRootTransform(
266 const gfx::Transform& inverted_root_transform);
268 template <class T> void ConvertLocationToTarget(T* source, T* target) {
269 if (!target || target == source)
271 // TODO(tdresser): Rewrite ConvertPointToTarget to use PointF. See
273 gfx::Point offset = gfx::ToFlooredPoint(location_);
274 T::ConvertPointToTarget(source, target, &offset);
275 gfx::Vector2d diff = gfx::ToFlooredPoint(location_) - offset;
276 location_= location_ - diff;
280 friend class LocatedEventTestApi;
281 explicit LocatedEvent(const base::NativeEvent& native_event);
283 // Create a new LocatedEvent which is identical to the provided model.
284 // If source / target windows are provided, the model location will be
285 // converted from |source| coordinate system to |target| coordinate system.
287 LocatedEvent(const LocatedEvent& model, T* source, T* target)
289 location_(model.location_),
290 root_location_(model.root_location_) {
291 ConvertLocationToTarget(source, target);
294 // Used for synthetic events in testing.
295 LocatedEvent(EventType type,
296 const gfx::PointF& location,
297 const gfx::PointF& root_location,
298 base::TimeDelta time_stamp,
301 gfx::PointF location_;
303 // |location_| multiplied by an optional transformation matrix for
304 // rotations, animations and skews.
305 gfx::PointF root_location_;
308 class EVENTS_EXPORT MouseEvent : public LocatedEvent {
310 explicit MouseEvent(const base::NativeEvent& native_event);
312 // Create a new MouseEvent based on the provided model.
313 // Uses the provided |type| and |flags| for the new event.
314 // If source / target windows are provided, the model location will be
315 // converted from |source| coordinate system to |target| coordinate system.
317 MouseEvent(const MouseEvent& model, T* source, T* target)
318 : LocatedEvent(model, source, target),
319 changed_button_flags_(model.changed_button_flags_) {
323 MouseEvent(const MouseEvent& model,
328 : LocatedEvent(model, source, target),
329 changed_button_flags_(model.changed_button_flags_) {
334 // Used for synthetic events in testing and by the gesture recognizer.
335 MouseEvent(EventType type,
336 const gfx::PointF& location,
337 const gfx::PointF& root_location,
339 int changed_button_flags);
341 // Conveniences to quickly test what button is down
342 bool IsOnlyLeftMouseButton() const {
343 return (flags() & EF_LEFT_MOUSE_BUTTON) &&
344 !(flags() & (EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON));
347 bool IsLeftMouseButton() const {
348 return (flags() & EF_LEFT_MOUSE_BUTTON) != 0;
351 bool IsOnlyMiddleMouseButton() const {
352 return (flags() & EF_MIDDLE_MOUSE_BUTTON) &&
353 !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON));
356 bool IsMiddleMouseButton() const {
357 return (flags() & EF_MIDDLE_MOUSE_BUTTON) != 0;
360 bool IsOnlyRightMouseButton() const {
361 return (flags() & EF_RIGHT_MOUSE_BUTTON) &&
362 !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON));
365 bool IsRightMouseButton() const {
366 return (flags() & EF_RIGHT_MOUSE_BUTTON) != 0;
369 bool IsAnyButton() const {
370 return (flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON |
371 EF_RIGHT_MOUSE_BUTTON)) != 0;
374 // Compares two mouse down events and returns true if the second one should
375 // be considered a repeat of the first.
376 static bool IsRepeatedClickEvent(
377 const MouseEvent& event1,
378 const MouseEvent& event2);
380 // Get the click count. Can be 1, 2 or 3 for mousedown messages, 0 otherwise.
381 int GetClickCount() const;
383 // Set the click count for a mousedown message. Can be 1, 2 or 3.
384 void SetClickCount(int click_count);
386 // Identifies the button that changed. During a press this corresponds to the
387 // button that was pressed and during a release this corresponds to the button
388 // that was released.
389 // NOTE: during a press and release flags() contains the complete set of
390 // flags. Use this to determine the button that was pressed or released.
391 int changed_button_flags() const { return changed_button_flags_; }
394 FRIEND_TEST_ALL_PREFIXES(EventTest, DoubleClickRequiresRelease);
395 FRIEND_TEST_ALL_PREFIXES(EventTest, SingleClickRightLeft);
397 // Returns the repeat count based on the previous mouse click, if it is
398 // recent enough and within a small enough distance.
399 static int GetRepeatCount(const MouseEvent& click_event);
401 // Resets the last_click_event_ for unit tests.
402 static void ResetLastClickForTest();
404 // See description above getter for details.
405 int changed_button_flags_;
407 static MouseEvent* last_click_event_;
409 // We can create a MouseEvent for a native event more than once. We set this
410 // to true when the next event either has a different timestamp or we see a
411 // release signalling that the press (click) event was completed.
412 static bool last_click_complete_;
417 class EVENTS_EXPORT MouseWheelEvent : public MouseEvent {
419 // See |offset| for details.
420 static const int kWheelDelta;
422 explicit MouseWheelEvent(const base::NativeEvent& native_event);
423 explicit MouseWheelEvent(const ScrollEvent& scroll_event);
424 MouseWheelEvent(const MouseEvent& mouse_event, int x_offset, int y_offset);
425 MouseWheelEvent(const MouseWheelEvent& mouse_wheel_event);
428 MouseWheelEvent(const MouseWheelEvent& model,
431 : MouseEvent(model, source, target, model.type(), model.flags()),
432 offset_(model.x_offset(), model.y_offset()) {
435 // The amount to scroll. This is in multiples of kWheelDelta.
436 // Note: x_offset() > 0/y_offset() > 0 means scroll left/up.
437 int x_offset() const { return offset_.x(); }
438 int y_offset() const { return offset_.y(); }
439 const gfx::Vector2d& offset() const { return offset_; }
441 // Overridden from LocatedEvent.
442 virtual void UpdateForRootTransform(
443 const gfx::Transform& inverted_root_transform) OVERRIDE;
446 gfx::Vector2d offset_;
449 class EVENTS_EXPORT TouchEvent : public LocatedEvent {
451 explicit TouchEvent(const base::NativeEvent& native_event);
453 // Create a new TouchEvent which is identical to the provided model.
454 // If source / target windows are provided, the model location will be
455 // converted from |source| coordinate system to |target| coordinate system.
457 TouchEvent(const TouchEvent& model, T* source, T* target)
458 : LocatedEvent(model, source, target),
459 touch_id_(model.touch_id_),
460 radius_x_(model.radius_x_),
461 radius_y_(model.radius_y_),
462 rotation_angle_(model.rotation_angle_),
463 force_(model.force_),
464 source_device_id_(model.source_device_id_) {
467 TouchEvent(EventType type,
468 const gfx::PointF& location,
470 base::TimeDelta time_stamp);
472 TouchEvent(EventType type,
473 const gfx::PointF& location,
476 base::TimeDelta timestamp,
482 virtual ~TouchEvent();
484 int touch_id() const { return touch_id_; }
485 float radius_x() const { return radius_x_; }
486 float radius_y() const { return radius_y_; }
487 float rotation_angle() const { return rotation_angle_; }
488 float force() const { return force_; }
489 int source_device_id() const { return source_device_id_; }
491 // Used for unit tests.
492 void set_radius_x(const float r) { radius_x_ = r; }
493 void set_radius_y(const float r) { radius_y_ = r; }
494 void set_source_device_id(int source_device_id) {
495 source_device_id_ = source_device_id;
498 // Overridden from LocatedEvent.
499 virtual void UpdateForRootTransform(
500 const gfx::Transform& inverted_root_transform) OVERRIDE;
503 void set_radius(float radius_x, float radius_y) {
504 radius_x_ = radius_x;
505 radius_y_ = radius_y;
508 void set_rotation_angle(float rotation_angle) {
509 rotation_angle_ = rotation_angle;
512 void set_force(float force) { force_ = force; }
515 // The identity (typically finger) of the touch starting at 0 and incrementing
516 // for each separable additional touch that the hardware can detect.
519 // Radius of the X (major) axis of the touch ellipse. 0.0 if unknown.
522 // Radius of the Y (minor) axis of the touch ellipse. 0.0 if unknown.
525 // Angle of the major axis away from the X axis. Default 0.0.
526 float rotation_angle_;
528 // Force (pressure) of the touch. Normalized to be [0, 1]. Default to be 0.0.
531 // The device id of the screen the event came from. Default to be -1.
532 int source_device_id_;
535 class EVENTS_EXPORT KeyEvent : public Event {
537 KeyEvent(const base::NativeEvent& native_event, bool is_char);
539 // Used for synthetic events.
540 KeyEvent(EventType type, KeyboardCode key_code, int flags, bool is_char);
542 // Used for synthetic events with code of DOM KeyboardEvent (e.g. 'KeyA')
543 // See also: ui/events/keycodes/dom4/keycode_converter_data.h
544 KeyEvent(EventType type, KeyboardCode key_code, const std::string& code,
545 int flags, bool is_char);
547 // This allows an I18N virtual keyboard to fabricate a keyboard event that
548 // does not have a corresponding KeyboardCode (example: U+00E1 Latin small
549 // letter A with acute, U+0410 Cyrillic capital letter A).
550 void set_character(uint16 character) { character_ = character; }
552 // Gets the character generated by this key event. It only supports Unicode
554 uint16 GetCharacter() const;
556 // Gets the platform key code. For XKB, this is the xksym value.
557 uint32 platform_keycode() const { return platform_keycode_; }
558 KeyboardCode key_code() const { return key_code_; }
559 bool is_char() const { return is_char_; }
561 // This is only intended to be used externally by classes that are modifying
562 // events in EventFilter::PreHandleKeyEvent(). set_character() should also be
564 void set_key_code(KeyboardCode key_code) { key_code_ = key_code; }
566 // Returns true for [Alt]+<num-pad digit> Unicode alt key codes used by Win.
567 // TODO(msw): Additional work may be needed for analogues on other platforms.
568 bool IsUnicodeKeyCode() const;
570 std::string code() const { return code_; }
572 // Normalizes flags_ to make it Windows/Mac compatible. Since the way
573 // of setting modifier mask on X is very different than Windows/Mac as shown
574 // in http://crbug.com/127142#c8, the normalization is necessary.
575 void NormalizeFlags();
577 // Returns true if the key event has already been processed by an input method
578 // and there is no need to pass the key event to the input method again.
579 bool IsTranslated() const;
580 // Marks this key event as translated or not translated.
581 void SetTranslated(bool translated);
584 // This allows a subclass TranslatedKeyEvent to be a non character event.
585 void set_is_char(bool is_char) { is_char_ = is_char; }
588 KeyboardCode key_code_;
590 // String of 'code' defined in DOM KeyboardEvent (e.g. 'KeyA', 'Space')
591 // http://www.w3.org/TR/uievents/#keyboard-key-codes.
593 // This value represents the physical position in the keyboard and can be
594 // converted from / to keyboard scan code like XKB.
597 // True if this is a translated character event (vs. a raw key down). Both
598 // share the same type: ET_KEY_PRESSED.
601 // The platform related keycode value. For XKB, it's keysym value.
602 // For now, this is used for CharacterComposer in ChromeOS.
603 uint32 platform_keycode_;
605 // String of 'key' defined in DOM KeyboardEvent (e.g. 'a', 'รข')
606 // http://www.w3.org/TR/uievents/#keyboard-key-codes.
608 // This value represents the text that the key event will insert to input
609 // field. For key with modifier key, it may have specifial text.
610 // e.g. CTRL+A has '\x01'.
613 static bool IsRepeated(const KeyEvent& event);
615 static KeyEvent* last_key_event_;
618 class EVENTS_EXPORT ScrollEvent : public MouseEvent {
620 explicit ScrollEvent(const base::NativeEvent& native_event);
622 ScrollEvent(const ScrollEvent& model,
625 : MouseEvent(model, source, target),
626 x_offset_(model.x_offset_),
627 y_offset_(model.y_offset_),
628 x_offset_ordinal_(model.x_offset_ordinal_),
629 y_offset_ordinal_(model.y_offset_ordinal_),
630 finger_count_(model.finger_count_){
634 ScrollEvent(EventType type,
635 const gfx::PointF& location,
636 base::TimeDelta time_stamp,
640 float x_offset_ordinal,
641 float y_offset_ordinal,
644 // Scale the scroll event's offset value.
645 // This is useful in the multi-monitor setup where it needs to be scaled
646 // to provide a consistent user experience.
647 void Scale(const float factor);
649 float x_offset() const { return x_offset_; }
650 float y_offset() const { return y_offset_; }
651 float x_offset_ordinal() const { return x_offset_ordinal_; }
652 float y_offset_ordinal() const { return y_offset_ordinal_; }
653 int finger_count() const { return finger_count_; }
656 // Potential accelerated offsets.
659 // Unaccelerated offsets.
660 float x_offset_ordinal_;
661 float y_offset_ordinal_;
662 // Number of fingers on the pad.
666 class EVENTS_EXPORT GestureEvent : public LocatedEvent {
668 GestureEvent(EventType type,
672 base::TimeDelta time_stamp,
673 const GestureEventDetails& details,
674 unsigned int touch_ids_bitfield);
676 // Create a new GestureEvent which is identical to the provided model.
677 // If source / target windows are provided, the model location will be
678 // converted from |source| coordinate system to |target| coordinate system.
679 template <typename T>
680 GestureEvent(const GestureEvent& model, T* source, T* target)
681 : LocatedEvent(model, source, target),
682 details_(model.details_),
683 touch_ids_bitfield_(model.touch_ids_bitfield_) {
686 virtual ~GestureEvent();
688 const GestureEventDetails& details() const { return details_; }
690 // Returns the lowest touch-id of any of the touches which make up this
691 // gesture. If there are no touches associated with this gesture, returns -1.
692 int GetLowestTouchId() const;
695 GestureEventDetails details_;
697 // The set of indices of ones in the binary representation of
698 // touch_ids_bitfield_ is the set of touch_ids associate with this gesture.
699 // This value is stored as a bitfield because the number of touch ids varies,
700 // but we currently don't need more than 32 touches at a time.
701 const unsigned int touch_ids_bitfield_;
706 #endif // UI_EVENTS_EVENT_H_