| Index: services/ui/ws/event_targeter.cc
|
| diff --git a/services/ui/ws/event_targeter.cc b/services/ui/ws/event_targeter.cc
|
| index 9329b4b536b4726e948574e44ecb88e1df6513b3..4ed9475d8dd6ce1fc3401dd63e95a6f52007f918 100644
|
| --- a/services/ui/ws/event_targeter.cc
|
| +++ b/services/ui/ws/event_targeter.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "services/ui/ws/event_targeter.h"
|
|
|
| +#include "base/command_line.h"
|
| +#include "base/task_scheduler/post_task.h"
|
| #include "services/ui/ws/event_dispatcher_delegate.h"
|
| #include "services/ui/ws/modal_window_controller.h"
|
| #include "services/ui/ws/window_finder.h"
|
| @@ -13,20 +15,78 @@
|
| namespace ui {
|
| namespace ws {
|
|
|
| +EventTargeter::HitTestRequest::HitTestRequest(const gfx::Point& location,
|
| + const int64_t display_id,
|
| + HitTestCallback callback)
|
| + : hittest_location(location),
|
| + hittest_display_id(display_id),
|
| + hittest_callback(std::move(callback)) {}
|
| +
|
| +EventTargeter::HitTestRequest::~HitTestRequest() {}
|
| +
|
| EventTargeter::EventTargeter(EventDispatcherDelegate* event_dispatcher_delegate,
|
| ModalWindowController* modal_window_controller)
|
| : event_dispatcher_delegate_(event_dispatcher_delegate),
|
| - modal_window_controller_(modal_window_controller) {}
|
| + modal_window_controller_(modal_window_controller),
|
| + hittest_in_flight_(false),
|
| + weak_ptr_factory_(this) {}
|
|
|
| EventTargeter::~EventTargeter() {}
|
|
|
| -PointerTarget EventTargeter::PointerTargetForEvent(
|
| - const ui::LocatedEvent& event,
|
| - int64_t* display_id) {
|
| +void EventTargeter::PointerTargetForEvent(
|
| + const ui::PointerEvent& event,
|
| + const int64_t display_id,
|
| + PointerTargetForEventCallback callback) {
|
| + target_callback_ = std::move(callback);
|
| + FindDeepestVisibleWindowForEvents(
|
| + event.root_location(), display_id,
|
| + base::BindOnce(&EventTargeter::PointerTargetForEventOnFoundWindow,
|
| + weak_ptr_factory_.GetWeakPtr(), event));
|
| +}
|
| +
|
| +void EventTargeter::FindDeepestVisibleWindowForEvents(
|
| + const gfx::Point& location,
|
| + const int64_t display_id,
|
| + HitTestCallback callback) {
|
| + if (IsHitTestInFlight()) {
|
| + std::unique_ptr<HitTestRequest> hittest_request =
|
| + base::MakeUnique<HitTestRequest>(location, display_id,
|
| + std::move(callback));
|
| + hittest_request_queue_.push(std::move(hittest_request));
|
| + return;
|
| + }
|
| +
|
| + hittest_callback_ = std::move(callback);
|
| + FindDeepestVisibleWindowForEventsImpl(location, display_id);
|
| +}
|
| +
|
| +void EventTargeter::ProcessNextHittesetRequestFromQueue() {
|
| + hittest_in_flight_ = false;
|
| + if (hittest_request_queue_.empty()) {
|
| + event_dispatcher_delegate_->ProcessNextEventFromQueue();
|
| + return;
|
| + }
|
| + std::unique_ptr<HitTestRequest> hittest_request =
|
| + std::move(hittest_request_queue_.front());
|
| +
|
| + hittest_request_queue_.pop();
|
| + hittest_callback_ = std::move(hittest_request->hittest_callback);
|
| + FindDeepestVisibleWindowForEventsImpl(hittest_request->hittest_location,
|
| + hittest_request->hittest_display_id);
|
| +}
|
| +
|
| +bool EventTargeter::IsHitTestInFlight() const {
|
| + if (hittest_in_flight_ || !hittest_request_queue_.empty())
|
| + return true;
|
| + return false;
|
| +}
|
| +
|
| +void EventTargeter::PointerTargetForEventOnFoundWindow(
|
| + const ui::PointerEvent& event,
|
| + const DeepestWindow& deepest_window,
|
| + const gfx::Point& new_location,
|
| + const int64_t new_display_id) {
|
| PointerTarget pointer_target;
|
| - gfx::Point event_root_location(event.root_location());
|
| - DeepestWindow deepest_window =
|
| - FindDeepestVisibleWindowForEvents(&event_root_location, display_id);
|
| pointer_target.window =
|
| modal_window_controller_->GetTargetForWindow(deepest_window.window);
|
| pointer_target.is_mouse_event = event.IsMousePointerEvent();
|
| @@ -34,16 +94,45 @@ PointerTarget EventTargeter::PointerTargetForEvent(
|
| deepest_window.window != pointer_target.window ||
|
| !pointer_target.window || deepest_window.in_non_client_area;
|
| pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
|
| - return pointer_target;
|
| + base::ResetAndReturn(&target_callback_)
|
| + .Run(pointer_target, deepest_window, new_location, new_display_id);
|
| +}
|
| +
|
| +void EventTargeter::FindDeepestVisibleWindowForEventsImpl(
|
| + const gfx::Point& location,
|
| + const int64_t display_id) {
|
| + // TODO(riajiang): After HitTestComponent is implemented, do synchronous
|
| + // hit-test for most cases using shared memory and only ask Blink
|
| + // asynchronously for hard cases. For now, assume all synchronous hit-tests
|
| + // failed if the "enable-async-event-targeting" flag is turned on.
|
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + "enable-async-event-targeting")) {
|
| + DCHECK(!hittest_in_flight_);
|
| + hittest_in_flight_ = true;
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE,
|
| + base::BindOnce(&EventTargeter::FindDeepestVisibleWindowForEventsAsync,
|
| + weak_ptr_factory_.GetWeakPtr(), location, display_id));
|
| + } else {
|
| + FindDeepestVisibleWindowForEventsAsync(location, display_id);
|
| + }
|
| }
|
|
|
| -DeepestWindow EventTargeter::FindDeepestVisibleWindowForEvents(
|
| - gfx::Point* location,
|
| - int64_t* display_id) {
|
| - ServerWindow* root =
|
| - event_dispatcher_delegate_->GetRootWindowContaining(location, display_id);
|
| - return root ? ui::ws::FindDeepestVisibleWindowForEvents(root, *location)
|
| - : DeepestWindow();
|
| +void EventTargeter::FindDeepestVisibleWindowForEventsAsync(
|
| + const gfx::Point& location,
|
| + const int64_t display_id) {
|
| + gfx::Point event_location(location);
|
| + int64_t event_display_id = display_id;
|
| + ServerWindow* root = event_dispatcher_delegate_->GetRootWindowContaining(
|
| + &event_location, &event_display_id);
|
| + if (root) {
|
| + base::ResetAndReturn(&hittest_callback_)
|
| + .Run(ui::ws::FindDeepestVisibleWindowForEvents(root, event_location),
|
| + event_location, event_display_id);
|
| + } else {
|
| + base::ResetAndReturn(&hittest_callback_)
|
| + .Run(DeepestWindow(), event_location, event_display_id);
|
| + }
|
| }
|
|
|
| } // namespace ws
|
|
|