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 |