Index: ui/aura/window_event_dispatcher.cc |
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc |
index 6cd3c43e2dad9addd866098702afd9b64af79343..b6b86af621f18115fe90631d4b130fd98b7d35d3 100644 |
--- a/ui/aura/window_event_dispatcher.cc |
+++ b/ui/aura/window_event_dispatcher.cc |
@@ -27,6 +27,7 @@ |
#include "ui/base/hit_test.h" |
#include "ui/compositor/dip_util.h" |
#include "ui/events/event.h" |
+#include "ui/events/event_targeter.h" |
#include "ui/events/event_utils.h" |
#include "ui/events/gestures/gesture_recognizer.h" |
#include "ui/events/gestures/gesture_types.h" |
@@ -60,6 +61,21 @@ bool IsEventCandidateForHold(const ui::Event& event) { |
return false; |
} |
+void ConvertEventLocationToTarget(ui::EventTarget* event_target, |
+ ui::EventTarget* target, |
+ ui::Event* event) { |
+ if (target != event_target && event->IsLocatedEvent()) { |
+ gfx::Point location = event->AsLocatedEvent()->location(); |
+ gfx::Point root_location = event->AsLocatedEvent()->root_location(); |
+ Window::ConvertPointToTarget(static_cast<Window*>(event_target), |
+ static_cast<Window*>(target), &location); |
+ Window::ConvertPointToTarget(static_cast<Window*>(event_target), |
+ static_cast<Window*>(target), &root_location); |
+ event->AsLocatedEvent()->set_location(location); |
+ event->AsLocatedEvent()->set_root_location(root_location); |
+ } |
+} |
+ |
} // namespace |
//////////////////////////////////////////////////////////////////////////////// |
@@ -76,6 +92,7 @@ WindowEventDispatcher::WindowEventDispatcher(WindowTreeHost* host) |
dispatching_held_event_(nullptr), |
observer_manager_(this), |
env_controller_(new EnvInputStateController), |
+ event_targeter_(new WindowTargeter), |
repost_event_factory_(this), |
held_event_factory_(this) { |
ui::GestureRecognizer::Get()->AddGestureEventHelper(this); |
@@ -90,6 +107,10 @@ WindowEventDispatcher::~WindowEventDispatcher() { |
ui::GestureRecognizer::Get()->RemoveGestureEventHelper(this); |
} |
+ui::EventTargeter* WindowEventDispatcher::GetDefaultEventTargeter() { |
+ return event_targeter_.get(); |
+} |
+ |
void WindowEventDispatcher::RepostEvent(const ui::LocatedEvent* event) { |
DCHECK(event->type() == ui::ET_MOUSE_PRESSED || |
event->type() == ui::ET_GESTURE_TAP_DOWN || |
@@ -416,8 +437,67 @@ void WindowEventDispatcher::ReleaseNativeCapture() { |
//////////////////////////////////////////////////////////////////////////////// |
// WindowEventDispatcher, ui::EventProcessor implementation: |
-ui::EventTarget* WindowEventDispatcher::GetRootTarget() { |
- return window(); |
+ui::EventTarget* WindowEventDispatcher::GetRootForEvent(ui::Event* event) { |
+ if (Env::GetInstance()->mode() == Env::Mode::LOCAL) |
+ return window(); |
+ |
+ if (!event->target()) |
+ return window(); |
+ |
+ ui::EventTarget* event_target = event->target(); |
+ |
+ // Mouse events should be dispatched to the window that processed the |
+ // mouse-press events (if any). |
+ if (event->IsScrollEvent() || event->IsMouseEvent()) { |
+ if (mouse_pressed_handler()) { |
+ ConvertEventLocationToTarget(event_target, mouse_pressed_handler(), |
+ event); |
+ return mouse_pressed_handler(); |
+ } |
+ } |
+ |
+ // All events should be directed towards the capture window (if any). |
sky
2017/02/24 21:22:54
Should this come before the scroll-event/mouse-eve
riajiang
2017/02/27 22:59:30
If there's a mouse_pressed_handler set then that h
|
+ Window* capture_window = client::GetCaptureWindow(window()); |
+ if (capture_window) { |
+ ConvertEventLocationToTarget(event_target, capture_window, event); |
+ return capture_window; |
+ } |
+ |
+ if (event->IsTouchEvent()) { |
+ // Query the gesture-recognizer to find targets for touch events. |
+ const ui::TouchEvent& touch = *event->AsTouchEvent(); |
+ ui::GestureConsumer* consumer = |
+ ui::GestureRecognizer::Get()->GetTouchLockedTarget(touch); |
+ if (consumer) { |
+ ConvertEventLocationToTarget(event_target, static_cast<Window*>(consumer), |
+ event); |
+ return static_cast<Window*>(consumer); |
+ } |
+ consumer = ui::GestureRecognizer::Get()->GetTargetForLocation( |
+ touch.location_f(), touch.source_device_id()); |
+ if (consumer) { |
+ ConvertEventLocationToTarget(event_target, static_cast<Window*>(consumer), |
+ event); |
+ return static_cast<Window*>(consumer); |
+ } |
+ |
+ // If the initial touch is outside the root window, target the root. |
+ if (!window()->bounds().Contains(touch.location())) { |
+ ConvertEventLocationToTarget(event_target, window(), event); |
+ return window(); |
+ } |
+ } |
+ |
+ ui::EventTarget* ancestor_with_targeter = event_target; |
+ for (ui::EventTarget* ancestor = event_target->GetParentTarget(); ancestor; |
+ ancestor = ancestor->GetParentTarget()) { |
+ if (ancestor->GetEventTargeter()) |
+ ancestor_with_targeter = ancestor; |
+ if (ancestor == window()) |
+ break; |
+ } |
+ ConvertEventLocationToTarget(event_target, ancestor_with_targeter, event); |
+ return ancestor_with_targeter; |
} |
void WindowEventDispatcher::OnEventProcessingStarted(ui::Event* event) { |