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

Side by Side Diff: services/ui/ws/event_targeter.cc

Issue 2884463002: Make event-targeting asynchronous in window server. (Closed)
Patch Set: cache; by value 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 unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "services/ui/ws/event_targeter.h" 5 #include "services/ui/ws/event_targeter.h"
6 6
7 #include "base/command_line.h"
8 #include "base/task_scheduler/post_task.h"
7 #include "services/ui/ws/event_dispatcher_delegate.h" 9 #include "services/ui/ws/event_dispatcher_delegate.h"
8 #include "services/ui/ws/modal_window_controller.h" 10 #include "services/ui/ws/modal_window_controller.h"
9 #include "services/ui/ws/window_finder.h" 11 #include "services/ui/ws/window_finder.h"
10 #include "ui/events/event.h" 12 #include "ui/events/event.h"
11 #include "ui/gfx/geometry/point.h" 13 #include "ui/gfx/geometry/point.h"
12 14
13 namespace ui { 15 namespace ui {
14 namespace ws { 16 namespace ws {
15 17
18 EventTargeter::HitTestRequest::HitTestRequest(const gfx::Point& location,
19 const int64_t display_id,
20 HitTestCallback callback)
21 : hittest_location(location),
22 hittest_display_id(display_id),
23 hittest_callback(std::move(callback)) {}
24
25 EventTargeter::HitTestRequest::~HitTestRequest() {}
26
16 EventTargeter::EventTargeter(EventDispatcherDelegate* event_dispatcher_delegate, 27 EventTargeter::EventTargeter(EventDispatcherDelegate* event_dispatcher_delegate,
17 ModalWindowController* modal_window_controller) 28 ModalWindowController* modal_window_controller)
18 : event_dispatcher_delegate_(event_dispatcher_delegate), 29 : event_dispatcher_delegate_(event_dispatcher_delegate),
19 modal_window_controller_(modal_window_controller) {} 30 modal_window_controller_(modal_window_controller),
31 hittest_in_flight_(false),
32 weak_ptr_factory_(this) {}
20 33
21 EventTargeter::~EventTargeter() {} 34 EventTargeter::~EventTargeter() {}
22 35
23 PointerTarget EventTargeter::PointerTargetForEvent( 36 void EventTargeter::PointerTargetForEvent(
24 const ui::LocatedEvent& event, 37 const ui::PointerEvent& event,
25 int64_t* display_id) { 38 const int64_t display_id,
39 PointerTargetForEventCallback callback) {
40 target_callback_ = std::move(callback);
41 FindDeepestVisibleWindowForEvents(
42 event.root_location(), display_id,
43 base::BindOnce(&EventTargeter::PointerTargetForEventOnFoundWindow,
44 weak_ptr_factory_.GetWeakPtr(), event));
45 }
46
47 void EventTargeter::FindDeepestVisibleWindowForEvents(
48 const gfx::Point& location,
49 const int64_t display_id,
50 HitTestCallback callback) {
51 if (IsHitTestInFlight()) {
52 std::unique_ptr<HitTestRequest> hittest_request =
53 base::MakeUnique<HitTestRequest>(location, display_id,
54 std::move(callback));
55 hittest_request_queue_.push(std::move(hittest_request));
56 return;
57 }
58
59 hittest_callback_ = std::move(callback);
60 FindDeepestVisibleWindowForEventsImpl(location, display_id);
61 }
62
63 void EventTargeter::ProcessNextHittesetRequestFromQueue() {
64 hittest_in_flight_ = false;
65 if (hittest_request_queue_.empty()) {
66 event_dispatcher_delegate_->ProcessNextEventFromQueue();
67 return;
68 }
69 std::unique_ptr<HitTestRequest> hittest_request =
70 std::move(hittest_request_queue_.front());
71
72 hittest_request_queue_.pop();
73 hittest_callback_ = std::move(hittest_request->hittest_callback);
74 FindDeepestVisibleWindowForEventsImpl(hittest_request->hittest_location,
75 hittest_request->hittest_display_id);
76 }
77
78 bool EventTargeter::IsHitTestInFlight() const {
79 if (hittest_in_flight_ || !hittest_request_queue_.empty())
80 return true;
81 return false;
82 }
83
84 void EventTargeter::PointerTargetForEventOnFoundWindow(
85 const ui::PointerEvent& event,
86 const DeepestWindow& deepest_window,
87 const gfx::Point& new_location,
88 const int64_t new_display_id) {
26 PointerTarget pointer_target; 89 PointerTarget pointer_target;
27 gfx::Point event_root_location(event.root_location());
28 DeepestWindow deepest_window =
29 FindDeepestVisibleWindowForEvents(&event_root_location, display_id);
30 pointer_target.window = 90 pointer_target.window =
31 modal_window_controller_->GetTargetForWindow(deepest_window.window); 91 modal_window_controller_->GetTargetForWindow(deepest_window.window);
32 pointer_target.is_mouse_event = event.IsMousePointerEvent(); 92 pointer_target.is_mouse_event = event.IsMousePointerEvent();
33 pointer_target.in_nonclient_area = 93 pointer_target.in_nonclient_area =
34 deepest_window.window != pointer_target.window || 94 deepest_window.window != pointer_target.window ||
35 !pointer_target.window || deepest_window.in_non_client_area; 95 !pointer_target.window || deepest_window.in_non_client_area;
36 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; 96 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
37 return pointer_target; 97 base::ResetAndReturn(&target_callback_)
98 .Run(pointer_target, deepest_window, new_location, new_display_id);
38 } 99 }
39 100
40 DeepestWindow EventTargeter::FindDeepestVisibleWindowForEvents( 101 void EventTargeter::FindDeepestVisibleWindowForEventsImpl(
41 gfx::Point* location, 102 const gfx::Point& location,
42 int64_t* display_id) { 103 const int64_t display_id) {
43 ServerWindow* root = 104 // TODO(riajiang): After HitTestComponent is implemented, do synchronous
44 event_dispatcher_delegate_->GetRootWindowContaining(location, display_id); 105 // hit-test for most cases using shared memory and only ask Blink
45 return root ? ui::ws::FindDeepestVisibleWindowForEvents(root, *location) 106 // asynchronously for hard cases. For now, assume all synchronous hit-tests
46 : DeepestWindow(); 107 // failed if the "enable-async-event-targeting" flag is turned on.
108 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
109 "enable-async-event-targeting")) {
110 DCHECK(!hittest_in_flight_);
111 hittest_in_flight_ = true;
112 base::ThreadTaskRunnerHandle::Get()->PostTask(
113 FROM_HERE,
114 base::BindOnce(&EventTargeter::FindDeepestVisibleWindowForEventsAsync,
115 weak_ptr_factory_.GetWeakPtr(), location, display_id));
116 } else {
117 FindDeepestVisibleWindowForEventsAsync(location, display_id);
118 }
119 }
120
121 void EventTargeter::FindDeepestVisibleWindowForEventsAsync(
122 const gfx::Point& location,
123 const int64_t display_id) {
124 gfx::Point event_location(location);
125 int64_t event_display_id = display_id;
126 ServerWindow* root = event_dispatcher_delegate_->GetRootWindowContaining(
127 &event_location, &event_display_id);
128 if (root) {
129 base::ResetAndReturn(&hittest_callback_)
130 .Run(ui::ws::FindDeepestVisibleWindowForEvents(root, event_location),
131 event_location, event_display_id);
132 } else {
133 base::ResetAndReturn(&hittest_callback_)
134 .Run(DeepestWindow(), event_location, event_display_id);
135 }
47 } 136 }
48 137
49 } // namespace ws 138 } // namespace ws
50 } // namespace ui 139 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698