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

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

Issue 2884463002: Make event-targeting asynchronous in window server. (Closed)
Patch Set: rebase and comments Created 3 years, 7 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
Index: services/ui/ws/event_targeter.cc
diff --git a/services/ui/ws/event_targeter.cc b/services/ui/ws/event_targeter.cc
index 7e1f3a4fc4c25374f83a066473075a3336698ac8..785faa750b0ed7db07f3405d1b8ad3b2406a1072 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_targeter_delegate.h"
#include "services/ui/ws/modal_window_controller.h"
#include "services/ui/ws/window_finder.h"
@@ -13,20 +15,63 @@
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,
ModalWindowController* modal_window_controller)
: event_targeter_delegate_(event_targeter_delegate),
- modal_window_controller_(modal_window_controller) {}
+ modal_window_controller_(modal_window_controller),
+ hit_test_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,
+ int64_t display_id,
+ PointerTargetForEventCallback callback) {
+ target_callback_ = std::move(callback);
sky 2017/06/02 23:28:20 Why do you need target_callback_ and hit_test_call
riajiang 2017/06/05 23:56:15 I was passing them around (with std::move), but af
+ FindDeepestVisibleWindowForLocation(
+ event.root_location(), display_id,
+ base::BindOnce(&EventTargeter::PointerTargetForEventOnFoundWindow,
+ weak_ptr_factory_.GetWeakPtr(), event));
+}
+
+void EventTargeter::FindDeepestVisibleWindowForLocation(
+ 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;
+ }
+
+ hit_test_callback_ = std::move(callback);
+ FindDeepestVisibleWindowForLocationImpl(location, display_id);
+}
+
+bool EventTargeter::IsHitTestInFlight() const {
+ if (hit_test_in_flight_ || !hit_test_request_queue_.empty())
sky 2017/06/02 23:28:20 Change this if to a return and get rid of the othe
riajiang 2017/06/05 23:56:15 Done.
+ return true;
+ return false;
+}
+
+void EventTargeter::PointerTargetForEventOnFoundWindow(
+ const ui::PointerEvent& event,
+ const DeepestWindow& deepest_window,
+ const gfx::Point& location_in_display,
+ int64_t 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 +79,61 @@ 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, location_in_display, display_id);
+}
+
+void EventTargeter::FindDeepestVisibleWindowForLocationImpl(
+ const gfx::Point& location,
+ 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(!hit_test_in_flight_);
+ hit_test_in_flight_ = true;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&EventTargeter::FindDeepestVisibleWindowForLocationAsync,
+ weak_ptr_factory_.GetWeakPtr(), location, display_id));
+ } else {
+ FindDeepestVisibleWindowForLocationAsync(location, display_id);
+ }
}
-DeepestWindow EventTargeter::FindDeepestVisibleWindowForEvents(
- gfx::Point* location,
- int64_t* display_id) {
- ServerWindow* root =
- event_targeter_delegate_->GetRootWindowContaining(location, display_id);
- return root ? ui::ws::FindDeepestVisibleWindowForEvents(root, *location)
- : DeepestWindow();
+void EventTargeter::FindDeepestVisibleWindowForLocationAsync(
+ const gfx::Point& location,
+ int64_t display_id) {
+ gfx::Point event_location(location);
+ int64_t event_display_id = display_id;
+ ServerWindow* root = event_targeter_delegate_->GetRootWindowContaining(
+ &event_location, &event_display_id);
+ if (root) {
+ base::ResetAndReturn(&hit_test_callback_)
+ .Run(ui::ws::FindDeepestVisibleWindowForLocation(root, event_location),
+ event_location, event_display_id);
+ } else {
+ base::ResetAndReturn(&hit_test_callback_)
+ .Run(DeepestWindow(), event_location, event_display_id);
+ }
+ ProcessNextHittesetRequestFromQueue();
+}
+
+void EventTargeter::ProcessNextHittesetRequestFromQueue() {
+ hit_test_in_flight_ = false;
+ if (hit_test_request_queue_.empty()) {
+ event_targeter_delegate_->ProcessNextEventFromQueue();
+ return;
+ }
+
+ std::unique_ptr<HitTestRequest> hittest_request =
+ std::move(hit_test_request_queue_.front());
+ hit_test_request_queue_.pop();
+ hit_test_callback_ = std::move(hittest_request->callback);
+ FindDeepestVisibleWindowForLocationImpl(hittest_request->location,
+ hittest_request->display_id);
}
} // namespace ws

Powered by Google App Engine
This is Rietveld 408576698