summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authortdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-09 21:12:17 +0000
committertdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-09 21:12:17 +0000
commit94307a6c3809d13dc47fe7aaa85fd30510e52bf6 (patch)
tree4cb49cb7c23372f08ea82c5d1090d8a6fe7b093b /ui
parentc619fd58cf27de336493d0f8d40f207a15f94474 (diff)
downloadchromium_src-94307a6c3809d13dc47fe7aaa85fd30510e52bf6.zip
chromium_src-94307a6c3809d13dc47fe7aaa85fd30510e52bf6.tar.gz
chromium_src-94307a6c3809d13dc47fe7aaa85fd30510e52bf6.tar.bz2
Target touches to the correct display.
ui::TouchEvents now know the id of their source device. The target of a touch can't be effected by a touch on another display. BUG=315651 TEST=GestureRecognizerTest.GestureEventTouchLockIgnoresOtherScreens Review URL: https://codereview.chromium.org/103173004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243974 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/aura/gestures/gesture_recognizer_unittest.cc48
-rw-r--r--ui/aura/test/aura_test_helper.cc1
-rw-r--r--ui/aura/window_targeter.cc3
-rw-r--r--ui/events/event.cc16
-rw-r--r--ui/events/event.h10
-rw-r--r--ui/events/gestures/gesture_point.cc4
-rw-r--r--ui/events/gestures/gesture_point.h7
-rw-r--r--ui/events/gestures/gesture_recognizer.h11
-rw-r--r--ui/events/gestures/gesture_recognizer_impl.cc11
-rw-r--r--ui/events/gestures/gesture_recognizer_impl.h2
-rw-r--r--ui/events/gestures/gesture_sequence.cc1
11 files changed, 92 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..79308df 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,11 @@ GestureRecognizer* GestureRecognizer::Get() {
return g_gesture_recognizer_instance;
}
+// GestureRecognizer, static
+void GestureRecognizer::Reset() {
+ 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_;