summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/extended_desktop_unittest.cc36
-rw-r--r--ui/aura/window_event_dispatcher.cc4
-rw-r--r--ui/aura/window_targeter.cc48
-rw-r--r--ui/aura/window_targeter.h2
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);