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

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

Issue 2884463002: Make event-targeting asynchronous in window server. (Closed)
Patch Set: Created 3 years, 7 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/command_line.h"
9 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/task_scheduler/post_task.h"
10 #include "base/time/time.h" 12 #include "base/time/time.h"
11 #include "services/ui/ws/accelerator.h" 13 #include "services/ui/ws/accelerator.h"
12 #include "services/ui/ws/drag_controller.h" 14 #include "services/ui/ws/drag_controller.h"
13 #include "services/ui/ws/drag_source.h" 15 #include "services/ui/ws/drag_source.h"
14 #include "services/ui/ws/event_dispatcher_delegate.h" 16 #include "services/ui/ws/event_dispatcher_delegate.h"
15 #include "services/ui/ws/server_window.h" 17 #include "services/ui/ws/server_window.h"
16 #include "services/ui/ws/server_window_delegate.h" 18 #include "services/ui/ws/server_window_delegate.h"
17 #include "services/ui/ws/window_coordinate_conversions.h" 19 #include "services/ui/ws/window_coordinate_conversions.h"
18 #include "services/ui/ws/window_finder.h" 20 #include "services/ui/ws/window_finder.h"
19 #include "ui/base/cursor/cursor.h" 21 #include "ui/base/cursor/cursor.h"
(...skipping 14 matching lines...) Expand all
34 ui::EF_RIGHT_MOUSE_BUTTON); 36 ui::EF_RIGHT_MOUSE_BUTTON);
35 return button_only_flags == ui::EF_LEFT_MOUSE_BUTTON || 37 return button_only_flags == ui::EF_LEFT_MOUSE_BUTTON ||
36 button_only_flags == ui::EF_MIDDLE_MOUSE_BUTTON || 38 button_only_flags == ui::EF_MIDDLE_MOUSE_BUTTON ||
37 button_only_flags == ui::EF_RIGHT_MOUSE_BUTTON; 39 button_only_flags == ui::EF_RIGHT_MOUSE_BUTTON;
38 } 40 }
39 41
40 } // namespace 42 } // namespace
41 43
42 //////////////////////////////////////////////////////////////////////////////// 44 ////////////////////////////////////////////////////////////////////////////////
43 45
46 EventDispatcher::HittestRequest::HittestRequest(gfx::Point location,
47 HittestCallback callback)
48 : hittest_location(location) {
49 hittest_callback = std::move(callback);
50 }
51
52 EventDispatcher::HittestRequest::~HittestRequest() {}
53
44 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) 54 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate)
45 : delegate_(delegate), 55 : delegate_(delegate),
46 capture_window_(nullptr), 56 capture_window_(nullptr),
47 capture_window_client_id_(kInvalidClientId), 57 capture_window_client_id_(kInvalidClientId),
48 modal_window_controller_(this), 58 modal_window_controller_(this),
49 mouse_button_down_(false), 59 mouse_button_down_(false),
50 mouse_cursor_source_window_(nullptr), 60 mouse_cursor_source_window_(nullptr),
51 mouse_cursor_in_non_client_area_(false) {} 61 mouse_cursor_in_non_client_area_(false),
62 hittest_in_flight_(false) {}
52 63
53 EventDispatcher::~EventDispatcher() { 64 EventDispatcher::~EventDispatcher() {
54 SetMouseCursorSourceWindow(nullptr); 65 SetMouseCursorSourceWindow(nullptr);
55 if (capture_window_) { 66 if (capture_window_) {
56 UnobserveWindow(capture_window_); 67 UnobserveWindow(capture_window_);
57 capture_window_ = nullptr; 68 capture_window_ = nullptr;
58 capture_window_client_id_ = kInvalidClientId; 69 capture_window_client_id_ = kInvalidClientId;
59 } 70 }
60 for (const auto& pair : pointer_targets_) { 71 for (const auto& pair : pointer_targets_) {
61 if (pair.second.window) 72 if (pair.second.window)
(...skipping 11 matching lines...) Expand all
73 while (!pointer_targets_.empty()) 84 while (!pointer_targets_.empty())
74 StopTrackingPointer(pointer_targets_.begin()->first); 85 StopTrackingPointer(pointer_targets_.begin()->first);
75 86
76 mouse_button_down_ = false; 87 mouse_button_down_ = false;
77 } 88 }
78 89
79 void EventDispatcher::SetMousePointerScreenLocation( 90 void EventDispatcher::SetMousePointerScreenLocation(
80 const gfx::Point& screen_location) { 91 const gfx::Point& screen_location) {
81 DCHECK(pointer_targets_.empty()); 92 DCHECK(pointer_targets_.empty());
82 mouse_pointer_last_location_ = screen_location; 93 mouse_pointer_last_location_ = screen_location;
83 UpdateCursorProviderByLastKnownLocation(); 94 UpdateCursorProviderByLastKnownLocation(base::Closure());
84 // Write our initial location back to our shared screen coordinate. This 95 // Write our initial location back to our shared screen coordinate. This
85 // shouldn't cause problems because we already read the cursor before we 96 // shouldn't cause problems because we already read the cursor before we
86 // process any events in views during window construction. 97 // process any events in views during window construction.
87 delegate_->OnMouseCursorLocationChanged(screen_location); 98 delegate_->OnMouseCursorLocationChanged(screen_location);
88 } 99 }
89 100
90 ui::CursorData EventDispatcher::GetCurrentMouseCursor() const { 101 ui::CursorData EventDispatcher::GetCurrentMouseCursor() const {
91 if (drag_controller_) 102 if (drag_controller_)
92 return drag_controller_->current_cursor(); 103 return drag_controller_->current_cursor();
93 104
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 // Begin tracking the capture window if it is not yet being observed. 149 // Begin tracking the capture window if it is not yet being observed.
139 if (window) { 150 if (window) {
140 ObserveWindow(window); 151 ObserveWindow(window);
141 // TODO(sky): this conditional is problematic for the case of capture moving 152 // TODO(sky): this conditional is problematic for the case of capture moving
142 // to a different display. 153 // to a different display.
143 if (!had_capture_window) 154 if (!had_capture_window)
144 delegate_->SetNativeCapture(window); 155 delegate_->SetNativeCapture(window);
145 } else { 156 } else {
146 delegate_->ReleaseNativeCapture(); 157 delegate_->ReleaseNativeCapture();
147 if (!mouse_button_down_) 158 if (!mouse_button_down_)
148 UpdateCursorProviderByLastKnownLocation(); 159 UpdateCursorProviderByLastKnownLocation(base::Closure());
149 } 160 }
150 return true; 161 return true;
151 } 162 }
152 163
153 void EventDispatcher::SetDragDropSourceWindow( 164 void EventDispatcher::SetDragDropSourceWindow(
154 DragSource* drag_source, 165 DragSource* drag_source,
155 ServerWindow* window, 166 ServerWindow* window,
156 DragTargetConnection* source_connection, 167 DragTargetConnection* source_connection,
157 int32_t drag_pointer, 168 int32_t drag_pointer,
158 const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data, 169 const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 // an embed root. This is done to match the behavior of aura, which sets the 221 // an embed root. This is done to match the behavior of aura, which sets the
211 // cursor on the root. 222 // cursor on the root.
212 const ClientSpecificId target_client_id = delegate_->GetEventTargetClientId( 223 const ClientSpecificId target_client_id = delegate_->GetEventTargetClientId(
213 mouse_cursor_source_window_, mouse_cursor_in_non_client_area_); 224 mouse_cursor_source_window_, mouse_cursor_in_non_client_area_);
214 const ServerWindow* window = mouse_cursor_source_window_; 225 const ServerWindow* window = mouse_cursor_source_window_;
215 while (window && window->id().client_id == target_client_id) 226 while (window && window->id().client_id == target_client_id)
216 window = window->parent(); 227 window = window->parent();
217 return window; 228 return window;
218 } 229 }
219 230
220 void EventDispatcher::UpdateNonClientAreaForCurrentWindow() { 231 void EventDispatcher::UpdateNonClientAreaForCurrentWindow(
232 const base::Closure& callback) {
221 if (mouse_cursor_source_window_) { 233 if (mouse_cursor_source_window_) {
222 DeepestWindow deepest_window = 234 FindDeepestVisibleWindowForEvents(
223 FindDeepestVisibleWindowForEvents(mouse_pointer_last_location_); 235 mouse_pointer_last_location_,
224 if (deepest_window.window == mouse_cursor_source_window_) { 236 base::BindOnce(
225 mouse_cursor_in_non_client_area_ = mouse_cursor_source_window_ 237 &EventDispatcher::UpdateNonClientAreaForCurrentWindowOnFoundWindow,
226 ? deepest_window.in_non_client_area 238 base::Unretained(this), callback));
227 : false;
228 }
229 } 239 }
230 } 240 }
231 241
232 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { 242 void EventDispatcher::UpdateCursorProviderByLastKnownLocation(
243 const base::Closure& callback) {
233 if (!mouse_button_down_) { 244 if (!mouse_button_down_) {
234 DeepestWindow deepest_window = 245 FindDeepestVisibleWindowForEvents(
235 FindDeepestVisibleWindowForEvents(mouse_pointer_last_location_); 246 mouse_pointer_last_location_,
236 SetMouseCursorSourceWindow(deepest_window.window); 247 base::BindOnce(&EventDispatcher::
237 if (mouse_cursor_source_window_) { 248 UpdateCursorProviderByLastKnownLocationOnFoundWindow,
238 mouse_cursor_in_non_client_area_ = deepest_window.in_non_client_area; 249 base::Unretained(this), callback));
239 } else {
240 gfx::Point location = mouse_pointer_last_location_;
241 SetMouseCursorSourceWindow(delegate_->GetRootWindowContaining(&location));
242 mouse_cursor_in_non_client_area_ = true;
243 }
244 } 250 }
245 } 251 }
246 252
247 bool EventDispatcher::AddAccelerator(uint32_t id, 253 bool EventDispatcher::AddAccelerator(uint32_t id,
248 mojom::EventMatcherPtr event_matcher) { 254 mojom::EventMatcherPtr event_matcher) {
249 std::unique_ptr<Accelerator> accelerator(new Accelerator(id, *event_matcher)); 255 std::unique_ptr<Accelerator> accelerator(new Accelerator(id, *event_matcher));
250 // If an accelerator with the same id or matcher already exists, then abort. 256 // If an accelerator with the same id or matcher already exists, then abort.
251 for (const auto& pair : accelerators_) { 257 for (const auto& pair : accelerators_) {
252 if (pair.first == id) { 258 if (pair.first == id) {
253 DVLOG(1) << "duplicate accelerator. Accelerator id=" << accelerator->id() 259 DVLOG(1) << "duplicate accelerator. Accelerator id=" << accelerator->id()
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 return; 346 return;
341 } 347 }
342 delegate_->OnEventTargetNotFound(event); 348 delegate_->OnEventTargetNotFound(event);
343 if (post_target) 349 if (post_target)
344 delegate_->OnAccelerator(post_target->id(), event, 350 delegate_->OnAccelerator(post_target->id(), event,
345 EventDispatcherDelegate::AcceleratorPhase::POST); 351 EventDispatcherDelegate::AcceleratorPhase::POST);
346 } 352 }
347 353
348 void EventDispatcher::ProcessPointerEvent(const ui::PointerEvent& event) { 354 void EventDispatcher::ProcessPointerEvent(const ui::PointerEvent& event) {
349 DCHECK(event.IsPointerEvent()); 355 DCHECK(event.IsPointerEvent());
356 PointerTargetForEvent(
357 event, base::BindOnce(&EventDispatcher::ProcessPointerEventOnFoundTarget,
358 base::Unretained(this), event));
359 }
360
361 void EventDispatcher::ProcessPointerEventOnFoundTarget(
362 const ui::PointerEvent& event,
363 PointerTarget pointer_target_found) {
364 ProcessNextHittesetRequestFromQueue();
365
350 const bool is_mouse_event = event.IsMousePointerEvent(); 366 const bool is_mouse_event = event.IsMousePointerEvent();
351 367
352 if (is_mouse_event) { 368 if (is_mouse_event) {
353 mouse_pointer_last_location_ = event.root_location(); 369 mouse_pointer_last_location_ = event.root_location();
354 delegate_->OnMouseCursorLocationChanged(event.root_location()); 370 delegate_->OnMouseCursorLocationChanged(event.root_location());
355 } 371 }
356 372
357 // Release capture on pointer up. For mouse we only release if there are 373 // Release capture on pointer up. For mouse we only release if there are
358 // no buttons down. 374 // no buttons down.
359 const bool is_pointer_going_up = 375 const bool is_pointer_going_up =
360 (event.type() == ui::ET_POINTER_UP || 376 (event.type() == ui::ET_POINTER_UP ||
361 event.type() == ui::ET_POINTER_CANCELLED) && 377 event.type() == ui::ET_POINTER_CANCELLED) &&
362 (!is_mouse_event || IsOnlyOneMouseButtonDown(event.flags())); 378 (!is_mouse_event || IsOnlyOneMouseButtonDown(event.flags()));
363 379
364 // Update mouse down state upon events which change it. 380 // Update mouse down state upon events which change it.
365 if (is_mouse_event) { 381 if (is_mouse_event) {
366 if (event.type() == ui::ET_POINTER_DOWN) 382 if (event.type() == ui::ET_POINTER_DOWN)
367 mouse_button_down_ = true; 383 mouse_button_down_ = true;
368 else if (is_pointer_going_up) 384 else if (is_pointer_going_up)
369 mouse_button_down_ = false; 385 mouse_button_down_ = false;
370 } 386 }
371 387
372 if (drag_controller_) { 388 if (drag_controller_) {
373 const PointerTarget target = PointerTargetForEvent(event); 389 if (drag_controller_->DispatchPointerEvent(event,
374 if (drag_controller_->DispatchPointerEvent(event, target.window)) 390 pointer_target_found.window))
375 return; 391 return;
376 } 392 }
377 393
378 if (capture_window_) { 394 if (capture_window_) {
379 SetMouseCursorSourceWindow(capture_window_); 395 SetMouseCursorSourceWindow(capture_window_);
380 DispatchToClient(capture_window_, capture_window_client_id_, event); 396 DispatchToClient(capture_window_, capture_window_client_id_, event);
381 return; 397 return;
382 } 398 }
383 399
384 const int32_t pointer_id = event.pointer_details().id; 400 const int32_t pointer_id = event.pointer_details().id;
385 if (!IsTrackingPointer(pointer_id) || 401 if (!IsTrackingPointer(pointer_id) ||
386 !pointer_targets_[pointer_id].is_pointer_down) { 402 !pointer_targets_[pointer_id].is_pointer_down) {
387 const bool any_pointers_down = AreAnyPointersDown(); 403 const bool any_pointers_down = AreAnyPointersDown();
388 UpdateTargetForPointer(pointer_id, event); 404 UpdateTargetForPointer(pointer_id, event, pointer_target_found);
389 if (is_mouse_event) 405 if (is_mouse_event)
390 SetMouseCursorSourceWindow(pointer_targets_[pointer_id].window); 406 SetMouseCursorSourceWindow(pointer_targets_[pointer_id].window);
391 407
392 PointerTarget& pointer_target = pointer_targets_[pointer_id]; 408 PointerTarget& pointer_target = pointer_targets_[pointer_id];
393 if (pointer_target.is_pointer_down) { 409 if (pointer_target.is_pointer_down) {
394 if (is_mouse_event) 410 if (is_mouse_event)
395 SetMouseCursorSourceWindow(pointer_target.window); 411 SetMouseCursorSourceWindow(pointer_target.window);
396 if (!any_pointers_down) { 412 if (!any_pointers_down) {
397 if (pointer_target.window) 413 if (pointer_target.window)
398 delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window); 414 delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window);
399 ServerWindow* capture_window = pointer_target.window; 415 ServerWindow* capture_window = pointer_target.window;
400 if (!capture_window) { 416 if (!capture_window) {
401 gfx::Point event_location = event.root_location(); 417 gfx::Point event_location = event.root_location();
402 capture_window = delegate_->GetRootWindowContaining(&event_location); 418 capture_window = delegate_->GetRootWindowContaining(&event_location);
403 } 419 }
404 delegate_->SetNativeCapture(capture_window); 420 delegate_->SetNativeCapture(capture_window);
405 } 421 }
406 } 422 }
407 } 423 }
408 424
409 // When we release the mouse button, we want the cursor to be sourced from 425 // When we release the mouse button, we want the cursor to be sourced from
410 // the window under the mouse pointer, even though we're sending the button 426 // the window under the mouse pointer, even though we're sending the button
411 // up event to the window that had implicit capture. We have to set this 427 // up event to the window that had implicit capture. We have to set this
412 // before we perform dispatch because the Delegate is going to read this 428 // before we perform dispatch because the Delegate is going to read this
413 // information from us. 429 // information from us.
414 if (is_pointer_going_up && is_mouse_event) 430 if (is_pointer_going_up && is_mouse_event)
415 UpdateCursorProviderByLastKnownLocation(); 431 UpdateCursorProviderByLastKnownLocation(base::Closure());
416 432
417 DispatchToPointerTarget(pointer_targets_[pointer_id], event); 433 DispatchToPointerTarget(pointer_targets_[pointer_id], event);
418 434
419 if (is_pointer_going_up) { 435 if (is_pointer_going_up) {
420 if (is_mouse_event) 436 if (is_mouse_event)
421 pointer_targets_[pointer_id].is_pointer_down = false; 437 pointer_targets_[pointer_id].is_pointer_down = false;
422 else 438 else
423 StopTrackingPointer(pointer_id); 439 StopTrackingPointer(pointer_id);
424 if (!AreAnyPointersDown()) 440 if (!AreAnyPointersDown())
425 delegate_->ReleaseNativeCapture(); 441 delegate_->ReleaseNativeCapture();
(...skipping 10 matching lines...) Expand all
436 } 452 }
437 453
438 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) { 454 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) {
439 DCHECK(IsTrackingPointer(pointer_id)); 455 DCHECK(IsTrackingPointer(pointer_id));
440 ServerWindow* window = pointer_targets_[pointer_id].window; 456 ServerWindow* window = pointer_targets_[pointer_id].window;
441 pointer_targets_.erase(pointer_id); 457 pointer_targets_.erase(pointer_id);
442 if (window) 458 if (window)
443 UnobserveWindow(window); 459 UnobserveWindow(window);
444 } 460 }
445 461
446 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id, 462 void EventDispatcher::UpdateTargetForPointer(
447 const ui::LocatedEvent& event) { 463 int32_t pointer_id,
464 const ui::PointerEvent& event,
465 const PointerTarget& pointer_target_found) {
448 if (!IsTrackingPointer(pointer_id)) { 466 if (!IsTrackingPointer(pointer_id)) {
449 StartTrackingPointer(pointer_id, PointerTargetForEvent(event)); 467 StartTrackingPointer(pointer_id, pointer_target_found);
450 return; 468 return;
451 } 469 }
452 470
453 const PointerTarget pointer_target = PointerTargetForEvent(event); 471 if (pointer_target_found.window == pointer_targets_[pointer_id].window &&
454 if (pointer_target.window == pointer_targets_[pointer_id].window && 472 pointer_target_found.in_nonclient_area ==
455 pointer_target.in_nonclient_area ==
456 pointer_targets_[pointer_id].in_nonclient_area) { 473 pointer_targets_[pointer_id].in_nonclient_area) {
457 // The targets are the same, only set the down state to true if necessary. 474 // The targets are the same, only set the down state to true if necessary.
458 // Down going to up is handled by ProcessLocatedEvent(). 475 // Down going to up is handled by ProcessLocatedEvent().
459 if (pointer_target.is_pointer_down) 476 if (pointer_target_found.is_pointer_down)
460 pointer_targets_[pointer_id].is_pointer_down = true; 477 pointer_targets_[pointer_id].is_pointer_down = true;
461 return; 478 return;
462 } 479 }
463 480
464 // The targets are changing. Send an exit if appropriate. 481 // The targets are changing. Send an exit if appropriate.
465 if (event.IsMousePointerEvent()) { 482 if (event.IsMousePointerEvent()) {
466 ui::PointerEvent exit_event( 483 ui::PointerEvent exit_event(
467 ui::ET_POINTER_EXITED, event.location(), event.root_location(), 484 ui::ET_POINTER_EXITED, event.location(), event.root_location(),
468 event.flags(), 0 /* changed_button_flags */, 485 event.flags(), 0 /* changed_button_flags */,
469 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 486 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE,
470 ui::MouseEvent::kMousePointerId), 487 ui::MouseEvent::kMousePointerId),
471 event.time_stamp()); 488 event.time_stamp());
472 DispatchToPointerTarget(pointer_targets_[pointer_id], exit_event); 489 DispatchToPointerTarget(pointer_targets_[pointer_id], exit_event);
473 } 490 }
474 491
475 // Technically we're updating in place, but calling start then stop makes for 492 // Technically we're updating in place, but calling start then stop makes for
476 // simpler code. 493 // simpler code.
477 StopTrackingPointer(pointer_id); 494 StopTrackingPointer(pointer_id);
478 StartTrackingPointer(pointer_id, pointer_target); 495 StartTrackingPointer(pointer_id, pointer_target_found);
479 } 496 }
480 497
481 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( 498 void EventDispatcher::PointerTargetForEvent(
482 const ui::LocatedEvent& event) { 499 const ui::PointerEvent& event,
500 PointerTargetForEventCallback callback) {
501 FindDeepestVisibleWindowForEvents(
502 event.root_location(),
503 base::BindOnce(&EventDispatcher::PointerTargetForEventOnFoundWindow,
504 base::Unretained(this), event, std::move(callback)));
505 }
506
507 void EventDispatcher::PointerTargetForEventOnFoundWindow(
508 const ui::PointerEvent& event,
509 PointerTargetForEventCallback callback,
510 DeepestWindow deepest_window) {
483 PointerTarget pointer_target; 511 PointerTarget pointer_target;
484 DeepestWindow deepest_window =
485 FindDeepestVisibleWindowForEvents(event.root_location());
486 pointer_target.window = 512 pointer_target.window =
487 modal_window_controller_.GetTargetForWindow(deepest_window.window); 513 modal_window_controller_.GetTargetForWindow(deepest_window.window);
488 pointer_target.is_mouse_event = event.IsMousePointerEvent(); 514 pointer_target.is_mouse_event = event.IsMousePointerEvent();
489 pointer_target.in_nonclient_area = 515 pointer_target.in_nonclient_area =
490 deepest_window.window != pointer_target.window || 516 deepest_window.window != pointer_target.window ||
491 !pointer_target.window || deepest_window.in_non_client_area; 517 !pointer_target.window || deepest_window.in_non_client_area;
492 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; 518 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
493 return pointer_target; 519 std::move(callback).Run(pointer_target);
494 } 520 }
495 521
496 bool EventDispatcher::AreAnyPointersDown() const { 522 bool EventDispatcher::AreAnyPointersDown() const {
497 for (const auto& pair : pointer_targets_) { 523 for (const auto& pair : pointer_targets_) {
498 if (pair.second.is_pointer_down) 524 if (pair.second.is_pointer_down)
499 return true; 525 return true;
500 } 526 }
501 return false; 527 return false;
502 } 528 }
503 529
(...skipping 29 matching lines...) Expand all
533 if (capture_window_ == window) { 559 if (capture_window_ == window) {
534 UnobserveWindow(window); 560 UnobserveWindow(window);
535 capture_window_ = nullptr; 561 capture_window_ = nullptr;
536 capture_window_client_id_ = kInvalidClientId; 562 capture_window_client_id_ = kInvalidClientId;
537 mouse_button_down_ = false; 563 mouse_button_down_ = false;
538 // A window only cares to be informed that it lost capture if it explicitly 564 // A window only cares to be informed that it lost capture if it explicitly
539 // requested capture. A window can lose capture if another window gains 565 // requested capture. A window can lose capture if another window gains
540 // explicit capture. 566 // explicit capture.
541 delegate_->OnCaptureChanged(nullptr, window); 567 delegate_->OnCaptureChanged(nullptr, window);
542 delegate_->ReleaseNativeCapture(); 568 delegate_->ReleaseNativeCapture();
543 UpdateCursorProviderByLastKnownLocation(); 569 UpdateCursorProviderByLastKnownLocation(base::Closure());
544 return; 570 return;
545 } 571 }
546 572
547 for (auto& pair : pointer_targets_) { 573 for (auto& pair : pointer_targets_) {
548 if (pair.second.window == window) { 574 if (pair.second.window == window) {
549 UnobserveWindow(window); 575 UnobserveWindow(window);
550 pair.second.window = nullptr; 576 pair.second.window = nullptr;
551 } 577 }
552 } 578 }
553 } 579 }
(...skipping 19 matching lines...) Expand all
573 Accelerator* EventDispatcher::FindAccelerator( 599 Accelerator* EventDispatcher::FindAccelerator(
574 const ui::KeyEvent& event, 600 const ui::KeyEvent& event,
575 const ui::mojom::AcceleratorPhase phase) { 601 const ui::mojom::AcceleratorPhase phase) {
576 for (const auto& pair : accelerators_) { 602 for (const auto& pair : accelerators_) {
577 if (pair.second->MatchesEvent(event, phase)) 603 if (pair.second->MatchesEvent(event, phase))
578 return pair.second.get(); 604 return pair.second.get();
579 } 605 }
580 return nullptr; 606 return nullptr;
581 } 607 }
582 608
583 DeepestWindow EventDispatcher::FindDeepestVisibleWindowForEvents( 609 void EventDispatcher::FindDeepestVisibleWindowForEvents(
584 const gfx::Point& location) { 610 const gfx::Point& location,
611 HittestCallback callback) {
612 if (hittest_in_flight_ || !hittest_request_queue_.empty()) {
613 std::unique_ptr<HittestRequest> hittest_request =
614 base::MakeUnique<HittestRequest>(location, std::move(callback));
615 hittest_request_queue_.push(std::move(hittest_request));
616 return;
617 }
618
619 FindDeepestVisibleWindowForEventsImpl(location, std::move(callback));
620 }
621
622 void EventDispatcher::FindDeepestVisibleWindowForEventsImpl(
623 const gfx::Point& location,
624 HittestCallback callback) {
625 // TODO(riajiang): After HittestComponent is implemented, do synchronous
626 // hit-test for most cases using shared memory and only ask Blink
627 // asynchronously for hard cases. For now, assume all synchronous hit-tests
628 // failed if the "enable-async-event-targeting" flag is turned on.
629 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
630 "enable-async-event-targeting")) {
631 DCHECK(!hittest_in_flight_);
632 hittest_in_flight_ = true;
633 base::ThreadTaskRunnerHandle::Get()->PostTask(
634 FROM_HERE,
635 base::BindOnce(&EventDispatcher::FindDeepestVisibleWindowForEventsAsync,
636 base::Unretained(this), location, std::move(callback)));
sky 2017/05/14 15:59:05 What guarantees this is valid by the time the call
riajiang 2017/05/15 18:34:41 As discussed, changed to use WeakPtrFactory.
637 } else {
638 FindDeepestVisibleWindowForEventsAsync(location, std::move(callback));
639 }
640 }
641
642 void EventDispatcher::FindDeepestVisibleWindowForEventsAsync(
643 const gfx::Point& location,
644 HittestCallback callback) {
585 gfx::Point relative_location(location); 645 gfx::Point relative_location(location);
586 // For the case of no root.
587 ServerWindow* root = delegate_->GetRootWindowContaining(&relative_location); 646 ServerWindow* root = delegate_->GetRootWindowContaining(&relative_location);
588 return root ? ui::ws::FindDeepestVisibleWindowForEvents(root, 647 if (root) {
589 relative_location) 648 std::move(callback).Run(
590 : DeepestWindow(); 649 ui::ws::FindDeepestVisibleWindowForEvents(root, relative_location));
650 } else {
651 std::move(callback).Run(DeepestWindow());
652 }
653 }
654
655 void EventDispatcher::UpdateNonClientAreaForCurrentWindowOnFoundWindow(
656 const base::Closure& callback,
657 DeepestWindow deepest_window) {
658 ProcessNextHittesetRequestFromQueue();
659
660 if (deepest_window.window == mouse_cursor_source_window_) {
661 mouse_cursor_in_non_client_area_ =
662 mouse_cursor_source_window_ ? deepest_window.in_non_client_area : false;
663 }
664 if (callback)
665 callback.Run();
666 }
667
668 void EventDispatcher::UpdateCursorProviderByLastKnownLocationOnFoundWindow(
669 const base::Closure& callback,
670 DeepestWindow deepest_window) {
671 ProcessNextHittesetRequestFromQueue();
672
673 SetMouseCursorSourceWindow(deepest_window.window);
674 if (mouse_cursor_source_window_) {
675 mouse_cursor_in_non_client_area_ = deepest_window.in_non_client_area;
676 } else {
677 gfx::Point location = mouse_pointer_last_location_;
678 SetMouseCursorSourceWindow(delegate_->GetRootWindowContaining(&location));
679 mouse_cursor_in_non_client_area_ = true;
680 }
681 if (callback)
682 callback.Run();
683 }
684
685 void EventDispatcher::ProcessNextHittesetRequestFromQueue() {
686 hittest_in_flight_ = false;
687 if (hittest_request_queue_.empty())
688 return;
689 std::unique_ptr<HittestRequest> hittest_request =
690 std::move(hittest_request_queue_.front());
691 hittest_request_queue_.pop();
692 FindDeepestVisibleWindowForEventsImpl(
693 hittest_request->hittest_location,
694 std::move(hittest_request->hittest_callback));
591 } 695 }
592 696
593 void EventDispatcher::CancelImplicitCaptureExcept(ServerWindow* window, 697 void EventDispatcher::CancelImplicitCaptureExcept(ServerWindow* window,
594 ClientSpecificId client_id) { 698 ClientSpecificId client_id) {
595 for (const auto& pair : pointer_targets_) { 699 for (const auto& pair : pointer_targets_) {
596 ServerWindow* target = pair.second.window; 700 ServerWindow* target = pair.second.window;
597 if (!target) 701 if (!target)
598 continue; 702 continue;
599 UnobserveWindow(target); 703 UnobserveWindow(target);
600 if (target == window) 704 if (target == window)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 if (mouse_cursor_source_window_ == window) 757 if (mouse_cursor_source_window_ == window)
654 SetMouseCursorSourceWindow(nullptr); 758 SetMouseCursorSourceWindow(nullptr);
655 } 759 }
656 760
657 void EventDispatcher::OnDragCursorUpdated() { 761 void EventDispatcher::OnDragCursorUpdated() {
658 delegate_->UpdateNativeCursorFromDispatcher(); 762 delegate_->UpdateNativeCursorFromDispatcher();
659 } 763 }
660 764
661 } // namespace ws 765 } // namespace ws
662 } // namespace ui 766 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698