| 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 "services/ui/ws/event_dispatcher.h" | 5 #include "services/ui/ws/event_dispatcher.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 bool IsOnlyOneMouseButtonDown(int flags) { | 31 bool IsOnlyOneMouseButtonDown(int flags) { |
| 32 const uint32_t button_only_flags = | 32 const uint32_t button_only_flags = |
| 33 flags & (ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON | | 33 flags & (ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON | |
| 34 ui::EF_RIGHT_MOUSE_BUTTON); | 34 ui::EF_RIGHT_MOUSE_BUTTON); |
| 35 return button_only_flags == ui::EF_LEFT_MOUSE_BUTTON || | 35 return button_only_flags == ui::EF_LEFT_MOUSE_BUTTON || |
| 36 button_only_flags == ui::EF_MIDDLE_MOUSE_BUTTON || | 36 button_only_flags == ui::EF_MIDDLE_MOUSE_BUTTON || |
| 37 button_only_flags == ui::EF_RIGHT_MOUSE_BUTTON; | 37 button_only_flags == ui::EF_RIGHT_MOUSE_BUTTON; |
| 38 } | 38 } |
| 39 | 39 |
| 40 bool IsLocationInNonclientArea(const ServerWindow* target, | |
| 41 const gfx::Point& location) { | |
| 42 if (!target->parent()) | |
| 43 return false; | |
| 44 | |
| 45 gfx::Rect client_area(target->bounds().size()); | |
| 46 client_area.Inset(target->client_area()); | |
| 47 if (client_area.Contains(location)) | |
| 48 return false; | |
| 49 | |
| 50 for (const auto& rect : target->additional_client_areas()) { | |
| 51 if (rect.Contains(location)) | |
| 52 return false; | |
| 53 } | |
| 54 | |
| 55 return true; | |
| 56 } | |
| 57 | |
| 58 } // namespace | 40 } // namespace |
| 59 | 41 |
| 60 //////////////////////////////////////////////////////////////////////////////// | 42 //////////////////////////////////////////////////////////////////////////////// |
| 61 | 43 |
| 62 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) | 44 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) |
| 63 : delegate_(delegate), | 45 : delegate_(delegate), |
| 64 capture_window_(nullptr), | 46 capture_window_(nullptr), |
| 65 capture_window_client_id_(kInvalidClientId), | 47 capture_window_client_id_(kInvalidClientId), |
| 66 modal_window_controller_(this), | 48 modal_window_controller_(this), |
| 67 mouse_button_down_(false), | 49 mouse_button_down_(false), |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 void EventDispatcher::ReleaseCaptureBlockedByAnyModalWindow() { | 196 void EventDispatcher::ReleaseCaptureBlockedByAnyModalWindow() { |
| 215 if (!capture_window_) | 197 if (!capture_window_) |
| 216 return; | 198 return; |
| 217 | 199 |
| 218 if (modal_window_controller_.IsWindowBlocked(capture_window_)) | 200 if (modal_window_controller_.IsWindowBlocked(capture_window_)) |
| 219 SetCaptureWindow(nullptr, kInvalidClientId); | 201 SetCaptureWindow(nullptr, kInvalidClientId); |
| 220 } | 202 } |
| 221 | 203 |
| 222 void EventDispatcher::UpdateNonClientAreaForCurrentWindow() { | 204 void EventDispatcher::UpdateNonClientAreaForCurrentWindow() { |
| 223 if (mouse_cursor_source_window_) { | 205 if (mouse_cursor_source_window_) { |
| 224 gfx::Point location = mouse_pointer_last_location_; | 206 DeepestWindow deepest_window = |
| 225 ServerWindow* target = FindDeepestVisibleWindowForEvents(&location); | 207 FindDeepestVisibleWindowForEvents(mouse_pointer_last_location_); |
| 226 if (target == mouse_cursor_source_window_) { | 208 if (deepest_window.window == mouse_cursor_source_window_) { |
| 227 mouse_cursor_in_non_client_area_ = | 209 mouse_cursor_in_non_client_area_ = mouse_cursor_source_window_ |
| 228 mouse_cursor_source_window_ | 210 ? deepest_window.in_non_client_area |
| 229 ? IsLocationInNonclientArea(mouse_cursor_source_window_, location) | 211 : false; |
| 230 : false; | |
| 231 } | 212 } |
| 232 } | 213 } |
| 233 } | 214 } |
| 234 | 215 |
| 235 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { | 216 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { |
| 236 if (!mouse_button_down_) { | 217 if (!mouse_button_down_) { |
| 237 gfx::Point location = mouse_pointer_last_location_; | 218 DeepestWindow deepest_window = |
| 238 mouse_cursor_source_window_ = FindDeepestVisibleWindowForEvents(&location); | 219 FindDeepestVisibleWindowForEvents(mouse_pointer_last_location_); |
| 239 if (!mouse_cursor_source_window_) { | 220 mouse_cursor_source_window_ = deepest_window.window; |
| 240 location = mouse_pointer_last_location_; | 221 if (mouse_cursor_source_window_) { |
| 222 mouse_cursor_in_non_client_area_ = deepest_window.in_non_client_area; |
| 223 } else { |
| 224 gfx::Point location = mouse_pointer_last_location_; |
| 241 mouse_cursor_source_window_ = | 225 mouse_cursor_source_window_ = |
| 242 delegate_->GetRootWindowContaining(&location); | 226 delegate_->GetRootWindowContaining(&location); |
| 227 mouse_cursor_in_non_client_area_ = true; |
| 243 } | 228 } |
| 244 | |
| 245 mouse_cursor_in_non_client_area_ = | |
| 246 mouse_cursor_source_window_ | |
| 247 ? IsLocationInNonclientArea(mouse_cursor_source_window_, location) | |
| 248 : false; | |
| 249 } | 229 } |
| 250 } | 230 } |
| 251 | 231 |
| 252 bool EventDispatcher::AddAccelerator(uint32_t id, | 232 bool EventDispatcher::AddAccelerator(uint32_t id, |
| 253 mojom::EventMatcherPtr event_matcher) { | 233 mojom::EventMatcherPtr event_matcher) { |
| 254 std::unique_ptr<Accelerator> accelerator(new Accelerator(id, *event_matcher)); | 234 std::unique_ptr<Accelerator> accelerator(new Accelerator(id, *event_matcher)); |
| 255 // If an accelerator with the same id or matcher already exists, then abort. | 235 // If an accelerator with the same id or matcher already exists, then abort. |
| 256 for (const auto& pair : accelerators_) { | 236 for (const auto& pair : accelerators_) { |
| 257 if (pair.first == id || accelerator->EqualEventMatcher(pair.second.get())) | 237 if (pair.first == id || accelerator->EqualEventMatcher(pair.second.get())) |
| 258 return false; | 238 return false; |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 | 440 |
| 461 // Technically we're updating in place, but calling start then stop makes for | 441 // Technically we're updating in place, but calling start then stop makes for |
| 462 // simpler code. | 442 // simpler code. |
| 463 StopTrackingPointer(pointer_id); | 443 StopTrackingPointer(pointer_id); |
| 464 StartTrackingPointer(pointer_id, pointer_target); | 444 StartTrackingPointer(pointer_id, pointer_target); |
| 465 } | 445 } |
| 466 | 446 |
| 467 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( | 447 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( |
| 468 const ui::LocatedEvent& event) { | 448 const ui::LocatedEvent& event) { |
| 469 PointerTarget pointer_target; | 449 PointerTarget pointer_target; |
| 470 gfx::Point location(event.root_location()); | 450 DeepestWindow deepest_window = |
| 471 ServerWindow* target_window = FindDeepestVisibleWindowForEvents(&location); | 451 FindDeepestVisibleWindowForEvents(event.root_location()); |
| 472 pointer_target.window = | 452 pointer_target.window = |
| 473 modal_window_controller_.GetTargetForWindow(target_window); | 453 modal_window_controller_.GetTargetForWindow(deepest_window.window); |
| 474 pointer_target.is_mouse_event = event.IsMousePointerEvent(); | 454 pointer_target.is_mouse_event = event.IsMousePointerEvent(); |
| 475 pointer_target.in_nonclient_area = | 455 pointer_target.in_nonclient_area = |
| 476 target_window != pointer_target.window || !pointer_target.window || | 456 deepest_window.window != pointer_target.window || |
| 477 IsLocationInNonclientArea(pointer_target.window, location); | 457 !pointer_target.window || deepest_window.in_non_client_area; |
| 478 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; | 458 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; |
| 479 return pointer_target; | 459 return pointer_target; |
| 480 } | 460 } |
| 481 | 461 |
| 482 bool EventDispatcher::AreAnyPointersDown() const { | 462 bool EventDispatcher::AreAnyPointersDown() const { |
| 483 for (const auto& pair : pointer_targets_) { | 463 for (const auto& pair : pointer_targets_) { |
| 484 if (pair.second.is_pointer_down) | 464 if (pair.second.is_pointer_down) |
| 485 return true; | 465 return true; |
| 486 } | 466 } |
| 487 return false; | 467 return false; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 Accelerator* EventDispatcher::FindAccelerator( | 539 Accelerator* EventDispatcher::FindAccelerator( |
| 560 const ui::KeyEvent& event, | 540 const ui::KeyEvent& event, |
| 561 const ui::mojom::AcceleratorPhase phase) { | 541 const ui::mojom::AcceleratorPhase phase) { |
| 562 for (const auto& pair : accelerators_) { | 542 for (const auto& pair : accelerators_) { |
| 563 if (pair.second->MatchesEvent(event, phase)) | 543 if (pair.second->MatchesEvent(event, phase)) |
| 564 return pair.second.get(); | 544 return pair.second.get(); |
| 565 } | 545 } |
| 566 return nullptr; | 546 return nullptr; |
| 567 } | 547 } |
| 568 | 548 |
| 569 ServerWindow* EventDispatcher::FindDeepestVisibleWindowForEvents( | 549 DeepestWindow EventDispatcher::FindDeepestVisibleWindowForEvents( |
| 570 gfx::Point* location) { | 550 const gfx::Point& location) { |
| 571 ServerWindow* root = delegate_->GetRootWindowContaining(location); | 551 gfx::Point relative_location(location); |
| 572 if (!root) | 552 // For the case of no root. |
| 573 return nullptr; | 553 ServerWindow* root = delegate_->GetRootWindowContaining(&relative_location); |
| 574 | 554 return root ? ui::ws::FindDeepestVisibleWindowForEvents(root, |
| 575 return ui::ws::FindDeepestVisibleWindowForEvents(root, location); | 555 relative_location) |
| 556 : DeepestWindow(); |
| 576 } | 557 } |
| 577 | 558 |
| 578 void EventDispatcher::CancelImplicitCaptureExcept(ServerWindow* window, | 559 void EventDispatcher::CancelImplicitCaptureExcept(ServerWindow* window, |
| 579 ClientSpecificId client_id) { | 560 ClientSpecificId client_id) { |
| 580 for (const auto& pair : pointer_targets_) { | 561 for (const auto& pair : pointer_targets_) { |
| 581 ServerWindow* target = pair.second.window; | 562 ServerWindow* target = pair.second.window; |
| 582 if (!target) | 563 if (!target) |
| 583 continue; | 564 continue; |
| 584 UnobserveWindow(target); | 565 UnobserveWindow(target); |
| 585 if (target == window) | 566 if (target == window) |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 if (mouse_cursor_source_window_ == window) | 619 if (mouse_cursor_source_window_ == window) |
| 639 mouse_cursor_source_window_ = nullptr; | 620 mouse_cursor_source_window_ = nullptr; |
| 640 } | 621 } |
| 641 | 622 |
| 642 void EventDispatcher::OnDragCursorUpdated() { | 623 void EventDispatcher::OnDragCursorUpdated() { |
| 643 delegate_->UpdateNativeCursorFromDispatcher(); | 624 delegate_->UpdateNativeCursorFromDispatcher(); |
| 644 } | 625 } |
| 645 | 626 |
| 646 } // namespace ws | 627 } // namespace ws |
| 647 } // namespace ui | 628 } // namespace ui |
| OLD | NEW |