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

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

Issue 2884463002: Make event-targeting asynchronous in window server. (Closed)
Patch Set: rebase and use EventTargeter 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(gfx::Point* location,
19 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 int64_t* display_id,
39 PointerTargetForEventCallback callback) {
40 target_callback_ = std::move(callback);
41 current_hittest_location_.reset(new gfx::Point(event.root_location()));
42 FindDeepestVisibleWindowForEvents(
43 current_hittest_location_.get(), display_id,
44 base::BindOnce(&EventTargeter::PointerTargetForEventOnFoundWindow,
45 weak_ptr_factory_.GetWeakPtr(), event));
46 }
47
48 void EventTargeter::FindDeepestVisibleWindowForEvents(
49 gfx::Point* location,
50 int64_t* display_id,
51 HitTestCallback callback) {
52 if (IsHitTestInFlight()) {
53 std::unique_ptr<HitTestRequest> hittest_request =
54 base::MakeUnique<HitTestRequest>(location, display_id,
55 std::move(callback));
56 hittest_request_queue_.push(std::move(hittest_request));
57 return;
58 }
59
60 hittest_callback_ = std::move(callback);
61 FindDeepestVisibleWindowForEventsImpl(location, display_id);
62 }
63
64 void EventTargeter::ProcessNextHittesetRequestFromQueue() {
65 hittest_in_flight_ = false;
66 if (hittest_request_queue_.empty()) {
67 event_dispatcher_delegate_->ProcessNextEventFromQueue();
68 return;
69 }
70 std::unique_ptr<HitTestRequest> hittest_request =
71 std::move(hittest_request_queue_.front());
72
73 hittest_request_queue_.pop();
74 hittest_callback_ = std::move(hittest_request->hittest_callback);
75 FindDeepestVisibleWindowForEventsImpl(hittest_request->hittest_location,
76 hittest_request->hittest_display_id);
77 }
78
79 bool EventTargeter::IsHitTestInFlight() const {
80 if (hittest_in_flight_ || !hittest_request_queue_.empty())
81 return true;
82 return false;
83 }
84
85 void EventTargeter::PointerTargetForEventOnFoundWindow(
86 const ui::PointerEvent& event,
87 DeepestWindow deepest_window) {
26 PointerTarget pointer_target; 88 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 = 89 pointer_target.window =
31 modal_window_controller_->GetTargetForWindow(deepest_window.window); 90 modal_window_controller_->GetTargetForWindow(deepest_window.window);
32 pointer_target.is_mouse_event = event.IsMousePointerEvent(); 91 pointer_target.is_mouse_event = event.IsMousePointerEvent();
33 pointer_target.in_nonclient_area = 92 pointer_target.in_nonclient_area =
34 deepest_window.window != pointer_target.window || 93 deepest_window.window != pointer_target.window ||
35 !pointer_target.window || deepest_window.in_non_client_area; 94 !pointer_target.window || deepest_window.in_non_client_area;
36 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; 95 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
37 return pointer_target; 96 base::ResetAndReturn(&target_callback_).Run(pointer_target);
38 } 97 }
39 98
40 DeepestWindow EventTargeter::FindDeepestVisibleWindowForEvents( 99 void EventTargeter::FindDeepestVisibleWindowForEventsImpl(gfx::Point* location,
100 int64_t* display_id) {
101 // TODO(riajiang): After HitTestComponent is implemented, do synchronous
102 // hit-test for most cases using shared memory and only ask Blink
103 // asynchronously for hard cases. For now, assume all synchronous hit-tests
104 // failed if the "enable-async-event-targeting" flag is turned on.
105 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
106 "enable-async-event-targeting")) {
107 DCHECK(!hittest_in_flight_);
108 hittest_in_flight_ = true;
109 base::ThreadTaskRunnerHandle::Get()->PostTask(
110 FROM_HERE,
111 base::BindOnce(&EventTargeter::FindDeepestVisibleWindowForEventsAsync,
112 weak_ptr_factory_.GetWeakPtr(), location, display_id));
113 } else {
114 FindDeepestVisibleWindowForEventsAsync(location, display_id);
115 }
116 }
117
118 void EventTargeter::FindDeepestVisibleWindowForEventsAsync(
41 gfx::Point* location, 119 gfx::Point* location,
42 int64_t* display_id) { 120 int64_t* display_id) {
43 ServerWindow* root = 121 ServerWindow* root =
44 event_dispatcher_delegate_->GetRootWindowContaining(location, display_id); 122 event_dispatcher_delegate_->GetRootWindowContaining(location, display_id);
45 return root ? ui::ws::FindDeepestVisibleWindowForEvents(root, *location) 123 if (root) {
46 : DeepestWindow(); 124 base::ResetAndReturn(&hittest_callback_)
125 .Run(ui::ws::FindDeepestVisibleWindowForEvents(root, *location));
126 } else {
127 base::ResetAndReturn(&hittest_callback_).Run(DeepestWindow());
128 }
47 } 129 }
48 130
49 } // namespace ws 131 } // namespace ws
50 } // namespace ui 132 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698