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

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: Clear the implicit pointer drags before start. 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
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 int32_t drag_pointer,
170 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data,
171 uint32_t drag_operations) {
172 CancelImplicitCaptureExcept(nullptr);
173 drag_controller_ = base::MakeUnique<DragController>(
174 drag_source, window, drag_pointer, std::move(mime_data), drag_operations);
175 }
176
177 void EventDispatcher::EndDragDrop() {
178 drag_controller_.reset();
179 }
180
182 void EventDispatcher::AddSystemModalWindow(ServerWindow* window) { 181 void EventDispatcher::AddSystemModalWindow(ServerWindow* window) {
183 modal_window_controller_.AddSystemModalWindow(window); 182 modal_window_controller_.AddSystemModalWindow(window);
184 } 183 }
185 184
186 void EventDispatcher::ReleaseCaptureBlockedByModalWindow( 185 void EventDispatcher::ReleaseCaptureBlockedByModalWindow(
187 const ServerWindow* modal_window) { 186 const ServerWindow* modal_window) {
188 if (!capture_window_) 187 if (!capture_window_)
189 return; 188 return;
190 189
191 if (modal_window_controller_.IsWindowBlockedBy(capture_window_, 190 if (modal_window_controller_.IsWindowBlockedBy(capture_window_,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 279
281 DCHECK(event.IsPointerEvent()); 280 DCHECK(event.IsPointerEvent());
282 ProcessPointerEvent(*event.AsPointerEvent()); 281 ProcessPointerEvent(*event.AsPointerEvent());
283 return; 282 return;
284 } 283 }
285 284
286 void EventDispatcher::ProcessKeyEvent(const ui::KeyEvent& event, 285 void EventDispatcher::ProcessKeyEvent(const ui::KeyEvent& event,
287 AcceleratorMatchPhase match_phase) { 286 AcceleratorMatchPhase match_phase) {
288 Accelerator* post_target = 287 Accelerator* post_target =
289 FindAccelerator(event, ui::mojom::AcceleratorPhase::POST_TARGET); 288 FindAccelerator(event, ui::mojom::AcceleratorPhase::POST_TARGET);
289 if (drag_controller_ && event.type() == ui::ET_KEY_PRESSED &&
290 event.key_code() == ui::VKEY_ESCAPE) {
291 drag_controller_->Cancel();
292 return;
293 }
290 ServerWindow* focused_window = 294 ServerWindow* focused_window =
291 delegate_->GetFocusedWindowForEventDispatcher(); 295 delegate_->GetFocusedWindowForEventDispatcher();
292 if (focused_window) { 296 if (focused_window) {
293 // Assume key events are for the client area. 297 // Assume key events are for the client area.
294 const bool in_nonclient_area = false; 298 const bool in_nonclient_area = false;
295 const ClientSpecificId client_id = 299 const ClientSpecificId client_id =
296 delegate_->GetEventTargetClientId(focused_window, in_nonclient_area); 300 delegate_->GetEventTargetClientId(focused_window, in_nonclient_area);
297 delegate_->DispatchInputEventToWindow(focused_window, client_id, event, 301 delegate_->DispatchInputEventToWindow(focused_window, client_id, event,
298 post_target); 302 post_target);
299 return; 303 return;
(...skipping 21 matching lines...) Expand all
321 (!is_mouse_event || IsOnlyOneMouseButtonDown(event.flags())); 325 (!is_mouse_event || IsOnlyOneMouseButtonDown(event.flags()));
322 326
323 // Update mouse down state upon events which change it. 327 // Update mouse down state upon events which change it.
324 if (is_mouse_event) { 328 if (is_mouse_event) {
325 if (event.type() == ui::ET_POINTER_DOWN) 329 if (event.type() == ui::ET_POINTER_DOWN)
326 mouse_button_down_ = true; 330 mouse_button_down_ = true;
327 else if (is_pointer_going_up) 331 else if (is_pointer_going_up)
328 mouse_button_down_ = false; 332 mouse_button_down_ = false;
329 } 333 }
330 334
335 if (drag_controller_) {
336 const PointerTarget target = PointerTargetForEvent(event);
337 if (drag_controller_->DispatchPointerEvent(event, target.window))
338 return;
339 }
340
331 if (capture_window_) { 341 if (capture_window_) {
332 mouse_cursor_source_window_ = capture_window_; 342 mouse_cursor_source_window_ = capture_window_;
333 DispatchToClient(capture_window_, capture_window_client_id_, event); 343 DispatchToClient(capture_window_, capture_window_client_id_, event);
334 return; 344 return;
335 } 345 }
336 346
337 const int32_t pointer_id = event.pointer_id(); 347 const int32_t pointer_id = event.pointer_id();
338 if (!IsTrackingPointer(pointer_id) || 348 if (!IsTrackingPointer(pointer_id) ||
339 !pointer_targets_[pointer_id].is_pointer_down) { 349 !pointer_targets_[pointer_id].is_pointer_down) {
340 const bool any_pointers_down = AreAnyPointersDown(); 350 const bool any_pointers_down = AreAnyPointersDown();
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 538
529 ServerWindow* EventDispatcher::FindDeepestVisibleWindowForEvents( 539 ServerWindow* EventDispatcher::FindDeepestVisibleWindowForEvents(
530 gfx::Point* location) { 540 gfx::Point* location) {
531 ServerWindow* root = delegate_->GetRootWindowContaining(location); 541 ServerWindow* root = delegate_->GetRootWindowContaining(location);
532 if (!root) 542 if (!root)
533 return nullptr; 543 return nullptr;
534 544
535 return ui::ws::FindDeepestVisibleWindowForEvents(root, location); 545 return ui::ws::FindDeepestVisibleWindowForEvents(root, location);
536 } 546 }
537 547
548 void EventDispatcher::CancelImplicitCaptureExcept(ServerWindow* window) {
549 for (const auto& pair : pointer_targets_) {
550 ServerWindow* target = pair.second.window;
551 if (!target)
552 continue;
553 UnobserveWindow(target);
554 if (window && target == window)
555 continue;
556
557 ui::EventType event_type = pair.second.is_mouse_event
558 ? ui::ET_POINTER_EXITED
559 : ui::ET_POINTER_CANCELLED;
560 ui::EventPointerType pointer_type =
561 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE
562 : ui::EventPointerType::POINTER_TYPE_TOUCH;
563 // TODO(jonross): Track previous location in PointerTarget for sending
564 // cancels.
565 ui::PointerEvent event(event_type, gfx::Point(), gfx::Point(), ui::EF_NONE,
566 pair.first, 0 /* changed_button_flags */,
567 ui::PointerDetails(pointer_type),
568 ui::EventTimeForNow());
569 DispatchToPointerTarget(pair.second, event);
570 }
571 pointer_targets_.clear();
572 }
573
538 void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window, 574 void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window,
539 ServerWindow* new_parent, 575 ServerWindow* new_parent,
540 ServerWindow* old_parent) { 576 ServerWindow* old_parent) {
541 // TODO(sky): moving to a different root likely needs to transfer capture. 577 // 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 578 // TODO(sky): this isn't quite right, I think the logic should be (assuming
543 // moving in same root and still drawn): 579 // moving in same root and still drawn):
544 // . if there is capture and window is still in the same root, continue 580 // . if there is capture and window is still in the same root, continue
545 // sending to it. 581 // sending to it.
546 // . if there isn't capture, then reevaluate each of the pointer targets 582 // . if there isn't capture, then reevaluate each of the pointer targets
547 // sending exit as necessary. 583 // sending exit as necessary.
(...skipping 10 matching lines...) Expand all
558 594
559 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { 595 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) {
560 CancelPointerEventsToTarget(window); 596 CancelPointerEventsToTarget(window);
561 597
562 if (mouse_cursor_source_window_ == window) 598 if (mouse_cursor_source_window_ == window)
563 mouse_cursor_source_window_ = nullptr; 599 mouse_cursor_source_window_ = nullptr;
564 } 600 }
565 601
566 } // namespace ws 602 } // namespace ws
567 } // namespace ui 603 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698