| Index: services/ui/ws/event_targeter.cc
|
| diff --git a/services/ui/ws/event_targeter.cc b/services/ui/ws/event_targeter.cc
|
| index 1fb3f79e02741cedd283a9456fdb7f32558141e0..531ea8e625acba20bee5e246590625f83447e91b 100644
|
| --- a/services/ui/ws/event_targeter.cc
|
| +++ b/services/ui/ws/event_targeter.cc
|
| @@ -4,18 +4,72 @@
|
|
|
| #include "services/ui/ws/event_targeter.h"
|
|
|
| +#include "base/command_line.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/task_scheduler/post_task.h"
|
| +#include "base/threading/thread_task_runner_handle.h"
|
| #include "services/ui/ws/event_targeter_delegate.h"
|
|
|
| namespace ui {
|
| namespace ws {
|
|
|
| +EventTargeter::HitTestRequest::HitTestRequest(const gfx::Point& location,
|
| + int64_t display_id,
|
| + HitTestCallback callback)
|
| + : location(location),
|
| + display_id(display_id),
|
| + callback(std::move(callback)) {}
|
| +
|
| +EventTargeter::HitTestRequest::~HitTestRequest() {}
|
| +
|
| EventTargeter::EventTargeter(EventTargeterDelegate* event_targeter_delegate)
|
| - : event_targeter_delegate_(event_targeter_delegate) {}
|
| + : event_targeter_delegate_(event_targeter_delegate),
|
| + hit_test_in_flight_(false),
|
| + weak_ptr_factory_(this) {}
|
|
|
| EventTargeter::~EventTargeter() {}
|
|
|
| -LocationTarget EventTargeter::FindTargetForLocation(const gfx::Point& location,
|
| - int64_t display_id) {
|
| +void EventTargeter::FindTargetForLocation(const gfx::Point& location,
|
| + int64_t display_id,
|
| + HitTestCallback callback) {
|
| + if (IsHitTestInFlight()) {
|
| + std::unique_ptr<HitTestRequest> hittest_request =
|
| + base::MakeUnique<HitTestRequest>(location, display_id,
|
| + std::move(callback));
|
| + hit_test_request_queue_.push(std::move(hittest_request));
|
| + return;
|
| + }
|
| +
|
| + ProcessFindTarget(location, display_id, std::move(callback));
|
| +}
|
| +
|
| +bool EventTargeter::IsHitTestInFlight() const {
|
| + return hit_test_in_flight_ || !hit_test_request_queue_.empty();
|
| +}
|
| +
|
| +void EventTargeter::ProcessFindTarget(const gfx::Point& location,
|
| + int64_t display_id,
|
| + HitTestCallback callback) {
|
| + // 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(!hit_test_in_flight_);
|
| + hit_test_in_flight_ = true;
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE, base::BindOnce(&EventTargeter::FindTargetForLocationNow,
|
| + weak_ptr_factory_.GetWeakPtr(), location,
|
| + display_id, base::Passed(&callback)));
|
| + } else {
|
| + FindTargetForLocationNow(location, display_id, std::move(callback));
|
| + }
|
| +}
|
| +
|
| +void EventTargeter::FindTargetForLocationNow(const gfx::Point& location,
|
| + int64_t display_id,
|
| + HitTestCallback callback) {
|
| LocationTarget location_target;
|
| location_target.location_in_root = location;
|
| location_target.display_id = display_id;
|
| @@ -26,7 +80,22 @@ LocationTarget EventTargeter::FindTargetForLocation(const gfx::Point& location,
|
| ui::ws::FindDeepestVisibleWindowForLocation(
|
| root, location_target.location_in_root);
|
| }
|
| - return location_target;
|
| + std::move(callback).Run(location_target);
|
| + ProcessNextHitTestRequestFromQueue();
|
| +}
|
| +
|
| +void EventTargeter::ProcessNextHitTestRequestFromQueue() {
|
| + hit_test_in_flight_ = false;
|
| + if (hit_test_request_queue_.empty()) {
|
| + event_targeter_delegate_->ProcessNextAvailableEvent();
|
| + return;
|
| + }
|
| +
|
| + std::unique_ptr<HitTestRequest> hittest_request =
|
| + std::move(hit_test_request_queue_.front());
|
| + hit_test_request_queue_.pop();
|
| + ProcessFindTarget(hittest_request->location, hittest_request->display_id,
|
| + std::move(hittest_request->callback));
|
| }
|
|
|
| } // namespace ws
|
|
|