summaryrefslogtreecommitdiffstats
path: root/ui/aura/window_event_dispatcher_unittest.cc
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-28 16:29:20 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-28 16:29:20 +0000
commitd5e3c65c19d58df811c624c8736e0aff7b1ad3cb (patch)
treee6df64ce7282f2fc397d466ac6afbb15384a7876 /ui/aura/window_event_dispatcher_unittest.cc
parentffa95137c87a13264831d6038db4600368495c9e (diff)
downloadchromium_src-d5e3c65c19d58df811c624c8736e0aff7b1ad3cb.zip
chromium_src-d5e3c65c19d58df811c624c8736e0aff7b1ad3cb.tar.gz
chromium_src-d5e3c65c19d58df811c624c8736e0aff7b1ad3cb.tar.bz2
aura: Fix a crash related to nested event-dispatch.
If events are being dispatched from a nested message-loop, and the target of the outer loop is hidden or moved to another dispatcher during dispatching events in the inner loop, then reset the target for the outer loop. BUG=347012 R=sky@chromium.org Review URL: https://codereview.chromium.org/180973007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254150 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/aura/window_event_dispatcher_unittest.cc')
-rw-r--r--ui/aura/window_event_dispatcher_unittest.cc95
1 files changed, 95 insertions, 0 deletions
diff --git a/ui/aura/window_event_dispatcher_unittest.cc b/ui/aura/window_event_dispatcher_unittest.cc
index 87e6193..e320d87 100644
--- a/ui/aura/window_event_dispatcher_unittest.cc
+++ b/ui/aura/window_event_dispatcher_unittest.cc
@@ -1836,4 +1836,99 @@ TEST_F(WindowEventDispatcherTest, HostCancelModeWithFocusedWindowOutside) {
client::GetFocusClient(root_window())->GetFocusedWindow());
}
+// Dispatches a mouse-move event to |target| when it receives a mouse-move
+// event.
+class DispatchEventHandler : public ui::EventHandler {
+ public:
+ explicit DispatchEventHandler(Window* target)
+ : target_(target),
+ dispatched_(false) {}
+ virtual ~DispatchEventHandler() {}
+
+ bool dispatched() const { return dispatched_; }
+ private:
+ // ui::EventHandler:
+ virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE {
+ if (mouse->type() == ui::ET_MOUSE_MOVED) {
+ ui::MouseEvent move(ui::ET_MOUSE_MOVED, target_->bounds().CenterPoint(),
+ target_->bounds().CenterPoint(), ui::EF_NONE, ui::EF_NONE);
+ target_->GetDispatcher()->OnEventFromSource(&move);
+ EXPECT_EQ(target_, move.target());
+ dispatched_ = true;
+ }
+ ui::EventHandler::OnMouseEvent(mouse);
+ }
+
+ Window* target_;
+ bool dispatched_;
+
+ DISALLOW_COPY_AND_ASSIGN(DispatchEventHandler);
+};
+
+// Moves |window| to |root_window| when it receives a mouse-move event.
+class MoveWindowHandler : public ui::EventHandler {
+ public:
+ MoveWindowHandler(Window* window, Window* root_window)
+ : window_to_move_(window),
+ root_window_to_move_to_(root_window) {}
+ virtual ~MoveWindowHandler() {}
+
+ private:
+ // ui::EventHandler:
+ virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE {
+ if (mouse->type() == ui::ET_MOUSE_MOVED) {
+ root_window_to_move_to_->AddChild(window_to_move_);
+ }
+ ui::EventHandler::OnMouseEvent(mouse);
+ }
+
+ Window* window_to_move_;
+ Window* root_window_to_move_to_;
+
+ DISALLOW_COPY_AND_ASSIGN(MoveWindowHandler);
+};
+
+// Tests that nested event dispatch works correctly if the target of the older
+// event being dispatched is moved to a different dispatcher in response to an
+// event in the inner loop.
+TEST_F(WindowEventDispatcherTest, NestedEventDispatchTargetMoved) {
+ scoped_ptr<WindowTreeHost> second_host(
+ WindowTreeHost::Create(gfx::Rect(20, 30, 100, 50)));
+ second_host->InitHost();
+ Window* second_root = second_host->window();
+
+ // Create two windows parented to |root_window()|.
+ test::TestWindowDelegate delegate;
+ scoped_ptr<Window> first(CreateTestWindowWithDelegate(&delegate, 123,
+ gfx::Rect(20, 10, 10, 20), root_window()));
+ scoped_ptr<Window> second(CreateTestWindowWithDelegate(&delegate, 234,
+ gfx::Rect(40, 10, 50, 20), root_window()));
+
+ // Setup a handler on |first| so that it dispatches an event to |second| when
+ // |first| receives an event.
+ DispatchEventHandler dispatch_event(second.get());
+ first->AddPreTargetHandler(&dispatch_event);
+
+ // Setup a handler on |second| so that it moves |first| into |second_root|
+ // when |second| receives an event.
+ MoveWindowHandler move_window(first.get(), second_root);
+ second->AddPreTargetHandler(&move_window);
+
+ // Some sanity checks: |first| is inside |root_window()|'s tree.
+ EXPECT_EQ(root_window(), first->GetRootWindow());
+ // The two root windows are different.
+ EXPECT_NE(root_window(), second_root);
+
+ // Dispatch an event to |first|.
+ ui::MouseEvent move(ui::ET_MOUSE_MOVED, first->bounds().CenterPoint(),
+ first->bounds().CenterPoint(), ui::EF_NONE, ui::EF_NONE);
+ dispatcher()->OnEventFromSource(&move);
+ EXPECT_EQ(first.get(), move.target());
+ EXPECT_TRUE(dispatch_event.dispatched());
+ EXPECT_EQ(second_root, first->GetRootWindow());
+
+ first->RemovePreTargetHandler(&dispatch_event);
+ second->RemovePreTargetHandler(&move_window);
+}
+
} // namespace aura