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