Chromium Code Reviews| 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 |