Index: ui/aura/window_targeter.cc |
diff --git a/ui/aura/window_targeter.cc b/ui/aura/window_targeter.cc |
index 7303e22bb0e00abefff87cdda6131b93f374d09d..192bd600c76b411badfaaf6ce75b6d9cb739a0ba 100644 |
--- a/ui/aura/window_targeter.cc |
+++ b/ui/aura/window_targeter.cc |
@@ -12,55 +12,28 @@ |
#include "ui/aura/window_event_dispatcher.h" |
#include "ui/aura/window_tree_host.h" |
#include "ui/events/event_target.h" |
+#include "ui/events/event_target_iterator.h" |
namespace aura { |
-namespace { |
- |
-bool IsLocatedEvent(const ui::Event& event) { |
- return event.IsMouseEvent() || event.IsTouchEvent() || |
- event.IsScrollEvent() || event.IsGestureEvent(); |
-} |
- |
-} // namespace |
- |
WindowTargeter::WindowTargeter() {} |
WindowTargeter::~WindowTargeter() {} |
-ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root, |
- ui::Event* event) { |
- 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->Contains(target)) { |
- // |window| is the root window, but |target| is not a descendent of |
- // |window|. So do not allow dispatching from here. Instead, dispatch the |
- // event through the WindowEventDispatcher that owns |target|. |
- aura::Window* new_root = target->GetRootWindow(); |
- if (IsLocatedEvent(*event)) { |
- // The event has been transformed to be in |target|'s coordinate system. |
- // But dispatching the event through the EventProcessor requires the event |
- // to be in the host's coordinate system. So, convert the event to be in |
- // the root's coordinate space, and then to the host's coordinate space by |
- // applying the host's transform. |
- ui::LocatedEvent* located_event = static_cast<ui::LocatedEvent*>(event); |
- located_event->ConvertLocationToTarget(target, new_root); |
- located_event->UpdateForRootTransform( |
- new_root->GetHost()->GetRootTransform()); |
+Window* WindowTargeter::FindTargetForLocatedEvent(Window* window, |
+ ui::LocatedEvent* event) { |
+ if (!window->parent()) { |
+ Window* target = FindTargetInRootWindow(window, *event); |
+ if (target) { |
+ window->ConvertEventToTarget(target, event); |
+ return target; |
} |
- ignore_result( |
- new_root->GetHost()->event_processor()->OnEventFromSource(event)); |
- |
- target = NULL; |
} |
- return target; |
+ return FindTargetForLocatedEventRecursively(window, event); |
} |
bool WindowTargeter::SubtreeCanAcceptEvent( |
- ui::EventTarget* target, |
+ Window* window, |
const ui::LocatedEvent& event) const { |
- aura::Window* window = static_cast<aura::Window*>(target); |
if (!window->IsVisible()) |
return false; |
if (window->ignore_events()) |
@@ -78,27 +51,56 @@ bool WindowTargeter::SubtreeCanAcceptEvent( |
} |
bool WindowTargeter::EventLocationInsideBounds( |
- ui::EventTarget* target, |
+ Window* window, |
const ui::LocatedEvent& event) const { |
- aura::Window* window = static_cast<aura::Window*>(target); |
gfx::Point point = event.location(); |
if (window->parent()) |
- aura::Window::ConvertPointToTarget(window->parent(), window, &point); |
+ Window::ConvertPointToTarget(window->parent(), window, &point); |
return gfx::Rect(window->bounds().size()).Contains(point); |
} |
-ui::EventTarget* WindowTargeter::FindTargetForLocatedEvent( |
- ui::EventTarget* root, |
- ui::LocatedEvent* event) { |
+ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root, |
+ ui::Event* event) { |
Window* window = static_cast<Window*>(root); |
- if (!window->parent()) { |
- Window* target = FindTargetInRootWindow(window, *event); |
- if (target) { |
- window->ConvertEventToTarget(target, event); |
- return target; |
+ Window* target = |
+ event->IsKeyEvent() |
+ ? FindTargetForKeyEvent(window, *static_cast<ui::KeyEvent*>(event)) |
+ : FindTargetForNonKeyEvent(window, event); |
+ if (target && !window->parent() && !window->Contains(target)) { |
+ // |window| is the root window, but |target| is not a descendent of |
+ // |window|. So do not allow dispatching from here. Instead, dispatch the |
+ // event through the WindowEventDispatcher that owns |target|. |
+ Window* new_root = target->GetRootWindow(); |
+ if (event->IsLocatedEvent()) { |
+ // The event has been transformed to be in |target|'s coordinate system. |
+ // But dispatching the event through the EventProcessor requires the event |
+ // to be in the host's coordinate system. So, convert the event to be in |
+ // the root's coordinate space, and then to the host's coordinate space by |
+ // applying the host's transform. |
+ ui::LocatedEvent* located_event = static_cast<ui::LocatedEvent*>(event); |
+ located_event->ConvertLocationToTarget(target, new_root); |
+ located_event->UpdateForRootTransform( |
+ new_root->GetHost()->GetRootTransform()); |
} |
+ ignore_result( |
+ new_root->GetHost()->event_processor()->OnEventFromSource(event)); |
+ |
+ target = nullptr; |
} |
- return EventTargeter::FindTargetForLocatedEvent(root, event); |
+ return target; |
+} |
+ |
+ui::EventTarget* WindowTargeter::FindNextBestTarget( |
+ ui::EventTarget* previous_target, |
+ ui::Event* event) { |
+ return nullptr; |
+} |
+ |
+bool WindowTargeter::SubtreeShouldBeExploredForEvent( |
+ Window* window, |
+ const ui::LocatedEvent& event) { |
+ return SubtreeCanAcceptEvent(window, event) && |
+ EventLocationInsideBounds(window, event); |
} |
Window* WindowTargeter::FindTargetForKeyEvent(Window* window, |
@@ -112,12 +114,20 @@ Window* WindowTargeter::FindTargetForKeyEvent(Window* window, |
client::EventClient* event_client = client::GetEventClient(root_window); |
if (event_client && |
!event_client->CanProcessEventsWithinSubtree(focused_window)) { |
- focus_client->FocusWindow(NULL); |
- return NULL; |
+ focus_client->FocusWindow(nullptr); |
+ return nullptr; |
} |
return focused_window ? focused_window : window; |
} |
+Window* WindowTargeter::FindTargetForNonKeyEvent(Window* root_window, |
+ ui::Event* event) { |
+ if (!event->IsLocatedEvent()) |
+ return root_window; |
+ return FindTargetForLocatedEvent(root_window, |
+ static_cast<ui::LocatedEvent*>(event)); |
+} |
+ |
Window* WindowTargeter::FindTargetInRootWindow(Window* root_window, |
const ui::LocatedEvent& event) { |
DCHECK_EQ(root_window, root_window->GetRootWindow()); |
@@ -153,7 +163,35 @@ Window* WindowTargeter::FindTargetInRootWindow(Window* root_window, |
return root_window; |
} |
- return NULL; |
+ return nullptr; |
+} |
+ |
+Window* WindowTargeter::FindTargetForLocatedEventRecursively( |
+ Window* root_window, |
+ ui::LocatedEvent* event) { |
+ scoped_ptr<ui::EventTargetIterator> iter = root_window->GetChildIterator(); |
+ if (iter) { |
+ ui::EventTarget* target = root_window; |
+ for (ui::EventTarget* child = iter->GetNextTarget(); child; |
+ child = iter->GetNextTarget()) { |
+ WindowTargeter* targeter = |
+ static_cast<WindowTargeter*>(child->GetEventTargeter()); |
+ if (!targeter) |
+ targeter = this; |
+ if (!targeter->SubtreeShouldBeExploredForEvent( |
+ static_cast<Window*>(child), *event)) { |
+ continue; |
+ } |
+ target->ConvertEventToTarget(child, event); |
+ target = child; |
+ Window* child_target_window = |
+ static_cast<Window*>(targeter->FindTargetForEvent(child, event)); |
+ if (child_target_window) |
+ return child_target_window; |
+ } |
+ target->ConvertEventToTarget(root_window, event); |
+ } |
+ return root_window->CanAcceptEvent(*event) ? root_window : nullptr; |
} |
} // namespace aura |