| OLD | NEW |
| 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> |
| 8 |
| 7 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 8 #include "cc/surfaces/surface_hittest.h" | 10 #include "cc/surfaces/surface_hittest.h" |
| 9 #include "components/mus/surfaces/surfaces_state.h" | 11 #include "components/mus/surfaces/surfaces_state.h" |
| 10 #include "components/mus/ws/accelerator.h" | 12 #include "components/mus/ws/accelerator.h" |
| 11 #include "components/mus/ws/display.h" | 13 #include "components/mus/ws/display.h" |
| 12 #include "components/mus/ws/event_dispatcher_delegate.h" | 14 #include "components/mus/ws/event_dispatcher_delegate.h" |
| 13 #include "components/mus/ws/server_window.h" | 15 #include "components/mus/ws/server_window.h" |
| 14 #include "components/mus/ws/server_window_delegate.h" | 16 #include "components/mus/ws/server_window_delegate.h" |
| 15 #include "components/mus/ws/window_coordinate_conversions.h" | 17 #include "components/mus/ws/window_coordinate_conversions.h" |
| 16 #include "components/mus/ws/window_finder.h" | 18 #include "components/mus/ws/window_finder.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 | 65 |
| 64 } // namespace | 66 } // namespace |
| 65 | 67 |
| 66 //////////////////////////////////////////////////////////////////////////////// | 68 //////////////////////////////////////////////////////////////////////////////// |
| 67 | 69 |
| 68 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) | 70 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) |
| 69 : delegate_(delegate), | 71 : delegate_(delegate), |
| 70 root_(nullptr), | 72 root_(nullptr), |
| 71 capture_window_(nullptr), | 73 capture_window_(nullptr), |
| 72 capture_window_in_nonclient_area_(false), | 74 capture_window_in_nonclient_area_(false), |
| 73 modal_window_controller_(this), | |
| 74 mouse_button_down_(false), | 75 mouse_button_down_(false), |
| 75 mouse_cursor_source_window_(nullptr) {} | 76 mouse_cursor_source_window_(nullptr) {} |
| 76 | 77 |
| 77 EventDispatcher::~EventDispatcher() { | 78 EventDispatcher::~EventDispatcher() { |
| 79 std::set<ServerWindow*> pointer_targets; |
| 78 if (capture_window_) { | 80 if (capture_window_) { |
| 79 UnobserveWindow(capture_window_); | 81 pointer_targets.insert(capture_window_); |
| 82 capture_window_->RemoveObserver(this); |
| 80 capture_window_ = nullptr; | 83 capture_window_ = nullptr; |
| 81 } | 84 } |
| 82 for (const auto& pair : pointer_targets_) { | 85 for (const auto& pair : pointer_targets_) { |
| 83 if (pair.second.window) | 86 if (pair.second.window && |
| 84 UnobserveWindow(pair.second.window); | 87 pointer_targets.insert(pair.second.window).second) { |
| 88 pair.second.window->RemoveObserver(this); |
| 89 } |
| 85 } | 90 } |
| 86 pointer_targets_.clear(); | 91 pointer_targets_.clear(); |
| 87 } | 92 } |
| 88 | 93 |
| 89 void EventDispatcher::Reset() { | 94 void EventDispatcher::Reset() { |
| 90 if (capture_window_) { | 95 if (capture_window_) { |
| 91 CancelPointerEventsToTarget(capture_window_); | 96 CancelPointerEventsToTarget(capture_window_); |
| 92 DCHECK(capture_window_ == nullptr); | 97 DCHECK(capture_window_ == nullptr); |
| 93 } | 98 } |
| 94 | 99 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 108 // process any events in views during window construction. | 113 // process any events in views during window construction. |
| 109 delegate_->OnMouseCursorLocationChanged(screen_location); | 114 delegate_->OnMouseCursorLocationChanged(screen_location); |
| 110 } | 115 } |
| 111 | 116 |
| 112 bool EventDispatcher::SetCaptureWindow(ServerWindow* window, | 117 bool EventDispatcher::SetCaptureWindow(ServerWindow* window, |
| 113 bool in_nonclient_area) { | 118 bool in_nonclient_area) { |
| 114 if (window == capture_window_) | 119 if (window == capture_window_) |
| 115 return true; | 120 return true; |
| 116 | 121 |
| 117 // A window that is blocked by a modal window cannot gain capture. | 122 // A window that is blocked by a modal window cannot gain capture. |
| 118 if (window && modal_window_controller_.IsWindowBlocked(window)) | 123 if (window && window->IsBlockedByModalWindow()) |
| 119 return false; | 124 return false; |
| 120 | 125 |
| 121 if (capture_window_) { | 126 if (capture_window_) { |
| 122 // Stop observing old capture window. |pointer_targets_| are cleared on | 127 // Stop observing old capture window. |pointer_targets_| are cleared on |
| 123 // initial setting of a capture window. | 128 // initial setting of a capture window. |
| 124 delegate_->OnServerWindowCaptureLost(capture_window_); | 129 delegate_->OnServerWindowCaptureLost(capture_window_); |
| 125 UnobserveWindow(capture_window_); | 130 capture_window_->RemoveObserver(this); |
| 126 } else { | 131 } else { |
| 127 // Cancel implicit capture to all other windows. | 132 // Cancel implicit capture to all other windows. |
| 133 std::set<ServerWindow*> unobserved_windows; |
| 128 for (const auto& pair : pointer_targets_) { | 134 for (const auto& pair : pointer_targets_) { |
| 129 ServerWindow* target = pair.second.window; | 135 ServerWindow* target = pair.second.window; |
| 130 if (!target) | 136 if (!target) |
| 131 continue; | 137 continue; |
| 132 UnobserveWindow(target); | 138 if (unobserved_windows.insert(target).second) |
| 139 target->RemoveObserver(this); |
| 133 if (target == window) | 140 if (target == window) |
| 134 continue; | 141 continue; |
| 135 | 142 |
| 136 ui::EventType event_type = pair.second.is_mouse_event | 143 ui::EventType event_type = pair.second.is_mouse_event |
| 137 ? ui::ET_POINTER_EXITED | 144 ? ui::ET_POINTER_EXITED |
| 138 : ui::ET_POINTER_CANCELLED; | 145 : ui::ET_POINTER_CANCELLED; |
| 139 ui::EventPointerType pointer_type = | 146 ui::EventPointerType pointer_type = |
| 140 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE | 147 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE |
| 141 : ui::EventPointerType::POINTER_TYPE_TOUCH; | 148 : ui::EventPointerType::POINTER_TYPE_TOUCH; |
| 142 // TODO(jonross): Track previous location in PointerTarget for sending | 149 // TODO(jonross): Track previous location in PointerTarget for sending |
| 143 // cancels. | 150 // cancels. |
| 144 ui::PointerEvent event(event_type, pointer_type, gfx::Point(), | 151 ui::PointerEvent event(event_type, pointer_type, gfx::Point(), |
| 145 gfx::Point(), ui::EF_NONE, pair.first, | 152 gfx::Point(), ui::EF_NONE, pair.first, |
| 146 ui::EventTimeForNow()); | 153 ui::EventTimeForNow()); |
| 147 DispatchToPointerTarget(pair.second, event); | 154 DispatchToPointerTarget(pair.second, event); |
| 148 } | 155 } |
| 149 pointer_targets_.clear(); | 156 pointer_targets_.clear(); |
| 150 } | 157 } |
| 151 | 158 |
| 152 // Begin tracking the capture window if it is not yet being observed. | 159 // Begin tracking the capture window if it is not yet being observed. |
| 153 if (window) { | 160 if (window) { |
| 154 ObserveWindow(window); | 161 window->AddObserver(this); |
| 155 if (!capture_window_) | 162 if (!capture_window_) |
| 156 delegate_->SetNativeCapture(); | 163 delegate_->SetNativeCapture(); |
| 157 } else { | 164 } else { |
| 158 delegate_->ReleaseNativeCapture(); | 165 delegate_->ReleaseNativeCapture(); |
| 159 if (!mouse_button_down_) | 166 if (!mouse_button_down_) |
| 160 UpdateCursorProviderByLastKnownLocation(); | 167 UpdateCursorProviderByLastKnownLocation(); |
| 161 } | 168 } |
| 162 | 169 |
| 163 capture_window_ = window; | 170 capture_window_ = window; |
| 164 capture_window_in_nonclient_area_ = in_nonclient_area; | 171 capture_window_in_nonclient_area_ = in_nonclient_area; |
| 165 return true; | 172 return true; |
| 166 } | 173 } |
| 167 | 174 |
| 168 void EventDispatcher::AddSystemModalWindow(ServerWindow* window) { | |
| 169 modal_window_controller_.AddSystemModalWindow(window); | |
| 170 } | |
| 171 | |
| 172 void EventDispatcher::ReleaseCaptureBlockedByModalWindow( | |
| 173 const ServerWindow* modal_window) { | |
| 174 if (!capture_window_) | |
| 175 return; | |
| 176 | |
| 177 if (modal_window_controller_.IsWindowBlockedBy(capture_window_, | |
| 178 modal_window)) { | |
| 179 SetCaptureWindow(nullptr, false); | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 void EventDispatcher::ReleaseCaptureBlockedByAnyModalWindow() { | |
| 184 if (!capture_window_) | |
| 185 return; | |
| 186 | |
| 187 if (modal_window_controller_.IsWindowBlocked(capture_window_)) | |
| 188 SetCaptureWindow(nullptr, false); | |
| 189 } | |
| 190 | |
| 191 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { | 175 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { |
| 192 if (!mouse_button_down_) { | 176 if (!mouse_button_down_) { |
| 193 gfx::Point location = mouse_pointer_last_location_; | 177 gfx::Point location = mouse_pointer_last_location_; |
| 194 mouse_cursor_source_window_ = | 178 mouse_cursor_source_window_ = |
| 195 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); | 179 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); |
| 196 } | 180 } |
| 197 } | 181 } |
| 198 | 182 |
| 199 bool EventDispatcher::AddAccelerator(uint32_t id, | 183 bool EventDispatcher::AddAccelerator(uint32_t id, |
| 200 mojom::EventMatcherPtr event_matcher) { | 184 mojom::EventMatcherPtr event_matcher) { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 StopTrackingPointer(pointer_id); | 310 StopTrackingPointer(pointer_id); |
| 327 if (!AreAnyPointersDown()) | 311 if (!AreAnyPointersDown()) |
| 328 delegate_->ReleaseNativeCapture(); | 312 delegate_->ReleaseNativeCapture(); |
| 329 } | 313 } |
| 330 } | 314 } |
| 331 | 315 |
| 332 void EventDispatcher::StartTrackingPointer( | 316 void EventDispatcher::StartTrackingPointer( |
| 333 int32_t pointer_id, | 317 int32_t pointer_id, |
| 334 const PointerTarget& pointer_target) { | 318 const PointerTarget& pointer_target) { |
| 335 DCHECK(!IsTrackingPointer(pointer_id)); | 319 DCHECK(!IsTrackingPointer(pointer_id)); |
| 336 ObserveWindow(pointer_target.window); | 320 if (!IsObservingWindow(pointer_target.window)) |
| 321 pointer_target.window->AddObserver(this); |
| 337 pointer_targets_[pointer_id] = pointer_target; | 322 pointer_targets_[pointer_id] = pointer_target; |
| 338 } | 323 } |
| 339 | 324 |
| 340 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) { | 325 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) { |
| 341 DCHECK(IsTrackingPointer(pointer_id)); | 326 DCHECK(IsTrackingPointer(pointer_id)); |
| 342 ServerWindow* window = pointer_targets_[pointer_id].window; | 327 ServerWindow* window = pointer_targets_[pointer_id].window; |
| 343 pointer_targets_.erase(pointer_id); | 328 pointer_targets_.erase(pointer_id); |
| 344 if (window) | 329 if (window && !IsObservingWindow(window)) |
| 345 UnobserveWindow(window); | 330 window->RemoveObserver(this); |
| 346 } | 331 } |
| 347 | 332 |
| 348 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id, | 333 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id, |
| 349 const ui::LocatedEvent& event) { | 334 const ui::LocatedEvent& event) { |
| 350 if (!IsTrackingPointer(pointer_id)) { | 335 if (!IsTrackingPointer(pointer_id)) { |
| 351 StartTrackingPointer(pointer_id, PointerTargetForEvent(event)); | 336 StartTrackingPointer(pointer_id, PointerTargetForEvent(event)); |
| 352 return; | 337 return; |
| 353 } | 338 } |
| 354 | 339 |
| 355 const PointerTarget pointer_target = PointerTargetForEvent(event); | 340 const PointerTarget pointer_target = PointerTargetForEvent(event); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 377 StopTrackingPointer(pointer_id); | 362 StopTrackingPointer(pointer_id); |
| 378 StartTrackingPointer(pointer_id, pointer_target); | 363 StartTrackingPointer(pointer_id, pointer_target); |
| 379 } | 364 } |
| 380 | 365 |
| 381 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( | 366 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( |
| 382 const ui::LocatedEvent& event) const { | 367 const ui::LocatedEvent& event) const { |
| 383 PointerTarget pointer_target; | 368 PointerTarget pointer_target; |
| 384 gfx::Point location(event.location()); | 369 gfx::Point location(event.location()); |
| 385 ServerWindow* target_window = | 370 ServerWindow* target_window = |
| 386 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); | 371 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); |
| 387 pointer_target.window = | 372 pointer_target.window = target_window->GetModalTarget(); |
| 388 modal_window_controller_.GetTargetForWindow(target_window); | |
| 389 pointer_target.is_mouse_event = event.IsMousePointerEvent(); | 373 pointer_target.is_mouse_event = event.IsMousePointerEvent(); |
| 390 pointer_target.in_nonclient_area = | 374 pointer_target.in_nonclient_area = |
| 391 target_window != pointer_target.window || | 375 target_window != pointer_target.window || |
| 392 IsLocationInNonclientArea(pointer_target.window, location); | 376 IsLocationInNonclientArea(pointer_target.window, location); |
| 393 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; | 377 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; |
| 394 return pointer_target; | 378 return pointer_target; |
| 395 } | 379 } |
| 396 | 380 |
| 397 bool EventDispatcher::AreAnyPointersDown() const { | 381 bool EventDispatcher::AreAnyPointersDown() const { |
| 398 for (const auto& pair : pointer_targets_) { | 382 for (const auto& pair : pointer_targets_) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 414 transform.TransformPoint(&location); | 398 transform.TransformPoint(&location); |
| 415 std::unique_ptr<ui::Event> clone = ui::Event::Clone(event); | 399 std::unique_ptr<ui::Event> clone = ui::Event::Clone(event); |
| 416 clone->AsLocatedEvent()->set_location(location); | 400 clone->AsLocatedEvent()->set_location(location); |
| 417 // TODO(jonross): add post-target accelerator support once accelerators | 401 // TODO(jonross): add post-target accelerator support once accelerators |
| 418 // support pointer events. | 402 // support pointer events. |
| 419 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, | 403 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, |
| 420 *clone, nullptr); | 404 *clone, nullptr); |
| 421 } | 405 } |
| 422 | 406 |
| 423 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { | 407 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { |
| 408 window->RemoveObserver(this); |
| 409 |
| 424 if (capture_window_ == window) { | 410 if (capture_window_ == window) { |
| 425 UnobserveWindow(window); | |
| 426 capture_window_ = nullptr; | 411 capture_window_ = nullptr; |
| 427 mouse_button_down_ = false; | 412 mouse_button_down_ = false; |
| 428 // A window only cares to be informed that it lost capture if it explicitly | 413 // A window only cares to be informed that it lost capture if it explicitly |
| 429 // requested capture. A window can lose capture if another window gains | 414 // requested capture. A window can lose capture if another window gains |
| 430 // explicit capture. | 415 // explicit capture. |
| 431 delegate_->OnServerWindowCaptureLost(window); | 416 delegate_->OnServerWindowCaptureLost(window); |
| 432 delegate_->ReleaseNativeCapture(); | 417 delegate_->ReleaseNativeCapture(); |
| 433 UpdateCursorProviderByLastKnownLocation(); | 418 UpdateCursorProviderByLastKnownLocation(); |
| 434 return; | 419 return; |
| 435 } | 420 } |
| 436 | 421 |
| 437 for (auto& pair : pointer_targets_) { | 422 for (auto& pair : pointer_targets_) { |
| 438 if (pair.second.window == window) { | 423 if (pair.second.window == window) |
| 439 UnobserveWindow(window); | |
| 440 pair.second.window = nullptr; | 424 pair.second.window = nullptr; |
| 441 } | |
| 442 } | 425 } |
| 443 } | 426 } |
| 444 | 427 |
| 445 void EventDispatcher::ObserveWindow(ServerWindow* window) { | 428 bool EventDispatcher::IsObservingWindow(ServerWindow* window) { |
| 446 auto res = observed_windows_.insert(std::make_pair(window, 0u)); | 429 for (const auto& pair : pointer_targets_) { |
| 447 res.first->second++; | 430 if (pair.second.window == window) |
| 448 if (res.second) | 431 return true; |
| 449 window->AddObserver(this); | |
| 450 } | |
| 451 | |
| 452 void EventDispatcher::UnobserveWindow(ServerWindow* window) { | |
| 453 auto it = observed_windows_.find(window); | |
| 454 DCHECK(it != observed_windows_.end()); | |
| 455 DCHECK_LT(0u, it->second); | |
| 456 it->second--; | |
| 457 if (!it->second) { | |
| 458 window->RemoveObserver(this); | |
| 459 observed_windows_.erase(it); | |
| 460 } | 432 } |
| 433 return false; |
| 461 } | 434 } |
| 462 | 435 |
| 463 Accelerator* EventDispatcher::FindAccelerator( | 436 Accelerator* EventDispatcher::FindAccelerator( |
| 464 const ui::KeyEvent& event, | 437 const ui::KeyEvent& event, |
| 465 const mojom::AcceleratorPhase phase) { | 438 const mojom::AcceleratorPhase phase) { |
| 466 for (const auto& pair : accelerators_) { | 439 for (const auto& pair : accelerators_) { |
| 467 if (pair.second->MatchesEvent(event, phase)) { | 440 if (pair.second->MatchesEvent(event, phase)) { |
| 468 return pair.second.get(); | 441 return pair.second.get(); |
| 469 } | 442 } |
| 470 } | 443 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 483 | 456 |
| 484 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { | 457 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { |
| 485 CancelPointerEventsToTarget(window); | 458 CancelPointerEventsToTarget(window); |
| 486 | 459 |
| 487 if (mouse_cursor_source_window_ == window) | 460 if (mouse_cursor_source_window_ == window) |
| 488 mouse_cursor_source_window_ = nullptr; | 461 mouse_cursor_source_window_ = nullptr; |
| 489 } | 462 } |
| 490 | 463 |
| 491 } // namespace ws | 464 } // namespace ws |
| 492 } // namespace mus | 465 } // namespace mus |
| OLD | NEW |