summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvarunjain@chromium.org <varunjain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-21 13:31:45 +0000
committervarunjain@chromium.org <varunjain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-21 13:31:45 +0000
commit64a5a8cb4268b15ea6ec734a00114ef30f9381fb (patch)
treeacf46e4070851d9be1ca5dfcd01d0ac0af557f71
parent676c561eae941ee83445be73fb9148859bfcdf64 (diff)
downloadchromium_src-64a5a8cb4268b15ea6ec734a00114ef30f9381fb.zip
chromium_src-64a5a8cb4268b15ea6ec734a00114ef30f9381fb.tar.gz
chromium_src-64a5a8cb4268b15ea6ec734a00114ef30f9381fb.tar.bz2
Gesture recognizer must be a singleton accross all aura::RootWindows
BUG=279317 Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=229753 R=sadrul@chromium.org, sky@chromium.org Review URL: https://codereview.chromium.org/25350006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229796 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/drag_drop/drag_drop_controller.cc2
-rw-r--r--ash/wm/toplevel_window_event_handler.cc2
-rw-r--r--chrome/browser/ui/views/tabs/tab_drag_controller.cc22
-rw-r--r--content/browser/renderer_host/render_widget_host_view_guest.cc21
-rw-r--r--content/browser/renderer_host/render_widget_host_view_guest.h5
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.cc19
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.h5
-rw-r--r--ui/aura/client/default_capture_client.cc4
-rw-r--r--ui/aura/gestures/gesture_recognizer_unittest.cc75
-rw-r--r--ui/aura/root_window.cc47
-rw-r--r--ui/aura/root_window.h15
-rw-r--r--ui/events/gestures/gesture_recognizer.h14
-rw-r--r--ui/events/gestures/gesture_recognizer_impl.cc72
-rw-r--r--ui/events/gestures/gesture_recognizer_impl.h26
-rw-r--r--ui/events/gestures/gesture_sequence.cc7
-rw-r--r--ui/events/gestures/gesture_sequence.h14
-rw-r--r--ui/events/gestures/gesture_types.h6
-rw-r--r--ui/views/corewm/capture_controller.cc7
-rw-r--r--ui/views/corewm/capture_controller_unittest.cc4
-rw-r--r--ui/views/widget/desktop_aura/desktop_capture_client.cc6
20 files changed, 251 insertions, 122 deletions
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index 48e7c35..d335465 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -181,7 +181,7 @@ int DragDropController::StartDragAndDrop(
// We need to transfer the current gesture sequence and the GR's touch event
// queue to the |drag_drop_tracker_|'s capture window so that when it takes
// capture, it still gets a valid gesture state.
- root_window->gesture_recognizer()->TransferEventsTo(source_window,
+ ui::GestureRecognizer::Get()->TransferEventsTo(source_window,
tracker->capture_window());
// We also send a gesture end to the source window so it can clear state.
// TODO(varunjain): Remove this whole block when gesture sequence
diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc
index f76d33d..f6d5902 100644
--- a/ash/wm/toplevel_window_event_handler.cc
+++ b/ash/wm/toplevel_window_event_handler.cc
@@ -341,7 +341,7 @@ aura::client::WindowMoveResult ToplevelWindowEventHandler::RunMoveLoop(
if (move_source == aura::client::WINDOW_MOVE_SOURCE_TOUCH &&
aura::Env::GetInstance()->is_touch_down()) {
in_gesture_drag_ = true;
- bool has_point = root_window->gesture_recognizer()->
+ bool has_point = ui::GestureRecognizer::Get()->
GetLastTouchPointForTarget(source, &drag_location);
DCHECK(has_point);
} else {
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
index 6f13d81..ba0564b 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -59,6 +59,11 @@
#include "ui/events/gestures/gesture_recognizer.h"
#endif
+#if defined(OS_WIN) && defined(USE_AURA)
+#include "ui/aura/window.h"
+#include "ui/events/gestures/gesture_recognizer.h"
+#endif
+
using content::OpenURLParams;
using content::UserMetricsAction;
using content::WebContents;
@@ -897,6 +902,18 @@ TabDragController::DragBrowserToNewTabStrip(
target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_);
else
browser_widget->ReleaseCapture();
+#if defined(OS_WIN) && defined(USE_AURA)
+ // The Gesture recognizer does not work well currently when capture changes
+ // while a touch gesture is in progress. So we need to manually transfer
+ // gesture sequence and the GR's touch events queue to the new window. This
+ // should really be done somewhere in capture change code and or inside the
+ // GR. But we currently do not have a consistent way for doing it that would
+ // work in all cases. Hence this hack.
+ ui::GestureRecognizer::Get()->TransferEventsTo(
+ browser_widget->GetNativeView(),
+ target_tabstrip->GetWidget()->GetNativeView());
+#endif
+
// The window is going away. Since the drag is still on going we don't want
// that to effect the position of any windows.
SetWindowPositionManaged(browser_widget->GetNativeView(), false);
@@ -2227,9 +2244,8 @@ gfx::Point TabDragController::GetCursorScreenPoint() {
aura::Window* widget_window = widget->GetNativeWindow();
DCHECK(widget_window->GetRootWindow());
gfx::Point touch_point;
- bool got_touch_point = widget_window->GetRootWindow()->
- gesture_recognizer()->GetLastTouchPointForTarget(widget_window,
- &touch_point);
+ bool got_touch_point = ui::GestureRecognizer::Get()->
+ GetLastTouchPointForTarget(widget_window, &touch_point);
DCHECK(got_touch_point);
ash::wm::ConvertPointToScreen(widget_window->GetRootWindow(), &touch_point);
return touch_point;
diff --git a/content/browser/renderer_host/render_widget_host_view_guest.cc b/content/browser/renderer_host/render_widget_host_view_guest.cc
index 05730b9..a339329 100644
--- a/content/browser/renderer_host/render_widget_host_view_guest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_guest.cc
@@ -54,12 +54,16 @@ RenderWidgetHostViewGuest::RenderWidgetHostViewGuest(
is_hidden_(host_->is_hidden()),
platform_view_(static_cast<RenderWidgetHostViewPort*>(platform_view)) {
#if defined(OS_WIN) || defined(USE_AURA)
- gesture_recognizer_.reset(ui::GestureRecognizer::Create(this));
+ gesture_recognizer_.reset(ui::GestureRecognizer::Create());
+ gesture_recognizer_->AddGestureEventHelper(this);
#endif // defined(OS_WIN) || defined(USE_AURA)
host_->SetView(this);
}
RenderWidgetHostViewGuest::~RenderWidgetHostViewGuest() {
+#if defined(OS_WIN) || defined(USE_AURA)
+ gesture_recognizer_->RemoveGestureEventHelper(this);
+#endif // defined(OS_WIN) || defined(USE_AURA)
}
RenderWidgetHost* RenderWidgetHostViewGuest::GetRenderWidgetHost() const {
@@ -507,21 +511,26 @@ void RenderWidgetHostViewGuest::DestroyGuestView() {
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
-bool RenderWidgetHostViewGuest::DispatchLongPressGestureEvent(
+bool RenderWidgetHostViewGuest::CanDispatchToConsumer(
+ ui::GestureConsumer* consumer) {
+ CHECK_EQ(static_cast<RenderWidgetHostViewGuest*>(consumer), this);
+ return true;
+}
+
+void RenderWidgetHostViewGuest::DispatchLongPressGestureEvent(
ui::GestureEvent* event) {
- return ForwardGestureEventToRenderer(event);
+ ForwardGestureEventToRenderer(event);
}
-bool RenderWidgetHostViewGuest::DispatchCancelTouchEvent(
+void RenderWidgetHostViewGuest::DispatchCancelTouchEvent(
ui::TouchEvent* event) {
if (!host_)
- return false;
+ return;
WebKit::WebTouchEvent cancel_event;
cancel_event.type = WebKit::WebInputEvent::TouchCancel;
cancel_event.timeStampSeconds = event->time_stamp().InSecondsF();
host_->ForwardTouchEventWithLatencyInfo(cancel_event, *event->latency());
- return true;
}
bool RenderWidgetHostViewGuest::ForwardGestureEventToRenderer(
diff --git a/content/browser/renderer_host/render_widget_host_view_guest.h b/content/browser/renderer_host/render_widget_host_view_guest.h
index 079410b..84435e4 100644
--- a/content/browser/renderer_host/render_widget_host_view_guest.h
+++ b/content/browser/renderer_host/render_widget_host_view_guest.h
@@ -186,8 +186,9 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
#endif
// Overridden from ui::GestureEventHelper.
- virtual bool DispatchLongPressGestureEvent(ui::GestureEvent* event) OVERRIDE;
- virtual bool DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
+ virtual bool CanDispatchToConsumer(ui::GestureConsumer* consumer) OVERRIDE;
+ virtual void DispatchLongPressGestureEvent(ui::GestureEvent* event) OVERRIDE;
+ virtual void DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
protected:
friend class RenderWidgetHostView;
diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc
index 0694e10..a440e6b 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.cc
+++ b/content/browser/renderer_host/render_widget_host_view_win.cc
@@ -411,14 +411,16 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget)
pointer_down_context_(false),
last_touch_location_(-1, -1),
touch_events_enabled_(ui::AreTouchEventsEnabled()),
- gesture_recognizer_(ui::GestureRecognizer::Create(this)) {
+ gesture_recognizer_(ui::GestureRecognizer::Create()) {
render_widget_host_->SetView(this);
registrar_.Add(this,
NOTIFICATION_RENDERER_PROCESS_TERMINATED,
NotificationService::AllBrowserContextsAndSources());
+ gesture_recognizer_->AddGestureEventHelper(this);
}
RenderWidgetHostViewWin::~RenderWidgetHostViewWin() {
+ gesture_recognizer_->RemoveGestureEventHelper(this);
UnlockMouse();
ResetTooltip();
}
@@ -944,16 +946,22 @@ void RenderWidgetHostViewWin::UpdateDesiredTouchMode() {
}
}
-bool RenderWidgetHostViewWin::DispatchLongPressGestureEvent(
+bool RenderWidgetHostViewWin::CanDispatchToConsumer(
+ ui::GestureConsumer* consumer) {
+ CHECK_EQ(static_cast<RenderWidgetHostViewWin*>(consumer), this);
+ return true;
+}
+
+void RenderWidgetHostViewWin::DispatchLongPressGestureEvent(
ui::GestureEvent* event) {
- return ForwardGestureEventToRenderer(event);
+ ForwardGestureEventToRenderer(event);
}
-bool RenderWidgetHostViewWin::DispatchCancelTouchEvent(
+void RenderWidgetHostViewWin::DispatchCancelTouchEvent(
ui::TouchEvent* event) {
if (!render_widget_host_ || !touch_events_enabled_ ||
!render_widget_host_->ShouldForwardTouchEvent()) {
- return false;
+ return;
}
DCHECK(event->type() == WebKit::WebInputEvent::TouchCancel);
WebKit::WebTouchEvent cancel_event;
@@ -961,7 +969,6 @@ bool RenderWidgetHostViewWin::DispatchCancelTouchEvent(
cancel_event.timeStampSeconds = event->time_stamp().InSecondsF();
render_widget_host_->ForwardTouchEventWithLatencyInfo(
cancel_event, *event->latency());
- return true;
}
void RenderWidgetHostViewWin::SetHasHorizontalScrollbar(
diff --git a/content/browser/renderer_host/render_widget_host_view_win.h b/content/browser/renderer_host/render_widget_host_view_win.h
index 84705bb..c9eca60 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.h
+++ b/content/browser/renderer_host/render_widget_host_view_win.h
@@ -259,8 +259,9 @@ class RenderWidgetHostViewWin
virtual void FatalAccessibilityTreeError() OVERRIDE;
// Overridden from ui::GestureEventHelper.
- virtual bool DispatchLongPressGestureEvent(ui::GestureEvent* event) OVERRIDE;
- virtual bool DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
+ virtual bool CanDispatchToConsumer(ui::GestureConsumer* consumer) OVERRIDE;
+ virtual void DispatchLongPressGestureEvent(ui::GestureEvent* event) OVERRIDE;
+ virtual void DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
// Overridden from ui::TextInputClient for Win8/metro TSF support.
// Following methods are not used in existing IMM32 related implementation.
diff --git a/ui/aura/client/default_capture_client.cc b/ui/aura/client/default_capture_client.cc
index 9b5fff5..dae3b7d 100644
--- a/ui/aura/client/default_capture_client.cc
+++ b/ui/aura/client/default_capture_client.cc
@@ -23,8 +23,8 @@ void DefaultCaptureClient::SetCapture(Window* window) {
if (capture_window_ == window)
return;
if (window) {
- root_window_->gesture_recognizer()->
- TransferEventsTo(capture_window_, window);
+ ui::GestureRecognizer::Get()->TransferEventsTo(
+ capture_window_, window);
}
Window* old_capture_window = capture_window_;
diff --git a/ui/aura/gestures/gesture_recognizer_unittest.cc b/ui/aura/gestures/gesture_recognizer_unittest.cc
index 38aca7f..a8db300 100644
--- a/ui/aura/gestures/gesture_recognizer_unittest.cc
+++ b/ui/aura/gestures/gesture_recognizer_unittest.cc
@@ -453,8 +453,8 @@ class TestOneShotGestureSequenceTimer
class TimerTestGestureSequence : public ui::GestureSequence {
public:
- explicit TimerTestGestureSequence(ui::GestureEventHelper* helper)
- : ui::GestureSequence(helper) {
+ explicit TimerTestGestureSequence(ui::GestureSequenceDelegate* delegate)
+ : ui::GestureSequence(delegate) {
}
void ForceTimeout() {
@@ -476,8 +476,7 @@ class TimerTestGestureSequence : public ui::GestureSequence {
class TestGestureRecognizer : public ui::GestureRecognizerImpl {
public:
- explicit TestGestureRecognizer(RootWindow* root_window)
- : GestureRecognizerImpl(root_window) {
+ TestGestureRecognizer() : GestureRecognizerImpl() {
}
ui::GestureSequence* GetGestureSequenceForTesting(Window* window) {
@@ -490,13 +489,12 @@ class TestGestureRecognizer : public ui::GestureRecognizerImpl {
class TimerTestGestureRecognizer : public TestGestureRecognizer {
public:
- explicit TimerTestGestureRecognizer(RootWindow* root_window)
- : TestGestureRecognizer(root_window) {
+ TimerTestGestureRecognizer() : TestGestureRecognizer() {
}
virtual ui::GestureSequence* CreateSequence(
- ui::GestureEventHelper* helper) OVERRIDE {
- return new TimerTestGestureSequence(helper);
+ ui::GestureSequenceDelegate* delegate) OVERRIDE {
+ return new TimerTestGestureSequence(delegate);
}
private:
@@ -507,6 +505,26 @@ base::TimeDelta GetTime() {
return ui::EventTimeForNow();
}
+class ScopedGestureRecognizerSetter {
+ public:
+ // Takes ownership of |new_gr|.
+ explicit ScopedGestureRecognizerSetter(ui::GestureRecognizer* new_gr)
+ : new_gr_(new_gr) {
+ original_gr_ = ui::GestureRecognizer::Get();
+ ui::SetGestureRecognizerForTesting(new_gr_.get());
+ }
+
+ virtual ~ScopedGestureRecognizerSetter() {
+ ui::SetGestureRecognizerForTesting(original_gr_);
+ }
+
+ private:
+ ui::GestureRecognizer* original_gr_;
+ scoped_ptr<ui::GestureRecognizer> new_gr_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedGestureRecognizerSetter);
+};
+
class TimedEvents {
private:
int simulated_now_;
@@ -1254,9 +1272,9 @@ TEST_F(GestureRecognizerTest, GestureEventLongPress) {
delegate->Reset();
TimerTestGestureRecognizer* gesture_recognizer =
- new TimerTestGestureRecognizer(root_window());
+ new TimerTestGestureRecognizer();
- root_window()->SetGestureRecognizerForTesting(gesture_recognizer);
+ ScopedGestureRecognizerSetter gr_setter(gesture_recognizer);
ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201),
kTouchId, tes.Now());
@@ -1300,12 +1318,12 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) {
delegate->Reset();
TimerTestGestureRecognizer* gesture_recognizer =
- new TimerTestGestureRecognizer(root_window());
+ new TimerTestGestureRecognizer();
TimerTestGestureSequence* gesture_sequence =
static_cast<TimerTestGestureSequence*>(
gesture_recognizer->GetGestureSequenceForTesting(window.get()));
- root_window()->SetGestureRecognizerForTesting(gesture_recognizer);
+ ScopedGestureRecognizerSetter gr_setter(gesture_recognizer);
ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201),
kTouchId, tes.Now());
@@ -1346,9 +1364,9 @@ TEST_F(GestureRecognizerTest, GestureEventLongTap) {
delegate->Reset();
TimerTestGestureRecognizer* gesture_recognizer =
- new TimerTestGestureRecognizer(root_window());
+ new TimerTestGestureRecognizer();
- root_window()->SetGestureRecognizerForTesting(gesture_recognizer);
+ ScopedGestureRecognizerSetter gr_setter(gesture_recognizer);
ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201),
kTouchId, tes.Now());
@@ -1392,12 +1410,12 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledBySecondTap) {
delegate.get(), -1234, bounds, root_window()));
TimerTestGestureRecognizer* gesture_recognizer =
- new TimerTestGestureRecognizer(root_window());
+ new TimerTestGestureRecognizer();
TimerTestGestureSequence* gesture_sequence =
static_cast<TimerTestGestureSequence*>(
gesture_recognizer->GetGestureSequenceForTesting(window.get()));
- root_window()->SetGestureRecognizerForTesting(gesture_recognizer);
+ ScopedGestureRecognizerSetter gr_setter(gesture_recognizer);
delegate->Reset();
ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201),
@@ -2058,10 +2076,9 @@ TEST_F(GestureRecognizerTest, GestureEventIgnoresDisconnectedEvents) {
// Check that a touch is locked to the window of the closest current touch
// within max_separation_for_gesture_touches_in_pixels
TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) {
- ui::GestureRecognizer* gesture_recognizer =
- new ui::GestureRecognizerImpl(root_window());
+ ui::GestureRecognizer* gesture_recognizer = new ui::GestureRecognizerImpl();
TimedEvents tes;
- root_window()->SetGestureRecognizerForTesting(gesture_recognizer);
+ ScopedGestureRecognizerSetter gr_setter(gesture_recognizer);
ui::GestureConsumer* target;
const int kNumWindows = 4;
@@ -2146,9 +2163,9 @@ TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) {
// by the root window's gesture sequence.
TEST_F(GestureRecognizerTest, GestureEventOutsideRootWindowTap) {
TestGestureRecognizer* gesture_recognizer =
- new TestGestureRecognizer(root_window());
+ new TestGestureRecognizer();
TimedEvents tes;
- root_window()->SetGestureRecognizerForTesting(gesture_recognizer);
+ ScopedGestureRecognizerSetter gr_setter(gesture_recognizer);
scoped_ptr<aura::Window> window(CreateTestWindowWithBounds(
gfx::Rect(-100, -100, 2000, 2000), root_window()));
@@ -2298,8 +2315,8 @@ TEST_F(GestureRecognizerTest, CaptureSendsGestureEnd) {
scoped_ptr<GestureEventConsumeDelegate> delegate(
new GestureEventConsumeDelegate());
TestGestureRecognizer* gesture_recognizer =
- new TestGestureRecognizer(root_window());
- root_window()->SetGestureRecognizerForTesting(gesture_recognizer);
+ new TestGestureRecognizer();
+ ScopedGestureRecognizerSetter gr_setter(gesture_recognizer);
scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
delegate.get(), -1234, gfx::Rect(10, 10, 300, 300), root_window()));
@@ -2378,8 +2395,8 @@ TEST_F(GestureRecognizerTest, PressDoesNotCrash) {
scoped_ptr<GestureEventConsumeDelegate> delegate(
new GestureEventConsumeDelegate());
TestGestureRecognizer* gesture_recognizer =
- new TestGestureRecognizer(root_window());
- root_window()->SetGestureRecognizerForTesting(gesture_recognizer);
+ new TestGestureRecognizer();
+ ScopedGestureRecognizerSetter gr_setter(gesture_recognizer);
TimedEvents tes;
scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
@@ -2815,9 +2832,9 @@ TEST_F(GestureRecognizerTest, FlushAllOnHide) {
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2);
window->Hide();
EXPECT_EQ(NULL,
- root_window()->gesture_recognizer()->GetTouchLockedTarget(&press1));
+ ui::GestureRecognizer::Get()->GetTouchLockedTarget(&press1));
EXPECT_EQ(NULL,
- root_window()->gesture_recognizer()->GetTouchLockedTarget(&press2));
+ ui::GestureRecognizer::Get()->GetTouchLockedTarget(&press2));
}
TEST_F(GestureRecognizerTest, LongPressTimerStopsOnPreventDefaultedTouchMoves) {
@@ -2831,12 +2848,12 @@ TEST_F(GestureRecognizerTest, LongPressTimerStopsOnPreventDefaultedTouchMoves) {
TimedEvents tes;
TimerTestGestureRecognizer* gesture_recognizer =
- new TimerTestGestureRecognizer(root_window());
+ new TimerTestGestureRecognizer();
TimerTestGestureSequence* gesture_sequence =
static_cast<TimerTestGestureSequence*>(
gesture_recognizer->GetGestureSequenceForTesting(window.get()));
- root_window()->SetGestureRecognizerForTesting(gesture_recognizer);
+ ScopedGestureRecognizerSetter gr_setter(gesture_recognizer);
delegate->Reset();
ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201),
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index 9014524..500f307 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -145,7 +145,6 @@ RootWindow::RootWindow(const CreateParams& params)
mouse_pressed_handler_(NULL),
mouse_moved_handler_(NULL),
event_dispatch_target_(NULL),
- gesture_recognizer_(ui::GestureRecognizer::Create(this)),
synthesize_mouse_move_(false),
move_hold_count_(0),
event_factory_(this),
@@ -159,11 +158,14 @@ RootWindow::RootWindow(const CreateParams& params)
prop_.reset(new ui::ViewProp(host_->GetAcceleratedWidget(),
kRootWindowForAcceleratedWidget,
this));
+ ui::GestureRecognizer::Get()->AddGestureEventHelper(this);
}
RootWindow::~RootWindow() {
TRACE_EVENT0("shutdown", "RootWindow::Destructor");
+ ui::GestureRecognizer::Get()->RemoveGestureEventHelper(this);
+
// Make sure to destroy the compositor before terminating so that state is
// cleared and we don't hit asserts.
compositor_.reset();
@@ -324,7 +326,7 @@ Window* RootWindow::GetGestureTarget(ui::GestureEvent* event) {
Window* target = client::GetCaptureWindow(this);
if (!target) {
target = ConsumerToWindow(
- gesture_recognizer_->GetTargetForGestureEvent(event));
+ ui::GestureRecognizer::Get()->GetTargetForGestureEvent(event));
}
return target;
@@ -445,15 +447,11 @@ void RootWindow::ProcessedTouchEvent(ui::TouchEvent* event,
Window* window,
ui::EventResult result) {
scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
- gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(
- *event, result, window));
+ gestures.reset(ui::GestureRecognizer::Get()->
+ ProcessTouchEventForGesture(*event, result, window));
ProcessGestures(gestures.get());
}
-void RootWindow::SetGestureRecognizerForTesting(ui::GestureRecognizer* gr) {
- gesture_recognizer_.reset(gr);
-}
-
gfx::AcceleratedWidget RootWindow::GetAcceleratedWidget() {
return host_->GetAcceleratedWidget();
}
@@ -656,7 +654,7 @@ void RootWindow::OnWindowHidden(Window* invisible, WindowHiddenReason reason) {
}
void RootWindow::CleanupGestureRecognizerState(Window* window) {
- gesture_recognizer_->CleanupStateForConsumer(window);
+ ui::GestureRecognizer::Get()->CleanupStateForConsumer(window);
const Windows& windows = window->children();
for (Windows::const_iterator iter = windows.begin();
iter != windows.end();
@@ -712,14 +710,6 @@ void RootWindow::OnDeviceScaleFactorChanged(
void RootWindow::UpdateCapture(Window* old_capture,
Window* new_capture) {
- if (!new_capture && old_capture && old_capture->GetRootWindow() != this) {
- // If we no longer contain the window that had capture make sure we clean
- // state in the GestureRecognizer. Since we don't contain the window we'll
- // never get notification of its destruction and clean up state.
- // We do this early on as OnCaptureLost() may delete |old_capture|.
- gesture_recognizer_->CleanupStateForConsumer(old_capture);
- }
-
// |mouse_moved_handler_| may have been set to a Window in a different root
// (see below). Clear it here to ensure we don't end up referencing a stale
// Window.
@@ -767,12 +757,17 @@ bool RootWindow::CanDispatchToTarget(ui::EventTarget* target) {
////////////////////////////////////////////////////////////////////////////////
// RootWindow, ui::GestureEventHelper implementation:
-bool RootWindow::DispatchLongPressGestureEvent(ui::GestureEvent* event) {
- return DispatchGestureEvent(event);
+bool RootWindow::CanDispatchToConsumer(ui::GestureConsumer* consumer) {
+ Window* window = ConsumerToWindow(consumer);;
+ return (window && window->GetRootWindow() == this);
+}
+
+void RootWindow::DispatchLongPressGestureEvent(ui::GestureEvent* event) {
+ DispatchGestureEvent(event);
}
-bool RootWindow::DispatchCancelTouchEvent(ui::TouchEvent* event) {
- return OnHostTouchEvent(event);
+void RootWindow::DispatchCancelTouchEvent(ui::TouchEvent* event) {
+ OnHostTouchEvent(event);
}
////////////////////////////////////////////////////////////////////////////////
@@ -1062,10 +1057,10 @@ bool RootWindow::DispatchTouchEventImpl(ui::TouchEvent* event) {
Window* target = client::GetCaptureWindow(this);
if (!target) {
target = ConsumerToWindow(
- gesture_recognizer_->GetTouchLockedTarget(event));
+ ui::GestureRecognizer::Get()->GetTouchLockedTarget(event));
if (!target) {
- target = ConsumerToWindow(
- gesture_recognizer_->GetTargetForLocation(event->location()));
+ target = ConsumerToWindow(ui::GestureRecognizer::Get()->
+ GetTargetForLocation(event->location()));
}
}
@@ -1096,8 +1091,8 @@ bool RootWindow::DispatchTouchEventImpl(ui::TouchEvent* event) {
// Get the list of GestureEvents from GestureRecognizer.
scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
- gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(
- event_for_gr, result, target));
+ gestures.reset(ui::GestureRecognizer::Get()->
+ ProcessTouchEventForGesture(event_for_gr, result, target));
return ProcessGestures(gestures.get()) ? true : handled;
}
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index b8c4455..7c84fa7 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -208,13 +208,6 @@ class AURA_EXPORT RootWindow : public Window,
Window* window,
ui::EventResult result);
- ui::GestureRecognizer* gesture_recognizer() const {
- return gesture_recognizer_.get();
- }
-
- // Provided only for testing:
- void SetGestureRecognizerForTesting(ui::GestureRecognizer* gr);
-
// Returns the accelerated widget from the RootWindowHost.
gfx::AcceleratedWidget GetAcceleratedWidget();
@@ -318,8 +311,9 @@ class AURA_EXPORT RootWindow : public Window,
virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE;
// Overridden from ui::GestureEventHelper.
- virtual bool DispatchLongPressGestureEvent(ui::GestureEvent* event) OVERRIDE;
- virtual bool DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
+ virtual bool CanDispatchToConsumer(ui::GestureConsumer* consumer) OVERRIDE;
+ virtual void DispatchLongPressGestureEvent(ui::GestureEvent* event) OVERRIDE;
+ virtual void DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
// Overridden from ui::LayerAnimationObserver:
virtual void OnLayerAnimationEnded(
@@ -386,9 +380,6 @@ class AURA_EXPORT RootWindow : public Window,
Window* mouse_moved_handler_;
Window* event_dispatch_target_;
- // The gesture_recognizer_ for this.
- scoped_ptr<ui::GestureRecognizer> gesture_recognizer_;
-
bool synthesize_mouse_move_;
bool waiting_on_compositing_end_;
bool draw_on_compositing_end_;
diff --git a/ui/events/gestures/gesture_recognizer.h b/ui/events/gestures/gesture_recognizer.h
index 604dd41..fd5136d 100644
--- a/ui/events/gestures/gesture_recognizer.h
+++ b/ui/events/gestures/gesture_recognizer.h
@@ -17,7 +17,8 @@ namespace ui {
// into gestures.
class EVENTS_EXPORT GestureRecognizer {
public:
- static GestureRecognizer* Create(GestureEventHelper* helper);
+ static GestureRecognizer* Create();
+ static GestureRecognizer* Get();
// List of GestureEvent*.
typedef ScopedVector<GestureEvent> Gestures;
@@ -64,6 +65,17 @@ class EVENTS_EXPORT GestureRecognizer {
// |consumer| false is returned and |point| is untouched.
virtual bool GetLastTouchPointForTarget(GestureConsumer* consumer,
gfx::Point* point) = 0;
+
+ // Subscribes |helper| for dispatching async gestures such as long press.
+ // The Gesture Recognizer does NOT take ownership of |helper| and it is the
+ // responsibility of the |helper| to call |RemoveGestureEventHelper()| on
+ // destruction.
+ virtual void AddGestureEventHelper(GestureEventHelper* helper) = 0;
+
+ // Unsubscribes |helper| from async gesture dispatch.
+ // Since the GestureRecognizer does not own the |helper|, it is not deleted
+ // and must be cleaned up appropriately by the caller.
+ virtual void RemoveGestureEventHelper(GestureEventHelper* helper) = 0;
};
} // namespace ui
diff --git a/ui/events/gestures/gesture_recognizer_impl.cc b/ui/events/gestures/gesture_recognizer_impl.cc
index a472a0c..3e1d02a 100644
--- a/ui/events/gestures/gesture_recognizer_impl.cc
+++ b/ui/events/gestures/gesture_recognizer_impl.cc
@@ -99,8 +99,7 @@ void TransferTouchIdToConsumerMap(
////////////////////////////////////////////////////////////////////////////////
// GestureRecognizerImpl, public:
-GestureRecognizerImpl::GestureRecognizerImpl(GestureEventHelper* helper)
- : helper_(helper) {
+GestureRecognizerImpl::GestureRecognizerImpl() {
gesture_consumer_ignorer_.reset(new GestureConsumerIgnorer());
}
@@ -159,13 +158,15 @@ void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer,
// Don't send a cancel to |current_consumer|, unless |new_consumer| is NULL.
for (TouchIdToConsumerMap::iterator i = touch_id_target_.begin();
i != touch_id_target_.end(); ++i) {
- if (i->second != new_consumer &&
+ if (i->second && i->second != new_consumer &&
(i->second != current_consumer || new_consumer == NULL) &&
i->second != gesture_consumer_ignorer_.get()) {
TouchEvent touch_event(ui::ET_TOUCH_CANCELLED, gfx::Point(0, 0),
ui::EF_IS_SYNTHESIZED, i->first,
ui::EventTimeForNow(), 0.0f, 0.0f, 0.0f, 0.0f);
- helper_->DispatchCancelTouchEvent(&touch_event);
+ GestureEventHelper* helper = FindDispatchHelperForConsumer(i->second);
+ if (helper)
+ helper->DispatchCancelTouchEvent(&touch_event);
DCHECK_EQ(gesture_consumer_ignorer_.get(), i->second);
}
}
@@ -194,8 +195,8 @@ bool GestureRecognizerImpl::GetLastTouchPointForTarget(
// GestureRecognizerImpl, protected:
GestureSequence* GestureRecognizerImpl::CreateSequence(
- GestureEventHelper* helper) {
- return new GestureSequence(helper);
+ GestureSequenceDelegate* delegate) {
+ return new GestureSequence(delegate);
}
////////////////////////////////////////////////////////////////////////////////
@@ -205,7 +206,7 @@ GestureSequence* GestureRecognizerImpl::GetGestureSequenceForConsumer(
GestureConsumer* consumer) {
GestureSequence* gesture_sequence = consumer_sequence_[consumer];
if (!gesture_sequence) {
- gesture_sequence = CreateSequence(helper_);
+ gesture_sequence = CreateSequence(this);
consumer_sequence_[consumer] = gesture_sequence;
}
return gesture_sequence;
@@ -243,9 +244,62 @@ void GestureRecognizerImpl::CleanupStateForConsumer(GestureConsumer* consumer) {
RemoveConsumerFromMap(consumer, &touch_id_target_for_gestures_);
}
+void GestureRecognizerImpl::AddGestureEventHelper(GestureEventHelper* helper) {
+ helpers_.push_back(helper);
+}
+
+void GestureRecognizerImpl::RemoveGestureEventHelper(
+ GestureEventHelper* helper) {
+ std::vector<GestureEventHelper*>::iterator it = std::find(helpers_.begin(),
+ helpers_.end(), helper);
+ if (it != helpers_.end())
+ helpers_.erase(it);
+}
+
+void GestureRecognizerImpl::DispatchLongPressGestureEvent(GestureEvent* event) {
+ GestureConsumer* consumer = GetTargetForGestureEvent(event);
+ if (consumer) {
+ GestureEventHelper* helper = FindDispatchHelperForConsumer(consumer);
+ if (helper)
+ helper->DispatchLongPressGestureEvent(event);
+ }
+}
+
+GestureEventHelper* GestureRecognizerImpl::FindDispatchHelperForConsumer(
+ GestureConsumer* consumer) {
+ std::vector<GestureEventHelper*>::iterator it;
+ for (it = helpers_.begin(); it != helpers_.end(); ++it) {
+ if ((*it)->CanDispatchToConsumer(consumer))
+ return (*it);
+ }
+ return NULL;
+}
+
// GestureRecognizer, static
-GestureRecognizer* GestureRecognizer::Create(GestureEventHelper* helper) {
- return new GestureRecognizerImpl(helper);
+GestureRecognizer* GestureRecognizer::Create() {
+ return new GestureRecognizerImpl();
+}
+
+static GestureRecognizerImpl* g_gesture_recognizer_instance = NULL;
+
+// GestureRecognizer, static
+GestureRecognizer* GestureRecognizer::Get() {
+ if (!g_gesture_recognizer_instance)
+ g_gesture_recognizer_instance = new GestureRecognizerImpl();
+ return g_gesture_recognizer_instance;
+}
+
+void SetGestureRecognizerForTesting(GestureRecognizer* gesture_recognizer) {
+ // Transfer helpers to the new GR.
+ std::vector<GestureEventHelper*>& helpers =
+ g_gesture_recognizer_instance->helpers();
+ std::vector<GestureEventHelper*>::iterator it;
+ for (it = helpers.begin(); it != helpers.end(); ++it)
+ gesture_recognizer->AddGestureEventHelper(*it);
+
+ helpers.clear();
+ g_gesture_recognizer_instance =
+ static_cast<GestureRecognizerImpl*>(gesture_recognizer);
}
} // namespace ui
diff --git a/ui/events/gestures/gesture_recognizer_impl.h b/ui/events/gestures/gesture_recognizer_impl.h
index 2ede77d5..35ddaac 100644
--- a/ui/events/gestures/gesture_recognizer_impl.h
+++ b/ui/events/gestures/gesture_recognizer_impl.h
@@ -13,6 +13,7 @@
#include "ui/events/event_constants.h"
#include "ui/events/events_export.h"
#include "ui/events/gestures/gesture_recognizer.h"
+#include "ui/events/gestures/gesture_sequence.h"
#include "ui/gfx/point.h"
namespace ui {
@@ -22,13 +23,16 @@ class GestureEventHelper;
class GestureSequence;
class TouchEvent;
-class EVENTS_EXPORT GestureRecognizerImpl : public GestureRecognizer {
+class EVENTS_EXPORT GestureRecognizerImpl : public GestureRecognizer,
+ public GestureSequenceDelegate {
public:
typedef std::map<int, GestureConsumer*> TouchIdToConsumerMap;
- explicit GestureRecognizerImpl(GestureEventHelper* helper);
+ GestureRecognizerImpl();
virtual ~GestureRecognizerImpl();
+ std::vector<GestureEventHelper*>& helpers() { return helpers_; }
+
// Overridden from GestureRecognizer
virtual GestureConsumer* GetTouchLockedTarget(TouchEvent* event) OVERRIDE;
virtual GestureConsumer* GetTargetForGestureEvent(
@@ -41,7 +45,7 @@ class EVENTS_EXPORT GestureRecognizerImpl : public GestureRecognizer {
gfx::Point* point) OVERRIDE;
protected:
- virtual GestureSequence* CreateSequence(GestureEventHelper* helper);
+ virtual GestureSequence* CreateSequence(GestureSequenceDelegate* delegate);
virtual GestureSequence* GetGestureSequenceForConsumer(GestureConsumer* c);
private:
@@ -54,6 +58,15 @@ class EVENTS_EXPORT GestureRecognizerImpl : public GestureRecognizer {
ui::EventResult result,
GestureConsumer* target) OVERRIDE;
virtual void CleanupStateForConsumer(GestureConsumer* consumer) OVERRIDE;
+ virtual void AddGestureEventHelper(GestureEventHelper* helper) OVERRIDE;
+ virtual void RemoveGestureEventHelper(GestureEventHelper* helper) OVERRIDE;
+
+ // Overridden from ui::GestureSequenceDelegate.
+ virtual void DispatchLongPressGestureEvent(GestureEvent* event) OVERRIDE;
+
+ // Convenience method to find the GestureEventHelper that can dispatch events
+ // to a specific |consumer|.
+ GestureEventHelper* FindDispatchHelperForConsumer(GestureConsumer* consumer);
std::map<GestureConsumer*, GestureSequence*> consumer_sequence_;
@@ -67,11 +80,16 @@ class EVENTS_EXPORT GestureRecognizerImpl : public GestureRecognizer {
// Touches cancelled by touch capture are routed to the
// gesture_consumer_ignorer_.
scoped_ptr<GestureConsumer> gesture_consumer_ignorer_;
- GestureEventHelper* helper_;
+
+ std::vector<GestureEventHelper*> helpers_;
DISALLOW_COPY_AND_ASSIGN(GestureRecognizerImpl);
};
+// Provided only for testing:
+EVENTS_EXPORT void SetGestureRecognizerForTesting(
+ GestureRecognizer* gesture_recognizer);
+
} // namespace ui
#endif // UI_EVENTS_GESTURES_GESTURE_RECOGNIZER_IMPL_H_
diff --git a/ui/events/gestures/gesture_sequence.cc b/ui/events/gestures/gesture_sequence.cc
index d364ed2..e728cbc 100644
--- a/ui/events/gestures/gesture_sequence.cc
+++ b/ui/events/gestures/gesture_sequence.cc
@@ -381,14 +381,15 @@ void UpdateGestureEventLatencyInfo(const TouchEvent& event,
////////////////////////////////////////////////////////////////////////////////
// GestureSequence Public:
-GestureSequence::GestureSequence(GestureEventHelper* helper)
+GestureSequence::GestureSequence(GestureSequenceDelegate* delegate)
: state_(GS_NO_GESTURE),
flags_(0),
pinch_distance_start_(0.f),
pinch_distance_current_(0.f),
scroll_type_(ST_FREE),
point_count_(0),
- helper_(helper) {
+ delegate_(delegate) {
+ CHECK(delegate_);
}
GestureSequence::~GestureSequence() {
@@ -1057,7 +1058,7 @@ void GestureSequence::AppendLongPressGestureEvent() {
flags_,
base::Time::FromDoubleT(point->last_touch_time()),
1 << point->touch_id()));
- helper_->DispatchLongPressGestureEvent(gesture.get());
+ delegate_->DispatchLongPressGestureEvent(gesture.get());
}
void GestureSequence::AppendLongTapGestureEvent(const GesturePoint& point,
diff --git a/ui/events/gestures/gesture_sequence.h b/ui/events/gestures/gesture_sequence.h
index 50d9000..9715194 100644
--- a/ui/events/gestures/gesture_sequence.h
+++ b/ui/events/gestures/gesture_sequence.h
@@ -31,13 +31,23 @@ enum ScrollType {
ST_VERTICAL,
};
+// Delegates dispatch of gesture events for which the GestureSequence does not
+// have enough context to dispatch itself.
+class EVENTS_EXPORT GestureSequenceDelegate {
+ public:
+ virtual void DispatchLongPressGestureEvent(GestureEvent* event) = 0;
+
+ protected:
+ virtual ~GestureSequenceDelegate() {}
+};
+
// A GestureSequence recognizes gestures from touch sequences.
class EVENTS_EXPORT GestureSequence {
public:
// Maximum number of points in a single gesture.
static const int kMaxGesturePoints = 12;
- explicit GestureSequence(GestureEventHelper* consumer);
+ explicit GestureSequence(GestureSequenceDelegate* delegate);
virtual ~GestureSequence();
typedef GestureRecognizer::Gestures Gestures;
@@ -219,7 +229,7 @@ class EVENTS_EXPORT GestureSequence {
// Location of the last touch event.
gfx::Point last_touch_location_;
- GestureEventHelper* helper_;
+ GestureSequenceDelegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(GestureSequence);
};
diff --git a/ui/events/gestures/gesture_types.h b/ui/events/gestures/gesture_types.h
index e87a219..b15788a 100644
--- a/ui/events/gestures/gesture_types.h
+++ b/ui/events/gestures/gesture_types.h
@@ -206,8 +206,10 @@ class EVENTS_EXPORT GestureEventHelper {
virtual ~GestureEventHelper() {
}
- virtual bool DispatchLongPressGestureEvent(GestureEvent* event) = 0;
- virtual bool DispatchCancelTouchEvent(TouchEvent* event) = 0;
+ // Returns true if this helper can dispatch events to |consumer|.
+ virtual bool CanDispatchToConsumer(GestureConsumer* consumer) = 0;
+ virtual void DispatchLongPressGestureEvent(GestureEvent* event) = 0;
+ virtual void DispatchCancelTouchEvent(TouchEvent* event) = 0;
};
} // namespace ui
diff --git a/ui/views/corewm/capture_controller.cc b/ui/views/corewm/capture_controller.cc
index c39a9ab..1276c82b 100644
--- a/ui/views/corewm/capture_controller.cc
+++ b/ui/views/corewm/capture_controller.cc
@@ -49,11 +49,8 @@ void CaptureController::SetCapture(aura::Window* new_capture_window) {
// along (and so shouldn't be canceled) and those that got moved, so
// just leave them all where they are.
if (new_capture_window) {
- for (RootWindows::const_iterator i = root_windows.begin();
- i != root_windows.end(); ++i) {
- (*i)->gesture_recognizer()->TransferEventsTo(
- old_capture_window, new_capture_window);
- }
+ ui::GestureRecognizer::Get()->TransferEventsTo(old_capture_window,
+ new_capture_window);
}
capture_window_ = new_capture_window;
diff --git a/ui/views/corewm/capture_controller_unittest.cc b/ui/views/corewm/capture_controller_unittest.cc
index 46a8a2e..edb2410 100644
--- a/ui/views/corewm/capture_controller_unittest.cc
+++ b/ui/views/corewm/capture_controller_unittest.cc
@@ -161,8 +161,8 @@ TEST_F(CaptureControllerTest, TouchTargetResetOnCaptureChange) {
ui::TouchEvent touch_event(
ui::ET_TOUCH_PRESSED, gfx::Point(), 0, 0, ui::EventTimeForNow(), 1.0f,
1.0f, 1.0f, 1.0f);
- EXPECT_EQ(static_cast<ui::GestureConsumer*>(NULL),
- root_window()->gesture_recognizer()->GetTouchLockedTarget(
+ EXPECT_EQ(static_cast<ui::GestureConsumer*>(w2.get()),
+ ui::GestureRecognizer::Get()->GetTouchLockedTarget(
&touch_event));
}
diff --git a/ui/views/widget/desktop_aura/desktop_capture_client.cc b/ui/views/widget/desktop_aura/desktop_capture_client.cc
index 118b5f2..5a5ec4e 100644
--- a/ui/views/widget/desktop_aura/desktop_capture_client.cc
+++ b/ui/views/widget/desktop_aura/desktop_capture_client.cc
@@ -48,10 +48,8 @@ void DesktopCaptureClient::SetCapture(aura::Window* new_capture_window) {
// along (and so shouldn't be canceled) and those that got moved, so
// just leave them all where they are.
if (new_capture_window) {
- for (Roots::const_iterator i = roots.begin(); i != roots.end(); ++i) {
- (*i)->gesture_recognizer()->TransferEventsTo(
- old_capture_window, new_capture_window);
- }
+ ui::GestureRecognizer::Get()->TransferEventsTo(old_capture_window,
+ new_capture_window);
}
capture_window_ = new_capture_window;