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/time/time.h" | 9 #include "base/time/time.h" |
10 #include "services/ui/ws/accelerator.h" | 10 #include "services/ui/ws/accelerator.h" |
11 #include "services/ui/ws/display.h" | 11 #include "services/ui/ws/display.h" |
12 #include "services/ui/ws/drag_controller.h" | |
13 #include "services/ui/ws/drag_source.h" | |
12 #include "services/ui/ws/event_dispatcher_delegate.h" | 14 #include "services/ui/ws/event_dispatcher_delegate.h" |
13 #include "services/ui/ws/server_window.h" | 15 #include "services/ui/ws/server_window.h" |
14 #include "services/ui/ws/server_window_delegate.h" | 16 #include "services/ui/ws/server_window_delegate.h" |
15 #include "services/ui/ws/window_coordinate_conversions.h" | 17 #include "services/ui/ws/window_coordinate_conversions.h" |
16 #include "services/ui/ws/window_finder.h" | 18 #include "services/ui/ws/window_finder.h" |
17 #include "ui/events/event_utils.h" | 19 #include "ui/events/event_utils.h" |
18 #include "ui/gfx/geometry/point.h" | 20 #include "ui/gfx/geometry/point.h" |
19 #include "ui/gfx/geometry/point_conversions.h" | 21 #include "ui/gfx/geometry/point_conversions.h" |
20 | 22 |
21 namespace ui { | 23 namespace ui { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 if (!window) | 118 if (!window) |
117 client_id = kInvalidClientId; | 119 client_id = kInvalidClientId; |
118 | 120 |
119 if (window == capture_window_ && client_id == capture_window_client_id_) | 121 if (window == capture_window_ && client_id == capture_window_client_id_) |
120 return true; | 122 return true; |
121 | 123 |
122 // A window that is blocked by a modal window cannot gain capture. | 124 // A window that is blocked by a modal window cannot gain capture. |
123 if (window && modal_window_controller_.IsWindowBlocked(window)) | 125 if (window && modal_window_controller_.IsWindowBlocked(window)) |
124 return false; | 126 return false; |
125 | 127 |
128 // If we're currently performing a drag and drop, reject setting the capture | |
129 // window. | |
130 if (drag_controller_) | |
131 return false; | |
132 | |
126 if (capture_window_) { | 133 if (capture_window_) { |
127 // Stop observing old capture window. |pointer_targets_| are cleared on | 134 // Stop observing old capture window. |pointer_targets_| are cleared on |
128 // initial setting of a capture window. | 135 // initial setting of a capture window. |
129 UnobserveWindow(capture_window_); | 136 UnobserveWindow(capture_window_); |
130 } else { | 137 } else { |
131 // Cancel implicit capture to all other windows. | 138 CancelImplicitCaptureExcept(window); |
132 for (const auto& pair : pointer_targets_) { | |
133 ServerWindow* target = pair.second.window; | |
134 if (!target) | |
135 continue; | |
136 UnobserveWindow(target); | |
137 if (target == window) | |
138 continue; | |
139 | |
140 ui::EventType event_type = pair.second.is_mouse_event | |
141 ? ui::ET_POINTER_EXITED | |
142 : ui::ET_POINTER_CANCELLED; | |
143 ui::EventPointerType pointer_type = | |
144 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE | |
145 : ui::EventPointerType::POINTER_TYPE_TOUCH; | |
146 // TODO(jonross): Track previous location in PointerTarget for sending | |
147 // cancels. | |
148 ui::PointerEvent event( | |
149 event_type, gfx::Point(), gfx::Point(), ui::EF_NONE, pair.first, | |
150 0 /* changed_button_flags */, ui::PointerDetails(pointer_type), | |
151 ui::EventTimeForNow()); | |
152 DispatchToPointerTarget(pair.second, event); | |
153 } | |
154 pointer_targets_.clear(); | |
155 } | 139 } |
156 | 140 |
157 // Set the capture before changing native capture; otherwise, the callback | 141 // Set the capture before changing native capture; otherwise, the callback |
158 // from native platform might try to set the capture again. | 142 // from native platform might try to set the capture again. |
159 const bool had_capture_window = capture_window_ != nullptr; | 143 const bool had_capture_window = capture_window_ != nullptr; |
160 ServerWindow* old_capture_window = capture_window_; | 144 ServerWindow* old_capture_window = capture_window_; |
161 capture_window_ = window; | 145 capture_window_ = window; |
162 capture_window_client_id_ = client_id; | 146 capture_window_client_id_ = client_id; |
163 | 147 |
164 delegate_->OnCaptureChanged(capture_window_, old_capture_window); | 148 delegate_->OnCaptureChanged(capture_window_, old_capture_window); |
165 | 149 |
166 // Begin tracking the capture window if it is not yet being observed. | 150 // Begin tracking the capture window if it is not yet being observed. |
167 if (window) { | 151 if (window) { |
168 ObserveWindow(window); | 152 ObserveWindow(window); |
169 // TODO(sky): this conditional is problematic for the case of capture moving | 153 // TODO(sky): this conditional is problematic for the case of capture moving |
170 // to a different display. | 154 // to a different display. |
171 if (!had_capture_window) | 155 if (!had_capture_window) |
172 delegate_->SetNativeCapture(window); | 156 delegate_->SetNativeCapture(window); |
173 } else { | 157 } else { |
174 delegate_->ReleaseNativeCapture(); | 158 delegate_->ReleaseNativeCapture(); |
175 if (!mouse_button_down_) | 159 if (!mouse_button_down_) |
176 UpdateCursorProviderByLastKnownLocation(); | 160 UpdateCursorProviderByLastKnownLocation(); |
177 } | 161 } |
178 | 162 |
179 return true; | 163 return true; |
180 } | 164 } |
181 | 165 |
166 void EventDispatcher::SetDragDropSourceWindow( | |
167 DragSource* drag_source, | |
168 ServerWindow* window, | |
169 DragTargetConnection* source_connection, | |
170 int32_t drag_pointer, | |
171 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data, | |
172 uint32_t drag_operations) { | |
173 CancelImplicitCaptureExcept(nullptr); | |
174 drag_controller_ = base::MakeUnique<DragController>( | |
175 drag_source, window, source_connection, drag_pointer, | |
176 std::move(mime_data), drag_operations); | |
177 } | |
178 | |
179 void EventDispatcher::EndDragDrop() { | |
180 drag_controller_.reset(); | |
181 } | |
182 | |
183 void EventDispatcher::OnWillDestroyDragTargetConnection( | |
184 DragTargetConnection* connection) { | |
185 if (drag_controller_) | |
186 drag_controller_->OnWillDestroyDragTargetConnection(connection); | |
187 } | |
188 | |
182 void EventDispatcher::AddSystemModalWindow(ServerWindow* window) { | 189 void EventDispatcher::AddSystemModalWindow(ServerWindow* window) { |
183 modal_window_controller_.AddSystemModalWindow(window); | 190 modal_window_controller_.AddSystemModalWindow(window); |
184 } | 191 } |
185 | 192 |
186 void EventDispatcher::ReleaseCaptureBlockedByModalWindow( | 193 void EventDispatcher::ReleaseCaptureBlockedByModalWindow( |
187 const ServerWindow* modal_window) { | 194 const ServerWindow* modal_window) { |
188 if (!capture_window_) | 195 if (!capture_window_) |
189 return; | 196 return; |
190 | 197 |
191 if (modal_window_controller_.IsWindowBlockedBy(capture_window_, | 198 if (modal_window_controller_.IsWindowBlockedBy(capture_window_, |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 | 287 |
281 DCHECK(event.IsPointerEvent()); | 288 DCHECK(event.IsPointerEvent()); |
282 ProcessPointerEvent(*event.AsPointerEvent()); | 289 ProcessPointerEvent(*event.AsPointerEvent()); |
283 return; | 290 return; |
284 } | 291 } |
285 | 292 |
286 void EventDispatcher::ProcessKeyEvent(const ui::KeyEvent& event, | 293 void EventDispatcher::ProcessKeyEvent(const ui::KeyEvent& event, |
287 AcceleratorMatchPhase match_phase) { | 294 AcceleratorMatchPhase match_phase) { |
288 Accelerator* post_target = | 295 Accelerator* post_target = |
289 FindAccelerator(event, ui::mojom::AcceleratorPhase::POST_TARGET); | 296 FindAccelerator(event, ui::mojom::AcceleratorPhase::POST_TARGET); |
297 if (drag_controller_ && event.type() == ui::ET_KEY_PRESSED && | |
298 event.key_code() == ui::VKEY_ESCAPE) { | |
299 drag_controller_->Cancel(); | |
300 return; | |
301 } | |
290 ServerWindow* focused_window = | 302 ServerWindow* focused_window = |
291 delegate_->GetFocusedWindowForEventDispatcher(); | 303 delegate_->GetFocusedWindowForEventDispatcher(); |
292 if (focused_window) { | 304 if (focused_window) { |
293 // Assume key events are for the client area. | 305 // Assume key events are for the client area. |
294 const bool in_nonclient_area = false; | 306 const bool in_nonclient_area = false; |
295 const ClientSpecificId client_id = | 307 const ClientSpecificId client_id = |
296 delegate_->GetEventTargetClientId(focused_window, in_nonclient_area); | 308 delegate_->GetEventTargetClientId(focused_window, in_nonclient_area); |
297 delegate_->DispatchInputEventToWindow(focused_window, client_id, event, | 309 delegate_->DispatchInputEventToWindow(focused_window, client_id, event, |
298 post_target); | 310 post_target); |
299 return; | 311 return; |
(...skipping 21 matching lines...) Expand all Loading... | |
321 (!is_mouse_event || IsOnlyOneMouseButtonDown(event.flags())); | 333 (!is_mouse_event || IsOnlyOneMouseButtonDown(event.flags())); |
322 | 334 |
323 // Update mouse down state upon events which change it. | 335 // Update mouse down state upon events which change it. |
324 if (is_mouse_event) { | 336 if (is_mouse_event) { |
325 if (event.type() == ui::ET_POINTER_DOWN) | 337 if (event.type() == ui::ET_POINTER_DOWN) |
326 mouse_button_down_ = true; | 338 mouse_button_down_ = true; |
327 else if (is_pointer_going_up) | 339 else if (is_pointer_going_up) |
328 mouse_button_down_ = false; | 340 mouse_button_down_ = false; |
329 } | 341 } |
330 | 342 |
343 if (drag_controller_) { | |
344 const PointerTarget target = PointerTargetForEvent(event); | |
345 if (drag_controller_->DispatchPointerEvent(event, target.window)) | |
346 return; | |
347 } | |
348 | |
331 if (capture_window_) { | 349 if (capture_window_) { |
332 mouse_cursor_source_window_ = capture_window_; | 350 mouse_cursor_source_window_ = capture_window_; |
333 DispatchToClient(capture_window_, capture_window_client_id_, event); | 351 DispatchToClient(capture_window_, capture_window_client_id_, event); |
334 return; | 352 return; |
335 } | 353 } |
336 | 354 |
337 const int32_t pointer_id = event.pointer_id(); | 355 const int32_t pointer_id = event.pointer_id(); |
338 if (!IsTrackingPointer(pointer_id) || | 356 if (!IsTrackingPointer(pointer_id) || |
339 !pointer_targets_[pointer_id].is_pointer_down) { | 357 !pointer_targets_[pointer_id].is_pointer_down) { |
340 const bool any_pointers_down = AreAnyPointersDown(); | 358 const bool any_pointers_down = AreAnyPointersDown(); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
528 | 546 |
529 ServerWindow* EventDispatcher::FindDeepestVisibleWindowForEvents( | 547 ServerWindow* EventDispatcher::FindDeepestVisibleWindowForEvents( |
530 gfx::Point* location) { | 548 gfx::Point* location) { |
531 ServerWindow* root = delegate_->GetRootWindowContaining(location); | 549 ServerWindow* root = delegate_->GetRootWindowContaining(location); |
532 if (!root) | 550 if (!root) |
533 return nullptr; | 551 return nullptr; |
534 | 552 |
535 return ui::ws::FindDeepestVisibleWindowForEvents(root, location); | 553 return ui::ws::FindDeepestVisibleWindowForEvents(root, location); |
536 } | 554 } |
537 | 555 |
556 void EventDispatcher::CancelImplicitCaptureExcept(ServerWindow* window) { | |
557 for (const auto& pair : pointer_targets_) { | |
558 ServerWindow* target = pair.second.window; | |
559 if (!target) | |
560 continue; | |
561 UnobserveWindow(target); | |
562 if (window && target == window) | |
sky
2016/09/13 18:15:32
I don't think you need the 'window' conditional.
Elliot Glaysher
2016/09/14 22:19:16
|window| can be null (called at line 173).
sky
2016/09/14 22:52:02
Sure, but the !target on line 559 means you know t
Elliot Glaysher
2016/09/15 17:12:40
Done.
| |
563 continue; | |
564 | |
565 ui::EventType event_type = pair.second.is_mouse_event | |
566 ? ui::ET_POINTER_EXITED | |
567 : ui::ET_POINTER_CANCELLED; | |
568 ui::EventPointerType pointer_type = | |
569 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE | |
570 : ui::EventPointerType::POINTER_TYPE_TOUCH; | |
571 // TODO(jonross): Track previous location in PointerTarget for sending | |
572 // cancels. | |
573 ui::PointerEvent event(event_type, gfx::Point(), gfx::Point(), ui::EF_NONE, | |
574 pair.first, 0 /* changed_button_flags */, | |
575 ui::PointerDetails(pointer_type), | |
576 ui::EventTimeForNow()); | |
577 DispatchToPointerTarget(pair.second, event); | |
578 } | |
579 pointer_targets_.clear(); | |
580 } | |
581 | |
538 void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window, | 582 void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window, |
539 ServerWindow* new_parent, | 583 ServerWindow* new_parent, |
540 ServerWindow* old_parent) { | 584 ServerWindow* old_parent) { |
541 // TODO(sky): moving to a different root likely needs to transfer capture. | 585 // TODO(sky): moving to a different root likely needs to transfer capture. |
542 // TODO(sky): this isn't quite right, I think the logic should be (assuming | 586 // TODO(sky): this isn't quite right, I think the logic should be (assuming |
543 // moving in same root and still drawn): | 587 // moving in same root and still drawn): |
544 // . if there is capture and window is still in the same root, continue | 588 // . if there is capture and window is still in the same root, continue |
545 // sending to it. | 589 // sending to it. |
546 // . if there isn't capture, then reevaluate each of the pointer targets | 590 // . if there isn't capture, then reevaluate each of the pointer targets |
547 // sending exit as necessary. | 591 // sending exit as necessary. |
(...skipping 10 matching lines...) Expand all Loading... | |
558 | 602 |
559 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { | 603 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { |
560 CancelPointerEventsToTarget(window); | 604 CancelPointerEventsToTarget(window); |
561 | 605 |
562 if (mouse_cursor_source_window_ == window) | 606 if (mouse_cursor_source_window_ == window) |
563 mouse_cursor_source_window_ = nullptr; | 607 mouse_cursor_source_window_ = nullptr; |
564 } | 608 } |
565 | 609 |
566 } // namespace ws | 610 } // namespace ws |
567 } // namespace ui | 611 } // namespace ui |
OLD | NEW |