diff options
-rw-r--r-- | ash/extended_desktop_unittest.cc | 36 | ||||
-rw-r--r-- | ui/aura/window_event_dispatcher.cc | 4 | ||||
-rw-r--r-- | ui/aura/window_targeter.cc | 48 | ||||
-rw-r--r-- | ui/aura/window_targeter.h | 2 |
4 files changed, 62 insertions, 28 deletions
diff --git a/ash/extended_desktop_unittest.cc b/ash/extended_desktop_unittest.cc index 0a7efa3..4276b5d 100644 --- a/ash/extended_desktop_unittest.cc +++ b/ash/extended_desktop_unittest.cc @@ -421,34 +421,46 @@ TEST_F(ExtendedDesktopTest, Capture) { EXPECT_EQ(r1_w1.get(), aura::client::GetCaptureWindow(r2_w1->GetRootWindow())); - aura::test::EventGenerator generator2(root_windows[1]); - generator2.MoveMouseToCenterOf(r2_w1.get()); - generator2.ClickLeftButton(); + aura::test::EventGenerator& generator = GetEventGenerator(); + generator.MoveMouseToCenterOf(r2_w1.get()); + // |r1_w1| will receive the events because it has capture. + EXPECT_EQ("1 1 0", r1_d1.GetMouseMotionCountsAndReset()); + EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset()); + EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset()); + + generator.ClickLeftButton(); EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset()); EXPECT_EQ("0 0", r2_d1.GetMouseButtonCountsAndReset()); // The mouse is outside. On chromeos, the mouse is warped to the // dest root window, but it's not implemented on Win yet, so // no mouse move event on Win. - EXPECT_EQ("1 1 0", r1_d1.GetMouseMotionCountsAndReset()); + EXPECT_EQ("0 0 0", r1_d1.GetMouseMotionCountsAndReset()); EXPECT_EQ("1 1", r1_d1.GetMouseButtonCountsAndReset()); - // Emulate passive grab. (15,15) on 1st display is (-985,15) on 2nd - // display. - generator2.MoveMouseTo(-985, 15); + + generator.MoveMouseTo(15, 15); EXPECT_EQ("0 1 0", r1_d1.GetMouseMotionCountsAndReset()); + EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset()); r1_w2->SetCapture(); EXPECT_EQ(r1_w2.get(), aura::client::GetCaptureWindow(r2_w1->GetRootWindow())); - generator2.MoveMouseBy(10, 10); - generator2.ClickLeftButton(); + generator.MoveMouseBy(10, 10); + // |r1_w2| has the capture. So it will receive the mouse-move event. + EXPECT_EQ("0 0 0", r1_d1.GetMouseMotionCountsAndReset()); + EXPECT_EQ("0 1 0", r1_d2.GetMouseMotionCountsAndReset()); + EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset()); + + generator.ClickLeftButton(); EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset()); EXPECT_EQ("0 0", r2_d1.GetMouseButtonCountsAndReset()); - EXPECT_EQ("1 1 0", r1_d2.GetMouseMotionCountsAndReset()); + EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset()); EXPECT_EQ("1 1", r1_d2.GetMouseButtonCountsAndReset()); + r1_w2->ReleaseCapture(); EXPECT_EQ(NULL, aura::client::GetCaptureWindow(r2_w1->GetRootWindow())); - generator2.MoveMouseTo(15, 15); - generator2.ClickLeftButton(); + + generator.MoveMouseToCenterOf(r2_w1.get()); + generator.ClickLeftButton(); EXPECT_EQ("1 1 0", r2_d1.GetMouseMotionCountsAndReset()); EXPECT_EQ("1 1", r2_d1.GetMouseButtonCountsAndReset()); // Make sure the mouse_moved_handler_ is properly reset. diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc index fce9acc..3fbfdba 100644 --- a/ui/aura/window_event_dispatcher.cc +++ b/ui/aura/window_event_dispatcher.cc @@ -547,6 +547,9 @@ bool WindowEventDispatcher::CanDispatchToTarget(ui::EventTarget* target) { ui::EventDispatchDetails WindowEventDispatcher::PreDispatchEvent( ui::EventTarget* target, ui::Event* event) { + Window* target_window = static_cast<Window*>(target); + CHECK(window()->Contains(target_window)); + if (!dispatching_held_event_) { bool can_be_held = IsEventCandidateForHold(*event); if (!move_hold_count_ || !can_be_held) { @@ -558,7 +561,6 @@ ui::EventDispatchDetails WindowEventDispatcher::PreDispatchEvent( } } - Window* target_window = static_cast<Window*>(target); if (event->IsMouseEvent()) { PreDispatchMouseEvent(target_window, static_cast<ui::MouseEvent*>(event)); } else if (event->IsScrollEvent()) { diff --git a/ui/aura/window_targeter.cc b/ui/aura/window_targeter.cc index 5df06b0..a50f981 100644 --- a/ui/aura/window_targeter.cc +++ b/ui/aura/window_targeter.cc @@ -45,23 +45,22 @@ bool WindowTargeter::EventLocationInsideBounds( ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root, ui::Event* event) { - if (event->IsKeyEvent()) { - Window* window = static_cast<Window*>(root); - Window* root_window = window->GetRootWindow(); - const ui::KeyEvent& key = static_cast<const ui::KeyEvent&>(*event); - if (key.key_code() == ui::VKEY_UNKNOWN) - return NULL; - client::EventClient* event_client = client::GetEventClient(root_window); - client::FocusClient* focus_client = client::GetFocusClient(root_window); - Window* focused_window = focus_client->GetFocusedWindow(); - if (event_client && - !event_client->CanProcessEventsWithinSubtree(focused_window)) { - focus_client->FocusWindow(NULL); - return NULL; + Window* window = static_cast<Window*>(root); + Window* target = event->IsKeyEvent() ? + FindTargetForKeyEvent(window, *static_cast<ui::KeyEvent*>(event)) : + static_cast<Window*>(EventTargeter::FindTargetForEvent(root, event)); + if (target && !window->parent()) { + // |window| is the root window. + if (!window->Contains(target)) { + // |target| is not a descendent of |window|. So do not allow dispatching + // from here. Instead, dispatch the event through the + // WindowEventDispatcher that owns |target|. + ui::EventDispatchDetails details ALLOW_UNUSED = + target->GetDispatcher()->OnEventFromSource(event); + target = NULL; } - return focused_window ? focused_window : window; } - return EventTargeter::FindTargetForEvent(root, event); + return target; } bool WindowTargeter::SubtreeShouldBeExploredForEvent( @@ -88,6 +87,25 @@ ui::EventTarget* WindowTargeter::FindTargetForLocatedEvent( return EventTargeter::FindTargetForLocatedEvent(root, event); } +Window* WindowTargeter::FindTargetForKeyEvent(Window* window, + const ui::KeyEvent& key) { + Window* root_window = window->GetRootWindow(); + if (key.key_code() == ui::VKEY_UNKNOWN) + return NULL; + client::FocusClient* focus_client = client::GetFocusClient(root_window); + Window* focused_window = focus_client->GetFocusedWindow(); + if (!focused_window) + return window; + + client::EventClient* event_client = client::GetEventClient(root_window); + if (event_client && + !event_client->CanProcessEventsWithinSubtree(focused_window)) { + focus_client->FocusWindow(NULL); + return NULL; + } + return focused_window ? focused_window : window; +} + Window* WindowTargeter::FindTargetInRootWindow(Window* root_window, const ui::LocatedEvent& event) { DCHECK_EQ(root_window, root_window->GetRootWindow()); diff --git a/ui/aura/window_targeter.h b/ui/aura/window_targeter.h index 8d35fed..0b0acb3 100644 --- a/ui/aura/window_targeter.h +++ b/ui/aura/window_targeter.h @@ -38,6 +38,8 @@ class AURA_EXPORT WindowTargeter : public ui::EventTargeter { const ui::LocatedEvent& event) OVERRIDE; private: + Window* FindTargetForKeyEvent(Window* root_window, + const ui::KeyEvent& event); Window* FindTargetInRootWindow(Window* root_window, const ui::LocatedEvent& event); |