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

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

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

Powered by Google App Engine
This is Rietveld 408576698