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

Side by Side 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, 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_targeter_delegate.h" 9 #include "services/ui/ws/event_targeter_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 int64_t display_id,
20 HitTestCallback callback)
21 : location(location),
22 display_id(display_id),
23 callback(std::move(callback)) {}
24
25 EventTargeter::HitTestRequest::~HitTestRequest() {}
26
16 EventTargeter::EventTargeter(EventTargeterDelegate* event_targeter_delegate, 27 EventTargeter::EventTargeter(EventTargeterDelegate* event_targeter_delegate,
17 ModalWindowController* modal_window_controller) 28 ModalWindowController* modal_window_controller)
18 : event_targeter_delegate_(event_targeter_delegate), 29 : event_targeter_delegate_(event_targeter_delegate),
19 modal_window_controller_(modal_window_controller) {} 30 modal_window_controller_(modal_window_controller),
31 hit_test_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 int64_t display_id,
39 PointerTargetForEventCallback callback) {
40 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
41 FindDeepestVisibleWindowForLocation(
42 event.root_location(), display_id,
43 base::BindOnce(&EventTargeter::PointerTargetForEventOnFoundWindow,
44 weak_ptr_factory_.GetWeakPtr(), event));
45 }
46
47 void EventTargeter::FindDeepestVisibleWindowForLocation(
48 const gfx::Point& location,
49 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 hit_test_request_queue_.push(std::move(hittest_request));
56 return;
57 }
58
59 hit_test_callback_ = std::move(callback);
60 FindDeepestVisibleWindowForLocationImpl(location, display_id);
61 }
62
63 bool EventTargeter::IsHitTestInFlight() const {
64 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.
65 return true;
66 return false;
67 }
68
69 void EventTargeter::PointerTargetForEventOnFoundWindow(
70 const ui::PointerEvent& event,
71 const DeepestWindow& deepest_window,
72 const gfx::Point& location_in_display,
73 int64_t display_id) {
26 PointerTarget pointer_target; 74 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 = 75 pointer_target.window =
31 modal_window_controller_->GetTargetForWindow(deepest_window.window); 76 modal_window_controller_->GetTargetForWindow(deepest_window.window);
32 pointer_target.is_mouse_event = event.IsMousePointerEvent(); 77 pointer_target.is_mouse_event = event.IsMousePointerEvent();
33 pointer_target.in_nonclient_area = 78 pointer_target.in_nonclient_area =
34 deepest_window.window != pointer_target.window || 79 deepest_window.window != pointer_target.window ||
35 !pointer_target.window || deepest_window.in_non_client_area; 80 !pointer_target.window || deepest_window.in_non_client_area;
36 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; 81 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
37 return pointer_target; 82 base::ResetAndReturn(&target_callback_)
83 .Run(pointer_target, deepest_window, location_in_display, display_id);
38 } 84 }
39 85
40 DeepestWindow EventTargeter::FindDeepestVisibleWindowForEvents( 86 void EventTargeter::FindDeepestVisibleWindowForLocationImpl(
41 gfx::Point* location, 87 const gfx::Point& location,
42 int64_t* display_id) { 88 int64_t display_id) {
43 ServerWindow* root = 89 // TODO(riajiang): After HitTestComponent is implemented, do synchronous
44 event_targeter_delegate_->GetRootWindowContaining(location, display_id); 90 // hit-test for most cases using shared memory and only ask Blink
45 return root ? ui::ws::FindDeepestVisibleWindowForEvents(root, *location) 91 // asynchronously for hard cases. For now, assume all synchronous hit-tests
46 : DeepestWindow(); 92 // failed if the "enable-async-event-targeting" flag is turned on.
93 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
94 "enable-async-event-targeting")) {
95 DCHECK(!hit_test_in_flight_);
96 hit_test_in_flight_ = true;
97 base::ThreadTaskRunnerHandle::Get()->PostTask(
98 FROM_HERE,
99 base::BindOnce(&EventTargeter::FindDeepestVisibleWindowForLocationAsync,
100 weak_ptr_factory_.GetWeakPtr(), location, display_id));
101 } else {
102 FindDeepestVisibleWindowForLocationAsync(location, display_id);
103 }
104 }
105
106 void EventTargeter::FindDeepestVisibleWindowForLocationAsync(
107 const gfx::Point& location,
108 int64_t display_id) {
109 gfx::Point event_location(location);
110 int64_t event_display_id = display_id;
111 ServerWindow* root = event_targeter_delegate_->GetRootWindowContaining(
112 &event_location, &event_display_id);
113 if (root) {
114 base::ResetAndReturn(&hit_test_callback_)
115 .Run(ui::ws::FindDeepestVisibleWindowForLocation(root, event_location),
116 event_location, event_display_id);
117 } else {
118 base::ResetAndReturn(&hit_test_callback_)
119 .Run(DeepestWindow(), event_location, event_display_id);
120 }
121 ProcessNextHittesetRequestFromQueue();
122 }
123
124 void EventTargeter::ProcessNextHittesetRequestFromQueue() {
125 hit_test_in_flight_ = false;
126 if (hit_test_request_queue_.empty()) {
127 event_targeter_delegate_->ProcessNextEventFromQueue();
128 return;
129 }
130
131 std::unique_ptr<HitTestRequest> hittest_request =
132 std::move(hit_test_request_queue_.front());
133 hit_test_request_queue_.pop();
134 hit_test_callback_ = std::move(hittest_request->callback);
135 FindDeepestVisibleWindowForLocationImpl(hittest_request->location,
136 hittest_request->display_id);
47 } 137 }
48 138
49 } // namespace ws 139 } // namespace ws
50 } // namespace ui 140 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698