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 e354514153314d22b0c40dd999b9a536bb6be0a0..a064291721dfeb79c68e9afc38e4d9ea6054768d 100644 |
| --- a/components/mus/ws/event_dispatcher.cc |
| +++ b/components/mus/ws/event_dispatcher.cc |
| @@ -156,17 +156,54 @@ class EventMatcher { |
| EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) |
| : delegate_(delegate), |
| root_(nullptr), |
| + capture_window_(nullptr), |
| mouse_button_down_(false), |
| mouse_cursor_source_window_(nullptr) {} |
| EventDispatcher::~EventDispatcher() { |
| std::set<ServerWindow*> pointer_targets; |
| + if (capture_window_) { |
| + pointer_targets.insert(capture_window_); |
| + capture_window_->RemoveObserver(this); |
| + capture_window_ = nullptr; |
| + } |
| 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::SetCaptureWindow(ServerWindow* window) { |
|
sky
2016/01/22 00:55:00
You need to also pass in in_nonclient_area. I thin
jonross
2016/01/22 20:31:28
I'm not sure if that is needed. There will not alw
sky
2016/01/22 22:15:37
For windows with no one embedded in them there is
jonross
2016/01/26 18:38:50
That makes sense. I'm passing this in now based on
|
| + if (window == capture_window_) |
| + return; |
| + |
| + // Cancel implicit capture to all other windows. |
| + PointerIdToTargetMap window_implicit_targets; |
| + std::set<ServerWindow*> unobserved_windows; |
|
jonross
2016/01/21 22:01:12
There was a comment in the previous review:
"The
jonross
2016/01/26 18:38:50
Done.
|
| + if (capture_window_) { |
| + delegate_->OnLostCapture(capture_window_); |
| + unobserved_windows.insert(capture_window_); |
| + capture_window_->RemoveObserver(this); |
| + } |
| + |
| + for (const auto& pair : pointer_targets_) { |
| + ServerWindow* target = pair.second.window; |
| + if (!target) |
| + continue; |
| + if (target == window) |
| + window_implicit_targets[pair.first] = pair.second; |
|
sky
2016/01/22 00:55:00
Why do you need to maintain pointer_targets_ when
jonross
2016/01/22 20:31:28
This was based on a comment in the original review
jonross
2016/01/26 18:38:50
Done.
|
| + else if (unobserved_windows.insert(target).second) |
| + target->RemoveObserver(this); |
|
sky
2016/01/22 00:55:00
You should send POINTER_CANCEL here.
jonross
2016/01/26 18:38:50
Done.
|
| + } |
| + pointer_targets_.swap(window_implicit_targets); |
| + |
| + capture_window_ = window; |
| + // Begin tracking the capture window if it is not yet being observed. |
| + if (window && pointer_targets_.empty()) |
| + window->AddObserver(this); |
| } |
| void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { |
| @@ -230,6 +267,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, std::move(event)); |
| + return; |
| + } |
| + |
| const bool is_mouse_event = |
| event->pointer_data && |
| event->pointer_data->kind == mojom::PointerKind::POINTER_KIND_MOUSE; |
| @@ -380,6 +424,15 @@ void EventDispatcher::DispatchToPointerTarget(const PointerTarget& target, |
| 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; |
|
sky
2016/01/22 00:55:00
Why the early out here? Don't we still need to res
jonross
2016/01/26 18:38:50
With the change to always clear pointer_targets_ i
|
| + } |
| + |
| for (auto& pair : pointer_targets_) { |
| if (pair.second.window == window) |
| pair.second.window = nullptr; |