| 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/Xlib.h> | 9 #include <X11/Xlib.h> |
| 10 #include <X11/keysym.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" | |
| 17 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 18 #include "ui/events/event_utils.h" | 17 #include "ui/events/event_utils.h" |
| 19 #include "ui/events/keycodes/keyboard_code_conversion.h" | 18 #include "ui/events/keycodes/keyboard_code_conversion.h" |
| 20 #include "ui/gfx/geometry/safe_integer_conversions.h" | 19 #include "ui/gfx/geometry/safe_integer_conversions.h" |
| 21 #include "ui/gfx/point3_f.h" | 20 #include "ui/gfx/point3_f.h" |
| 22 #include "ui/gfx/point_conversions.h" | 21 #include "ui/gfx/point_conversions.h" |
| 23 #include "ui/gfx/transform.h" | 22 #include "ui/gfx/transform.h" |
| 24 #include "ui/gfx/transform_util.h" | 23 #include "ui/gfx/transform_util.h" |
| 25 | 24 |
| 26 #if defined(USE_X11) | 25 #if defined(USE_X11) |
| 27 #include "ui/events/keycodes/keyboard_code_conversion_x.h" | 26 #include "ui/events/keycodes/keyboard_code_conversion_x.h" |
| 28 #elif defined(USE_OZONE) | |
| 29 #include "ui/events/keycodes/keyboard_code_conversion.h" | |
| 30 #endif | 27 #endif |
| 31 | 28 |
| 32 namespace { | |
| 33 | |
| 34 std::string EventTypeName(ui::EventType type) { | |
| 35 #define RETURN_IF_TYPE(t) if (type == ui::t) return #t | |
| 36 #define CASE_TYPE(t) case ui::t: return #t | |
| 37 switch (type) { | |
| 38 CASE_TYPE(ET_UNKNOWN); | |
| 39 CASE_TYPE(ET_MOUSE_PRESSED); | |
| 40 CASE_TYPE(ET_MOUSE_DRAGGED); | |
| 41 CASE_TYPE(ET_MOUSE_RELEASED); | |
| 42 CASE_TYPE(ET_MOUSE_MOVED); | |
| 43 CASE_TYPE(ET_MOUSE_ENTERED); | |
| 44 CASE_TYPE(ET_MOUSE_EXITED); | |
| 45 CASE_TYPE(ET_KEY_PRESSED); | |
| 46 CASE_TYPE(ET_KEY_RELEASED); | |
| 47 CASE_TYPE(ET_MOUSEWHEEL); | |
| 48 CASE_TYPE(ET_MOUSE_CAPTURE_CHANGED); | |
| 49 CASE_TYPE(ET_TOUCH_RELEASED); | |
| 50 CASE_TYPE(ET_TOUCH_PRESSED); | |
| 51 CASE_TYPE(ET_TOUCH_MOVED); | |
| 52 CASE_TYPE(ET_TOUCH_CANCELLED); | |
| 53 CASE_TYPE(ET_DROP_TARGET_EVENT); | |
| 54 CASE_TYPE(ET_TRANSLATED_KEY_PRESS); | |
| 55 CASE_TYPE(ET_TRANSLATED_KEY_RELEASE); | |
| 56 CASE_TYPE(ET_GESTURE_SCROLL_BEGIN); | |
| 57 CASE_TYPE(ET_GESTURE_SCROLL_END); | |
| 58 CASE_TYPE(ET_GESTURE_SCROLL_UPDATE); | |
| 59 CASE_TYPE(ET_GESTURE_SHOW_PRESS); | |
| 60 CASE_TYPE(ET_GESTURE_WIN8_EDGE_SWIPE); | |
| 61 CASE_TYPE(ET_GESTURE_TAP); | |
| 62 CASE_TYPE(ET_GESTURE_TAP_DOWN); | |
| 63 CASE_TYPE(ET_GESTURE_TAP_CANCEL); | |
| 64 CASE_TYPE(ET_GESTURE_BEGIN); | |
| 65 CASE_TYPE(ET_GESTURE_END); | |
| 66 CASE_TYPE(ET_GESTURE_TWO_FINGER_TAP); | |
| 67 CASE_TYPE(ET_GESTURE_PINCH_BEGIN); | |
| 68 CASE_TYPE(ET_GESTURE_PINCH_END); | |
| 69 CASE_TYPE(ET_GESTURE_PINCH_UPDATE); | |
| 70 CASE_TYPE(ET_GESTURE_LONG_PRESS); | |
| 71 CASE_TYPE(ET_GESTURE_LONG_TAP); | |
| 72 CASE_TYPE(ET_GESTURE_SWIPE); | |
| 73 CASE_TYPE(ET_GESTURE_TAP_UNCONFIRMED); | |
| 74 CASE_TYPE(ET_GESTURE_DOUBLE_TAP); | |
| 75 CASE_TYPE(ET_SCROLL); | |
| 76 CASE_TYPE(ET_SCROLL_FLING_START); | |
| 77 CASE_TYPE(ET_SCROLL_FLING_CANCEL); | |
| 78 CASE_TYPE(ET_CANCEL_MODE); | |
| 79 CASE_TYPE(ET_UMA_DATA); | |
| 80 case ui::ET_LAST: NOTREACHED(); return std::string(); | |
| 81 // Don't include default, so that we get an error when new type is added. | |
| 82 } | |
| 83 #undef CASE_TYPE | |
| 84 | |
| 85 NOTREACHED(); | |
| 86 return std::string(); | |
| 87 } | |
| 88 | |
| 89 bool IsX11SendEventTrue(const base::NativeEvent& event) { | |
| 90 #if defined(USE_X11) | |
| 91 return event && event->xany.send_event; | |
| 92 #else | |
| 93 return false; | |
| 94 #endif | |
| 95 } | |
| 96 | |
| 97 bool X11EventHasNonStandardState(const base::NativeEvent& event) { | |
| 98 #if defined(USE_X11) | |
| 99 const unsigned int kAllStateMask = | |
| 100 Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask | | |
| 101 Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask | | |
| 102 LockMask | ControlMask | AnyModifier; | |
| 103 return event && (event->xkey.state & ~kAllStateMask) != 0; | |
| 104 #else | |
| 105 return false; | |
| 106 #endif | |
| 107 } | |
| 108 | |
| 109 } // namespace | |
| 110 | |
| 111 namespace ui { | 29 namespace ui { |
| 112 | 30 |
| 113 //////////////////////////////////////////////////////////////////////////////// | 31 //////////////////////////////////////////////////////////////////////////////// |
| 114 // Event | 32 // Event |
| 115 | 33 |
| 116 // static | 34 // static |
| 117 scoped_ptr<Event> Event::Clone(const Event& event) { | 35 scoped_ptr<Event> Event::Clone(const Event& event) { |
| 118 if (event.IsKeyEvent()) { | 36 if (event.IsKeyEvent()) { |
| 119 return scoped_ptr<Event>(new KeyEvent(static_cast<const KeyEvent&>(event))); | 37 return scoped_ptr<Event>(new KeyEvent(static_cast<const KeyEvent&>(event))); |
| 120 } | 38 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 141 | 59 |
| 142 if (event.IsScrollEvent()) { | 60 if (event.IsScrollEvent()) { |
| 143 return scoped_ptr<Event>( | 61 return scoped_ptr<Event>( |
| 144 new ScrollEvent(static_cast<const ScrollEvent&>(event))); | 62 new ScrollEvent(static_cast<const ScrollEvent&>(event))); |
| 145 } | 63 } |
| 146 | 64 |
| 147 return scoped_ptr<Event>(new Event(event)); | 65 return scoped_ptr<Event>(new Event(event)); |
| 148 } | 66 } |
| 149 | 67 |
| 150 Event::~Event() { | 68 Event::~Event() { |
| 151 if (delete_native_event_) | |
| 152 ReleaseCopiedNativeEvent(native_event_); | |
| 153 } | 69 } |
| 154 | 70 |
| 155 GestureEvent* Event::AsGestureEvent() { | 71 GestureEvent* Event::AsGestureEvent() { |
| 156 CHECK(IsGestureEvent()); | 72 CHECK(IsGestureEvent()); |
| 157 return static_cast<GestureEvent*>(this); | 73 return static_cast<GestureEvent*>(this); |
| 158 } | 74 } |
| 159 | 75 |
| 160 const GestureEvent* Event::AsGestureEvent() const { | 76 const GestureEvent* Event::AsGestureEvent() const { |
| 161 CHECK(IsGestureEvent()); | 77 CHECK(IsGestureEvent()); |
| 162 return static_cast<const GestureEvent*>(this); | 78 return static_cast<const GestureEvent*>(this); |
| 163 } | 79 } |
| 164 | 80 |
| 165 bool Event::HasNativeEvent() const { | |
| 166 base::NativeEvent null_event; | |
| 167 std::memset(&null_event, 0, sizeof(null_event)); | |
| 168 return !!std::memcmp(&native_event_, &null_event, sizeof(null_event)); | |
| 169 } | |
| 170 | |
| 171 void Event::StopPropagation() { | 81 void Event::StopPropagation() { |
| 172 // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch | 82 // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch |
| 173 // events. | 83 // events. |
| 174 // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH); | 84 // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH); |
| 175 CHECK(cancelable_); | 85 CHECK(cancelable_); |
| 176 result_ = static_cast<EventResult>(result_ | ER_CONSUMED); | 86 result_ = static_cast<EventResult>(result_ | ER_CONSUMED); |
| 177 } | 87 } |
| 178 | 88 |
| 179 void Event::SetHandled() { | 89 void Event::SetHandled() { |
| 180 // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch | 90 // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch |
| 181 // events. | 91 // events. |
| 182 // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH); | 92 // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH); |
| 183 CHECK(cancelable_); | 93 CHECK(cancelable_); |
| 184 result_ = static_cast<EventResult>(result_ | ER_HANDLED); | 94 result_ = static_cast<EventResult>(result_ | ER_HANDLED); |
| 185 } | 95 } |
| 186 | 96 |
| 97 Event::Event() |
| 98 : type_(ET_UNKNOWN), |
| 99 time_stamp_(base::TimeDelta()), |
| 100 flags_(EF_NONE), |
| 101 cancelable_(true), |
| 102 target_(NULL), |
| 103 phase_(EP_PREDISPATCH), |
| 104 result_(ER_UNHANDLED), |
| 105 source_device_id_(ED_UNKNOWN_DEVICE) { |
| 106 } |
| 107 |
| 187 Event::Event(EventType type, base::TimeDelta time_stamp, int flags) | 108 Event::Event(EventType type, base::TimeDelta time_stamp, int flags) |
| 188 : type_(type), | 109 : type_(type), |
| 189 time_stamp_(time_stamp), | 110 time_stamp_(time_stamp), |
| 190 flags_(flags), | 111 flags_(flags), |
| 191 native_event_(base::NativeEvent()), | |
| 192 delete_native_event_(false), | |
| 193 cancelable_(true), | 112 cancelable_(true), |
| 194 target_(NULL), | 113 target_(NULL), |
| 195 phase_(EP_PREDISPATCH), | 114 phase_(EP_PREDISPATCH), |
| 196 result_(ER_UNHANDLED), | 115 result_(ER_UNHANDLED), |
| 197 source_device_id_(ED_UNKNOWN_DEVICE) { | 116 source_device_id_(ED_UNKNOWN_DEVICE) { |
| 198 if (type_ < ET_LAST) | |
| 199 name_ = EventTypeName(type_); | |
| 200 } | |
| 201 | |
| 202 Event::Event(const base::NativeEvent& native_event, | |
| 203 EventType type, | |
| 204 int flags) | |
| 205 : type_(type), | |
| 206 time_stamp_(EventTimeFromNative(native_event)), | |
| 207 flags_(flags), | |
| 208 native_event_(native_event), | |
| 209 delete_native_event_(false), | |
| 210 cancelable_(true), | |
| 211 target_(NULL), | |
| 212 phase_(EP_PREDISPATCH), | |
| 213 result_(ER_UNHANDLED), | |
| 214 source_device_id_(ED_UNKNOWN_DEVICE) { | |
| 215 base::TimeDelta delta = EventTimeForNow() - time_stamp_; | |
| 216 if (type_ < ET_LAST) | |
| 217 name_ = EventTypeName(type_); | |
| 218 base::HistogramBase::Sample delta_sample = | |
| 219 static_cast<base::HistogramBase::Sample>(delta.InMicroseconds()); | |
| 220 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser", delta_sample, 1, 1000000, | |
| 221 100); | |
| 222 std::string name_for_event = | |
| 223 base::StringPrintf("Event.Latency.Browser.%s", name_.c_str()); | |
| 224 base::HistogramBase* counter_for_type = | |
| 225 base::Histogram::FactoryGet( | |
| 226 name_for_event, | |
| 227 1, | |
| 228 1000000, | |
| 229 100, | |
| 230 base::HistogramBase::kUmaTargetedHistogramFlag); | |
| 231 counter_for_type->Add(delta_sample); | |
| 232 | |
| 233 #if defined(USE_X11) | |
| 234 if (native_event->type == GenericEvent) { | |
| 235 XIDeviceEvent* xiev = | |
| 236 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | |
| 237 source_device_id_ = xiev->sourceid; | |
| 238 } | |
| 239 #endif | |
| 240 } | 117 } |
| 241 | 118 |
| 242 Event::Event(const Event& copy) | 119 Event::Event(const Event& copy) |
| 243 : type_(copy.type_), | 120 : type_(copy.type_), |
| 244 time_stamp_(copy.time_stamp_), | 121 time_stamp_(copy.time_stamp_), |
| 245 latency_(copy.latency_), | 122 latency_(copy.latency_), |
| 246 flags_(copy.flags_), | 123 flags_(copy.flags_), |
| 247 native_event_(CopyNativeEvent(copy.native_event_)), | |
| 248 delete_native_event_(true), | |
| 249 cancelable_(true), | 124 cancelable_(true), |
| 250 target_(NULL), | 125 target_(NULL), |
| 251 phase_(EP_PREDISPATCH), | 126 phase_(EP_PREDISPATCH), |
| 252 result_(ER_UNHANDLED), | 127 result_(ER_UNHANDLED), |
| 253 source_device_id_(copy.source_device_id_) { | 128 source_device_id_(copy.source_device_id_) { |
| 254 if (type_ < ET_LAST) | |
| 255 name_ = EventTypeName(type_); | |
| 256 } | 129 } |
| 257 | 130 |
| 258 void Event::SetType(EventType type) { | 131 void Event::SetType(EventType type) { |
| 259 if (type_ < ET_LAST) | |
| 260 name_ = std::string(); | |
| 261 type_ = type; | 132 type_ = type; |
| 262 if (type_ < ET_LAST) | |
| 263 name_ = EventTypeName(type_); | |
| 264 } | 133 } |
| 265 | 134 |
| 266 //////////////////////////////////////////////////////////////////////////////// | 135 //////////////////////////////////////////////////////////////////////////////// |
| 267 // CancelModeEvent | 136 // CancelModeEvent |
| 268 | 137 |
| 269 CancelModeEvent::CancelModeEvent() | 138 CancelModeEvent::CancelModeEvent() |
| 270 : Event(ET_CANCEL_MODE, base::TimeDelta(), 0) { | 139 : Event(ET_CANCEL_MODE, base::TimeDelta(), 0) { |
| 271 set_cancelable(false); | 140 set_cancelable(false); |
| 272 } | 141 } |
| 273 | 142 |
| 274 CancelModeEvent::~CancelModeEvent() { | 143 CancelModeEvent::~CancelModeEvent() { |
| 275 } | 144 } |
| 276 | 145 |
| 277 //////////////////////////////////////////////////////////////////////////////// | 146 //////////////////////////////////////////////////////////////////////////////// |
| 278 // LocatedEvent | 147 // LocatedEvent |
| 279 | 148 |
| 149 LocatedEvent::LocatedEvent() : Event() { |
| 150 } |
| 151 |
| 280 LocatedEvent::~LocatedEvent() { | 152 LocatedEvent::~LocatedEvent() { |
| 281 } | 153 } |
| 282 | 154 |
| 283 LocatedEvent::LocatedEvent(const base::NativeEvent& native_event) | |
| 284 : Event(native_event, | |
| 285 EventTypeFromNative(native_event), | |
| 286 EventFlagsFromNative(native_event)), | |
| 287 location_(EventLocationFromNative(native_event)), | |
| 288 root_location_(location_) { | |
| 289 } | |
| 290 | |
| 291 LocatedEvent::LocatedEvent(EventType type, | 155 LocatedEvent::LocatedEvent(EventType type, |
| 292 const gfx::PointF& location, | 156 const gfx::PointF& location, |
| 293 const gfx::PointF& root_location, | 157 const gfx::PointF& root_location, |
| 294 base::TimeDelta time_stamp, | 158 base::TimeDelta time_stamp, |
| 295 int flags) | 159 int flags) |
| 296 : Event(type, time_stamp, flags), | 160 : Event(type, time_stamp, flags), |
| 297 location_(location), | 161 location_(location), |
| 298 root_location_(root_location) { | 162 root_location_(root_location) { |
| 299 } | 163 } |
| 300 | 164 |
| 301 void LocatedEvent::UpdateForRootTransform( | 165 void LocatedEvent::UpdateForRootTransform( |
| 302 const gfx::Transform& reversed_root_transform) { | 166 const gfx::Transform& reversed_root_transform) { |
| 303 // Transform has to be done at root level. | 167 // Transform has to be done at root level. |
| 304 gfx::Point3F p(location_); | 168 gfx::Point3F p(location_); |
| 305 reversed_root_transform.TransformPoint(&p); | 169 reversed_root_transform.TransformPoint(&p); |
| 306 location_ = p.AsPointF(); | 170 location_ = p.AsPointF(); |
| 307 root_location_ = location_; | 171 root_location_ = location_; |
| 308 } | 172 } |
| 309 | 173 |
| 310 //////////////////////////////////////////////////////////////////////////////// | 174 //////////////////////////////////////////////////////////////////////////////// |
| 311 // MouseEvent | 175 // MouseEvent |
| 312 | 176 |
| 313 MouseEvent::MouseEvent(const base::NativeEvent& native_event) | 177 MouseEvent::MouseEvent() : LocatedEvent(), changed_button_flags_(0) { |
| 314 : LocatedEvent(native_event), | |
| 315 changed_button_flags_( | |
| 316 GetChangedMouseButtonFlagsFromNative(native_event)) { | |
| 317 if (type() == ET_MOUSE_PRESSED || type() == ET_MOUSE_RELEASED) | |
| 318 SetClickCount(GetRepeatCount(*this)); | |
| 319 } | 178 } |
| 320 | 179 |
| 321 MouseEvent::MouseEvent(EventType type, | 180 MouseEvent::MouseEvent(EventType type, |
| 322 const gfx::PointF& location, | 181 const gfx::PointF& location, |
| 323 const gfx::PointF& root_location, | 182 const gfx::PointF& root_location, |
| 324 int flags, | 183 int flags, |
| 325 int changed_button_flags) | 184 int changed_button_flags) |
| 326 : LocatedEvent(type, location, root_location, EventTimeForNow(), flags), | 185 : LocatedEvent(type, location, root_location, EventTimeForNow(), flags), |
| 327 changed_button_flags_(changed_button_flags) { | 186 changed_button_flags_(changed_button_flags) { |
| 328 if (this->type() == ET_MOUSE_MOVED && IsAnyButton()) | 187 if (this->type() == ET_MOUSE_MOVED && IsAnyButton()) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 354 | 213 |
| 355 if (std::abs(event2.x() - event1.x()) > kDoubleClickWidth / 2) | 214 if (std::abs(event2.x() - event1.x()) > kDoubleClickWidth / 2) |
| 356 return false; | 215 return false; |
| 357 | 216 |
| 358 if (std::abs(event2.y() - event1.y()) > kDoubleClickHeight / 2) | 217 if (std::abs(event2.y() - event1.y()) > kDoubleClickHeight / 2) |
| 359 return false; | 218 return false; |
| 360 | 219 |
| 361 return true; | 220 return true; |
| 362 } | 221 } |
| 363 | 222 |
| 364 // static | |
| 365 int MouseEvent::GetRepeatCount(const MouseEvent& event) { | |
| 366 int click_count = 1; | |
| 367 if (last_click_event_) { | |
| 368 if (event.type() == ui::ET_MOUSE_RELEASED) { | |
| 369 if (event.changed_button_flags() == | |
| 370 last_click_event_->changed_button_flags()) { | |
| 371 last_click_complete_ = true; | |
| 372 return last_click_event_->GetClickCount(); | |
| 373 } else { | |
| 374 // If last_click_event_ has changed since this button was pressed | |
| 375 // return a click count of 1. | |
| 376 return click_count; | |
| 377 } | |
| 378 } | |
| 379 if (event.time_stamp() != last_click_event_->time_stamp()) | |
| 380 last_click_complete_ = true; | |
| 381 if (!last_click_complete_ || | |
| 382 IsX11SendEventTrue(event.native_event())) { | |
| 383 click_count = last_click_event_->GetClickCount(); | |
| 384 } else if (IsRepeatedClickEvent(*last_click_event_, event)) { | |
| 385 click_count = last_click_event_->GetClickCount() + 1; | |
| 386 } | |
| 387 delete last_click_event_; | |
| 388 } | |
| 389 last_click_event_ = new MouseEvent(event); | |
| 390 last_click_complete_ = false; | |
| 391 if (click_count > 3) | |
| 392 click_count = 3; | |
| 393 last_click_event_->SetClickCount(click_count); | |
| 394 return click_count; | |
| 395 } | |
| 396 | |
| 397 void MouseEvent::ResetLastClickForTest() { | |
| 398 if (last_click_event_) { | |
| 399 delete last_click_event_; | |
| 400 last_click_event_ = NULL; | |
| 401 last_click_complete_ = false; | |
| 402 } | |
| 403 } | |
| 404 | |
| 405 // static | |
| 406 MouseEvent* MouseEvent::last_click_event_ = NULL; | |
| 407 bool MouseEvent::last_click_complete_ = false; | |
| 408 | |
| 409 int MouseEvent::GetClickCount() const { | 223 int MouseEvent::GetClickCount() const { |
| 410 if (type() != ET_MOUSE_PRESSED && type() != ET_MOUSE_RELEASED) | 224 if (type() != ET_MOUSE_PRESSED && type() != ET_MOUSE_RELEASED) |
| 411 return 0; | 225 return 0; |
| 412 | 226 |
| 413 if (flags() & EF_IS_TRIPLE_CLICK) | 227 if (flags() & EF_IS_TRIPLE_CLICK) |
| 414 return 3; | 228 return 3; |
| 415 else if (flags() & EF_IS_DOUBLE_CLICK) | 229 else if (flags() & EF_IS_DOUBLE_CLICK) |
| 416 return 2; | 230 return 2; |
| 417 else | 231 else |
| 418 return 1; | 232 return 1; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 439 f &= ~EF_IS_DOUBLE_CLICK; | 253 f &= ~EF_IS_DOUBLE_CLICK; |
| 440 f |= EF_IS_TRIPLE_CLICK; | 254 f |= EF_IS_TRIPLE_CLICK; |
| 441 break; | 255 break; |
| 442 } | 256 } |
| 443 set_flags(f); | 257 set_flags(f); |
| 444 } | 258 } |
| 445 | 259 |
| 446 //////////////////////////////////////////////////////////////////////////////// | 260 //////////////////////////////////////////////////////////////////////////////// |
| 447 // MouseWheelEvent | 261 // MouseWheelEvent |
| 448 | 262 |
| 449 MouseWheelEvent::MouseWheelEvent(const base::NativeEvent& native_event) | 263 MouseWheelEvent::MouseWheelEvent() : MouseEvent(), offset_() { |
| 450 : MouseEvent(native_event), | |
| 451 offset_(GetMouseWheelOffset(native_event)) { | |
| 452 } | 264 } |
| 453 | 265 |
| 454 MouseWheelEvent::MouseWheelEvent(const ScrollEvent& scroll_event) | 266 MouseWheelEvent::MouseWheelEvent(const ScrollEvent& scroll_event) |
| 455 : MouseEvent(scroll_event), | 267 : MouseEvent(scroll_event), |
| 456 offset_(gfx::ToRoundedInt(scroll_event.x_offset()), | 268 offset_(gfx::ToRoundedInt(scroll_event.x_offset()), |
| 457 gfx::ToRoundedInt(scroll_event.y_offset())) { | 269 gfx::ToRoundedInt(scroll_event.y_offset())) { |
| 458 SetType(ET_MOUSEWHEEL); | 270 SetType(ET_MOUSEWHEEL); |
| 459 } | 271 } |
| 460 | 272 |
| 461 MouseWheelEvent::MouseWheelEvent(const MouseEvent& mouse_event, | 273 MouseWheelEvent::MouseWheelEvent(const MouseEvent& mouse_event, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 } | 314 } |
| 503 if (decomp.scale[1]) { | 315 if (decomp.scale[1]) { |
| 504 offset_.set_y( | 316 offset_.set_y( |
| 505 gfx::ToRoundedInt(SkMScalarToFloat(offset_.y() * decomp.scale[1]))); | 317 gfx::ToRoundedInt(SkMScalarToFloat(offset_.y() * decomp.scale[1]))); |
| 506 } | 318 } |
| 507 } | 319 } |
| 508 | 320 |
| 509 //////////////////////////////////////////////////////////////////////////////// | 321 //////////////////////////////////////////////////////////////////////////////// |
| 510 // TouchEvent | 322 // TouchEvent |
| 511 | 323 |
| 512 TouchEvent::TouchEvent(const base::NativeEvent& native_event) | 324 TouchEvent::TouchEvent() |
| 513 : LocatedEvent(native_event), | 325 : LocatedEvent(), |
| 514 touch_id_(GetTouchId(native_event)), | 326 touch_id_(0), |
| 515 radius_x_(GetTouchRadiusX(native_event)), | 327 radius_x_(0), |
| 516 radius_y_(GetTouchRadiusY(native_event)), | 328 radius_y_(0), |
| 517 rotation_angle_(GetTouchAngle(native_event)), | 329 rotation_angle_(0), |
| 518 force_(GetTouchForce(native_event)) { | 330 force_(0) { |
| 519 latency()->AddLatencyNumberWithTimestamp( | |
| 520 INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, | |
| 521 0, | |
| 522 0, | |
| 523 base::TimeTicks::FromInternalValue(time_stamp().ToInternalValue()), | |
| 524 1); | |
| 525 | |
| 526 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); | |
| 527 | |
| 528 if (type() == ET_TOUCH_PRESSED) | |
| 529 IncrementTouchIdRefCount(native_event); | |
| 530 } | 331 } |
| 531 | 332 |
| 532 TouchEvent::TouchEvent(EventType type, | 333 TouchEvent::TouchEvent(EventType type, |
| 533 const gfx::PointF& location, | 334 const gfx::PointF& location, |
| 534 int touch_id, | 335 int touch_id, |
| 535 base::TimeDelta time_stamp) | 336 base::TimeDelta time_stamp) |
| 536 : LocatedEvent(type, location, location, time_stamp, 0), | 337 : LocatedEvent(type, location, location, time_stamp, 0), |
| 537 touch_id_(touch_id), | 338 touch_id_(touch_id), |
| 538 radius_x_(0.0f), | 339 radius_x_(0.0f), |
| 539 radius_y_(0.0f), | 340 radius_y_(0.0f), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 554 : LocatedEvent(type, location, location, time_stamp, flags), | 355 : LocatedEvent(type, location, location, time_stamp, flags), |
| 555 touch_id_(touch_id), | 356 touch_id_(touch_id), |
| 556 radius_x_(radius_x), | 357 radius_x_(radius_x), |
| 557 radius_y_(radius_y), | 358 radius_y_(radius_y), |
| 558 rotation_angle_(angle), | 359 rotation_angle_(angle), |
| 559 force_(force) { | 360 force_(force) { |
| 560 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); | 361 latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); |
| 561 } | 362 } |
| 562 | 363 |
| 563 TouchEvent::~TouchEvent() { | 364 TouchEvent::~TouchEvent() { |
| 564 // In ctor TouchEvent(native_event) we call GetTouchId() which in X11 | |
| 565 // platform setups the tracking_id to slot mapping. So in dtor here, | |
| 566 // if this touch event is a release event, we clear the mapping accordingly. | |
| 567 if (HasNativeEvent()) | |
| 568 ClearTouchIdIfReleased(native_event()); | |
| 569 } | 365 } |
| 570 | 366 |
| 571 void TouchEvent::UpdateForRootTransform( | 367 void TouchEvent::UpdateForRootTransform( |
| 572 const gfx::Transform& inverted_root_transform) { | 368 const gfx::Transform& inverted_root_transform) { |
| 573 LocatedEvent::UpdateForRootTransform(inverted_root_transform); | 369 LocatedEvent::UpdateForRootTransform(inverted_root_transform); |
| 574 gfx::DecomposedTransform decomp; | 370 gfx::DecomposedTransform decomp; |
| 575 bool success = gfx::DecomposeTransform(&decomp, inverted_root_transform); | 371 bool success = gfx::DecomposeTransform(&decomp, inverted_root_transform); |
| 576 DCHECK(success); | 372 DCHECK(success); |
| 577 if (decomp.scale[0]) | 373 if (decomp.scale[0]) |
| 578 radius_x_ *= decomp.scale[0]; | 374 radius_x_ *= decomp.scale[0]; |
| 579 if (decomp.scale[1]) | 375 if (decomp.scale[1]) |
| 580 radius_y_ *= decomp.scale[1]; | 376 radius_y_ *= decomp.scale[1]; |
| 581 } | 377 } |
| 582 | 378 |
| 583 //////////////////////////////////////////////////////////////////////////////// | 379 //////////////////////////////////////////////////////////////////////////////// |
| 584 // KeyEvent | 380 // KeyEvent |
| 585 | 381 |
| 586 // static | 382 KeyEvent::KeyEvent() |
| 587 KeyEvent* KeyEvent::last_key_event_ = NULL; | 383 : Event(), |
| 588 | 384 key_code_(VKEY_UNKNOWN), |
| 589 // static | 385 code_(), |
| 590 bool KeyEvent::IsRepeated(const KeyEvent& event) { | 386 is_char_(false), |
| 591 // A safe guard in case if there were continous key pressed events that are | 387 platform_keycode_(0), |
| 592 // not auto repeat. | |
| 593 const int kMaxAutoRepeatTimeMs = 2000; | |
| 594 // Ignore key events that have non standard state masks as it may be | |
| 595 // reposted by an IME. IBUS-GTK uses this field to detect the | |
| 596 // re-posted event for example. crbug.com/385873. | |
| 597 if (X11EventHasNonStandardState(event.native_event())) | |
| 598 return false; | |
| 599 if (event.is_char()) | |
| 600 return false; | |
| 601 if (event.type() == ui::ET_KEY_RELEASED) { | |
| 602 delete last_key_event_; | |
| 603 last_key_event_ = NULL; | |
| 604 return false; | |
| 605 } | |
| 606 CHECK_EQ(ui::ET_KEY_PRESSED, event.type()); | |
| 607 if (!last_key_event_) { | |
| 608 last_key_event_ = new KeyEvent(event); | |
| 609 return false; | |
| 610 } | |
| 611 if (event.key_code() == last_key_event_->key_code() && | |
| 612 event.flags() == last_key_event_->flags() && | |
| 613 (event.time_stamp() - last_key_event_->time_stamp()).InMilliseconds() < | |
| 614 kMaxAutoRepeatTimeMs) { | |
| 615 return true; | |
| 616 } | |
| 617 delete last_key_event_; | |
| 618 last_key_event_ = new KeyEvent(event); | |
| 619 return false; | |
| 620 } | |
| 621 | |
| 622 KeyEvent::KeyEvent(const base::NativeEvent& native_event) | |
| 623 : Event(native_event, | |
| 624 EventTypeFromNative(native_event), | |
| 625 EventFlagsFromNative(native_event)), | |
| 626 key_code_(KeyboardCodeFromNative(native_event)), | |
| 627 code_(CodeFromNative(native_event)), | |
| 628 is_char_(IsCharFromNative(native_event)), | |
| 629 platform_keycode_(PlatformKeycodeFromNative(native_event)), | |
| 630 character_(0) { | 388 character_(0) { |
| 631 if (IsRepeated(*this)) | |
| 632 set_flags(flags() | ui::EF_IS_REPEAT); | |
| 633 | |
| 634 #if defined(USE_X11) | |
| 635 NormalizeFlags(); | |
| 636 #endif | |
| 637 #if defined(OS_WIN) | |
| 638 // Only Windows has native character events. | |
| 639 if (is_char_) | |
| 640 character_ = native_event.wParam; | |
| 641 #endif | |
| 642 } | 389 } |
| 643 | 390 |
| 644 KeyEvent::KeyEvent(EventType type, | 391 KeyEvent::KeyEvent(EventType type, |
| 645 KeyboardCode key_code, | 392 KeyboardCode key_code, |
| 646 int flags) | 393 int flags) |
| 647 : Event(type, EventTimeForNow(), flags), | 394 : Event(type, EventTimeForNow(), flags), |
| 648 key_code_(key_code), | 395 key_code_(key_code), |
| 649 is_char_(false), | 396 is_char_(false), |
| 650 platform_keycode_(0), | 397 platform_keycode_(0), |
| 651 character_() { | 398 character_() { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 return character_; | 456 return character_; |
| 710 | 457 |
| 711 // TODO(kpschoedel): streamline these cases after settling Ozone | 458 // TODO(kpschoedel): streamline these cases after settling Ozone |
| 712 // positional coding. | 459 // positional coding. |
| 713 #if defined(OS_WIN) | 460 #if defined(OS_WIN) |
| 714 // Native Windows character events always have is_char_ == true, | 461 // Native Windows character events always have is_char_ == true, |
| 715 // so this is a synthetic or native keystroke event. | 462 // so this is a synthetic or native keystroke event. |
| 716 character_ = GetCharacterFromKeyCode(key_code_, flags()); | 463 character_ = GetCharacterFromKeyCode(key_code_, flags()); |
| 717 return character_; | 464 return character_; |
| 718 #elif defined(USE_X11) | 465 #elif defined(USE_X11) |
| 719 if (!native_event()) { | 466 character_ = GetCharacterFromKeyCode(key_code_, flags()); |
| 720 character_ = GetCharacterFromKeyCode(key_code_, flags()); | 467 return character_; |
| 721 return character_; | |
| 722 } | |
| 723 | |
| 724 DCHECK(native_event()->type == KeyPress || | |
| 725 native_event()->type == KeyRelease || | |
| 726 (native_event()->type == GenericEvent && | |
| 727 (native_event()->xgeneric.evtype == XI_KeyPress || | |
| 728 native_event()->xgeneric.evtype == XI_KeyRelease))); | |
| 729 | |
| 730 // When a control key is held, prefer ASCII characters to non ASCII | |
| 731 // characters in order to use it for shortcut keys. GetCharacterFromKeyCode | |
| 732 // returns 'a' for VKEY_A even if the key is actually bound to 'à' in X11. | |
| 733 // GetCharacterFromXEvent returns 'à' in that case. | |
| 734 return IsControlDown() ? | |
| 735 GetCharacterFromKeyCode(key_code_, flags()) : | |
| 736 GetCharacterFromXEvent(native_event()); | |
| 737 #else | 468 #else |
| 738 if (native_event()) { | |
| 739 DCHECK(EventTypeFromNative(native_event()) == ET_KEY_PRESSED || | |
| 740 EventTypeFromNative(native_event()) == ET_KEY_RELEASED); | |
| 741 } | |
| 742 | |
| 743 return GetCharacterFromKeyCode(key_code_, flags()); | 469 return GetCharacterFromKeyCode(key_code_, flags()); |
| 744 #endif | 470 #endif |
| 745 } | 471 } |
| 746 | 472 |
| 747 base::char16 KeyEvent::GetText() const { | 473 base::char16 KeyEvent::GetText() const { |
| 748 if ((flags() & EF_CONTROL_DOWN) != 0) { | 474 if ((flags() & EF_CONTROL_DOWN) != 0) { |
| 749 return GetControlCharacterForKeycode(key_code_, | 475 return GetControlCharacterForKeycode(key_code_, |
| 750 (flags() & EF_SHIFT_DOWN) != 0); | 476 (flags() & EF_SHIFT_DOWN) != 0); |
| 751 } | 477 } |
| 752 return GetUnmodifiedText(); | 478 return GetUnmodifiedText(); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 | 630 |
| 905 uint16 KeyEvent::GetConflatedWindowsKeyCode() const { | 631 uint16 KeyEvent::GetConflatedWindowsKeyCode() const { |
| 906 if (is_char_) | 632 if (is_char_) |
| 907 return character_; | 633 return character_; |
| 908 return key_code_; | 634 return key_code_; |
| 909 } | 635 } |
| 910 | 636 |
| 911 //////////////////////////////////////////////////////////////////////////////// | 637 //////////////////////////////////////////////////////////////////////////////// |
| 912 // ScrollEvent | 638 // ScrollEvent |
| 913 | 639 |
| 914 ScrollEvent::ScrollEvent(const base::NativeEvent& native_event) | 640 ScrollEvent::ScrollEvent() : MouseEvent() { |
| 915 : MouseEvent(native_event) { | |
| 916 if (type() == ET_SCROLL) { | |
| 917 GetScrollOffsets(native_event, | |
| 918 &x_offset_, &y_offset_, | |
| 919 &x_offset_ordinal_, &y_offset_ordinal_, | |
| 920 &finger_count_); | |
| 921 } else if (type() == ET_SCROLL_FLING_START || | |
| 922 type() == ET_SCROLL_FLING_CANCEL) { | |
| 923 GetFlingData(native_event, | |
| 924 &x_offset_, &y_offset_, | |
| 925 &x_offset_ordinal_, &y_offset_ordinal_, | |
| 926 NULL); | |
| 927 } else { | |
| 928 NOTREACHED() << "Unexpected event type " << type() | |
| 929 << " when constructing a ScrollEvent."; | |
| 930 } | |
| 931 } | 641 } |
| 932 | 642 |
| 933 ScrollEvent::ScrollEvent(EventType type, | 643 ScrollEvent::ScrollEvent(EventType type, |
| 934 const gfx::PointF& location, | 644 const gfx::PointF& location, |
| 935 base::TimeDelta time_stamp, | 645 base::TimeDelta time_stamp, |
| 936 int flags, | 646 int flags, |
| 937 float x_offset, | 647 float x_offset, |
| 938 float y_offset, | 648 float y_offset, |
| 939 float x_offset_ordinal, | 649 float x_offset_ordinal, |
| 940 float y_offset_ordinal, | 650 float y_offset_ordinal, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 969 gfx::PointF(x, y), | 679 gfx::PointF(x, y), |
| 970 time_stamp, | 680 time_stamp, |
| 971 flags | EF_FROM_TOUCH), | 681 flags | EF_FROM_TOUCH), |
| 972 details_(details) { | 682 details_(details) { |
| 973 } | 683 } |
| 974 | 684 |
| 975 GestureEvent::~GestureEvent() { | 685 GestureEvent::~GestureEvent() { |
| 976 } | 686 } |
| 977 | 687 |
| 978 } // namespace ui | 688 } // namespace ui |
| OLD | NEW |