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) |