Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Unified Diff: services/ui/ws/event_targeter.cc

Issue 2884463002: Make event-targeting asynchronous in window server. (Closed)
Patch Set: comments Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « services/ui/ws/event_targeter.h ('k') | services/ui/ws/event_targeter_delegate.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « services/ui/ws/event_targeter.h ('k') | services/ui/ws/event_targeter_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698