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 "cc/surfaces/surface_hittest.h" | 9 #include "cc/surfaces/surface_hittest.h" |
10 #include "components/mus/surfaces/surfaces_state.h" | 10 #include "components/mus/surfaces/surfaces_state.h" |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 mojom::EventType event_type_; | 132 mojom::EventType event_type_; |
133 mojom::EventFlags event_flags_; | 133 mojom::EventFlags event_flags_; |
134 mojom::KeyboardCode keyboard_code_; | 134 mojom::KeyboardCode keyboard_code_; |
135 mojom::PointerKind pointer_kind_; | 135 mojom::PointerKind pointer_kind_; |
136 gfx::RectF pointer_region_; | 136 gfx::RectF pointer_region_; |
137 }; | 137 }; |
138 | 138 |
139 //////////////////////////////////////////////////////////////////////////////// | 139 //////////////////////////////////////////////////////////////////////////////// |
140 | 140 |
141 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) | 141 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) |
142 : delegate_(delegate), root_(nullptr) {} | 142 : delegate_(delegate), |
| 143 root_(nullptr), |
| 144 mouse_button_down_(false), |
| 145 mouse_cursor_source_window_(nullptr) {} |
143 | 146 |
144 EventDispatcher::~EventDispatcher() { | 147 EventDispatcher::~EventDispatcher() { |
145 std::set<ServerWindow*> pointer_targets; | 148 std::set<ServerWindow*> pointer_targets; |
146 for (const auto& pair : pointer_targets_) { | 149 for (const auto& pair : pointer_targets_) { |
147 if (pair.second.window && | 150 if (pair.second.window && |
148 pointer_targets.insert(pair.second.window).second) { | 151 pointer_targets.insert(pair.second.window).second) { |
149 pair.second.window->RemoveObserver(this); | 152 pair.second.window->RemoveObserver(this); |
150 } | 153 } |
151 } | 154 } |
152 } | 155 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 } | 199 } |
197 | 200 |
198 void EventDispatcher::ProcessKeyEvent(mojom::EventPtr event) { | 201 void EventDispatcher::ProcessKeyEvent(mojom::EventPtr event) { |
199 ServerWindow* focused_window = | 202 ServerWindow* focused_window = |
200 delegate_->GetFocusedWindowForEventDispatcher(); | 203 delegate_->GetFocusedWindowForEventDispatcher(); |
201 if (focused_window) | 204 if (focused_window) |
202 delegate_->DispatchInputEventToWindow(focused_window, false, event.Pass()); | 205 delegate_->DispatchInputEventToWindow(focused_window, false, event.Pass()); |
203 } | 206 } |
204 | 207 |
205 void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) { | 208 void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) { |
| 209 bool is_mouse_event = |
| 210 event->pointer_data && |
| 211 event->pointer_data->kind == mojom::PointerKind::POINTER_KIND_MOUSE; |
| 212 |
206 const int32_t pointer_id = event->pointer_data->pointer_id; | 213 const int32_t pointer_id = event->pointer_data->pointer_id; |
207 if (event->action == mojom::EVENT_TYPE_WHEEL || | 214 if (event->action == mojom::EVENT_TYPE_WHEEL || |
208 (event->action == mojom::EVENT_TYPE_POINTER_MOVE && | 215 (event->action == mojom::EVENT_TYPE_POINTER_MOVE && |
209 pointer_targets_.count(pointer_id) == 0)) { | 216 pointer_targets_.count(pointer_id) == 0)) { |
210 PointerTarget pointer_target; | 217 PointerTarget pointer_target; |
211 if (pointer_targets_.count(pointer_id) != 0) { | 218 if (pointer_targets_.count(pointer_id) != 0) { |
212 pointer_target = pointer_targets_[pointer_id]; | 219 pointer_target = pointer_targets_[pointer_id]; |
213 } else { | 220 } else { |
214 gfx::Point location(EventLocationToPoint(*event)); | 221 gfx::Point location(EventLocationToPoint(*event)); |
215 pointer_target.window = | 222 pointer_target.window = |
216 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); | 223 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); |
217 } | 224 } |
| 225 if (is_mouse_event && !mouse_button_down_) |
| 226 mouse_cursor_source_window_ = pointer_target.window; |
218 DispatchToPointerTarget(pointer_target, event.Pass()); | 227 DispatchToPointerTarget(pointer_target, event.Pass()); |
219 return; | 228 return; |
220 } | 229 } |
221 | 230 |
222 // Pointer down implicitly captures. | 231 // Pointer down implicitly captures. |
223 if (pointer_targets_.count(pointer_id) == 0) { | 232 if (pointer_targets_.count(pointer_id) == 0) { |
224 DCHECK(event->action == mojom::EVENT_TYPE_POINTER_DOWN); | 233 DCHECK(event->action == mojom::EVENT_TYPE_POINTER_DOWN); |
225 const bool is_first_pointer_down = pointer_targets_.empty(); | 234 const bool is_first_pointer_down = pointer_targets_.empty(); |
226 gfx::Point location(EventLocationToPoint(*event)); | 235 gfx::Point location(EventLocationToPoint(*event)); |
227 ServerWindow* target = | 236 ServerWindow* target = |
228 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); | 237 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); |
229 DCHECK(target); | 238 DCHECK(target); |
230 if (!IsObservingWindow(target)) | 239 if (!IsObservingWindow(target)) |
231 target->AddObserver(this); | 240 target->AddObserver(this); |
232 | 241 |
| 242 if (is_mouse_event) { |
| 243 mouse_button_down_ = true; |
| 244 mouse_cursor_source_window_ = target; |
| 245 } |
| 246 |
233 pointer_targets_[pointer_id].window = target; | 247 pointer_targets_[pointer_id].window = target; |
234 pointer_targets_[pointer_id].in_nonclient_area = | 248 pointer_targets_[pointer_id].in_nonclient_area = |
235 IsLocationInNonclientArea(target, location); | 249 IsLocationInNonclientArea(target, location); |
236 | 250 |
237 if (is_first_pointer_down) | 251 if (is_first_pointer_down) |
238 delegate_->SetFocusedWindowFromEventDispatcher(target); | 252 delegate_->SetFocusedWindowFromEventDispatcher(target); |
239 } | 253 } |
240 | 254 |
241 // Release capture on pointer up. For mouse we only release if there are | 255 // Release capture on pointer up. For mouse we only release if there are |
242 // no buttons down. | 256 // no buttons down. |
243 const bool should_reset_target = | 257 const bool should_reset_target = |
244 (event->action == mojom::EVENT_TYPE_POINTER_UP || | 258 (event->action == mojom::EVENT_TYPE_POINTER_UP || |
245 event->action == mojom::EVENT_TYPE_POINTER_CANCEL) && | 259 event->action == mojom::EVENT_TYPE_POINTER_CANCEL) && |
246 (event->pointer_data->kind != mojom::POINTER_KIND_MOUSE || | 260 (event->pointer_data->kind != mojom::POINTER_KIND_MOUSE || |
247 IsOnlyOneMouseButtonDown(event->flags)); | 261 IsOnlyOneMouseButtonDown(event->flags)); |
248 | 262 |
| 263 if (should_reset_target && is_mouse_event) { |
| 264 // When we release the mouse button, we want the cursor to be sourced from |
| 265 // the window under the mouse pointer, even though we're sending the button |
| 266 // up event to the window that had implicit capture. We have to set this |
| 267 // before we perform dispatch because the Delegate is going to read this |
| 268 // information from us. |
| 269 mouse_button_down_ = false; |
| 270 gfx::Point location(EventLocationToPoint(*event)); |
| 271 mouse_cursor_source_window_ = |
| 272 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); |
| 273 } |
| 274 |
249 DispatchToPointerTarget(pointer_targets_[pointer_id], event.Pass()); | 275 DispatchToPointerTarget(pointer_targets_[pointer_id], event.Pass()); |
250 | 276 |
251 if (should_reset_target) { | 277 if (should_reset_target) { |
252 ServerWindow* target = pointer_targets_[pointer_id].window; | 278 ServerWindow* target = pointer_targets_[pointer_id].window; |
253 pointer_targets_.erase(pointer_id); | 279 pointer_targets_.erase(pointer_id); |
254 if (target && !IsObservingWindow(target)) | 280 if (target && !IsObservingWindow(target)) |
255 target->RemoveObserver(this); | 281 target->RemoveObserver(this); |
256 } | 282 } |
257 } | 283 } |
258 | 284 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 ServerWindow* old_parent) { | 330 ServerWindow* old_parent) { |
305 CancelPointerEventsToTarget(window); | 331 CancelPointerEventsToTarget(window); |
306 } | 332 } |
307 | 333 |
308 void EventDispatcher::OnWindowVisibilityChanged(ServerWindow* window) { | 334 void EventDispatcher::OnWindowVisibilityChanged(ServerWindow* window) { |
309 CancelPointerEventsToTarget(window); | 335 CancelPointerEventsToTarget(window); |
310 } | 336 } |
311 | 337 |
312 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { | 338 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { |
313 CancelPointerEventsToTarget(window); | 339 CancelPointerEventsToTarget(window); |
| 340 |
| 341 if (mouse_cursor_source_window_ == window) |
| 342 mouse_cursor_source_window_ = nullptr; |
314 } | 343 } |
315 | 344 |
316 } // namespace ws | 345 } // namespace ws |
317 } // namespace mus | 346 } // namespace mus |
OLD | NEW |