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 |
100 while (!pointer_targets_.empty()) | 95 while (!pointer_targets_.empty()) |
101 StopTrackingPointer(pointer_targets_.begin()->first); | 96 StopTrackingPointer(pointer_targets_.begin()->first); |
102 | 97 |
103 mouse_button_down_ = false; | 98 mouse_button_down_ = false; |
104 } | 99 } |
105 | 100 |
106 void EventDispatcher::SetMousePointerScreenLocation( | 101 void EventDispatcher::SetMousePointerScreenLocation( |
107 const gfx::Point& screen_location) { | 102 const gfx::Point& screen_location) { |
108 DCHECK(pointer_targets_.empty()); | 103 DCHECK(pointer_targets_.empty()); |
109 mouse_pointer_last_location_ = screen_location; | 104 mouse_pointer_last_location_ = screen_location; |
110 UpdateCursorProviderByLastKnownLocation(); | 105 UpdateCursorProviderByLastKnownLocation(); |
111 } | 106 } |
112 | 107 |
113 bool EventDispatcher::SetCaptureWindow(ServerWindow* window, | 108 bool EventDispatcher::SetCaptureWindow(ServerWindow* window, |
114 bool in_nonclient_area) { | 109 bool in_nonclient_area) { |
115 if (window == capture_window_) | 110 if (window == capture_window_) |
116 return true; | 111 return true; |
117 | 112 |
118 // A window that is blocked by a modal window cannot gain capture. | 113 // A window that is blocked by a modal window cannot gain capture. |
119 if (window && window->IsBlockedByModalWindow()) | 114 if (window && modal_window_controller_.IsWindowBlocked(window)) |
120 return false; | 115 return false; |
121 | 116 |
122 if (capture_window_) { | 117 if (capture_window_) { |
123 // Stop observing old capture window. |pointer_targets_| are cleared on | 118 // Stop observing old capture window. |pointer_targets_| are cleared on |
124 // initial setting of a capture window. | 119 // initial setting of a capture window. |
125 delegate_->OnServerWindowCaptureLost(capture_window_); | 120 delegate_->OnServerWindowCaptureLost(capture_window_); |
126 capture_window_->RemoveObserver(this); | 121 UnobserveWindow(capture_window_); |
127 } else { | 122 } else { |
128 // Cancel implicit capture to all other windows. | 123 // Cancel implicit capture to all other windows. |
129 std::set<ServerWindow*> unobserved_windows; | |
130 for (const auto& pair : pointer_targets_) { | 124 for (const auto& pair : pointer_targets_) { |
131 ServerWindow* target = pair.second.window; | 125 ServerWindow* target = pair.second.window; |
132 if (!target) | 126 if (!target) |
133 continue; | 127 continue; |
134 if (unobserved_windows.insert(target).second) | 128 UnobserveWindow(target); |
135 target->RemoveObserver(this); | |
136 if (target == window) | 129 if (target == window) |
137 continue; | 130 continue; |
138 | 131 |
139 ui::EventType event_type = pair.second.is_mouse_event | 132 ui::EventType event_type = pair.second.is_mouse_event |
140 ? ui::ET_POINTER_EXITED | 133 ? ui::ET_POINTER_EXITED |
141 : ui::ET_POINTER_CANCELLED; | 134 : ui::ET_POINTER_CANCELLED; |
142 ui::EventPointerType pointer_type = | 135 ui::EventPointerType pointer_type = |
143 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE | 136 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE |
144 : ui::EventPointerType::POINTER_TYPE_TOUCH; | 137 : ui::EventPointerType::POINTER_TYPE_TOUCH; |
145 // TODO(jonross): Track previous location in PointerTarget for sending | 138 // TODO(jonross): Track previous location in PointerTarget for sending |
146 // cancels. | 139 // cancels. |
147 ui::PointerEvent event(event_type, pointer_type, gfx::Point(), | 140 ui::PointerEvent event(event_type, pointer_type, gfx::Point(), |
148 gfx::Point(), ui::EF_NONE, pair.first, | 141 gfx::Point(), ui::EF_NONE, pair.first, |
149 ui::EventTimeForNow()); | 142 ui::EventTimeForNow()); |
150 DispatchToPointerTarget(pair.second, event); | 143 DispatchToPointerTarget(pair.second, event); |
151 } | 144 } |
152 pointer_targets_.clear(); | 145 pointer_targets_.clear(); |
153 } | 146 } |
154 | 147 |
155 // Begin tracking the capture window if it is not yet being observed. | 148 // Begin tracking the capture window if it is not yet being observed. |
156 if (window) { | 149 if (window) { |
157 window->AddObserver(this); | 150 ObserveWindow(window); |
158 if (!capture_window_) | 151 if (!capture_window_) |
159 delegate_->SetNativeCapture(); | 152 delegate_->SetNativeCapture(); |
160 } else { | 153 } else { |
161 delegate_->ReleaseNativeCapture(); | 154 delegate_->ReleaseNativeCapture(); |
162 if (!mouse_button_down_) | 155 if (!mouse_button_down_) |
163 UpdateCursorProviderByLastKnownLocation(); | 156 UpdateCursorProviderByLastKnownLocation(); |
164 } | 157 } |
165 | 158 |
166 capture_window_ = window; | 159 capture_window_ = window; |
167 capture_window_in_nonclient_area_ = in_nonclient_area; | 160 capture_window_in_nonclient_area_ = in_nonclient_area; |
168 return true; | 161 return true; |
169 } | 162 } |
170 | 163 |
| 164 void EventDispatcher::AddSystemModalWindow(ServerWindow* window) { |
| 165 modal_window_controller_.AddSystemModalWindow(window); |
| 166 } |
| 167 |
| 168 void EventDispatcher::ReleaseCaptureBlockedByModalWindow( |
| 169 const ServerWindow* modal_window) { |
| 170 if (!capture_window_) |
| 171 return; |
| 172 |
| 173 if (modal_window_controller_.IsWindowBlockedBy(capture_window_, |
| 174 modal_window)) { |
| 175 SetCaptureWindow(nullptr, false); |
| 176 } |
| 177 } |
| 178 |
| 179 void EventDispatcher::ReleaseCaptureBlockedByAnyModalWindow() { |
| 180 if (!capture_window_) |
| 181 return; |
| 182 |
| 183 if (modal_window_controller_.IsWindowBlocked(capture_window_)) |
| 184 SetCaptureWindow(nullptr, false); |
| 185 } |
| 186 |
171 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { | 187 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { |
172 if (!mouse_button_down_) { | 188 if (!mouse_button_down_) { |
173 gfx::Point location = mouse_pointer_last_location_; | 189 gfx::Point location = mouse_pointer_last_location_; |
174 mouse_cursor_source_window_ = | 190 mouse_cursor_source_window_ = |
175 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); | 191 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); |
176 } | 192 } |
177 } | 193 } |
178 | 194 |
179 bool EventDispatcher::AddAccelerator(uint32_t id, | 195 bool EventDispatcher::AddAccelerator(uint32_t id, |
180 mojom::EventMatcherPtr event_matcher) { | 196 mojom::EventMatcherPtr event_matcher) { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 StopTrackingPointer(pointer_id); | 320 StopTrackingPointer(pointer_id); |
305 if (!AreAnyPointersDown()) | 321 if (!AreAnyPointersDown()) |
306 delegate_->ReleaseNativeCapture(); | 322 delegate_->ReleaseNativeCapture(); |
307 } | 323 } |
308 } | 324 } |
309 | 325 |
310 void EventDispatcher::StartTrackingPointer( | 326 void EventDispatcher::StartTrackingPointer( |
311 int32_t pointer_id, | 327 int32_t pointer_id, |
312 const PointerTarget& pointer_target) { | 328 const PointerTarget& pointer_target) { |
313 DCHECK(!IsTrackingPointer(pointer_id)); | 329 DCHECK(!IsTrackingPointer(pointer_id)); |
314 if (!IsObservingWindow(pointer_target.window)) | 330 ObserveWindow(pointer_target.window); |
315 pointer_target.window->AddObserver(this); | |
316 pointer_targets_[pointer_id] = pointer_target; | 331 pointer_targets_[pointer_id] = pointer_target; |
317 } | 332 } |
318 | 333 |
319 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) { | 334 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) { |
320 DCHECK(IsTrackingPointer(pointer_id)); | 335 DCHECK(IsTrackingPointer(pointer_id)); |
321 ServerWindow* window = pointer_targets_[pointer_id].window; | 336 ServerWindow* window = pointer_targets_[pointer_id].window; |
322 pointer_targets_.erase(pointer_id); | 337 pointer_targets_.erase(pointer_id); |
323 if (window && !IsObservingWindow(window)) | 338 if (window) |
324 window->RemoveObserver(this); | 339 UnobserveWindow(window); |
325 } | 340 } |
326 | 341 |
327 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id, | 342 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id, |
328 const ui::LocatedEvent& event) { | 343 const ui::LocatedEvent& event) { |
329 if (!IsTrackingPointer(pointer_id)) { | 344 if (!IsTrackingPointer(pointer_id)) { |
330 StartTrackingPointer(pointer_id, PointerTargetForEvent(event)); | 345 StartTrackingPointer(pointer_id, PointerTargetForEvent(event)); |
331 return; | 346 return; |
332 } | 347 } |
333 | 348 |
334 const PointerTarget pointer_target = PointerTargetForEvent(event); | 349 const PointerTarget pointer_target = PointerTargetForEvent(event); |
(...skipping 21 matching lines...) Expand all Loading... |
356 StopTrackingPointer(pointer_id); | 371 StopTrackingPointer(pointer_id); |
357 StartTrackingPointer(pointer_id, pointer_target); | 372 StartTrackingPointer(pointer_id, pointer_target); |
358 } | 373 } |
359 | 374 |
360 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( | 375 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( |
361 const ui::LocatedEvent& event) const { | 376 const ui::LocatedEvent& event) const { |
362 PointerTarget pointer_target; | 377 PointerTarget pointer_target; |
363 gfx::Point location(event.location()); | 378 gfx::Point location(event.location()); |
364 ServerWindow* target_window = | 379 ServerWindow* target_window = |
365 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); | 380 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); |
366 pointer_target.window = target_window->GetModalTarget(); | 381 pointer_target.window = |
| 382 modal_window_controller_.GetTargetForWindow(target_window); |
367 pointer_target.is_mouse_event = event.IsMousePointerEvent(); | 383 pointer_target.is_mouse_event = event.IsMousePointerEvent(); |
368 pointer_target.in_nonclient_area = | 384 pointer_target.in_nonclient_area = |
369 target_window != pointer_target.window || | 385 target_window != pointer_target.window || |
370 IsLocationInNonclientArea(pointer_target.window, location); | 386 IsLocationInNonclientArea(pointer_target.window, location); |
371 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; | 387 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; |
372 return pointer_target; | 388 return pointer_target; |
373 } | 389 } |
374 | 390 |
375 bool EventDispatcher::AreAnyPointersDown() const { | 391 bool EventDispatcher::AreAnyPointersDown() const { |
376 for (const auto& pair : pointer_targets_) { | 392 for (const auto& pair : pointer_targets_) { |
(...skipping 15 matching lines...) Expand all Loading... |
392 transform.TransformPoint(&location); | 408 transform.TransformPoint(&location); |
393 std::unique_ptr<ui::Event> clone = ui::Event::Clone(event); | 409 std::unique_ptr<ui::Event> clone = ui::Event::Clone(event); |
394 clone->AsLocatedEvent()->set_location(location); | 410 clone->AsLocatedEvent()->set_location(location); |
395 // TODO(jonross): add post-target accelerator support once accelerators | 411 // TODO(jonross): add post-target accelerator support once accelerators |
396 // support pointer events. | 412 // support pointer events. |
397 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, | 413 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, |
398 *clone, nullptr); | 414 *clone, nullptr); |
399 } | 415 } |
400 | 416 |
401 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { | 417 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { |
402 window->RemoveObserver(this); | |
403 | |
404 if (capture_window_ == window) { | 418 if (capture_window_ == window) { |
| 419 UnobserveWindow(window); |
405 capture_window_ = nullptr; | 420 capture_window_ = nullptr; |
406 mouse_button_down_ = false; | 421 mouse_button_down_ = false; |
407 // A window only cares to be informed that it lost capture if it explicitly | 422 // A window only cares to be informed that it lost capture if it explicitly |
408 // requested capture. A window can lose capture if another window gains | 423 // requested capture. A window can lose capture if another window gains |
409 // explicit capture. | 424 // explicit capture. |
410 delegate_->OnServerWindowCaptureLost(window); | 425 delegate_->OnServerWindowCaptureLost(window); |
411 delegate_->ReleaseNativeCapture(); | 426 delegate_->ReleaseNativeCapture(); |
412 UpdateCursorProviderByLastKnownLocation(); | 427 UpdateCursorProviderByLastKnownLocation(); |
413 return; | 428 return; |
414 } | 429 } |
415 | 430 |
416 for (auto& pair : pointer_targets_) { | 431 for (auto& pair : pointer_targets_) { |
417 if (pair.second.window == window) | 432 if (pair.second.window == window) { |
| 433 UnobserveWindow(window); |
418 pair.second.window = nullptr; | 434 pair.second.window = nullptr; |
| 435 } |
419 } | 436 } |
420 } | 437 } |
421 | 438 |
422 bool EventDispatcher::IsObservingWindow(ServerWindow* window) { | 439 void EventDispatcher::ObserveWindow(ServerWindow* window) { |
423 for (const auto& pair : pointer_targets_) { | 440 auto res = observed_windows_.insert(std::make_pair(window, 0u)); |
424 if (pair.second.window == window) | 441 res.first->second++; |
425 return true; | 442 if (res.second) |
| 443 window->AddObserver(this); |
| 444 } |
| 445 |
| 446 void EventDispatcher::UnobserveWindow(ServerWindow* window) { |
| 447 auto it = observed_windows_.find(window); |
| 448 DCHECK(it != observed_windows_.end()); |
| 449 DCHECK_LT(0u, it->second); |
| 450 it->second--; |
| 451 if (!it->second) { |
| 452 window->RemoveObserver(this); |
| 453 observed_windows_.erase(it); |
426 } | 454 } |
427 return false; | |
428 } | 455 } |
429 | 456 |
430 Accelerator* EventDispatcher::FindAccelerator( | 457 Accelerator* EventDispatcher::FindAccelerator( |
431 const ui::KeyEvent& event, | 458 const ui::KeyEvent& event, |
432 const mojom::AcceleratorPhase phase) { | 459 const mojom::AcceleratorPhase phase) { |
433 for (const auto& pair : accelerators_) { | 460 for (const auto& pair : accelerators_) { |
434 if (pair.second->MatchesEvent(event, phase)) { | 461 if (pair.second->MatchesEvent(event, phase)) { |
435 return pair.second.get(); | 462 return pair.second.get(); |
436 } | 463 } |
437 } | 464 } |
(...skipping 12 matching lines...) Expand all Loading... |
450 | 477 |
451 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { | 478 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { |
452 CancelPointerEventsToTarget(window); | 479 CancelPointerEventsToTarget(window); |
453 | 480 |
454 if (mouse_cursor_source_window_ == window) | 481 if (mouse_cursor_source_window_ == window) |
455 mouse_cursor_source_window_ = nullptr; | 482 mouse_cursor_source_window_ = nullptr; |
456 } | 483 } |
457 | 484 |
458 } // namespace ws | 485 } // namespace ws |
459 } // namespace mus | 486 } // namespace mus |
OLD | NEW |