Chromium Code Reviews| Index: components/mus/ws/event_dispatcher.cc |
| diff --git a/components/mus/ws/event_dispatcher.cc b/components/mus/ws/event_dispatcher.cc |
| index 2df70cadcf6cb314cdf9ee42e91d4fa687e30194..1daa3b87f300b2eea35e4f7a86a03cc622b909e6 100644 |
| --- a/components/mus/ws/event_dispatcher.cc |
| +++ b/components/mus/ws/event_dispatcher.cc |
| @@ -141,16 +141,19 @@ class EventMatcher { |
| //////////////////////////////////////////////////////////////////////////////// |
| EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) |
| - : delegate_(delegate), root_(nullptr) {} |
| + : delegate_(delegate), root_(nullptr), capture_window_(nullptr) {} |
| EventDispatcher::~EventDispatcher() { |
| - std::set<ServerWindow*> pointer_targets; |
| - for (const auto& pair : pointer_targets_) { |
| - if (pair.second.window && |
| - pointer_targets.insert(pair.second.window).second) { |
| - pair.second.window->RemoveObserver(this); |
| - } |
| - } |
| + CancelAllPointerEvents(); |
| +} |
| + |
| +void EventDispatcher::SetCaptureWindow(ServerWindow* window) { |
| + // Cancel all implicit captures. |
| + CancelAllPointerEvents(); |
|
sky
2015/11/17 01:06:42
If window is in pointer_targets_ won't this incorr
|
| + capture_window_ = window; |
| + // Track the lifetime of the window with explicit capture. |
| + if (window) |
| + window->AddObserver(this); |
| } |
| void EventDispatcher::AddAccelerator(uint32_t id, |
| @@ -205,6 +208,13 @@ void EventDispatcher::ProcessKeyEvent(mojom::EventPtr event) { |
| } |
| void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) { |
| + if (capture_window_) { |
| + PointerTarget pointer_target; |
| + pointer_target.window = capture_window_; |
| + DispatchToPointerTarget(pointer_target, event.Pass()); |
| + return; |
| + } |
| + |
| const int32_t pointer_id = event->pointer_data->pointer_id; |
| if (event->action == mojom::EVENT_TYPE_WHEEL || |
| (event->action == mojom::EVENT_TYPE_POINTER_MOVE && |
| @@ -272,8 +282,31 @@ void EventDispatcher::DispatchToPointerTarget(const PointerTarget& target, |
| event.Pass()); |
| } |
| +void EventDispatcher::CancelAllPointerEvents() { |
| + if (capture_window_) { |
|
sky
2015/11/17 01:06:42
Based on the name I wouldn't expect this to reset
|
| + capture_window_->RemoveObserver(this); |
| + capture_window_ = nullptr; |
| + } |
| + std::set<ServerWindow*> pointer_targets; |
|
sky
2015/11/17 01:06:42
The windows should see a cancel when this happens.
|
| + for (const auto& pair : pointer_targets_) { |
| + if (pair.second.window && |
| + pointer_targets.insert(pair.second.window).second) { |
| + pair.second.window->RemoveObserver(this); |
| + } |
| + } |
| + pointer_targets_.clear(); |
| +} |
| + |
| void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { |
| window->RemoveObserver(this); |
| + if (capture_window_ == window) { |
| + capture_window_ = nullptr; |
| + // A window only cares to be informed that it lost capture if it explicitly |
| + // requested capture. A window can lose capture if another window gains |
| + // explicit capture. |
| + delegate_->OnLostCapture(window); |
| + return; |
| + } |
| for (auto& pair : pointer_targets_) { |
| if (pair.second.window == window) |