#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/event_types.h"
+#include "base/gtest_prod_util.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "ui/events/event_constants.h"
#include "ui/events/gesture_event_details.h"
class EVENTS_EXPORT Event {
public:
+ static scoped_ptr<Event> Clone(const Event& event);
+
virtual ~Event();
class DispatcherApi {
int flags() const { return flags_; }
// This is only intended to be used externally by classes that are modifying
- // events in EventFilter::PreHandleKeyEvent().
+ // events in an EventRewriter.
void set_flags(int flags) { flags_ = flags; }
EventTarget* target() const { return target_; }
const LatencyInfo* latency() const { return &latency_; }
void set_latency(const LatencyInfo& latency) { latency_ = latency; }
+ int source_device_id() const { return source_device_id_; }
+
// By default, events are "cancelable", this means any default processing that
// the containing abstraction layer may perform can be prevented by calling
// SetHandled(). SetHandled() or StopPropagation() must not be called for
bool IsCapsLockDown() const { return (flags_ & EF_CAPS_LOCK_DOWN) != 0; }
bool IsAltDown() const { return (flags_ & EF_ALT_DOWN) != 0; }
bool IsAltGrDown() const { return (flags_ & EF_ALTGR_DOWN) != 0; }
+ bool IsCommandDown() const { return (flags_ & EF_COMMAND_DOWN) != 0; }
+ bool IsRepeat() const { return (flags_ & EF_IS_REPEAT) != 0; }
bool IsKeyEvent() const {
return type_ == ET_KEY_PRESSED ||
return type_ == ET_TOUCH_RELEASED ||
type_ == ET_TOUCH_PRESSED ||
type_ == ET_TOUCH_MOVED ||
- type_ == ET_TOUCH_STATIONARY ||
type_ == ET_TOUCH_CANCELLED;
}
case ET_GESTURE_PINCH_UPDATE:
case ET_GESTURE_LONG_PRESS:
case ET_GESTURE_LONG_TAP:
- case ET_GESTURE_MULTIFINGER_SWIPE:
+ case ET_GESTURE_SWIPE:
case ET_GESTURE_SHOW_PRESS:
case ET_GESTURE_WIN8_EDGE_SWIPE:
// When adding a gesture event which is paired with an event which
return type_ == ET_MOUSEWHEEL;
}
+ bool IsLocatedEvent() const {
+ return IsMouseEvent() || IsScrollEvent() || IsTouchEvent() ||
+ IsGestureEvent();
+ }
+
+ // Convenience methods to cast |this| to a GestureEvent. IsGestureEvent()
+ // must be true as a precondition to calling these methods.
+ GestureEvent* AsGestureEvent();
+ const GestureEvent* AsGestureEvent() const;
+
// Returns true if the event has a valid |native_event_|.
bool HasNativeEvent() const;
private:
friend class EventTestApi;
- // Safely initializes the native event members of this class.
- void Init();
- void InitWithNativeEvent(const base::NativeEvent& native_event);
-
EventType type_;
std::string name_;
base::TimeDelta time_stamp_;
EventTarget* target_;
EventPhase phase_;
EventResult result_;
+
+ // The device id the event came from, or ED_UNKNOWN_DEVICE if the information
+ // is not available.
+ int source_device_id_;
};
class EVENTS_EXPORT CancelModeEvent : public Event {
// TODO(tdresser): Always return floating point location. See
// crbug.com/337824.
gfx::Point location() const { return gfx::ToFlooredPoint(location_); }
- gfx::PointF location_f() const { return location_; }
+ const gfx::PointF& location_f() const { return location_; }
void set_root_location(const gfx::PointF& root_location) {
root_location_ = root_location;
}
gfx::Point root_location() const {
return gfx::ToFlooredPoint(root_location_);
}
+ const gfx::PointF& root_location_f() const {
+ return root_location_;
+ }
// Transform the locations using |inverted_root_transform|.
// This is applied to both |location_| and |root_location_|.
// flags. Use this to determine the button that was pressed or released.
int changed_button_flags() const { return changed_button_flags_; }
+ // Updates the button that changed.
+ void set_changed_button_flags(int flags) { changed_button_flags_ = flags; }
+
private:
+ FRIEND_TEST_ALL_PREFIXES(EventTest, DoubleClickRequiresRelease);
+ FRIEND_TEST_ALL_PREFIXES(EventTest, SingleClickRightLeft);
+
// Returns the repeat count based on the previous mouse click, if it is
// recent enough and within a small enough distance.
static int GetRepeatCount(const MouseEvent& click_event);
+ // Resets the last_click_event_ for unit tests.
+ static void ResetLastClickForTest();
+
// See description above getter for details.
int changed_button_flags_;
static MouseEvent* last_click_event_;
+
+ // We can create a MouseEvent for a native event more than once. We set this
+ // to true when the next event either has a different timestamp or we see a
+ // release signalling that the press (click) event was completed.
+ static bool last_click_complete_;
};
class ScrollEvent;
template <class T>
MouseWheelEvent(const MouseWheelEvent& model,
T* source,
- T* target,
- EventType type,
- int flags)
- : MouseEvent(model, source, target, type, flags),
- offset_(model.x_offset(), model.y_offset()){
+ T* target)
+ : MouseEvent(model, source, target, model.type(), model.flags()),
+ offset_(model.x_offset(), model.y_offset()) {
}
+ // Used for synthetic events in testing and by the gesture recognizer.
+ MouseWheelEvent(const gfx::Vector2d& offset,
+ const gfx::PointF& location,
+ const gfx::PointF& root_location,
+ int flags,
+ int changed_button_flags);
+
// The amount to scroll. This is in multiples of kWheelDelta.
// Note: x_offset() > 0/y_offset() > 0 means scroll left/up.
int x_offset() const { return offset_.x(); }
radius_x_(model.radius_x_),
radius_y_(model.radius_y_),
rotation_angle_(model.rotation_angle_),
- force_(model.force_),
- source_device_id_(model.source_device_id_) {
+ force_(model.force_) {
}
TouchEvent(EventType type,
float radius_y() const { return radius_y_; }
float rotation_angle() const { return rotation_angle_; }
float force() const { return force_; }
- int source_device_id() const { return source_device_id_; }
-
- // Relocate the touch-point to a new |origin|.
- // This is useful when touch event is in X Root Window coordinates,
- // and it needs to be mapped into Aura Root Window coordinates.
- void Relocate(const gfx::Point& origin);
// Used for unit tests.
void set_radius_x(const float r) { radius_x_ = r; }
void set_radius_y(const float r) { radius_y_ = r; }
- void set_source_device_id(int source_device_id) {
- source_device_id_ = source_device_id;
- }
// Overridden from LocatedEvent.
virtual void UpdateForRootTransform(
// Force (pressure) of the touch. Normalized to be [0, 1]. Default to be 0.0.
float force_;
+};
- // The device id of the screen the event came from. Default to be -1.
- int source_device_id_;
+// An interface that individual platforms can use to store additional data on
+// KeyEvent.
+//
+// Currently only used in mojo.
+class EVENTS_EXPORT ExtendedKeyEventData {
+ public:
+ virtual ~ExtendedKeyEventData() {}
+
+ virtual ExtendedKeyEventData* Clone() const = 0;
};
+// A KeyEvent is really two distinct classes, melded together due to the
+// DOM legacy of Windows key events: a keystroke event (is_char_ == false),
+// or a character event (is_char_ == true).
+//
+// For a keystroke event,
+// -- is_char_ is false.
+// -- type() can be any one of ET_KEY_PRESSED, ET_KEY_RELEASED,
+// ET_TRANSLATED_KEY_PRESS, or ET_TRANSLATED_KEY_RELEASE.
+// -- character_ functions as a bypass or cache for GetCharacter().
+// -- key_code_ is a VKEY_ value associated with the key. For printable
+// characters, this may or may not be a mapped value, imitating MS Windows:
+// if the mapped key generates a character that has an associated VKEY_
+// code, then key_code_ is that code; if not, then key_code_ is the unmapped
+// VKEY_ code. For example, US, Greek, Cyrillic, Japanese, etc. all use
+// VKEY_Q for the key beside Tab, while French uses VKEY_A.
+// -- code_ is in one-to-one correspondence with a physical keyboard
+// location, and does not vary depending on key layout.
+//
+// For a character event,
+// -- is_char_ is true.
+// -- type() is ET_KEY_PRESSED.
+// -- character_ is a UTF-16 character value.
+// -- key_code_ is conflated with character_ by some code, because both
+// arrive in the wParam field of a Windows event.
+// -- code_ is the empty string.
+//
class EVENTS_EXPORT KeyEvent : public Event {
public:
- KeyEvent(const base::NativeEvent& native_event, bool is_char);
+ // Create a KeyEvent from a NativeEvent. For Windows this native event can
+ // be either a keystroke message (WM_KEYUP/WM_KEYDOWN) or a character message
+ // (WM_CHAR). Other systems have only keystroke events.
+ explicit KeyEvent(const base::NativeEvent& native_event);
- // Used for synthetic events.
- KeyEvent(EventType type, KeyboardCode key_code, int flags, bool is_char);
+ // Create a keystroke event.
+ KeyEvent(EventType type, KeyboardCode key_code, int flags);
+
+ // Create a character event.
+ KeyEvent(base::char16 character, KeyboardCode key_code, int flags);
// Used for synthetic events with code of DOM KeyboardEvent (e.g. 'KeyA')
// See also: ui/events/keycodes/dom4/keycode_converter_data.h
- KeyEvent(EventType type, KeyboardCode key_code, const std::string& code,
- int flags, bool is_char);
+ KeyEvent(EventType type,
+ KeyboardCode key_code,
+ const std::string& code,
+ int flags);
+
+ KeyEvent(const KeyEvent& rhs);
+
+ KeyEvent& operator=(const KeyEvent& rhs);
+
+ virtual ~KeyEvent();
+
+ // TODO(erg): While we transition to mojo, we have to hack around a mismatch
+ // in our event types. Our ui::Events don't really have all the data we need
+ // to process key events, and we instead do per-platform conversions with
+ // native HWNDs or XEvents. And we can't reliably send those native data
+ // types across mojo types in a cross-platform way. So instead, we set the
+ // resulting data when read across IPC boundaries.
+ void SetExtendedKeyEventData(scoped_ptr<ExtendedKeyEventData> data);
+ const ExtendedKeyEventData* extended_key_event_data() const {
+ return extended_key_event_data_.get();
+ }
- // This allows an I18N virtual keyboard to fabricate a keyboard event that
+ // This bypasses the normal mapping from keystroke events to characters,
+ // which allows an I18N virtual keyboard to fabricate a keyboard event that
// does not have a corresponding KeyboardCode (example: U+00E1 Latin small
// letter A with acute, U+0410 Cyrillic capital letter A).
- void set_character(uint16 character) { character_ = character; }
+ void set_character(base::char16 character) { character_ = character; }
// Gets the character generated by this key event. It only supports Unicode
// BMP characters.
- uint16 GetCharacter() const;
-
+ base::char16 GetCharacter() const;
+
+ // If this is a keystroke event with key_code_ VKEY_RETURN, returns '\r';
+ // otherwise returns the same as GetCharacter().
+ base::char16 GetUnmodifiedText() const;
+
+ // If the Control key is down in the event, returns a layout-independent
+ // character (corresponding to US layout); otherwise returns the same
+ // as GetUnmodifiedText().
+ base::char16 GetText() const;
+
+ // Gets the platform key code. For XKB, this is the xksym value.
+ void set_platform_keycode(uint32 keycode) { platform_keycode_ = keycode; }
+ uint32 platform_keycode() const { return platform_keycode_; }
+
+ // Gets the associated (Windows-based) KeyboardCode for this key event.
+ // Historically, this has also been used to obtain the character associated
+ // with a character event, because both use the Window message 'wParam' field.
+ // This should be avoided; if necessary for backwards compatibility, use
+ // GetConflatedWindowsKeyCode().
KeyboardCode key_code() const { return key_code_; }
+
+ // True if this is a character event, false if this is a keystroke event.
bool is_char() const { return is_char_; }
// This is only intended to be used externally by classes that are modifying
- // events in EventFilter::PreHandleKeyEvent(). set_character() should also be
- // called.
+ // events in an EventRewriter.
void set_key_code(KeyboardCode key_code) { key_code_ = key_code; }
+ // Returns the same value as key_code(), except that located codes are
+ // returned in place of non-located ones (e.g. VKEY_LSHIFT or VKEY_RSHIFT
+ // instead of VKEY_SHIFT). This is a hybrid of semantic and physical
+ // for legacy DOM reasons.
+ KeyboardCode GetLocatedWindowsKeyboardCode() const;
+
+ // For a keystroke event, returns the same value as key_code().
+ // For a character event, returns the same value as GetCharacter().
+ // This exists for backwards compatibility with Windows key events.
+ uint16 GetConflatedWindowsKeyCode() const;
+
// Returns true for [Alt]+<num-pad digit> Unicode alt key codes used by Win.
// TODO(msw): Additional work may be needed for analogues on other platforms.
bool IsUnicodeKeyCode() const;
std::string code() const { return code_; }
- // Normalizes flags_ to make it Windows/Mac compatible. Since the way
- // of setting modifier mask on X is very different than Windows/Mac as shown
- // in http://crbug.com/127142#c8, the normalization is necessary.
+ // Normalizes flags_ so that it describes the state after the event.
+ // (Native X11 event flags describe the state before the event.)
void NormalizeFlags();
+ // Returns true if the key event has already been processed by an input method
+ // and there is no need to pass the key event to the input method again.
+ bool IsTranslated() const;
+ // Marks this key event as translated or not translated.
+ void SetTranslated(bool translated);
+
protected:
+ friend class KeyEventTestApi;
+
// This allows a subclass TranslatedKeyEvent to be a non character event.
void set_is_char(bool is_char) { is_char_ = is_char; }
private:
+ // True if the key press originated from a 'right' key (VKEY_RSHIFT, etc.).
+ bool IsRightSideKey() const;
+
KeyboardCode key_code_;
// String of 'code' defined in DOM KeyboardEvent (e.g. 'KeyA', 'Space')
// converted from / to keyboard scan code like XKB.
std::string code_;
- // True if this is a translated character event (vs. a raw key down). Both
- // share the same type: ET_KEY_PRESSED.
+ // True if this is a character event, false if this is a keystroke event.
bool is_char_;
- uint16 character_;
-};
-
-// A key event which is translated by an input method (IME).
-// For example, if an IME receives a KeyEvent(VKEY_SPACE), and it does not
-// consume the key, the IME usually generates and dispatches a
-// TranslatedKeyEvent(VKEY_SPACE) event. If the IME receives a KeyEvent and
-// it does consume the event, it might dispatch a
-// TranslatedKeyEvent(VKEY_PROCESSKEY) event as defined in the DOM spec.
-class EVENTS_EXPORT TranslatedKeyEvent : public KeyEvent {
- public:
- TranslatedKeyEvent(const base::NativeEvent& native_event, bool is_char);
+ // The platform related keycode value. For XKB, it's keysym value.
+ // For now, this is used for CharacterComposer in ChromeOS.
+ uint32 platform_keycode_;
- // Used for synthetic events such as a VKEY_PROCESSKEY key event.
- TranslatedKeyEvent(bool is_press, KeyboardCode key_code, int flags);
+ // String of 'key' defined in DOM KeyboardEvent (e.g. 'a', 'รข')
+ // http://www.w3.org/TR/uievents/#keyboard-key-codes.
+ //
+ // This value represents the text that the key event will insert to input
+ // field. For key with modifier key, it may have specifial text.
+ // e.g. CTRL+A has '\x01'.
+ mutable base::char16 character_;
- explicit TranslatedKeyEvent(const KeyEvent& key_event);
+ // Parts of our event handling require raw native events (see both the
+ // windows and linux implementations of web_input_event in content/). Because
+ // mojo instead serializes and deserializes events in potentially different
+ // processes, we need to have a mechanism to keep track of this data.
+ scoped_ptr<ExtendedKeyEventData> extended_key_event_data_;
- // Changes the type() of the object from ET_TRANSLATED_KEY_* to ET_KEY_* so
- // that RenderWidgetHostViewAura and NativeWidgetAura could handle the event.
- void ConvertToKeyEvent();
+ static bool IsRepeated(const KeyEvent& event);
- private:
- DISALLOW_COPY_AND_ASSIGN(TranslatedKeyEvent);
+ static KeyEvent* last_key_event_;
};
class EVENTS_EXPORT ScrollEvent : public MouseEvent {
class EVENTS_EXPORT GestureEvent : public LocatedEvent {
public:
- GestureEvent(EventType type,
- float x,
+ GestureEvent(float x,
float y,
int flags,
base::TimeDelta time_stamp,
- const GestureEventDetails& details,
- unsigned int touch_ids_bitfield);
+ const GestureEventDetails& details);
// Create a new GestureEvent which is identical to the provided model.
// If source / target windows are provided, the model location will be
template <typename T>
GestureEvent(const GestureEvent& model, T* source, T* target)
: LocatedEvent(model, source, target),
- details_(model.details_),
- touch_ids_bitfield_(model.touch_ids_bitfield_) {
+ details_(model.details_) {
}
virtual ~GestureEvent();
const GestureEventDetails& details() const { return details_; }
- // Returns the lowest touch-id of any of the touches which make up this
- // gesture. If there are no touches associated with this gesture, returns -1.
- int GetLowestTouchId() const;
-
private:
GestureEventDetails details_;
-
- // The set of indices of ones in the binary representation of
- // touch_ids_bitfield_ is the set of touch_ids associate with this gesture.
- // This value is stored as a bitfield because the number of touch ids varies,
- // but we currently don't need more than 32 touches at a time.
- const unsigned int touch_ids_bitfield_;
};
} // namespace ui