summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/aura/root_window.cc13
-rw-r--r--ui/aura/root_window.h4
-rw-r--r--ui/aura/root_window_unittest.cc38
3 files changed, 54 insertions, 1 deletions
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index 8e96cba..aba54cb 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -747,7 +747,18 @@ void RootWindow::OnWindowHidden(Window* invisible, bool destroyed) {
mouse_event_dispatch_target_ = NULL;
if (invisible->Contains(event_dispatch_target_))
event_dispatch_target_ = NULL;
- gesture_recognizer_->FlushTouchQueue(invisible);
+
+ CleanupGestureRecognizerState(invisible);
+}
+
+void RootWindow::CleanupGestureRecognizerState(Window* window) {
+ gesture_recognizer_->FlushTouchQueue(window);
+ Windows windows = window->children();
+ for (Windows::const_iterator iter = windows.begin();
+ iter != windows.end();
+ ++iter) {
+ CleanupGestureRecognizerState(*iter);
+ }
}
void RootWindow::OnWindowAddedToRootWindow(Window* attached) {
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index 9db3aa4..3dac081 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -293,6 +293,10 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// |destroyed| is set to true when the window is being destroyed.
void OnWindowHidden(Window* invisible, bool destroyed);
+ // Cleans up the gesture recognizer for all windows in |window| (including
+ // |window| itself).
+ void CleanupGestureRecognizerState(Window* window);
+
// Overridden from ui::EventDispatcher.
virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE;
virtual void ProcessPreTargetList(ui::EventHandlerList* list) OVERRIDE;
diff --git a/ui/aura/root_window_unittest.cc b/ui/aura/root_window_unittest.cc
index 7e9e093..cc7a729 100644
--- a/ui/aura/root_window_unittest.cc
+++ b/ui/aura/root_window_unittest.cc
@@ -742,4 +742,42 @@ TEST_F(RootWindowTest, DeleteWindowDuringDispatch) {
EXPECT_FALSE(d11.got_event());
}
+namespace {
+
+// A window delegate that detaches the parent of the target's parent window when
+// it receives a tap event.
+class DetachesParentOnTapDelegate : public test::TestWindowDelegate {
+ public:
+ DetachesParentOnTapDelegate() {}
+ virtual ~DetachesParentOnTapDelegate() {}
+
+ private:
+ virtual ui::EventResult OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
+ if (event->type() == ui::ET_GESTURE_TAP_DOWN)
+ return ui::ER_HANDLED;
+
+ if (event->type() == ui::ET_GESTURE_TAP) {
+ Window* parent = static_cast<Window*>(event->target())->parent();
+ parent->parent()->RemoveChild(parent);
+ return ui::ER_HANDLED;
+ }
+ return ui::ER_UNHANDLED;
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(DetachesParentOnTapDelegate);
+};
+
+} // namespace
+
+// Tests that the gesture recognizer is reset for all child windows when a
+// window hides. No expectations, just checks that the test does not crash.
+TEST_F(RootWindowTest, GestureRecognizerResetsTargetWhenParentHides) {
+ scoped_ptr<Window> w1(CreateWindow(1, root_window(), NULL));
+ DetachesParentOnTapDelegate delegate;
+ scoped_ptr<Window> parent(CreateWindow(22, w1.get(), NULL));
+ Window* child = CreateWindow(11, parent.get(), &delegate);
+ test::EventGenerator generator(root_window(), child);
+ generator.GestureTapAt(gfx::Point(40, 40));
+}
+
} // namespace aura