diff options
-rw-r--r-- | ui/aura/gestures/gesture_recognizer_unittest.cc | 48 | ||||
-rw-r--r-- | ui/aura/test/aura_test_helper.cc | 1 | ||||
-rw-r--r-- | ui/aura/window_targeter.cc | 3 | ||||
-rw-r--r-- | ui/events/event.cc | 16 | ||||
-rw-r--r-- | ui/events/event.h | 10 | ||||
-rw-r--r-- | ui/events/gestures/gesture_point.cc | 4 | ||||
-rw-r--r-- | ui/events/gestures/gesture_point.h | 7 | ||||
-rw-r--r-- | ui/events/gestures/gesture_recognizer.h | 11 | ||||
-rw-r--r-- | ui/events/gestures/gesture_recognizer_impl.cc | 12 | ||||
-rw-r--r-- | ui/events/gestures/gesture_recognizer_impl.h | 2 | ||||
-rw-r--r-- | ui/events/gestures/gesture_sequence.cc | 1 |
11 files changed, 93 insertions, 22 deletions
diff --git a/ui/aura/gestures/gesture_recognizer_unittest.cc b/ui/aura/gestures/gesture_recognizer_unittest.cc index 1ed8b30..529af63 100644 --- a/ui/aura/gestures/gesture_recognizer_unittest.cc +++ b/ui/aura/gestures/gesture_recognizer_unittest.cc @@ -2169,13 +2169,13 @@ TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) { // Touches should now be associated with the closest touch within // ui::GestureConfiguration::max_separation_for_gesture_touches_in_pixels - target = gesture_recognizer->GetTargetForLocation(gfx::Point(11, 11)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(11, 11), -1); EXPECT_EQ("0", WindowIDAsString(target)); - target = gesture_recognizer->GetTargetForLocation(gfx::Point(511, 11)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(511, 11), -1); EXPECT_EQ("1", WindowIDAsString(target)); - target = gesture_recognizer->GetTargetForLocation(gfx::Point(11, 511)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(11, 511), -1); EXPECT_EQ("2", WindowIDAsString(target)); - target = gesture_recognizer->GetTargetForLocation(gfx::Point(511, 511)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(511, 511), -1); EXPECT_EQ("3", WindowIDAsString(target)); // Add a touch in the middle associated with windows[2] @@ -2186,20 +2186,20 @@ TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) { kNumWindows, tes.Now()); dispatcher()->AsWindowTreeHostDelegate()->OnHostTouchEvent(&move); - target = gesture_recognizer->GetTargetForLocation(gfx::Point(250, 250)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(250, 250), -1); EXPECT_EQ("2", WindowIDAsString(target)); // Make sure that ties are broken by distance to a current touch // Closer to the point in the bottom right. - target = gesture_recognizer->GetTargetForLocation(gfx::Point(380, 380)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(380, 380), -1); EXPECT_EQ("3", WindowIDAsString(target)); // This touch is closer to the point in the middle - target = gesture_recognizer->GetTargetForLocation(gfx::Point(300, 300)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(300, 300), -1); EXPECT_EQ("2", WindowIDAsString(target)); // A touch too far from other touches won't be locked to anything - target = gesture_recognizer->GetTargetForLocation(gfx::Point(1000, 1000)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(1000, 1000), -1); EXPECT_TRUE(target == NULL); // Move a touch associated with windows[2] to 1000, 1000 @@ -2207,7 +2207,7 @@ TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) { kNumWindows, tes.Now()); dispatcher()->AsWindowTreeHostDelegate()->OnHostTouchEvent(&move2); - target = gesture_recognizer->GetTargetForLocation(gfx::Point(1000, 1000)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(1000, 1000), -1); EXPECT_EQ("2", WindowIDAsString(target)); for (int i = 0; i < kNumWindows; ++i) { @@ -2217,6 +2217,36 @@ TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) { } } +// Check that a touch's target will not be effected by a touch on a different +// screen. +TEST_F(GestureRecognizerTest, GestureEventTouchLockIgnoresOtherScreens) { + scoped_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + gfx::Rect bounds(0, 0, 10, 10); + scoped_ptr<aura::Window> window( + CreateTestWindowWithDelegate(delegate.get(), 0, bounds, root_window())); + + const int kTouchId1 = 8; + const int kTouchId2 = 2; + TimedEvents tes; + + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(5, 5), + kTouchId1, tes.Now()); + press1.set_source_device_id(1); + dispatcher()->AsWindowTreeHostDelegate()->OnHostTouchEvent(&press1); + + ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), + kTouchId2, tes.Now()); + press2.set_source_device_id(2); + dispatcher()->AsWindowTreeHostDelegate()->OnHostTouchEvent(&press2); + + // The second press should not have been locked to the same target as the + // first, as they occured on different displays. + EXPECT_NE( + ui::GestureRecognizer::Get()->GetTouchLockedTarget(press1), + ui::GestureRecognizer::Get()->GetTouchLockedTarget(press2)); +} + // Check that touch events outside the root window are still handled // by the root window's gesture sequence. TEST_F(GestureRecognizerTest, GestureEventOutsideRootWindowTap) { diff --git a/ui/aura/test/aura_test_helper.cc b/ui/aura/test/aura_test_helper.cc index 6cef5d9..001c56f 100644 --- a/ui/aura/test/aura_test_helper.cc +++ b/ui/aura/test/aura_test_helper.cc @@ -105,6 +105,7 @@ void AuraTestHelper::TearDown() { focus_client_.reset(); client::SetFocusClient(root_window(), NULL); root_window_.reset(); + ui::GestureRecognizer::Reset(); test_screen_.reset(); gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, NULL); diff --git a/ui/aura/window_targeter.cc b/ui/aura/window_targeter.cc index 5d65627..398ee173 100644 --- a/ui/aura/window_targeter.cc +++ b/ui/aura/window_targeter.cc @@ -110,7 +110,8 @@ Window* WindowTargeter::FindTargetInRootWindow(Window* root_window, if (consumer) return static_cast<Window*>(consumer); consumer = - ui::GestureRecognizer::Get()->GetTargetForLocation(event.location()); + ui::GestureRecognizer::Get()->GetTargetForLocation( + event.location(), touch.source_device_id()); if (consumer) return static_cast<Window*>(consumer); diff --git a/ui/events/event.cc b/ui/events/event.cc index 22e1625..936139f 100644 --- a/ui/events/event.cc +++ b/ui/events/event.cc @@ -5,6 +5,7 @@ #include "ui/events/event.h" #if defined(USE_X11) +#include <X11/extensions/XInput2.h> #include <X11/Xlib.h> #endif @@ -437,7 +438,8 @@ TouchEvent::TouchEvent(const base::NativeEvent& native_event) radius_x_(GetTouchRadiusX(native_event)), radius_y_(GetTouchRadiusY(native_event)), rotation_angle_(GetTouchAngle(native_event)), - force_(GetTouchForce(native_event)) { + force_(GetTouchForce(native_event)), + source_device_id_(-1) { latency()->AddLatencyNumberWithTimestamp( INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, @@ -445,6 +447,12 @@ TouchEvent::TouchEvent(const base::NativeEvent& native_event) base::TimeTicks::FromInternalValue(time_stamp().ToInternalValue()), 1, true); + +#if defined(USE_X11) + XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(native_event->xcookie.data); + source_device_id_ = xiev->deviceid; +#endif + latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); } @@ -457,7 +465,8 @@ TouchEvent::TouchEvent(EventType type, radius_x_(0.0f), radius_y_(0.0f), rotation_angle_(0.0f), - force_(0.0f) { + force_(0.0f), + source_device_id_(-1) { latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); } @@ -475,7 +484,8 @@ TouchEvent::TouchEvent(EventType type, radius_x_(radius_x), radius_y_(radius_y), rotation_angle_(angle), - force_(force) { + force_(force), + source_device_id_(-1) { latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); } diff --git a/ui/events/event.h b/ui/events/event.h index 596f31e..55687035 100644 --- a/ui/events/event.h +++ b/ui/events/event.h @@ -437,7 +437,8 @@ class EVENTS_EXPORT TouchEvent : public LocatedEvent { radius_x_(model.radius_x_), radius_y_(model.radius_y_), rotation_angle_(model.rotation_angle_), - force_(model.force_) { + force_(model.force_), + source_device_id_(model.source_device_id_) { } TouchEvent(EventType type, @@ -462,6 +463,7 @@ class EVENTS_EXPORT TouchEvent : public LocatedEvent { 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, @@ -471,6 +473,9 @@ class EVENTS_EXPORT TouchEvent : public LocatedEvent { // 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( @@ -504,6 +509,9 @@ class EVENTS_EXPORT TouchEvent : public LocatedEvent { // 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_; }; class EVENTS_EXPORT KeyEvent : public Event { diff --git a/ui/events/gestures/gesture_point.cc b/ui/events/gestures/gesture_point.cc index fa47727..eafd344 100644 --- a/ui/events/gestures/gesture_point.cc +++ b/ui/events/gestures/gesture_point.cc @@ -24,7 +24,8 @@ GesturePoint::GesturePoint() velocity_calculator_( GestureConfiguration::points_buffered_for_velocity()), point_id_(-1), - touch_id_(-1) { + touch_id_(-1), + source_device_id_(-1) { } GesturePoint::~GesturePoint() {} @@ -34,6 +35,7 @@ void GesturePoint::Reset() { ResetVelocity(); point_id_ = -1; clear_enclosing_rectangle(); + source_device_id_ = -1; } void GesturePoint::ResetVelocity() { diff --git a/ui/events/gestures/gesture_point.h b/ui/events/gestures/gesture_point.h index f9540fa..85cfd84 100644 --- a/ui/events/gestures/gesture_point.h +++ b/ui/events/gestures/gesture_point.h @@ -79,6 +79,11 @@ class GesturePoint { const gfx::Rect& enclosing_rectangle() const { return enclosing_rect_; } + void set_source_device_id(int source_device_id) { + source_device_id_ = source_device_id; + } + int source_device_id() const { return source_device_id_; } + private: // Various statistical functions to manipulate gestures. @@ -131,6 +136,8 @@ class GesturePoint { // Count of the number of events with same direction. gfx::Vector2d same_direction_count_; + int source_device_id_; + DISALLOW_COPY_AND_ASSIGN(GesturePoint); }; diff --git a/ui/events/gestures/gesture_recognizer.h b/ui/events/gestures/gesture_recognizer.h index 92d225a..4b53c2f 100644 --- a/ui/events/gestures/gesture_recognizer.h +++ b/ui/events/gestures/gesture_recognizer.h @@ -19,6 +19,7 @@ class EVENTS_EXPORT GestureRecognizer { public: static GestureRecognizer* Create(); static GestureRecognizer* Get(); + static void Reset(); // List of GestureEvent*. typedef ScopedVector<GestureEvent> Gestures; @@ -46,10 +47,12 @@ class EVENTS_EXPORT GestureRecognizer { virtual GestureConsumer* GetTargetForGestureEvent( const GestureEvent& event) = 0; - // If there is an active touch within - // GestureConfiguration::max_separation_for_gesture_touches_in_pixels, - // of |location|, returns the target of the nearest active touch. - virtual GestureConsumer* GetTargetForLocation(const gfx::Point& location) = 0; + // Returns the target of the nearest active touch with source device of + // |source_device_id|, within + // GestureConfiguration::max_separation_for_gesture_touches_in_pixels of + // |location|, or NULL if no such point exists. + virtual GestureConsumer* GetTargetForLocation( + const gfx::Point& location, int source_device_id) = 0; // Makes |new_consumer| the target for events previously targeting // |current_consumer|. All other targets are canceled. diff --git a/ui/events/gestures/gesture_recognizer_impl.cc b/ui/events/gestures/gesture_recognizer_impl.cc index 4a59934..c166658 100644 --- a/ui/events/gestures/gesture_recognizer_impl.cc +++ b/ui/events/gestures/gesture_recognizer_impl.cc @@ -78,15 +78,17 @@ GestureConsumer* GestureRecognizerImpl::GetTargetForGestureEvent( } GestureConsumer* GestureRecognizerImpl::GetTargetForLocation( - const gfx::Point& location) { + const gfx::Point& location, int source_device_id) { const GesturePoint* closest_point = NULL; int64 closest_distance_squared = 0; std::map<GestureConsumer*, GestureSequence*>::iterator i; for (i = consumer_sequence_.begin(); i != consumer_sequence_.end(); ++i) { const GesturePoint* points = i->second->points(); for (int j = 0; j < GestureSequence::kMaxGesturePoints; ++j) { - if (!points[j].in_use()) + if (!points[j].in_use() || + source_device_id != points[j].source_device_id()) { continue; + } gfx::Vector2d delta = points[j].last_touch_position() - location; // Relative distance is all we need here, so LengthSquared() is // appropriate, and cheaper than Length(). @@ -271,6 +273,12 @@ GestureRecognizer* GestureRecognizer::Get() { return g_gesture_recognizer_instance; } +// GestureRecognizer, static +void GestureRecognizer::Reset() { + delete g_gesture_recognizer_instance; + g_gesture_recognizer_instance = NULL; +} + void SetGestureRecognizerForTesting(GestureRecognizer* gesture_recognizer) { // Transfer helpers to the new GR. std::vector<GestureEventHelper*>& helpers = diff --git a/ui/events/gestures/gesture_recognizer_impl.h b/ui/events/gestures/gesture_recognizer_impl.h index 59c92cf..16ba7a4 100644 --- a/ui/events/gestures/gesture_recognizer_impl.h +++ b/ui/events/gestures/gesture_recognizer_impl.h @@ -39,7 +39,7 @@ class EVENTS_EXPORT GestureRecognizerImpl : public GestureRecognizer, virtual GestureConsumer* GetTargetForGestureEvent( const GestureEvent& event) OVERRIDE; virtual GestureConsumer* GetTargetForLocation( - const gfx::Point& location) OVERRIDE; + const gfx::Point& location, int source_device_id) OVERRIDE; virtual void TransferEventsTo(GestureConsumer* current_consumer, GestureConsumer* new_consumer) OVERRIDE; virtual bool GetLastTouchPointForTarget(GestureConsumer* consumer, diff --git a/ui/events/gestures/gesture_sequence.cc b/ui/events/gestures/gesture_sequence.cc index 65d813a..7b37f45 100644 --- a/ui/events/gestures/gesture_sequence.cc +++ b/ui/events/gestures/gesture_sequence.cc @@ -520,6 +520,7 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( } new_point->set_point_id(point_count_++); new_point->set_touch_id(event.touch_id()); + new_point->set_source_device_id(event.source_device_id()); } GestureState last_state = state_; |