Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: services/ui/ws/event_dispatcher.cc

Issue 2266603002: mus: Implement interwindow drag and drop (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « services/ui/ws/event_dispatcher.h ('k') | services/ui/ws/server_window.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 (target == window)
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
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
OLDNEW
« no previous file with comments | « services/ui/ws/event_dispatcher.h ('k') | services/ui/ws/server_window.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698