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

Side by Side Diff: components/mus/ws/event_dispatcher.cc

Issue 1677513002: mus Window Server: implement event capture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "components/mus/ws/event_dispatcher.h" 5 #include "components/mus/ws/event_dispatcher.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/time/time.h"
9 #include "cc/surfaces/surface_hittest.h" 10 #include "cc/surfaces/surface_hittest.h"
10 #include "components/mus/surfaces/surfaces_state.h" 11 #include "components/mus/surfaces/surfaces_state.h"
11 #include "components/mus/ws/event_dispatcher_delegate.h" 12 #include "components/mus/ws/event_dispatcher_delegate.h"
12 #include "components/mus/ws/server_window.h" 13 #include "components/mus/ws/server_window.h"
13 #include "components/mus/ws/server_window_delegate.h" 14 #include "components/mus/ws/server_window_delegate.h"
14 #include "components/mus/ws/window_coordinate_conversions.h" 15 #include "components/mus/ws/window_coordinate_conversions.h"
15 #include "components/mus/ws/window_finder.h" 16 #include "components/mus/ws/window_finder.h"
16 #include "components/mus/ws/window_tree_host_impl.h" 17 #include "components/mus/ws/window_tree_host_impl.h"
17 #include "mojo/converters/geometry/geometry_type_converters.h" 18 #include "mojo/converters/geometry/geometry_type_converters.h"
18 #include "ui/gfx/geometry/point.h" 19 #include "ui/gfx/geometry/point.h"
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 mojom::KeyboardCode keyboard_code_; 151 mojom::KeyboardCode keyboard_code_;
151 mojom::PointerKind pointer_kind_; 152 mojom::PointerKind pointer_kind_;
152 gfx::RectF pointer_region_; 153 gfx::RectF pointer_region_;
153 }; 154 };
154 155
155 //////////////////////////////////////////////////////////////////////////////// 156 ////////////////////////////////////////////////////////////////////////////////
156 157
157 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) 158 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate)
158 : delegate_(delegate), 159 : delegate_(delegate),
159 root_(nullptr), 160 root_(nullptr),
161 capture_window_(nullptr),
162 capture_window_in_nonclient_area_(false),
160 mouse_button_down_(false), 163 mouse_button_down_(false),
161 mouse_cursor_source_window_(nullptr) {} 164 mouse_cursor_source_window_(nullptr) {}
162 165
163 EventDispatcher::~EventDispatcher() { 166 EventDispatcher::~EventDispatcher() {
164 std::set<ServerWindow*> pointer_targets; 167 std::set<ServerWindow*> pointer_targets;
168 if (capture_window_) {
169 pointer_targets.insert(capture_window_);
170 capture_window_->RemoveObserver(this);
171 capture_window_ = nullptr;
172 }
165 for (const auto& pair : pointer_targets_) { 173 for (const auto& pair : pointer_targets_) {
166 if (pair.second.window && 174 if (pair.second.window &&
167 pointer_targets.insert(pair.second.window).second) { 175 pointer_targets.insert(pair.second.window).second) {
168 pair.second.window->RemoveObserver(this); 176 pair.second.window->RemoveObserver(this);
169 } 177 }
170 } 178 }
179 pointer_targets_.clear();
180 }
181
182 void EventDispatcher::SetCaptureWindow(ServerWindow* window,
183 bool in_nonclient_area) {
184 if (window == capture_window_)
185 return;
186
187 if (capture_window_) {
188 // Stop observing old capture window. |pointer_targets_| are cleared on
189 // intial setting of a capture window.
190 delegate_->OnLostCapture(capture_window_);
191 capture_window_->RemoveObserver(this);
192 } else {
193 // Cancel implicit capture to all other windows.
194 std::set<ServerWindow*> unobserved_windows;
195 for (const auto& pair : pointer_targets_) {
196 ServerWindow* target = pair.second.window;
197 if (!target)
198 continue;
199 if (unobserved_windows.insert(target).second)
200 target->RemoveObserver(this);
201 if (target == window)
202 continue;
203 mojom::EventPtr cancel_event = mojom::Event::New();
204 cancel_event->action = mojom::EventType::POINTER_CANCEL;
205 cancel_event->flags = mojom::kEventFlagNone;
206 cancel_event->time_stamp = base::TimeTicks::Now().ToInternalValue();
207 cancel_event->pointer_data = mojom::PointerData::New();
208 // TODO(jonross): Track previous location in PointerTarget for sending
209 // cancels
210 cancel_event->pointer_data->location = mojom::LocationData::New();
211 cancel_event->pointer_data->pointer_id = pair.first;
212 DispatchToPointerTarget(pair.second, std::move(cancel_event));
213 }
214 pointer_targets_.clear();
215 }
216 capture_window_ = window;
217 capture_window_in_nonclient_area_ = in_nonclient_area;
218 // Begin tracking the capture window if it is not yet being observed.
219 if (window)
220 window->AddObserver(this);
221 else if (!mouse_button_down_)
222 UpdateCursorProviderByLastKnownLocation();
171 } 223 }
172 224
173 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { 225 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
174 if (!mouse_button_down_) { 226 if (!mouse_button_down_) {
175 gfx::Point location = mouse_pointer_last_location_; 227 gfx::Point location = mouse_pointer_last_location_;
176 mouse_cursor_source_window_ = 228 mouse_cursor_source_window_ =
177 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); 229 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
178 } 230 }
179 } 231 }
180 232
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 std::move(event)); 282 std::move(event));
231 } 283 }
232 284
233 void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) { 285 void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) {
234 const bool is_mouse_event = event->pointer_data && 286 const bool is_mouse_event = event->pointer_data &&
235 event->pointer_data->kind == mojom::PointerKind::MOUSE; 287 event->pointer_data->kind == mojom::PointerKind::MOUSE;
236 288
237 if (is_mouse_event) 289 if (is_mouse_event)
238 mouse_pointer_last_location_ = EventLocationToPoint(*event); 290 mouse_pointer_last_location_ = EventLocationToPoint(*event);
239 291
292 // Release capture on pointer up. For mouse we only release if there are
293 // no buttons down.
294 const bool is_pointer_going_up =
295 (event->action == mojom::EventType::POINTER_UP ||
296 event->action == mojom::EventType::POINTER_CANCEL) &&
297 (event->pointer_data->kind != mojom::PointerKind::MOUSE ||
298 IsOnlyOneMouseButtonDown(event->flags));
299
300 // Update mouse down state upon events which change it.
301 if (is_mouse_event) {
302 if (event->action == mojom::EventType::POINTER_DOWN)
303 mouse_button_down_ = true;
304 else if (is_pointer_going_up)
305 mouse_button_down_ = false;
306 }
307
308 if (capture_window_) {
309 mouse_cursor_source_window_ = capture_window_;
310 PointerTarget pointer_target;
311 pointer_target.window = capture_window_;
312 pointer_target.in_nonclient_area = capture_window_in_nonclient_area_;
313 DispatchToPointerTarget(pointer_target, std::move(event));
314 return;
315 }
316
240 const int32_t pointer_id = event->pointer_data->pointer_id; 317 const int32_t pointer_id = event->pointer_data->pointer_id;
241 if (!IsTrackingPointer(pointer_id) || 318 if (!IsTrackingPointer(pointer_id) ||
242 !pointer_targets_[pointer_id].is_pointer_down) { 319 !pointer_targets_[pointer_id].is_pointer_down) {
243 const bool any_pointers_down = AreAnyPointersDown(); 320 const bool any_pointers_down = AreAnyPointersDown();
244 UpdateTargetForPointer(*event); 321 UpdateTargetForPointer(*event);
245 if (is_mouse_event) 322 if (is_mouse_event)
246 mouse_cursor_source_window_ = pointer_targets_[pointer_id].window; 323 mouse_cursor_source_window_ = pointer_targets_[pointer_id].window;
247 324
248 PointerTarget& pointer_target = pointer_targets_[pointer_id]; 325 PointerTarget& pointer_target = pointer_targets_[pointer_id];
249 if (pointer_target.is_pointer_down) { 326 if (pointer_target.is_pointer_down) {
250 if (is_mouse_event) { 327 if (is_mouse_event)
251 mouse_button_down_ = true;
252 mouse_cursor_source_window_ = pointer_target.window; 328 mouse_cursor_source_window_ = pointer_target.window;
253 }
254 if (!any_pointers_down) 329 if (!any_pointers_down)
255 delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window); 330 delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window);
256 } 331 }
257 } 332 }
258 333
259 // Release capture on pointer up. For mouse we only release if there are 334 // When we release the mouse button, we want the cursor to be sourced from
260 // no buttons down. 335 // the window under the mouse pointer, even though we're sending the button
261 const bool is_pointer_going_up = 336 // up event to the window that had implicit capture. We have to set this
262 (event->action == mojom::EventType::POINTER_UP || 337 // before we perform dispatch because the Delegate is going to read this
263 event->action == mojom::EventType::POINTER_CANCEL) && 338 // information from us.
264 (event->pointer_data->kind != mojom::PointerKind::MOUSE || 339 if (is_pointer_going_up && is_mouse_event)
265 IsOnlyOneMouseButtonDown(event->flags)); 340 UpdateCursorProviderByLastKnownLocation();
266
267 if (is_pointer_going_up && is_mouse_event) {
268 // When we release the mouse button, we want the cursor to be sourced from
269 // the window under the mouse pointer, even though we're sending the button
270 // up event to the window that had implicit capture. We have to set this
271 // before we perform dispatch because the Delegate is going to read this
272 // information from us.
273 mouse_button_down_ = false;
274 gfx::Point location(EventLocationToPoint(*event));
275 mouse_cursor_source_window_ =
276 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
277 }
278 341
279 DispatchToPointerTarget(pointer_targets_[pointer_id], std::move(event)); 342 DispatchToPointerTarget(pointer_targets_[pointer_id], std::move(event));
280 343
281 if (is_pointer_going_up) { 344 if (is_pointer_going_up) {
282 if (is_mouse_event) 345 if (is_mouse_event)
283 pointer_targets_[pointer_id].is_pointer_down = false; 346 pointer_targets_[pointer_id].is_pointer_down = false;
284 else 347 else
285 StopTrackingPointer(pointer_id); 348 StopTrackingPointer(pointer_id);
286 } 349 }
287 } 350 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 transform.TransformPoint(&location); 436 transform.TransformPoint(&location);
374 event->pointer_data->location->x = location.x(); 437 event->pointer_data->location->x = location.x();
375 event->pointer_data->location->y = location.y(); 438 event->pointer_data->location->y = location.y();
376 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, 439 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area,
377 std::move(event)); 440 std::move(event));
378 } 441 }
379 442
380 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { 443 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
381 window->RemoveObserver(this); 444 window->RemoveObserver(this);
382 445
446 if (capture_window_ == window) {
447 capture_window_ = nullptr;
448 // A window only cares to be informed that it lost capture if it explicitly
449 // requested capture. A window can lose capture if another window gains
450 // explicit capture.
451 delegate_->OnLostCapture(window);
452 mouse_button_down_ = false;
453 UpdateCursorProviderByLastKnownLocation();
454 return;
455 }
456
383 for (auto& pair : pointer_targets_) { 457 for (auto& pair : pointer_targets_) {
384 if (pair.second.window == window) 458 if (pair.second.window == window)
385 pair.second.window = nullptr; 459 pair.second.window = nullptr;
386 } 460 }
387 } 461 }
388 462
389 bool EventDispatcher::IsObservingWindow(ServerWindow* window) { 463 bool EventDispatcher::IsObservingWindow(ServerWindow* window) {
390 for (const auto& pair : pointer_targets_) { 464 for (const auto& pair : pointer_targets_) {
391 if (pair.second.window == window) 465 if (pair.second.window == window)
392 return true; 466 return true;
(...skipping 25 matching lines...) Expand all
418 492
419 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { 493 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) {
420 CancelPointerEventsToTarget(window); 494 CancelPointerEventsToTarget(window);
421 495
422 if (mouse_cursor_source_window_ == window) 496 if (mouse_cursor_source_window_ == window)
423 mouse_cursor_source_window_ = nullptr; 497 mouse_cursor_source_window_ = nullptr;
424 } 498 }
425 499
426 } // namespace ws 500 } // namespace ws
427 } // namespace mus 501 } // namespace mus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698