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

Side by Side Diff: services/ui/ws/event_dispatcher.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 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 "services/ui/ws/event_dispatcher.h" 5 #include "services/ui/ws/event_dispatcher.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 const ClientSpecificId target_client_id = delegate_->GetEventTargetClientId( 217 const ClientSpecificId target_client_id = delegate_->GetEventTargetClientId(
218 mouse_cursor_source_window_, mouse_cursor_in_non_client_area_); 218 mouse_cursor_source_window_, mouse_cursor_in_non_client_area_);
219 const ServerWindow* window = mouse_cursor_source_window_; 219 const ServerWindow* window = mouse_cursor_source_window_;
220 while (window && window->id().client_id == target_client_id) 220 while (window && window->id().client_id == target_client_id)
221 window = window->parent(); 221 window = window->parent();
222 return window; 222 return window;
223 } 223 }
224 224
225 void EventDispatcher::UpdateNonClientAreaForCurrentWindow() { 225 void EventDispatcher::UpdateNonClientAreaForCurrentWindow() {
226 if (mouse_cursor_source_window_) { 226 if (mouse_cursor_source_window_) {
227 DeepestWindow deepest_window = 227 event_targeter_->FindDeepestVisibleWindowForEvents(
228 event_targeter_->FindDeepestVisibleWindowForEvents( 228 &mouse_pointer_last_location_, &mouse_pointer_display_id_,
229 &mouse_pointer_last_location_, &mouse_pointer_display_id_); 229 base::BindOnce(
230 if (deepest_window.window == mouse_cursor_source_window_) { 230 &EventDispatcher::UpdateNonClientAreaForCurrentWindowOnFoundWindow,
231 mouse_cursor_in_non_client_area_ = mouse_cursor_source_window_ 231 base::Unretained(this)));
232 ? deepest_window.in_non_client_area
233 : false;
234 }
235 } 232 }
236 } 233 }
237 234
238 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { 235 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
sky 2017/05/30 17:26:02 This class is mostly written assuming synchronous
riajiang 2017/05/31 22:44:03 True! I didn't notice that UpdateCursorProviderByL
239 if (!mouse_button_down_) { 236 if (!mouse_button_down_) {
240 DeepestWindow deepest_window = 237 event_targeter_->FindDeepestVisibleWindowForEvents(
241 event_targeter_->FindDeepestVisibleWindowForEvents( 238 &mouse_pointer_last_location_, &mouse_pointer_display_id_,
242 &mouse_pointer_last_location_, &mouse_pointer_display_id_); 239 base::BindOnce(&EventDispatcher::
243 SetMouseCursorSourceWindow(deepest_window.window); 240 UpdateCursorProviderByLastKnownLocationOnFoundWindow,
244 if (mouse_cursor_source_window_) { 241 base::Unretained(this)));
245 mouse_cursor_in_non_client_area_ = deepest_window.in_non_client_area;
246 } else {
247 SetMouseCursorSourceWindow(delegate_->GetRootWindowContaining(
248 &mouse_pointer_last_location_, &mouse_pointer_display_id_));
249 mouse_cursor_in_non_client_area_ = true;
250 }
251 } 242 }
252 } 243 }
253 244
254 bool EventDispatcher::AddAccelerator(uint32_t id, 245 bool EventDispatcher::AddAccelerator(uint32_t id,
255 mojom::EventMatcherPtr event_matcher) { 246 mojom::EventMatcherPtr event_matcher) {
256 std::unique_ptr<Accelerator> accelerator(new Accelerator(id, *event_matcher)); 247 std::unique_ptr<Accelerator> accelerator(new Accelerator(id, *event_matcher));
257 // If an accelerator with the same id or matcher already exists, then abort. 248 // If an accelerator with the same id or matcher already exists, then abort.
258 for (const auto& pair : accelerators_) { 249 for (const auto& pair : accelerators_) {
259 if (pair.first == id) { 250 if (pair.first == id) {
260 DVLOG(1) << "duplicate accelerator. Accelerator id=" << accelerator->id() 251 DVLOG(1) << "duplicate accelerator. Accelerator id=" << accelerator->id()
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 return; 340 return;
350 } 341 }
351 delegate_->OnEventTargetNotFound(event, event_display_id_); 342 delegate_->OnEventTargetNotFound(event, event_display_id_);
352 if (post_target) 343 if (post_target)
353 delegate_->OnAccelerator(post_target->id(), event_display_id_, event, 344 delegate_->OnAccelerator(post_target->id(), event_display_id_, event,
354 EventDispatcherDelegate::AcceleratorPhase::POST); 345 EventDispatcherDelegate::AcceleratorPhase::POST);
355 } 346 }
356 347
357 void EventDispatcher::ProcessPointerEvent(const ui::PointerEvent& event) { 348 void EventDispatcher::ProcessPointerEvent(const ui::PointerEvent& event) {
358 DCHECK(event.IsPointerEvent()); 349 DCHECK(event.IsPointerEvent());
350 event_targeter_->PointerTargetForEvent(
351 event, &event_display_id_,
352 base::BindOnce(&EventDispatcher::ProcessPointerEventOnFoundTarget,
353 base::Unretained(this), event));
354 }
355
356 void EventDispatcher::ProcessPointerEventOnFoundTarget(
357 const ui::PointerEvent& event,
358 PointerTarget pointer_target_found) {
359 event_targeter_->ProcessNextHittesetRequestFromQueue();
360
359 const bool is_mouse_event = event.IsMousePointerEvent(); 361 const bool is_mouse_event = event.IsMousePointerEvent();
360 362
361 if (is_mouse_event) { 363 if (is_mouse_event) {
362 mouse_pointer_last_location_ = event.root_location(); 364 mouse_pointer_last_location_ = event.root_location();
363 mouse_pointer_display_id_ = event_display_id_; 365 mouse_pointer_display_id_ = event_display_id_;
364 delegate_->OnMouseCursorLocationChanged(event.root_location(), 366 delegate_->OnMouseCursorLocationChanged(event.root_location(),
365 event_display_id_); 367 event_display_id_);
366 } 368 }
367 369
368 // Release capture on pointer up. For mouse we only release if there are 370 // Release capture on pointer up. For mouse we only release if there are
369 // no buttons down. 371 // no buttons down.
370 const bool is_pointer_going_up = 372 const bool is_pointer_going_up =
371 (event.type() == ui::ET_POINTER_UP || 373 (event.type() == ui::ET_POINTER_UP ||
372 event.type() == ui::ET_POINTER_CANCELLED) && 374 event.type() == ui::ET_POINTER_CANCELLED) &&
373 (!is_mouse_event || IsOnlyOneMouseButtonDown(event.flags())); 375 (!is_mouse_event || IsOnlyOneMouseButtonDown(event.flags()));
374 376
375 // Update mouse down state upon events which change it. 377 // Update mouse down state upon events which change it.
376 if (is_mouse_event) { 378 if (is_mouse_event) {
377 if (event.type() == ui::ET_POINTER_DOWN) 379 if (event.type() == ui::ET_POINTER_DOWN)
378 mouse_button_down_ = true; 380 mouse_button_down_ = true;
379 else if (is_pointer_going_up) 381 else if (is_pointer_going_up)
380 mouse_button_down_ = false; 382 mouse_button_down_ = false;
381 } 383 }
382 384
383 if (drag_controller_) { 385 if (drag_controller_) {
384 const PointerTarget target = 386 if (drag_controller_->DispatchPointerEvent(event,
385 event_targeter_->PointerTargetForEvent(event, &event_display_id_); 387 pointer_target_found.window))
386 if (drag_controller_->DispatchPointerEvent(event, target.window))
387 return; 388 return;
388 } 389 }
389 390
390 if (capture_window_) { 391 if (capture_window_) {
391 SetMouseCursorSourceWindow(capture_window_); 392 SetMouseCursorSourceWindow(capture_window_);
392 DispatchToClient(capture_window_, capture_window_client_id_, event); 393 DispatchToClient(capture_window_, capture_window_client_id_, event);
393 return; 394 return;
394 } 395 }
395 396
396 const int32_t pointer_id = event.pointer_details().id; 397 const int32_t pointer_id = event.pointer_details().id;
397 if (!IsTrackingPointer(pointer_id) || 398 if (!IsTrackingPointer(pointer_id) ||
398 !pointer_targets_[pointer_id].is_pointer_down) { 399 !pointer_targets_[pointer_id].is_pointer_down) {
399 const bool any_pointers_down = AreAnyPointersDown(); 400 const bool any_pointers_down = AreAnyPointersDown();
400 UpdateTargetForPointer(pointer_id, event); 401 UpdateTargetForPointer(pointer_id, event, pointer_target_found);
401 if (is_mouse_event) 402 if (is_mouse_event)
402 SetMouseCursorSourceWindow(pointer_targets_[pointer_id].window); 403 SetMouseCursorSourceWindow(pointer_targets_[pointer_id].window);
403 404
404 PointerTarget& pointer_target = pointer_targets_[pointer_id]; 405 PointerTarget& pointer_target = pointer_targets_[pointer_id];
405 if (pointer_target.is_pointer_down) { 406 if (pointer_target.is_pointer_down) {
406 if (is_mouse_event) 407 if (is_mouse_event)
407 SetMouseCursorSourceWindow(pointer_target.window); 408 SetMouseCursorSourceWindow(pointer_target.window);
408 if (!any_pointers_down) { 409 if (!any_pointers_down) {
409 if (pointer_target.window) 410 if (pointer_target.window)
410 delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window); 411 delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 } 451 }
451 452
452 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) { 453 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) {
453 DCHECK(IsTrackingPointer(pointer_id)); 454 DCHECK(IsTrackingPointer(pointer_id));
454 ServerWindow* window = pointer_targets_[pointer_id].window; 455 ServerWindow* window = pointer_targets_[pointer_id].window;
455 pointer_targets_.erase(pointer_id); 456 pointer_targets_.erase(pointer_id);
456 if (window) 457 if (window)
457 UnobserveWindow(window); 458 UnobserveWindow(window);
458 } 459 }
459 460
460 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id, 461 void EventDispatcher::UpdateTargetForPointer(
461 const ui::LocatedEvent& event) { 462 int32_t pointer_id,
463 const ui::PointerEvent& event,
464 const PointerTarget& pointer_target_found) {
462 if (!IsTrackingPointer(pointer_id)) { 465 if (!IsTrackingPointer(pointer_id)) {
463 StartTrackingPointer(pointer_id, event_targeter_->PointerTargetForEvent( 466 StartTrackingPointer(pointer_id, pointer_target_found);
464 event, &event_display_id_));
465 return; 467 return;
466 } 468 }
467 469
468 const PointerTarget pointer_target = 470 if (pointer_target_found.window == pointer_targets_[pointer_id].window &&
469 event_targeter_->PointerTargetForEvent(event, &event_display_id_); 471 pointer_target_found.in_nonclient_area ==
470 if (pointer_target.window == pointer_targets_[pointer_id].window &&
471 pointer_target.in_nonclient_area ==
472 pointer_targets_[pointer_id].in_nonclient_area) { 472 pointer_targets_[pointer_id].in_nonclient_area) {
473 // The targets are the same, only set the down state to true if necessary. 473 // The targets are the same, only set the down state to true if necessary.
474 // Down going to up is handled by ProcessLocatedEvent(). 474 // Down going to up is handled by ProcessLocatedEvent().
475 if (pointer_target.is_pointer_down) 475 if (pointer_target_found.is_pointer_down)
476 pointer_targets_[pointer_id].is_pointer_down = true; 476 pointer_targets_[pointer_id].is_pointer_down = true;
477 return; 477 return;
478 } 478 }
479 479
480 // The targets are changing. Send an exit if appropriate. 480 // The targets are changing. Send an exit if appropriate.
481 if (event.IsMousePointerEvent()) { 481 if (event.IsMousePointerEvent()) {
482 ui::PointerEvent exit_event( 482 ui::PointerEvent exit_event(
483 ui::ET_POINTER_EXITED, event.location(), event.root_location(), 483 ui::ET_POINTER_EXITED, event.location(), event.root_location(),
484 event.flags(), 0 /* changed_button_flags */, 484 event.flags(), 0 /* changed_button_flags */,
485 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 485 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE,
486 ui::MouseEvent::kMousePointerId), 486 ui::MouseEvent::kMousePointerId),
487 event.time_stamp()); 487 event.time_stamp());
488 DispatchToPointerTarget(pointer_targets_[pointer_id], exit_event); 488 DispatchToPointerTarget(pointer_targets_[pointer_id], exit_event);
489 } 489 }
490 490
491 // Technically we're updating in place, but calling start then stop makes for 491 // Technically we're updating in place, but calling start then stop makes for
492 // simpler code. 492 // simpler code.
493 StopTrackingPointer(pointer_id); 493 StopTrackingPointer(pointer_id);
494 StartTrackingPointer(pointer_id, pointer_target); 494 StartTrackingPointer(pointer_id, pointer_target_found);
495 }
496
497 void EventDispatcher::UpdateNonClientAreaForCurrentWindowOnFoundWindow(
498 DeepestWindow deepest_window) {
499 event_targeter_->ProcessNextHittesetRequestFromQueue();
500
501 if (deepest_window.window == mouse_cursor_source_window_) {
502 mouse_cursor_in_non_client_area_ =
503 mouse_cursor_source_window_ ? deepest_window.in_non_client_area : false;
504 }
505 delegate_->UpdateNativeCursorFromDispatcher();
506 }
507
508 void EventDispatcher::UpdateCursorProviderByLastKnownLocationOnFoundWindow(
509 DeepestWindow deepest_window) {
510 event_targeter_->ProcessNextHittesetRequestFromQueue();
511
512 SetMouseCursorSourceWindow(deepest_window.window);
513 if (mouse_cursor_source_window_) {
514 mouse_cursor_in_non_client_area_ = deepest_window.in_non_client_area;
515 } else {
516 SetMouseCursorSourceWindow(delegate_->GetRootWindowContaining(
517 &mouse_pointer_last_location_, &mouse_pointer_display_id_));
518 mouse_cursor_in_non_client_area_ = true;
519 }
520 delegate_->UpdateNativeCursorFromDispatcher();
495 } 521 }
496 522
497 bool EventDispatcher::AreAnyPointersDown() const { 523 bool EventDispatcher::AreAnyPointersDown() const {
498 for (const auto& pair : pointer_targets_) { 524 for (const auto& pair : pointer_targets_) {
499 if (pair.second.is_pointer_down) 525 if (pair.second.is_pointer_down)
500 return true; 526 return true;
501 } 527 }
502 return false; 528 return false;
503 } 529 }
504 530
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 if (mouse_cursor_source_window_ == window) 671 if (mouse_cursor_source_window_ == window)
646 SetMouseCursorSourceWindow(nullptr); 672 SetMouseCursorSourceWindow(nullptr);
647 } 673 }
648 674
649 void EventDispatcher::OnDragCursorUpdated() { 675 void EventDispatcher::OnDragCursorUpdated() {
650 delegate_->UpdateNativeCursorFromDispatcher(); 676 delegate_->UpdateNativeCursorFromDispatcher();
651 } 677 }
652 678
653 } // namespace ws 679 } // namespace ws
654 } // namespace ui 680 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698