OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/events/event.h" | 5 #include "ui/events/event.h" |
6 | 6 |
7 #if defined(USE_X11) | 7 #if defined(USE_X11) |
8 #include <X11/extensions/XInput2.h> | 8 #include <X11/extensions/XInput2.h> |
| 9 #include <X11/keysym.h> |
9 #include <X11/Xlib.h> | 10 #include <X11/Xlib.h> |
10 #include <X11/keysym.h> | |
11 #endif | 11 #endif |
12 | 12 |
13 #include <cmath> | 13 #include <cmath> |
14 #include <cstring> | 14 #include <cstring> |
15 | 15 |
| 16 #include "base/metrics/histogram.h" |
16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
| 18 #include "ui/events/base_event_utils.h" |
17 #include "ui/events/event_utils.h" | 19 #include "ui/events/event_utils.h" |
| 20 #include "ui/events/keycodes/dom/dom_code.h" |
| 21 #include "ui/events/keycodes/dom/dom_key.h" |
| 22 #include "ui/events/keycodes/dom/keycode_converter.h" |
18 #include "ui/events/keycodes/keyboard_code_conversion.h" | 23 #include "ui/events/keycodes/keyboard_code_conversion.h" |
| 24 #include "ui/gfx/geometry/point3_f.h" |
| 25 #include "ui/gfx/geometry/point_conversions.h" |
19 #include "ui/gfx/geometry/safe_integer_conversions.h" | 26 #include "ui/gfx/geometry/safe_integer_conversions.h" |
20 #include "ui/gfx/point3_f.h" | |
21 #include "ui/gfx/point_conversions.h" | |
22 #include "ui/gfx/transform.h" | 27 #include "ui/gfx/transform.h" |
23 #include "ui/gfx/transform_util.h" | 28 #include "ui/gfx/transform_util.h" |
24 | 29 |
| 30 #if defined(USE_X11) |
| 31 #include "ui/events/keycodes/keyboard_code_conversion_x.h" |
| 32 #elif defined(USE_OZONE) |
| 33 #include "ui/events/ozone/layout/keyboard_layout_engine.h" |
| 34 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" |
| 35 #endif |
| 36 |
| 37 namespace { |
| 38 |
| 39 std::string EventTypeName(ui::EventType type) { |
| 40 #define RETURN_IF_TYPE(t) if (type == ui::t) return #t |
| 41 #define CASE_TYPE(t) case ui::t: return #t |
| 42 switch (type) { |
| 43 CASE_TYPE(ET_UNKNOWN); |
| 44 CASE_TYPE(ET_MOUSE_PRESSED); |
| 45 CASE_TYPE(ET_MOUSE_DRAGGED); |
| 46 CASE_TYPE(ET_MOUSE_RELEASED); |
| 47 CASE_TYPE(ET_MOUSE_MOVED); |
| 48 CASE_TYPE(ET_MOUSE_ENTERED); |
| 49 CASE_TYPE(ET_MOUSE_EXITED); |
| 50 CASE_TYPE(ET_KEY_PRESSED); |
| 51 CASE_TYPE(ET_KEY_RELEASED); |
| 52 CASE_TYPE(ET_MOUSEWHEEL); |
| 53 CASE_TYPE(ET_MOUSE_CAPTURE_CHANGED); |
| 54 CASE_TYPE(ET_TOUCH_RELEASED); |
| 55 CASE_TYPE(ET_TOUCH_PRESSED); |
| 56 CASE_TYPE(ET_TOUCH_MOVED); |
| 57 CASE_TYPE(ET_TOUCH_CANCELLED); |
| 58 CASE_TYPE(ET_DROP_TARGET_EVENT); |
| 59 CASE_TYPE(ET_GESTURE_SCROLL_BEGIN); |
| 60 CASE_TYPE(ET_GESTURE_SCROLL_END); |
| 61 CASE_TYPE(ET_GESTURE_SCROLL_UPDATE); |
| 62 CASE_TYPE(ET_GESTURE_SHOW_PRESS); |
| 63 CASE_TYPE(ET_GESTURE_WIN8_EDGE_SWIPE); |
| 64 CASE_TYPE(ET_GESTURE_TAP); |
| 65 CASE_TYPE(ET_GESTURE_TAP_DOWN); |
| 66 CASE_TYPE(ET_GESTURE_TAP_CANCEL); |
| 67 CASE_TYPE(ET_GESTURE_BEGIN); |
| 68 CASE_TYPE(ET_GESTURE_END); |
| 69 CASE_TYPE(ET_GESTURE_TWO_FINGER_TAP); |
| 70 CASE_TYPE(ET_GESTURE_PINCH_BEGIN); |
| 71 CASE_TYPE(ET_GESTURE_PINCH_END); |
| 72 CASE_TYPE(ET_GESTURE_PINCH_UPDATE); |
| 73 CASE_TYPE(ET_GESTURE_LONG_PRESS); |
| 74 CASE_TYPE(ET_GESTURE_LONG_TAP); |
| 75 CASE_TYPE(ET_GESTURE_SWIPE); |
| 76 CASE_TYPE(ET_GESTURE_TAP_UNCONFIRMED); |
| 77 CASE_TYPE(ET_GESTURE_DOUBLE_TAP); |
| 78 CASE_TYPE(ET_SCROLL); |
| 79 CASE_TYPE(ET_SCROLL_FLING_START); |
| 80 CASE_TYPE(ET_SCROLL_FLING_CANCEL); |
| 81 CASE_TYPE(ET_CANCEL_MODE); |
| 82 CASE_TYPE(ET_UMA_DATA); |
| 83 case ui::ET_LAST: NOTREACHED(); return std::string(); |
| 84 // Don't include default, so that we get an error when new type is added. |
| 85 } |
| 86 #undef CASE_TYPE |
| 87 |
| 88 NOTREACHED(); |
| 89 return std::string(); |
| 90 } |
| 91 |
| 92 bool IsX11SendEventTrue(const base::NativeEvent& event) { |
| 93 #if defined(USE_X11) |
| 94 return event && event->xany.send_event; |
| 95 #else |
| 96 return false; |
| 97 #endif |
| 98 } |
| 99 |
| 100 bool X11EventHasNonStandardState(const base::NativeEvent& event) { |
| 101 #if defined(USE_X11) |
| 102 const unsigned int kAllStateMask = |
| 103 Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask | |
| 104 Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask | |
| 105 LockMask | ControlMask | AnyModifier; |
| 106 return event && (event->xkey.state & ~kAllStateMask) != 0; |
| 107 #else |
| 108 return false; |
| 109 #endif |
| 110 } |
| 111 |
| 112 } // namespace |
| 113 |
25 namespace ui { | 114 namespace ui { |
26 | 115 |
27 //////////////////////////////////////////////////////////////////////////////// | 116 //////////////////////////////////////////////////////////////////////////////// |
28 // Event | 117 // Event |
29 | 118 |
30 // static | 119 // static |
31 scoped_ptr<Event> Event::Clone(const Event& event) { | 120 scoped_ptr<Event> Event::Clone(const Event& event) { |
32 if (event.IsKeyEvent()) { | 121 if (event.IsKeyEvent()) { |
33 return scoped_ptr<Event>(new KeyEvent(static_cast<const KeyEvent&>(event))); | 122 return make_scoped_ptr(new KeyEvent(static_cast<const KeyEvent&>(event))); |
34 } | 123 } |
35 | 124 |
36 if (event.IsMouseEvent()) { | 125 if (event.IsMouseEvent()) { |
37 if (event.IsMouseWheelEvent()) { | 126 if (event.IsMouseWheelEvent()) { |
38 return scoped_ptr<Event>( | 127 return make_scoped_ptr( |
39 new MouseWheelEvent(static_cast<const MouseWheelEvent&>(event))); | 128 new MouseWheelEvent(static_cast<const MouseWheelEvent&>(event))); |
40 } | 129 } |
41 | 130 |
42 return scoped_ptr<Event>( | 131 return make_scoped_ptr( |
43 new MouseEvent(static_cast<const MouseEvent&>(event))); | 132 new MouseEvent(static_cast<const MouseEvent&>(event))); |
44 } | 133 } |
45 | 134 |
46 if (event.IsTouchEvent()) { | 135 if (event.IsTouchEvent()) { |
47 return scoped_ptr<Event>( | 136 return make_scoped_ptr( |
48 new TouchEvent(static_cast<const TouchEvent&>(event))); | 137 new TouchEvent(static_cast<const TouchEvent&>(event))); |
49 } | 138 } |
50 | 139 |
51 if (event.IsGestureEvent()) { | 140 if (event.IsGestureEvent()) { |
52 return scoped_ptr<Event>( | 141 return make_scoped_ptr( |
53 new GestureEvent(static_cast<const GestureEvent&>(event))); | 142 new GestureEvent(static_cast<const GestureEvent&>(event))); |
54 } | 143 } |
55 | 144 |
56 if (event.IsScrollEvent()) { | 145 if (event.IsScrollEvent()) { |
57 return scoped_ptr<Event>( | 146 return make_scoped_ptr( |
58 new ScrollEvent(static_cast<const ScrollEvent&>(event))); | 147 new ScrollEvent(static_cast<const ScrollEvent&>(event))); |
59 } | 148 } |
60 | 149 |
61 return scoped_ptr<Event>(new Event(event)); | 150 return make_scoped_ptr(new Event(event)); |
62 } | 151 } |
63 | 152 |
64 Event::~Event() { | 153 Event::~Event() { |
| 154 if (delete_native_event_) |
| 155 ReleaseCopiedNativeEvent(native_event_); |
65 } | 156 } |
66 | 157 |
67 GestureEvent* Event::AsGestureEvent() { | 158 GestureEvent* Event::AsGestureEvent() { |
68 CHECK(IsGestureEvent()); | 159 CHECK(IsGestureEvent()); |
69 return static_cast<GestureEvent*>(this); | 160 return static_cast<GestureEvent*>(this); |
70 } | 161 } |
71 | 162 |
72 const GestureEvent* Event::AsGestureEvent() const { | 163 const GestureEvent* Event::AsGestureEvent() const { |
73 CHECK(IsGestureEvent()); | 164 CHECK(IsGestureEvent()); |
74 return static_cast<const GestureEvent*>(this); | 165 return static_cast<const GestureEvent*>(this); |
75 } | 166 } |
76 | 167 |
| 168 bool Event::HasNativeEvent() const { |
| 169 base::NativeEvent null_event; |
| 170 std::memset(&null_event, 0, sizeof(null_event)); |
| 171 return !!std::memcmp(&native_event_, &null_event, sizeof(null_event)); |
| 172 } |
| 173 |
77 void Event::StopPropagation() { | 174 void Event::StopPropagation() { |
78 // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch | 175 // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch |
79 // events. | 176 // events. |
80 // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH); | 177 // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH); |
81 CHECK(cancelable_); | 178 CHECK(cancelable_); |
82 result_ = static_cast<EventResult>(result_ | ER_CONSUMED); | 179 result_ = static_cast<EventResult>(result_ | ER_CONSUMED); |
83 } | 180 } |
84 | 181 |
85 void Event::SetHandled() { | 182 void Event::SetHandled() { |
86 // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch | 183 // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch |
87 // events. | 184 // events. |
88 // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH); | 185 // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH); |
89 CHECK(cancelable_); | 186 CHECK(cancelable_); |
90 result_ = static_cast<EventResult>(result_ | ER_HANDLED); | 187 result_ = static_cast<EventResult>(result_ | ER_HANDLED); |
91 } | 188 } |
92 | 189 |
93 Event::Event() | |
94 : type_(ET_UNKNOWN), | |
95 time_stamp_(base::TimeDelta()), | |
96 flags_(EF_NONE), | |
97 cancelable_(true), | |
98 target_(NULL), | |
99 phase_(EP_PREDISPATCH), | |
100 result_(ER_UNHANDLED), | |
101 source_device_id_(ED_UNKNOWN_DEVICE) { | |
102 } | |
103 | |
104 Event::Event(EventType type, base::TimeDelta time_stamp, int flags) | 190 Event::Event(EventType type, base::TimeDelta time_stamp, int flags) |
105 : type_(type), | 191 : type_(type), |
106 time_stamp_(time_stamp), | 192 time_stamp_(time_stamp), |
107 flags_(flags), | 193 flags_(flags), |
| 194 native_event_(base::NativeEvent()), |
| 195 delete_native_event_(false), |
108 cancelable_(true), | 196 cancelable_(true), |
109 target_(NULL), | 197 target_(NULL), |
110 phase_(EP_PREDISPATCH), | 198 phase_(EP_PREDISPATCH), |
111 result_(ER_UNHANDLED), | 199 result_(ER_UNHANDLED), |
112 source_device_id_(ED_UNKNOWN_DEVICE) { | 200 source_device_id_(ED_UNKNOWN_DEVICE) { |
| 201 if (type_ < ET_LAST) |
| 202 name_ = EventTypeName(type_); |
| 203 } |
| 204 |
| 205 Event::Event(const base::NativeEvent& native_event, |
| 206 EventType type, |
| 207 int flags) |
| 208 : type_(type), |
| 209 time_stamp_(EventTimeFromNative(native_event)), |
| 210 flags_(flags), |
| 211 native_event_(native_event), |
| 212 delete_native_event_(false), |
| 213 cancelable_(true), |
| 214 target_(NULL), |
| 215 phase_(EP_PREDISPATCH), |
| 216 result_(ER_UNHANDLED), |
| 217 source_device_id_(ED_UNKNOWN_DEVICE) { |
| 218 base::TimeDelta delta = EventTimeForNow() - time_stamp_; |
| 219 if (type_ < ET_LAST) |
| 220 name_ = EventTypeName(type_); |
| 221 base::HistogramBase::Sample delta_sample = |
| 222 static_cast<base::HistogramBase::Sample>(delta.InMicroseconds()); |
| 223 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser", delta_sample, 1, 1000000, |
| 224 100); |
| 225 std::string name_for_event = |
| 226 base::StringPrintf("Event.Latency.Browser.%s", name_.c_str()); |
| 227 base::HistogramBase* counter_for_type = |
| 228 base::Histogram::FactoryGet( |
| 229 name_for_event, |
| 230 1, |
| 231 1000000, |
| 232 100, |
| 233 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 234 counter_for_type->Add(delta_sample); |
| 235 |
| 236 #if defined(USE_X11) |
| 237 if (native_event->type == GenericEvent) { |
| 238 XIDeviceEvent* xiev = |
| 239 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 240 source_device_id_ = xiev->sourceid; |
| 241 } |
| 242 #endif |
| 243 #if defined(USE_OZONE) |
| 244 source_device_id_ = |
| 245 static_cast<const Event*>(native_event)->source_device_id(); |
| 246 #endif |
113 } | 247 } |
114 | 248 |
115 Event::Event(const Event& copy) | 249 Event::Event(const Event& copy) |
116 : type_(copy.type_), | 250 : type_(copy.type_), |
117 time_stamp_(copy.time_stamp_), | 251 time_stamp_(copy.time_stamp_), |
118 latency_(copy.latency_), | 252 latency_(copy.latency_), |
119 flags_(copy.flags_), | 253 flags_(copy.flags_), |
| 254 native_event_(CopyNativeEvent(copy.native_event_)), |
| 255 delete_native_event_(true), |
120 cancelable_(true), | 256 cancelable_(true), |
121 target_(NULL), | 257 target_(NULL), |
122 phase_(EP_PREDISPATCH), | 258 phase_(EP_PREDISPATCH), |
123 result_(ER_UNHANDLED), | 259 result_(ER_UNHANDLED), |
124 source_device_id_(copy.source_device_id_) { | 260 source_device_id_(copy.source_device_id_) { |
| 261 if (type_ < ET_LAST) |
| 262 name_ = EventTypeName(type_); |
125 } | 263 } |
126 | 264 |
127 void Event::SetType(EventType type) { | 265 void Event::SetType(EventType type) { |
| 266 if (type_ < ET_LAST) |
| 267 name_ = std::string(); |
128 type_ = type; | 268 type_ = type; |
| 269 if (type_ < ET_LAST) |
| 270 name_ = EventTypeName(type_); |
129 } | 271 } |
130 | 272 |
131 //////////////////////////////////////////////////////////////////////////////// | 273 //////////////////////////////////////////////////////////////////////////////// |
132 // CancelModeEvent | 274 // CancelModeEvent |
133 | 275 |
134 CancelModeEvent::CancelModeEvent() | 276 CancelModeEvent::CancelModeEvent() |
135 : Event(ET_CANCEL_MODE, base::TimeDelta(), 0) { | 277 : Event(ET_CANCEL_MODE, base::TimeDelta(), 0) { |
136 set_cancelable(false); | 278 set_cancelable(false); |
137 } | 279 } |
138 | 280 |
139 CancelModeEvent::~CancelModeEvent() { | 281 CancelModeEvent::~CancelModeEvent() { |
140 } | 282 } |
141 | 283 |
142 //////////////////////////////////////////////////////////////////////////////// | 284 //////////////////////////////////////////////////////////////////////////////// |
143 // LocatedEvent | 285 // LocatedEvent |
144 | 286 |
145 LocatedEvent::LocatedEvent() : Event() { | |
146 } | |
147 | |
148 LocatedEvent::~LocatedEvent() { | 287 LocatedEvent::~LocatedEvent() { |
149 } | 288 } |
150 | 289 |
| 290 LocatedEvent::LocatedEvent(const base::NativeEvent& native_event) |
| 291 : Event(native_event, |
| 292 EventTypeFromNative(native_event), |
| 293 EventFlagsFromNative(native_event)), |
| 294 location_(EventLocationFromNative(native_event)), |
| 295 root_location_(location_) { |
| 296 } |
| 297 |
151 LocatedEvent::LocatedEvent(EventType type, | 298 LocatedEvent::LocatedEvent(EventType type, |
152 const gfx::PointF& location, | 299 const gfx::PointF& location, |
153 const gfx::PointF& root_location, | 300 const gfx::PointF& root_location, |
154 base::TimeDelta time_stamp, | 301 base::TimeDelta time_stamp, |
155 int flags) | 302 int flags) |
156 : Event(type, time_stamp, flags), | 303 : Event(type, time_stamp, flags), |
157 location_(location), | 304 location_(location), |
158 root_location_(root_location) { | 305 root_location_(root_location) { |
159 } | 306 } |
160 | 307 |
161 void LocatedEvent::UpdateForRootTransform( | 308 void LocatedEvent::UpdateForRootTransform( |
162 const gfx::Transform& reversed_root_transform) { | 309 const gfx::Transform& reversed_root_transform) { |
163 // Transform has to be done at root level. | 310 // Transform has to be done at root level. |
164 gfx::Point3F p(location_); | 311 gfx::Point3F p(location_); |
165 reversed_root_transform.TransformPoint(&p); | 312 reversed_root_transform.TransformPoint(&p); |
166 location_ = p.AsPointF(); | 313 location_ = p.AsPointF(); |
167 root_location_ = location_; | 314 root_location_ = location_; |
168 } | 315 } |
169 | 316 |
170 //////////////////////////////////////////////////////////////////////////////// | 317 //////////////////////////////////////////////////////////////////////////////// |
171 // MouseEvent | 318 // MouseEvent |
172 | 319 |
173 MouseEvent::MouseEvent() : LocatedEvent(), changed_button_flags_(0) { | 320 MouseEvent::MouseEvent(const base::NativeEvent& native_event) |
| 321 : LocatedEvent(native_event), |
| 322 changed_button_flags_( |
| 323 GetChangedMouseButtonFlagsFromNative(native_event)) { |
| 324 if (type() == ET_MOUSE_PRESSED || type() == ET_MOUSE_RELEASED) |
| 325 SetClickCount(GetRepeatCount(*this)); |
174 } | 326 } |
175 | 327 |
176 MouseEvent::MouseEvent(EventType type, | 328 MouseEvent::MouseEvent(EventType type, |
177 const gfx::PointF& location, | 329 const gfx::PointF& location, |
178 const gfx::PointF& root_location, | 330 const gfx::PointF& root_location, |
| 331 base::TimeDelta time_stamp, |
179 int flags, | 332 int flags, |
180 int changed_button_flags) | 333 int changed_button_flags) |
181 : LocatedEvent(type, location, root_location, EventTimeForNow(), flags), | 334 : LocatedEvent(type, location, root_location, time_stamp, flags), |
182 changed_button_flags_(changed_button_flags) { | 335 changed_button_flags_(changed_button_flags) { |
183 if (this->type() == ET_MOUSE_MOVED && IsAnyButton()) | 336 if (this->type() == ET_MOUSE_MOVED && IsAnyButton()) |
184 SetType(ET_MOUSE_DRAGGED); | 337 SetType(ET_MOUSE_DRAGGED); |
185 } | 338 } |
186 | 339 |
187 // static | 340 // static |
188 bool MouseEvent::IsRepeatedClickEvent( | 341 bool MouseEvent::IsRepeatedClickEvent( |
189 const MouseEvent& event1, | 342 const MouseEvent& event1, |
190 const MouseEvent& event2) { | 343 const MouseEvent& event2) { |
191 // These values match the Windows defaults. | 344 // These values match the Windows defaults. |
192 static const int kDoubleClickTimeMS = 500; | 345 static const int kDoubleClickTimeMS = 500; |
193 static const int kDoubleClickWidth = 4; | 346 static const int kDoubleClickWidth = 4; |
194 static const int kDoubleClickHeight = 4; | 347 static const int kDoubleClickHeight = 4; |
195 | 348 |
196 if (event1.type() != ET_MOUSE_PRESSED || | 349 if (event1.type() != ET_MOUSE_PRESSED || |
197 event2.type() != ET_MOUSE_PRESSED) | 350 event2.type() != ET_MOUSE_PRESSED) |
198 return false; | 351 return false; |
199 | 352 |
200 // Compare flags, but ignore EF_IS_DOUBLE_CLICK to allow triple clicks. | 353 // Compare flags, but ignore EF_IS_DOUBLE_CLICK to allow triple clicks. |
201 if ((event1.flags() & ~EF_IS_DOUBLE_CLICK) != | 354 if ((event1.flags() & ~EF_IS_DOUBLE_CLICK) != |
202 (event2.flags() & ~EF_IS_DOUBLE_CLICK)) | 355 (event2.flags() & ~EF_IS_DOUBLE_CLICK)) |
203 return false; | 356 return false; |
204 | 357 |
| 358 // The new event has been created from the same native event. |
| 359 if (event1.time_stamp() == event2.time_stamp()) |
| 360 return false; |
| 361 |
205 base::TimeDelta time_difference = event2.time_stamp() - event1.time_stamp(); | 362 base::TimeDelta time_difference = event2.time_stamp() - event1.time_stamp(); |
206 | 363 |
207 if (time_difference.InMilliseconds() > kDoubleClickTimeMS) | 364 if (time_difference.InMilliseconds() > kDoubleClickTimeMS) |
208 return false; | 365 return false; |
209 | 366 |
210 if (std::abs(event2.x() - event1.x()) > kDoubleClickWidth / 2) | 367 if (std::abs(event2.x() - event1.x()) > kDoubleClickWidth / 2) |
211 return false; | 368 return false; |
212 | 369 |
213 if (std::abs(event2.y() - event1.y()) > kDoubleClickHeight / 2) | 370 if (std::abs(event2.y() - event1.y()) > kDoubleClickHeight / 2) |
214 return false; | 371 return false; |
215 | 372 |
216 return true; | 373 return true; |
217 } | 374 } |
218 | 375 |
| 376 // static |
| 377 int MouseEvent::GetRepeatCount(const MouseEvent& event) { |
| 378 int click_count = 1; |
| 379 if (last_click_event_) { |
| 380 if (event.type() == ui::ET_MOUSE_RELEASED) { |
| 381 if (event.changed_button_flags() == |
| 382 last_click_event_->changed_button_flags()) { |
| 383 last_click_complete_ = true; |
| 384 return last_click_event_->GetClickCount(); |
| 385 } else { |
| 386 // If last_click_event_ has changed since this button was pressed |
| 387 // return a click count of 1. |
| 388 return click_count; |
| 389 } |
| 390 } |
| 391 if (event.time_stamp() != last_click_event_->time_stamp()) |
| 392 last_click_complete_ = true; |
| 393 if (!last_click_complete_ || |
| 394 IsX11SendEventTrue(event.native_event())) { |
| 395 click_count = last_click_event_->GetClickCount(); |
| 396 } else if (IsRepeatedClickEvent(*last_click_event_, event)) { |
| 397 click_count = last_click_event_->GetClickCount() + 1; |
| 398 } |
| 399 delete last_click_event_; |
| 400 } |
| 401 last_click_event_ = new MouseEvent(event); |
| 402 last_click_complete_ = false; |
| 403 if (click_count > 3) |
| 404 click_count = 3; |
| 405 last_click_event_->SetClickCount(click_count); |
| 406 return click_count; |
| 407 } |
| 408 |
| 409 void MouseEvent::ResetLastClickForTest() { |
| 410 if (last_click_event_) { |
| 411 delete last_click_event_; |
| 412 last_click_event_ = NULL; |
| 413 last_click_complete_ = false; |
| 414 } |
| 415 } |
| 416 |
| 417 // static |
| 418 MouseEvent* MouseEvent::last_click_event_ = NULL; |
| 419 bool MouseEvent::last_click_complete_ = false; |
| 420 |
219 int MouseEvent::GetClickCount() const { | 421 int MouseEvent::GetClickCount() const { |
220 if (type() != ET_MOUSE_PRESSED && type() != ET_MOUSE_RELEASED) | 422 if (type() != ET_MOUSE_PRESSED && type() != ET_MOUSE_RELEASED) |
221 return 0; | 423 return 0; |
222 | 424 |
223 if (flags() & EF_IS_TRIPLE_CLICK) | 425 if (flags() & EF_IS_TRIPLE_CLICK) |
224 return 3; | 426 return 3; |
225 else if (flags() & EF_IS_DOUBLE_CLICK) | 427 else if (flags() & EF_IS_DOUBLE_CLICK) |
226 return 2; | 428 return 2; |
227 else | 429 else |
228 return 1; | 430 return 1; |
(...skipping 20 matching lines...) Expand all Loading... |
249 f &= ~EF_IS_DOUBLE_CLICK; | 451 f &= ~EF_IS_DOUBLE_CLICK; |
250 f |= EF_IS_TRIPLE_CLICK; | 452 f |= EF_IS_TRIPLE_CLICK; |
251 break; | 453 break; |
252 } | 454 } |
253 set_flags(f); | 455 set_flags(f); |
254 } | 456 } |
255 | 457 |
256 //////////////////////////////////////////////////////////////////////////////// | 458 //////////////////////////////////////////////////////////////////////////////// |
257 // MouseWheelEvent | 459 // MouseWheelEvent |
258 | 460 |
259 MouseWheelEvent::MouseWheelEvent() : MouseEvent(), offset_() { | 461 MouseWheelEvent::MouseWheelEvent(const base::NativeEvent& native_event) |
| 462 : MouseEvent(native_event), |
| 463 offset_(GetMouseWheelOffset(native_event)) { |
260 } | 464 } |
261 | 465 |
262 MouseWheelEvent::MouseWheelEvent(const ScrollEvent& scroll_event) | 466 MouseWheelEvent::MouseWheelEvent(const ScrollEvent& scroll_event) |
263 : MouseEvent(scroll_event), | 467 : MouseEvent(scroll_event), |
264 offset_(gfx::ToRoundedInt(scroll_event.x_offset()), | 468 offset_(gfx::ToRoundedInt(scroll_event.x_offset()), |
265 gfx::ToRoundedInt(scroll_event.y_offset())) { | 469 gfx::ToRoundedInt(scroll_event.y_offset())) { |
266 SetType(ET_MOUSEWHEEL); | 470 SetType(ET_MOUSEWHEEL); |
267 } | 471 } |
268 | 472 |
269 MouseWheelEvent::MouseWheelEvent(const MouseEvent& mouse_event, | 473 MouseWheelEvent::MouseWheelEvent(const MouseEvent& mouse_event, |
270 int x_offset, | 474 int x_offset, |
271 int y_offset) | 475 int y_offset) |
272 : MouseEvent(mouse_event), offset_(x_offset, y_offset) { | 476 : MouseEvent(mouse_event), offset_(x_offset, y_offset) { |
273 DCHECK(type() == ET_MOUSEWHEEL); | 477 DCHECK(type() == ET_MOUSEWHEEL); |
274 } | 478 } |
275 | 479 |
276 MouseWheelEvent::MouseWheelEvent(const MouseWheelEvent& mouse_wheel_event) | 480 MouseWheelEvent::MouseWheelEvent(const MouseWheelEvent& mouse_wheel_event) |
277 : MouseEvent(mouse_wheel_event), | 481 : MouseEvent(mouse_wheel_event), |
278 offset_(mouse_wheel_event.offset()) { | 482 offset_(mouse_wheel_event.offset()) { |
279 DCHECK(type() == ET_MOUSEWHEEL); | 483 DCHECK(type() == ET_MOUSEWHEEL); |
280 } | 484 } |
281 | 485 |
282 MouseWheelEvent::MouseWheelEvent(const gfx::Vector2d& offset, | 486 MouseWheelEvent::MouseWheelEvent(const gfx::Vector2d& offset, |
283 const gfx::PointF& location, | 487 const gfx::PointF& location, |
284 const gfx::PointF& root_location, | 488 const gfx::PointF& root_location, |
| 489 base::TimeDelta time_stamp, |
285 int flags, | 490 int flags, |
286 int changed_button_flags) | 491 int changed_button_flags) |
287 : MouseEvent(ui::ET_MOUSEWHEEL, location, root_location, flags, | 492 : MouseEvent(ui::ET_MOUSEWHEEL, |
| 493 location, |
| 494 root_location, |
| 495 time_stamp, |
| 496 flags, |
288 changed_button_flags), | 497 changed_button_flags), |
289 offset_(offset) { | 498 offset_(offset) { |
290 } | 499 } |
291 | 500 |
| 501 #if defined(OS_WIN) |
| 502 // This value matches windows WHEEL_DELTA. |
| 503 // static |
| 504 const int MouseWheelEvent::kWheelDelta = 120; |
| 505 #else |
292 // This value matches GTK+ wheel scroll amount. | 506 // This value matches GTK+ wheel scroll amount. |
293 const int MouseWheelEvent::kWheelDelta = 53; | 507 const int MouseWheelEvent::kWheelDelta = 53; |
294 | 508 #endif |
295 void MouseWheelEvent::UpdateForRootTransform( | |
296 const gfx::Transform& inverted_root_transform) { | |
297 LocatedEvent::UpdateForRootTransform(inverted_root_transform); | |
298 gfx::DecomposedTransform decomp; | |
299 bool success = gfx::DecomposeTransform(&decomp, inverted_root_transform); | |
300 DCHECK(success); | |
301 if (decomp.scale[0]) { | |
302 offset_.set_x( | |
303 gfx::ToRoundedInt(SkMScalarToFloat(offset_.x() * decomp.scale[0]))); | |
304 } | |
305 if (decomp.scale[1]) { | |
306 offset_.set_y( | |
307 gfx::ToRoundedInt(SkMScalarToFloat(offset_.y() * decomp.scale[1]))); | |
308 } | |
309 } | |
310 | 509 |
311 //////////////////////////////////////////////////////////////////////////////// | 510 //////////////////////////////////////////////////////////////////////////////// |
312 // TouchEvent | 511 // TouchEvent |
313 | 512 |
314 TouchEvent::TouchEvent() | 513 TouchEvent::TouchEvent(const base::NativeEvent& native_event) |
315 : LocatedEvent(), | 514 : LocatedEvent(native_event), |
316 touch_id_(0), | 515 touch_id_(GetTouchId(native_event)), |
317 radius_x_(0), | 516 unique_event_id_(ui::GetNextTouchEventId()), |
318 radius_y_(0), | 517 radius_x_(GetTouchRadiusX(native_event)), |
319 rotation_angle_(0), | 518 radius_y_(GetTouchRadiusY(native_event)), |
320 force_(0) { | 519 rotation_angle_(GetTouchAngle(native_event)), |
| 520 force_(GetTouchForce(native_event)), |
| 521 may_cause_scrolling_(false), |
| 522 should_remove_native_touch_id_mapping_(false) { |
| 523 latency()->AddLatencyNumberWithTimestamp( |
| 524 INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, 0, |
| 525 base::TimeTicks::FromInternalValue(time_stamp().ToInternalValue()), 1); |
| 526 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); |
| 527 |
| 528 FixRotationAngle(); |
| 529 if (type() == ET_TOUCH_RELEASED || type() == ET_TOUCH_CANCELLED) |
| 530 should_remove_native_touch_id_mapping_ = true; |
321 } | 531 } |
322 | 532 |
323 TouchEvent::TouchEvent(EventType type, | 533 TouchEvent::TouchEvent(EventType type, |
324 const gfx::PointF& location, | 534 const gfx::PointF& location, |
325 int touch_id, | 535 int touch_id, |
326 base::TimeDelta time_stamp) | 536 base::TimeDelta time_stamp) |
327 : LocatedEvent(type, location, location, time_stamp, 0), | 537 : LocatedEvent(type, location, location, time_stamp, 0), |
328 touch_id_(touch_id), | 538 touch_id_(touch_id), |
| 539 unique_event_id_(ui::GetNextTouchEventId()), |
329 radius_x_(0.0f), | 540 radius_x_(0.0f), |
330 radius_y_(0.0f), | 541 radius_y_(0.0f), |
331 rotation_angle_(0.0f), | 542 rotation_angle_(0.0f), |
332 force_(0.0f) { | 543 force_(0.0f), |
| 544 may_cause_scrolling_(false), |
| 545 should_remove_native_touch_id_mapping_(false) { |
333 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); | 546 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); |
334 } | 547 } |
335 | 548 |
336 TouchEvent::TouchEvent(EventType type, | 549 TouchEvent::TouchEvent(EventType type, |
337 const gfx::PointF& location, | 550 const gfx::PointF& location, |
338 int flags, | 551 int flags, |
339 int touch_id, | 552 int touch_id, |
340 base::TimeDelta time_stamp, | 553 base::TimeDelta time_stamp, |
341 float radius_x, | 554 float radius_x, |
342 float radius_y, | 555 float radius_y, |
343 float angle, | 556 float angle, |
344 float force) | 557 float force) |
345 : LocatedEvent(type, location, location, time_stamp, flags), | 558 : LocatedEvent(type, location, location, time_stamp, flags), |
346 touch_id_(touch_id), | 559 touch_id_(touch_id), |
| 560 unique_event_id_(ui::GetNextTouchEventId()), |
347 radius_x_(radius_x), | 561 radius_x_(radius_x), |
348 radius_y_(radius_y), | 562 radius_y_(radius_y), |
349 rotation_angle_(angle), | 563 rotation_angle_(angle), |
350 force_(force) { | 564 force_(force), |
| 565 may_cause_scrolling_(false), |
| 566 should_remove_native_touch_id_mapping_(false) { |
351 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); | 567 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); |
| 568 FixRotationAngle(); |
| 569 } |
| 570 |
| 571 TouchEvent::TouchEvent(const TouchEvent& copy) |
| 572 : LocatedEvent(copy), |
| 573 touch_id_(copy.touch_id_), |
| 574 unique_event_id_(copy.unique_event_id_), |
| 575 radius_x_(copy.radius_x_), |
| 576 radius_y_(copy.radius_y_), |
| 577 rotation_angle_(copy.rotation_angle_), |
| 578 force_(copy.force_), |
| 579 may_cause_scrolling_(copy.may_cause_scrolling_), |
| 580 should_remove_native_touch_id_mapping_(false) { |
| 581 // Copied events should not remove touch id mapping, as this either causes the |
| 582 // mapping to be lost before the initial event has finished dispatching, or |
| 583 // the copy to attempt to remove the mapping from a null |native_event_|. |
352 } | 584 } |
353 | 585 |
354 TouchEvent::~TouchEvent() { | 586 TouchEvent::~TouchEvent() { |
| 587 // In ctor TouchEvent(native_event) we call GetTouchId() which in X11 |
| 588 // platform setups the tracking_id to slot mapping. So in dtor here, |
| 589 // if this touch event is a release event, we clear the mapping accordingly. |
| 590 if (should_remove_native_touch_id_mapping_) { |
| 591 DCHECK(type() == ET_TOUCH_RELEASED || type() == ET_TOUCH_CANCELLED); |
| 592 if (type() == ET_TOUCH_RELEASED || type() == ET_TOUCH_CANCELLED) |
| 593 ClearTouchIdIfReleased(native_event()); |
| 594 } |
355 } | 595 } |
356 | 596 |
357 void TouchEvent::UpdateForRootTransform( | 597 void TouchEvent::UpdateForRootTransform( |
358 const gfx::Transform& inverted_root_transform) { | 598 const gfx::Transform& inverted_root_transform) { |
359 LocatedEvent::UpdateForRootTransform(inverted_root_transform); | 599 LocatedEvent::UpdateForRootTransform(inverted_root_transform); |
360 gfx::DecomposedTransform decomp; | 600 gfx::DecomposedTransform decomp; |
361 bool success = gfx::DecomposeTransform(&decomp, inverted_root_transform); | 601 bool success = gfx::DecomposeTransform(&decomp, inverted_root_transform); |
362 DCHECK(success); | 602 DCHECK(success); |
363 if (decomp.scale[0]) | 603 if (decomp.scale[0]) |
364 radius_x_ *= decomp.scale[0]; | 604 radius_x_ *= decomp.scale[0]; |
365 if (decomp.scale[1]) | 605 if (decomp.scale[1]) |
366 radius_y_ *= decomp.scale[1]; | 606 radius_y_ *= decomp.scale[1]; |
367 } | 607 } |
368 | 608 |
| 609 void TouchEvent::DisableSynchronousHandling() { |
| 610 DispatcherApi dispatcher_api(this); |
| 611 dispatcher_api.set_result( |
| 612 static_cast<EventResult>(result() | ER_DISABLE_SYNC_HANDLING)); |
| 613 } |
| 614 |
| 615 void TouchEvent::FixRotationAngle() { |
| 616 while (rotation_angle_ < 0) |
| 617 rotation_angle_ += 180; |
| 618 while (rotation_angle_ >= 180) |
| 619 rotation_angle_ -= 180; |
| 620 } |
| 621 |
369 //////////////////////////////////////////////////////////////////////////////// | 622 //////////////////////////////////////////////////////////////////////////////// |
370 // KeyEvent | 623 // KeyEvent |
371 | 624 |
372 KeyEvent::KeyEvent() | 625 // static |
373 : Event(), | 626 KeyEvent* KeyEvent::last_key_event_ = NULL; |
374 key_code_(VKEY_UNKNOWN), | 627 |
375 code_(), | 628 // static |
376 is_char_(false), | 629 bool KeyEvent::IsRepeated(const KeyEvent& event) { |
377 platform_keycode_(0), | 630 // A safe guard in case if there were continous key pressed events that are |
| 631 // not auto repeat. |
| 632 const int kMaxAutoRepeatTimeMs = 2000; |
| 633 // Ignore key events that have non standard state masks as it may be |
| 634 // reposted by an IME. IBUS-GTK uses this field to detect the |
| 635 // re-posted event for example. crbug.com/385873. |
| 636 if (X11EventHasNonStandardState(event.native_event())) |
| 637 return false; |
| 638 if (event.is_char()) |
| 639 return false; |
| 640 if (event.type() == ui::ET_KEY_RELEASED) { |
| 641 delete last_key_event_; |
| 642 last_key_event_ = NULL; |
| 643 return false; |
| 644 } |
| 645 CHECK_EQ(ui::ET_KEY_PRESSED, event.type()); |
| 646 if (!last_key_event_) { |
| 647 last_key_event_ = new KeyEvent(event); |
| 648 return false; |
| 649 } else if (event.time_stamp() == last_key_event_->time_stamp()) { |
| 650 // The KeyEvent is created from the same native event. |
| 651 return (last_key_event_->flags() & ui::EF_IS_REPEAT) != 0; |
| 652 } |
| 653 if (event.key_code() == last_key_event_->key_code() && |
| 654 event.flags() == (last_key_event_->flags() & ~ui::EF_IS_REPEAT) && |
| 655 (event.time_stamp() - last_key_event_->time_stamp()).InMilliseconds() < |
| 656 kMaxAutoRepeatTimeMs) { |
| 657 last_key_event_->set_time_stamp(event.time_stamp()); |
| 658 last_key_event_->set_flags(last_key_event_->flags() | ui::EF_IS_REPEAT); |
| 659 return true; |
| 660 } |
| 661 delete last_key_event_; |
| 662 last_key_event_ = new KeyEvent(event); |
| 663 return false; |
| 664 } |
| 665 |
| 666 KeyEvent::KeyEvent(const base::NativeEvent& native_event) |
| 667 : Event(native_event, |
| 668 EventTypeFromNative(native_event), |
| 669 EventFlagsFromNative(native_event)), |
| 670 key_code_(KeyboardCodeFromNative(native_event)), |
| 671 code_(CodeFromNative(native_event)), |
| 672 is_char_(IsCharFromNative(native_event)), |
| 673 platform_keycode_(PlatformKeycodeFromNative(native_event)), |
| 674 key_(DomKey::NONE), |
378 character_(0) { | 675 character_(0) { |
| 676 if (IsRepeated(*this)) |
| 677 set_flags(flags() | ui::EF_IS_REPEAT); |
| 678 |
| 679 #if defined(USE_X11) |
| 680 NormalizeFlags(); |
| 681 #endif |
| 682 #if defined(OS_WIN) |
| 683 // Only Windows has native character events. |
| 684 if (is_char_) |
| 685 character_ = native_event.wParam; |
| 686 #endif |
379 } | 687 } |
380 | 688 |
381 KeyEvent::KeyEvent(EventType type, | 689 KeyEvent::KeyEvent(EventType type, |
382 KeyboardCode key_code, | 690 KeyboardCode key_code, |
383 int flags) | 691 int flags) |
384 : Event(type, EventTimeForNow(), flags), | 692 : Event(type, EventTimeForNow(), flags), |
385 key_code_(key_code), | 693 key_code_(key_code), |
| 694 code_(UsLayoutKeyboardCodeToDomCode(key_code)), |
386 is_char_(false), | 695 is_char_(false), |
387 platform_keycode_(0), | 696 platform_keycode_(0), |
| 697 key_(DomKey::NONE), |
388 character_() { | 698 character_() { |
389 } | 699 } |
390 | 700 |
391 KeyEvent::KeyEvent(EventType type, | 701 KeyEvent::KeyEvent(EventType type, |
392 KeyboardCode key_code, | 702 KeyboardCode key_code, |
393 const std::string& code, | 703 DomCode code, |
394 int flags) | 704 int flags) |
395 : Event(type, EventTimeForNow(), flags), | 705 : Event(type, EventTimeForNow(), flags), |
396 key_code_(key_code), | 706 key_code_(key_code), |
397 code_(code), | 707 code_(code), |
398 is_char_(false), | 708 is_char_(false), |
399 platform_keycode_(0), | 709 platform_keycode_(0), |
| 710 key_(DomKey::NONE), |
400 character_(0) { | 711 character_(0) { |
401 } | 712 } |
402 | 713 |
| 714 KeyEvent::KeyEvent(EventType type, |
| 715 KeyboardCode key_code, |
| 716 DomCode code, |
| 717 int flags, |
| 718 DomKey key, |
| 719 base::char16 character, |
| 720 base::TimeDelta time_stamp) |
| 721 : Event(type, time_stamp, flags), |
| 722 key_code_(key_code), |
| 723 code_(code), |
| 724 is_char_(false), |
| 725 platform_keycode_(0), |
| 726 key_(key), |
| 727 character_(character) { |
| 728 } |
| 729 |
403 KeyEvent::KeyEvent(base::char16 character, KeyboardCode key_code, int flags) | 730 KeyEvent::KeyEvent(base::char16 character, KeyboardCode key_code, int flags) |
404 : Event(ET_KEY_PRESSED, EventTimeForNow(), flags), | 731 : Event(ET_KEY_PRESSED, EventTimeForNow(), flags), |
405 key_code_(key_code), | 732 key_code_(key_code), |
406 code_(""), | 733 code_(DomCode::NONE), |
407 is_char_(true), | 734 is_char_(true), |
408 platform_keycode_(0), | 735 platform_keycode_(0), |
| 736 key_(DomKey::CHARACTER), |
409 character_(character) { | 737 character_(character) { |
410 } | 738 } |
411 | 739 |
412 KeyEvent::KeyEvent(const KeyEvent& rhs) | 740 KeyEvent::KeyEvent(const KeyEvent& rhs) |
413 : Event(rhs), | 741 : Event(rhs), |
414 key_code_(rhs.key_code_), | 742 key_code_(rhs.key_code_), |
415 code_(rhs.code_), | 743 code_(rhs.code_), |
416 is_char_(rhs.is_char_), | 744 is_char_(rhs.is_char_), |
417 platform_keycode_(rhs.platform_keycode_), | 745 platform_keycode_(rhs.platform_keycode_), |
| 746 key_(rhs.key_), |
418 character_(rhs.character_) { | 747 character_(rhs.character_) { |
419 if (rhs.extended_key_event_data_) | 748 if (rhs.extended_key_event_data_) |
420 extended_key_event_data_.reset(rhs.extended_key_event_data_->Clone()); | 749 extended_key_event_data_.reset(rhs.extended_key_event_data_->Clone()); |
421 } | 750 } |
422 | 751 |
423 KeyEvent& KeyEvent::operator=(const KeyEvent& rhs) { | 752 KeyEvent& KeyEvent::operator=(const KeyEvent& rhs) { |
424 if (this != &rhs) { | 753 if (this != &rhs) { |
425 Event::operator=(rhs); | 754 Event::operator=(rhs); |
426 key_code_ = rhs.key_code_; | 755 key_code_ = rhs.key_code_; |
427 code_ = rhs.code_; | 756 code_ = rhs.code_; |
| 757 key_ = rhs.key_; |
428 is_char_ = rhs.is_char_; | 758 is_char_ = rhs.is_char_; |
429 platform_keycode_ = rhs.platform_keycode_; | 759 platform_keycode_ = rhs.platform_keycode_; |
430 character_ = rhs.character_; | 760 character_ = rhs.character_; |
431 | 761 |
432 if (rhs.extended_key_event_data_) | 762 if (rhs.extended_key_event_data_) |
433 extended_key_event_data_.reset(rhs.extended_key_event_data_->Clone()); | 763 extended_key_event_data_.reset(rhs.extended_key_event_data_->Clone()); |
434 } | 764 } |
435 return *this; | 765 return *this; |
436 } | 766 } |
437 | 767 |
438 KeyEvent::~KeyEvent() {} | 768 KeyEvent::~KeyEvent() {} |
439 | 769 |
440 void KeyEvent::SetExtendedKeyEventData(scoped_ptr<ExtendedKeyEventData> data) { | 770 void KeyEvent::SetExtendedKeyEventData(scoped_ptr<ExtendedKeyEventData> data) { |
441 extended_key_event_data_ = data.Pass(); | 771 extended_key_event_data_ = data.Pass(); |
442 } | 772 } |
443 | 773 |
| 774 void KeyEvent::ApplyLayout() const { |
| 775 // If the client has set the character (e.g. faked key events from virtual |
| 776 // keyboard), it's client's responsibility to set the dom key correctly. |
| 777 // Otherwise, set the dom key as unidentified. |
| 778 // Please refer to crbug.com/443889. |
| 779 if (character_ != 0) { |
| 780 key_ = DomKey::UNIDENTIFIED; |
| 781 return; |
| 782 } |
| 783 ui::DomCode code = code_; |
| 784 if (code == DomCode::NONE) { |
| 785 // Catch old code that tries to do layout without a physical key, and try |
| 786 // to recover using the KeyboardCode. Once key events are fully defined |
| 787 // on construction (see TODO in event.h) this will go away. |
| 788 LOG(WARNING) << "DomCode::NONE keycode=" << key_code_; |
| 789 code = UsLayoutKeyboardCodeToDomCode(key_code_); |
| 790 if (code == DomCode::NONE) { |
| 791 key_ = DomKey::UNIDENTIFIED; |
| 792 return; |
| 793 } |
| 794 } |
| 795 KeyboardCode dummy_key_code; |
| 796 #if defined(OS_WIN) |
| 797 // Native Windows character events always have is_char_ == true, |
| 798 // so this is a synthetic or native keystroke event. |
| 799 // Therefore, perform only the fallback action. |
| 800 #elif defined(USE_X11) |
| 801 // When a control key is held, prefer ASCII characters to non ASCII |
| 802 // characters in order to use it for shortcut keys. GetCharacterFromKeyCode |
| 803 // returns 'a' for VKEY_A even if the key is actually bound to 'Ã ' in X11. |
| 804 // GetCharacterFromXEvent returns 'Ã ' in that case. |
| 805 if (!IsControlDown() && native_event()) { |
| 806 GetMeaningFromXEvent(native_event(), &key_, &character_); |
| 807 return; |
| 808 } |
| 809 #elif defined(USE_OZONE) |
| 810 if (KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup( |
| 811 code, flags(), &key_, &character_, &dummy_key_code, |
| 812 &platform_keycode_)) { |
| 813 return; |
| 814 } |
| 815 #else |
| 816 if (native_event()) { |
| 817 DCHECK(EventTypeFromNative(native_event()) == ET_KEY_PRESSED || |
| 818 EventTypeFromNative(native_event()) == ET_KEY_RELEASED); |
| 819 } |
| 820 #endif |
| 821 if (!DomCodeToUsLayoutMeaning(code, flags(), &key_, &character_, |
| 822 &dummy_key_code)) { |
| 823 key_ = DomKey::UNIDENTIFIED; |
| 824 } |
| 825 } |
| 826 |
| 827 DomKey KeyEvent::GetDomKey() const { |
| 828 // Determination of character_ and key_ may be done lazily. |
| 829 if (key_ == DomKey::NONE) |
| 830 ApplyLayout(); |
| 831 return key_; |
| 832 } |
| 833 |
444 base::char16 KeyEvent::GetCharacter() const { | 834 base::char16 KeyEvent::GetCharacter() const { |
445 if (is_char_ || character_) | 835 // Determination of character_ and key_ may be done lazily. |
446 return character_; | 836 if (key_ == DomKey::NONE) |
447 | 837 ApplyLayout(); |
448 // TODO(kpschoedel): streamline these cases after settling Ozone | |
449 // positional coding. | |
450 #if defined(USE_X11) | |
451 character_ = GetCharacterFromKeyCode(key_code_, flags()); | |
452 return character_; | 838 return character_; |
453 #else | |
454 return GetCharacterFromKeyCode(key_code_, flags()); | |
455 #endif | |
456 } | 839 } |
457 | 840 |
458 base::char16 KeyEvent::GetText() const { | 841 base::char16 KeyEvent::GetText() const { |
459 if ((flags() & EF_CONTROL_DOWN) != 0) { | 842 if ((flags() & EF_CONTROL_DOWN) != 0) { |
460 return GetControlCharacterForKeycode(key_code_, | 843 base::char16 character; |
461 (flags() & EF_SHIFT_DOWN) != 0); | 844 ui::DomKey key; |
| 845 ui::KeyboardCode key_code; |
| 846 if (DomCodeToControlCharacter(code_, flags(), &key, &character, &key_code)) |
| 847 return character; |
462 } | 848 } |
463 return GetUnmodifiedText(); | 849 return GetUnmodifiedText(); |
464 } | 850 } |
465 | 851 |
466 base::char16 KeyEvent::GetUnmodifiedText() const { | 852 base::char16 KeyEvent::GetUnmodifiedText() const { |
467 if (!is_char_ && (key_code_ == VKEY_RETURN)) | 853 if (!is_char_ && (key_code_ == VKEY_RETURN)) |
468 return '\r'; | 854 return '\r'; |
469 return GetCharacter(); | 855 return GetCharacter(); |
470 } | 856 } |
471 | 857 |
472 bool KeyEvent::IsUnicodeKeyCode() const { | 858 bool KeyEvent::IsUnicodeKeyCode() const { |
| 859 #if defined(OS_WIN) |
| 860 if (!IsAltDown()) |
| 861 return false; |
| 862 const int key = key_code(); |
| 863 if (key >= VKEY_NUMPAD0 && key <= VKEY_NUMPAD9) |
| 864 return true; |
| 865 // Check whether the user is using the numeric keypad with num-lock off. |
| 866 // In that case, EF_EXTENDED will not be set; if it is set, the key event |
| 867 // originated from the relevant non-numpad dedicated key, e.g. [Insert]. |
| 868 return (!(flags() & EF_EXTENDED) && |
| 869 (key == VKEY_INSERT || key == VKEY_END || key == VKEY_DOWN || |
| 870 key == VKEY_NEXT || key == VKEY_LEFT || key == VKEY_CLEAR || |
| 871 key == VKEY_RIGHT || key == VKEY_HOME || key == VKEY_UP || |
| 872 key == VKEY_PRIOR)); |
| 873 #else |
473 return false; | 874 return false; |
| 875 #endif |
474 } | 876 } |
475 | 877 |
476 void KeyEvent::NormalizeFlags() { | 878 void KeyEvent::NormalizeFlags() { |
477 int mask = 0; | 879 int mask = 0; |
478 switch (key_code()) { | 880 switch (key_code()) { |
479 case VKEY_CONTROL: | 881 case VKEY_CONTROL: |
480 mask = EF_CONTROL_DOWN; | 882 mask = EF_CONTROL_DOWN; |
481 break; | 883 break; |
482 case VKEY_SHIFT: | 884 case VKEY_SHIFT: |
483 mask = EF_SHIFT_DOWN; | 885 mask = EF_SHIFT_DOWN; |
484 break; | 886 break; |
485 case VKEY_MENU: | 887 case VKEY_MENU: |
486 mask = EF_ALT_DOWN; | 888 mask = EF_ALT_DOWN; |
487 break; | 889 break; |
488 case VKEY_CAPITAL: | 890 case VKEY_CAPITAL: |
489 mask = EF_CAPS_LOCK_DOWN; | 891 mask = EF_CAPS_LOCK_DOWN; |
490 break; | 892 break; |
491 default: | 893 default: |
492 return; | 894 return; |
493 } | 895 } |
494 if (type() == ET_KEY_PRESSED) | 896 if (type() == ET_KEY_PRESSED) |
495 set_flags(flags() | mask); | 897 set_flags(flags() | mask); |
496 else | 898 else |
497 set_flags(flags() & ~mask); | 899 set_flags(flags() & ~mask); |
498 } | 900 } |
499 | 901 |
500 bool KeyEvent::IsTranslated() const { | |
501 switch (type()) { | |
502 case ET_KEY_PRESSED: | |
503 case ET_KEY_RELEASED: | |
504 return false; | |
505 case ET_TRANSLATED_KEY_PRESS: | |
506 case ET_TRANSLATED_KEY_RELEASE: | |
507 return true; | |
508 default: | |
509 NOTREACHED(); | |
510 return false; | |
511 } | |
512 } | |
513 | |
514 void KeyEvent::SetTranslated(bool translated) { | |
515 switch (type()) { | |
516 case ET_KEY_PRESSED: | |
517 case ET_TRANSLATED_KEY_PRESS: | |
518 SetType(translated ? ET_TRANSLATED_KEY_PRESS : ET_KEY_PRESSED); | |
519 break; | |
520 case ET_KEY_RELEASED: | |
521 case ET_TRANSLATED_KEY_RELEASE: | |
522 SetType(translated ? ET_TRANSLATED_KEY_RELEASE : ET_KEY_RELEASED); | |
523 break; | |
524 default: | |
525 NOTREACHED(); | |
526 } | |
527 } | |
528 | |
529 bool KeyEvent::IsRightSideKey() const { | |
530 switch (key_code_) { | |
531 case VKEY_CONTROL: | |
532 case VKEY_SHIFT: | |
533 case VKEY_MENU: | |
534 case VKEY_LWIN: | |
535 #if defined(USE_X11) | |
536 // Under X11, setting code_ requires platform-dependent information, and | |
537 // currently assumes that X keycodes are based on Linux evdev keycodes. | |
538 // In certain test environments this is not the case, and code_ is not | |
539 // set accurately, so we need a different mechanism. Fortunately X11 key | |
540 // mapping preserves the left-right distinction, so testing keysyms works | |
541 // if the value is available (as it is for all X11 native-based events). | |
542 if (platform_keycode_) { | |
543 return (platform_keycode_ == XK_Shift_R) || | |
544 (platform_keycode_ == XK_Control_R) || | |
545 (platform_keycode_ == XK_Alt_R) || | |
546 (platform_keycode_ == XK_Meta_R) || | |
547 (platform_keycode_ == XK_Super_R) || | |
548 (platform_keycode_ == XK_Hyper_R); | |
549 } | |
550 // Fall through to the generic code if we have no platform_keycode_. | |
551 // Under X11, this must be a synthetic event, so we can require that | |
552 // code_ be set correctly. | |
553 #endif | |
554 return ((code_.size() > 5) && | |
555 (code_.compare(code_.size() - 5, 5, "Right", 5)) == 0); | |
556 default: | |
557 return false; | |
558 } | |
559 } | |
560 | |
561 KeyboardCode KeyEvent::GetLocatedWindowsKeyboardCode() const { | 902 KeyboardCode KeyEvent::GetLocatedWindowsKeyboardCode() const { |
562 switch (key_code_) { | 903 return NonLocatedToLocatedKeyboardCode(key_code_, code_); |
563 case VKEY_SHIFT: | |
564 return IsRightSideKey() ? VKEY_RSHIFT : VKEY_LSHIFT; | |
565 case VKEY_CONTROL: | |
566 return IsRightSideKey() ? VKEY_RCONTROL : VKEY_LCONTROL; | |
567 case VKEY_MENU: | |
568 return IsRightSideKey() ? VKEY_RMENU : VKEY_LMENU; | |
569 case VKEY_LWIN: | |
570 return IsRightSideKey() ? VKEY_RWIN : VKEY_LWIN; | |
571 // TODO(kpschoedel): EF_NUMPAD_KEY is present only on X11. Currently this | |
572 // function is only called on X11. Likely the tests here will be replaced | |
573 // with a DOM-based code enumeration test in the course of Ozone | |
574 // platform-indpendent key event work. | |
575 case VKEY_0: | |
576 return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD0 : VKEY_0; | |
577 case VKEY_1: | |
578 return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD1 : VKEY_1; | |
579 case VKEY_2: | |
580 return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD2 : VKEY_2; | |
581 case VKEY_3: | |
582 return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD3 : VKEY_3; | |
583 case VKEY_4: | |
584 return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD4 : VKEY_4; | |
585 case VKEY_5: | |
586 return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD5 : VKEY_5; | |
587 case VKEY_6: | |
588 return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD6 : VKEY_6; | |
589 case VKEY_7: | |
590 return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD7 : VKEY_7; | |
591 case VKEY_8: | |
592 return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD8 : VKEY_8; | |
593 case VKEY_9: | |
594 return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD9 : VKEY_9; | |
595 default: | |
596 return key_code_; | |
597 } | |
598 } | 904 } |
599 | 905 |
600 uint16 KeyEvent::GetConflatedWindowsKeyCode() const { | 906 uint16 KeyEvent::GetConflatedWindowsKeyCode() const { |
601 if (is_char_) | 907 if (is_char_) |
602 return character_; | 908 return character_; |
603 return key_code_; | 909 return key_code_; |
604 } | 910 } |
605 | 911 |
| 912 std::string KeyEvent::GetCodeString() const { |
| 913 return KeycodeConverter::DomCodeToCodeString(code_); |
| 914 } |
| 915 |
606 //////////////////////////////////////////////////////////////////////////////// | 916 //////////////////////////////////////////////////////////////////////////////// |
607 // ScrollEvent | 917 // ScrollEvent |
608 | 918 |
609 ScrollEvent::ScrollEvent() : MouseEvent() { | 919 ScrollEvent::ScrollEvent(const base::NativeEvent& native_event) |
| 920 : MouseEvent(native_event) { |
| 921 if (type() == ET_SCROLL) { |
| 922 GetScrollOffsets(native_event, |
| 923 &x_offset_, &y_offset_, |
| 924 &x_offset_ordinal_, &y_offset_ordinal_, |
| 925 &finger_count_); |
| 926 } else if (type() == ET_SCROLL_FLING_START || |
| 927 type() == ET_SCROLL_FLING_CANCEL) { |
| 928 GetFlingData(native_event, |
| 929 &x_offset_, &y_offset_, |
| 930 &x_offset_ordinal_, &y_offset_ordinal_, |
| 931 NULL); |
| 932 } else { |
| 933 NOTREACHED() << "Unexpected event type " << type() |
| 934 << " when constructing a ScrollEvent."; |
| 935 } |
610 } | 936 } |
611 | 937 |
612 ScrollEvent::ScrollEvent(EventType type, | 938 ScrollEvent::ScrollEvent(EventType type, |
613 const gfx::PointF& location, | 939 const gfx::PointF& location, |
614 base::TimeDelta time_stamp, | 940 base::TimeDelta time_stamp, |
615 int flags, | 941 int flags, |
616 float x_offset, | 942 float x_offset, |
617 float y_offset, | 943 float y_offset, |
618 float x_offset_ordinal, | 944 float x_offset_ordinal, |
619 float y_offset_ordinal, | 945 float y_offset_ordinal, |
620 int finger_count) | 946 int finger_count) |
621 : MouseEvent(type, location, location, flags, 0), | 947 : MouseEvent(type, location, location, time_stamp, flags, 0), |
622 x_offset_(x_offset), | 948 x_offset_(x_offset), |
623 y_offset_(y_offset), | 949 y_offset_(y_offset), |
624 x_offset_ordinal_(x_offset_ordinal), | 950 x_offset_ordinal_(x_offset_ordinal), |
625 y_offset_ordinal_(y_offset_ordinal), | 951 y_offset_ordinal_(y_offset_ordinal), |
626 finger_count_(finger_count) { | 952 finger_count_(finger_count) { |
627 set_time_stamp(time_stamp); | |
628 CHECK(IsScrollEvent()); | 953 CHECK(IsScrollEvent()); |
629 } | 954 } |
630 | 955 |
631 void ScrollEvent::Scale(const float factor) { | 956 void ScrollEvent::Scale(const float factor) { |
632 x_offset_ *= factor; | 957 x_offset_ *= factor; |
633 y_offset_ *= factor; | 958 y_offset_ *= factor; |
634 x_offset_ordinal_ *= factor; | 959 x_offset_ordinal_ *= factor; |
635 y_offset_ordinal_ *= factor; | 960 y_offset_ordinal_ *= factor; |
636 } | 961 } |
637 | 962 |
(...skipping 10 matching lines...) Expand all Loading... |
648 gfx::PointF(x, y), | 973 gfx::PointF(x, y), |
649 time_stamp, | 974 time_stamp, |
650 flags | EF_FROM_TOUCH), | 975 flags | EF_FROM_TOUCH), |
651 details_(details) { | 976 details_(details) { |
652 } | 977 } |
653 | 978 |
654 GestureEvent::~GestureEvent() { | 979 GestureEvent::~GestureEvent() { |
655 } | 980 } |
656 | 981 |
657 } // namespace ui | 982 } // namespace ui |
OLD | NEW |