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> | 7 #include <set> |
8 | 8 |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "cc/surfaces/surface_hittest.h" | 10 #include "cc/surfaces/surface_hittest.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 return false; | 45 return false; |
46 | 46 |
47 for (const auto& rect : target->additional_client_areas()) { | 47 for (const auto& rect : target->additional_client_areas()) { |
48 if (rect.Contains(location)) | 48 if (rect.Contains(location)) |
49 return false; | 49 return false; |
50 } | 50 } |
51 | 51 |
52 return true; | 52 return true; |
53 } | 53 } |
54 | 54 |
55 ServerWindow* GetClosestModalTargetForWindow(ServerWindow* target) { | |
sky
2016/03/08 17:07:53
Add description as closest isn't clear in this con
mohsen
2016/03/09 08:26:48
Renamed to GetModalChildForWindowAncestor() (also
| |
56 for (ServerWindow* window = target; window; window = window->parent()) { | |
57 for (const auto& transient_child : window->transient_children()) { | |
58 if (transient_child->is_modal() && transient_child->IsDrawn()) | |
59 return transient_child; | |
60 } | |
61 } | |
62 return target; | |
63 } | |
64 | |
65 ServerWindow* GetModalTargetForWindow(ServerWindow* target) { | |
66 ServerWindow* closest_target = GetClosestModalTargetForWindow(target); | |
67 if (closest_target == target) | |
68 return target; | |
69 return GetModalTargetForWindow(closest_target); | |
70 } | |
71 | |
55 } // namespace | 72 } // namespace |
56 | 73 |
57 class EventMatcher { | 74 class EventMatcher { |
58 public: | 75 public: |
59 explicit EventMatcher(const mojom::EventMatcher& matcher) | 76 explicit EventMatcher(const mojom::EventMatcher& matcher) |
60 : fields_to_match_(NONE), | 77 : fields_to_match_(NONE), |
61 accelerator_phase_(mojom::AcceleratorPhase::PRE_TARGET), | 78 accelerator_phase_(mojom::AcceleratorPhase::PRE_TARGET), |
62 event_type_(ui::ET_UNKNOWN), | 79 event_type_(ui::ET_UNKNOWN), |
63 event_flags_(ui::EF_NONE), | 80 event_flags_(ui::EF_NONE), |
64 ignore_event_flags_(ui::EF_NONE), | 81 ignore_event_flags_(ui::EF_NONE), |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
209 } | 226 } |
210 for (const auto& pair : pointer_targets_) { | 227 for (const auto& pair : pointer_targets_) { |
211 if (pair.second.window && | 228 if (pair.second.window && |
212 pointer_targets.insert(pair.second.window).second) { | 229 pointer_targets.insert(pair.second.window).second) { |
213 pair.second.window->RemoveObserver(this); | 230 pair.second.window->RemoveObserver(this); |
214 } | 231 } |
215 } | 232 } |
216 pointer_targets_.clear(); | 233 pointer_targets_.clear(); |
217 } | 234 } |
218 | 235 |
219 void EventDispatcher::SetCaptureWindow(ServerWindow* window, | 236 bool EventDispatcher::SetCaptureWindow(ServerWindow* window, |
220 bool in_nonclient_area) { | 237 bool in_nonclient_area) { |
221 if (window == capture_window_) | 238 if (window == capture_window_) |
222 return; | 239 return true; |
240 | |
241 // A window that is blocked by a modal window cannot gain capture. | |
242 if (window && GetClosestModalTargetForWindow(window) != window) | |
243 return false; | |
223 | 244 |
224 if (capture_window_) { | 245 if (capture_window_) { |
225 // Stop observing old capture window. |pointer_targets_| are cleared on | 246 // Stop observing old capture window. |pointer_targets_| are cleared on |
226 // intial setting of a capture window. | 247 // initial setting of a capture window. |
227 delegate_->OnServerWindowCaptureLost(capture_window_); | 248 delegate_->OnServerWindowCaptureLost(capture_window_); |
228 capture_window_->RemoveObserver(this); | 249 capture_window_->RemoveObserver(this); |
229 } else { | 250 } else { |
230 // Cancel implicit capture to all other windows. | 251 // Cancel implicit capture to all other windows. |
231 std::set<ServerWindow*> unobserved_windows; | 252 std::set<ServerWindow*> unobserved_windows; |
232 for (const auto& pair : pointer_targets_) { | 253 for (const auto& pair : pointer_targets_) { |
233 ServerWindow* target = pair.second.window; | 254 ServerWindow* target = pair.second.window; |
234 if (!target) | 255 if (!target) |
235 continue; | 256 continue; |
236 if (unobserved_windows.insert(target).second) | 257 if (unobserved_windows.insert(target).second) |
237 target->RemoveObserver(this); | 258 target->RemoveObserver(this); |
238 if (target == window) | 259 if (target == window) |
239 continue; | 260 continue; |
240 | 261 |
241 ui::EventType event_type = pair.second.is_mouse_event | 262 ui::EventType event_type = pair.second.is_mouse_event |
242 ? ui::ET_POINTER_EXITED | 263 ? ui::ET_POINTER_EXITED |
243 : ui::ET_POINTER_CANCELLED; | 264 : ui::ET_POINTER_CANCELLED; |
244 ui::EventPointerType pointer_type = | 265 ui::EventPointerType pointer_type = |
245 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE | 266 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE |
246 : ui::EventPointerType::POINTER_TYPE_TOUCH; | 267 : ui::EventPointerType::POINTER_TYPE_TOUCH; |
247 // TODO(jonross): Track previous location in PointerTarget for sending | 268 // TODO(jonross): Track previous location in PointerTarget for sending |
248 // cancels | 269 // cancels. |
249 ui::PointerEvent event(event_type, pointer_type, gfx::Point(), | 270 ui::PointerEvent event(event_type, pointer_type, gfx::Point(), |
250 gfx::Point(), ui::EF_NONE, pair.first, | 271 gfx::Point(), ui::EF_NONE, pair.first, |
251 ui::EventTimeForNow()); | 272 ui::EventTimeForNow()); |
252 DispatchToPointerTarget(pair.second, event); | 273 DispatchToPointerTarget(pair.second, event); |
253 } | 274 } |
254 pointer_targets_.clear(); | 275 pointer_targets_.clear(); |
255 } | 276 } |
256 | 277 |
257 // Begin tracking the capture window if it is not yet being observed. | 278 // Begin tracking the capture window if it is not yet being observed. |
258 if (window) { | 279 if (window) { |
259 window->AddObserver(this); | 280 window->AddObserver(this); |
260 if (!capture_window_) | 281 if (!capture_window_) |
261 delegate_->SetNativeCapture(); | 282 delegate_->SetNativeCapture(); |
262 } else { | 283 } else { |
263 delegate_->ReleaseNativeCapture(); | 284 delegate_->ReleaseNativeCapture(); |
264 if (!mouse_button_down_) | 285 if (!mouse_button_down_) |
265 UpdateCursorProviderByLastKnownLocation(); | 286 UpdateCursorProviderByLastKnownLocation(); |
266 } | 287 } |
267 | 288 |
268 capture_window_ = window; | 289 capture_window_ = window; |
269 capture_window_in_nonclient_area_ = in_nonclient_area; | 290 capture_window_in_nonclient_area_ = in_nonclient_area; |
291 return true; | |
270 } | 292 } |
271 | 293 |
272 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { | 294 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { |
273 if (!mouse_button_down_) { | 295 if (!mouse_button_down_) { |
274 gfx::Point location = mouse_pointer_last_location_; | 296 gfx::Point location = mouse_pointer_last_location_; |
275 mouse_cursor_source_window_ = | 297 mouse_cursor_source_window_ = |
276 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); | 298 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); |
277 } | 299 } |
278 } | 300 } |
279 | 301 |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
444 // Technically we're updating in place, but calling start then stop makes for | 466 // Technically we're updating in place, but calling start then stop makes for |
445 // simpler code. | 467 // simpler code. |
446 StopTrackingPointer(pointer_id); | 468 StopTrackingPointer(pointer_id); |
447 StartTrackingPointer(pointer_id, pointer_target); | 469 StartTrackingPointer(pointer_id, pointer_target); |
448 } | 470 } |
449 | 471 |
450 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( | 472 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( |
451 const ui::PointerEvent& event) const { | 473 const ui::PointerEvent& event) const { |
452 PointerTarget pointer_target; | 474 PointerTarget pointer_target; |
453 gfx::Point location(event.location()); | 475 gfx::Point location(event.location()); |
454 pointer_target.window = | 476 ServerWindow* target_window = |
455 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); | 477 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); |
478 pointer_target.window = GetModalTargetForWindow(target_window); | |
456 pointer_target.is_mouse_event = event.IsMousePointerEvent(); | 479 pointer_target.is_mouse_event = event.IsMousePointerEvent(); |
457 pointer_target.in_nonclient_area = | 480 pointer_target.in_nonclient_area = |
481 target_window != pointer_target.window || | |
458 IsLocationInNonclientArea(pointer_target.window, location); | 482 IsLocationInNonclientArea(pointer_target.window, location); |
459 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; | 483 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; |
460 return pointer_target; | 484 return pointer_target; |
461 } | 485 } |
462 | 486 |
463 bool EventDispatcher::AreAnyPointersDown() const { | 487 bool EventDispatcher::AreAnyPointersDown() const { |
464 for (const auto& pair : pointer_targets_) { | 488 for (const auto& pair : pointer_targets_) { |
465 if (pair.second.is_pointer_down) | 489 if (pair.second.is_pointer_down) |
466 return true; | 490 return true; |
467 } | 491 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
535 | 559 |
536 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { | 560 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { |
537 CancelPointerEventsToTarget(window); | 561 CancelPointerEventsToTarget(window); |
538 | 562 |
539 if (mouse_cursor_source_window_ == window) | 563 if (mouse_cursor_source_window_ == window) |
540 mouse_cursor_source_window_ = nullptr; | 564 mouse_cursor_source_window_ = nullptr; |
541 } | 565 } |
542 | 566 |
543 } // namespace ws | 567 } // namespace ws |
544 } // namespace mus | 568 } // namespace mus |
OLD | NEW |