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

Side by Side Diff: ash/drag_drop/drag_drop_controller.cc

Issue 10855159: Support Drag and Drop across displays. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Disable DragDropTrackerTest on Win Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « ash/drag_drop/drag_drop_controller.h ('k') | ash/drag_drop/drag_drop_controller_unittest.cc » ('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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ash/drag_drop/drag_drop_controller.h" 5 #include "ash/drag_drop/drag_drop_controller.h"
6 6
7 #include "ash/drag_drop/drag_drop_tracker.h"
7 #include "ash/drag_drop/drag_image_view.h" 8 #include "ash/drag_drop/drag_image_view.h"
8 #include "ash/shell.h" 9 #include "ash/shell.h"
9 #include "ash/wm/coordinate_conversion.h" 10 #include "ash/wm/coordinate_conversion.h"
10 #include "ash/wm/cursor_manager.h" 11 #include "ash/wm/cursor_manager.h"
11 #include "base/message_loop.h" 12 #include "base/message_loop.h"
12 #include "base/run_loop.h" 13 #include "base/run_loop.h"
13 #include "ui/aura/client/capture_client.h" 14 #include "ui/aura/client/capture_client.h"
14 #include "ui/aura/client/drag_drop_delegate.h" 15 #include "ui/aura/client/drag_drop_delegate.h"
15 #include "ui/aura/env.h" 16 #include "ui/aura/env.h"
16 #include "ui/aura/root_window.h" 17 #include "ui/aura/root_window.h"
(...skipping 20 matching lines...) Expand all
37 } // namespace 38 } // namespace
38 39
39 //////////////////////////////////////////////////////////////////////////////// 40 ////////////////////////////////////////////////////////////////////////////////
40 // DragDropController, public: 41 // DragDropController, public:
41 42
42 DragDropController::DragDropController() 43 DragDropController::DragDropController()
43 : drag_image_(NULL), 44 : drag_image_(NULL),
44 drag_data_(NULL), 45 drag_data_(NULL),
45 drag_operation_(0), 46 drag_operation_(0),
46 drag_window_(NULL), 47 drag_window_(NULL),
47 drag_drop_in_progress_(false),
48 should_block_during_drag_drop_(true) { 48 should_block_during_drag_drop_(true) {
49 Shell::GetInstance()->AddEnvEventFilter(this); 49 Shell::GetInstance()->AddEnvEventFilter(this);
50 } 50 }
51 51
52 DragDropController::~DragDropController() { 52 DragDropController::~DragDropController() {
53 Shell::GetInstance()->RemoveEnvEventFilter(this); 53 Shell::GetInstance()->RemoveEnvEventFilter(this);
54 Cleanup(); 54 Cleanup();
55 if (drag_image_.get()) 55 if (drag_image_.get())
56 drag_image_.reset(); 56 drag_image_.reset();
57 } 57 }
58 58
59 int DragDropController::StartDragAndDrop(const ui::OSExchangeData& data, 59 int DragDropController::StartDragAndDrop(const ui::OSExchangeData& data,
60 aura::RootWindow* root_window,
60 const gfx::Point& root_location, 61 const gfx::Point& root_location,
61 int operation) { 62 int operation) {
62 DCHECK(!drag_drop_in_progress_); 63 DCHECK(!IsDragDropInProgress());
63 // TODO(oshima): Add CaptureClient client API. 64
64 aura::Window* capture_window =
65 aura::client::GetCaptureWindow(Shell::GetPrimaryRootWindow());
66 if (capture_window)
67 capture_window->ReleaseCapture();
68 drag_drop_in_progress_ = true;
69 drag_cursor_ = ui::kCursorPointer; 65 drag_cursor_ = ui::kCursorPointer;
66 drag_drop_tracker_.reset(new DragDropTracker(root_window));
70 67
71 drag_data_ = &data; 68 drag_data_ = &data;
72 drag_operation_ = operation; 69 drag_operation_ = operation;
73 const ui::OSExchangeDataProviderAura& provider = 70 const ui::OSExchangeDataProviderAura& provider =
74 static_cast<const ui::OSExchangeDataProviderAura&>(data.provider()); 71 static_cast<const ui::OSExchangeDataProviderAura&>(data.provider());
75 72
76 drag_image_.reset(new DragImageView); 73 drag_image_.reset(new DragImageView);
77 drag_image_->SetImage(provider.drag_image()); 74 drag_image_->SetImage(provider.drag_image());
78 drag_image_offset_ = provider.drag_image_offset(); 75 drag_image_offset_ = provider.drag_image_offset();
79 drag_image_->SetBoundsInScreen(gfx::Rect( 76 drag_image_->SetBoundsInScreen(gfx::Rect(
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 delegate->OnDragExited(); 187 delegate->OnDragExited();
191 188
192 Cleanup(); 189 Cleanup();
193 drag_operation_ = 0; 190 drag_operation_ = 0;
194 StartCanceledAnimation(); 191 StartCanceledAnimation();
195 if (should_block_during_drag_drop_) 192 if (should_block_during_drag_drop_)
196 quit_closure_.Run(); 193 quit_closure_.Run();
197 } 194 }
198 195
199 bool DragDropController::IsDragDropInProgress() { 196 bool DragDropController::IsDragDropInProgress() {
200 return drag_drop_in_progress_; 197 return !!drag_drop_tracker_.get();
201 } 198 }
202 199
203 gfx::NativeCursor DragDropController::GetDragCursor() { 200 gfx::NativeCursor DragDropController::GetDragCursor() {
204 return drag_cursor_; 201 return drag_cursor_;
205 } 202 }
206 203
207 bool DragDropController::PreHandleKeyEvent(aura::Window* target, 204 bool DragDropController::PreHandleKeyEvent(aura::Window* target,
208 ui::KeyEvent* event) { 205 ui::KeyEvent* event) {
209 if (drag_drop_in_progress_ && event->key_code() == ui::VKEY_ESCAPE) { 206 if (IsDragDropInProgress() && event->key_code() == ui::VKEY_ESCAPE) {
210 DragCancel(); 207 DragCancel();
211 return true; 208 return true;
212 } 209 }
213 return false; 210 return false;
214 } 211 }
215 212
216 bool DragDropController::PreHandleMouseEvent(aura::Window* target, 213 bool DragDropController::PreHandleMouseEvent(aura::Window* target,
217 ui::MouseEvent* event) { 214 ui::MouseEvent* event) {
218 if (!drag_drop_in_progress_) 215 if (!IsDragDropInProgress())
219 return false; 216 return false;
220 switch (event->type()) { 217 aura::Window* translated_target = drag_drop_tracker_->GetTarget(*event);
218 if (!translated_target) {
219 DragCancel();
220 return true;
221 }
222 scoped_ptr<ui::MouseEvent> translated_event(
223 drag_drop_tracker_->ConvertMouseEvent(translated_target, *event));
224 switch (translated_event->type()) {
221 case ui::ET_MOUSE_DRAGGED: 225 case ui::ET_MOUSE_DRAGGED:
222 DragUpdate(target, *event); 226 DragUpdate(translated_target, *translated_event.get());
223 break; 227 break;
224 case ui::ET_MOUSE_RELEASED: 228 case ui::ET_MOUSE_RELEASED:
225 Drop(target, *event); 229 Drop(translated_target, *translated_event.get());
226 break; 230 break;
227 default: 231 default:
228 // We could reach here if the user drops outside the root window.
229 // We could also reach here because RootWindow may sometimes generate a 232 // We could also reach here because RootWindow may sometimes generate a
230 // bunch of fake mouse events 233 // bunch of fake mouse events
231 // (aura::RootWindow::PostMouseMoveEventAfterWindowChange). 234 // (aura::RootWindow::PostMouseMoveEventAfterWindowChange).
232 break; 235 break;
233 } 236 }
234 return true; 237 return true;
235 } 238 }
236 239
237 ui::TouchStatus DragDropController::PreHandleTouchEvent( 240 ui::TouchStatus DragDropController::PreHandleTouchEvent(
238 aura::Window* target, 241 aura::Window* target,
239 ui::TouchEvent* event) { 242 ui::TouchEvent* event) {
240 // TODO(sad): Also check for the touch-id. 243 // TODO(sad): Also check for the touch-id.
241 if (!drag_drop_in_progress_) 244 // TODO(varunjain): Add code for supporting drag-and-drop across displays
245 // (http://crbug.com/114755).
246 if (!IsDragDropInProgress())
242 return ui::TOUCH_STATUS_UNKNOWN; 247 return ui::TOUCH_STATUS_UNKNOWN;
243 switch (event->type()) { 248 switch (event->type()) {
244 case ui::ET_TOUCH_MOVED: 249 case ui::ET_TOUCH_MOVED:
245 DragUpdate(target, *event); 250 DragUpdate(target, *event);
246 break; 251 break;
247 case ui::ET_TOUCH_RELEASED: 252 case ui::ET_TOUCH_RELEASED:
248 Drop(target, *event); 253 Drop(target, *event);
249 break; 254 break;
250 case ui::ET_TOUCH_CANCELLED: 255 case ui::ET_TOUCH_CANCELLED:
251 DragCancel(); 256 DragCancel();
(...skipping 18 matching lines...) Expand all
270 } 275 }
271 276
272 //////////////////////////////////////////////////////////////////////////////// 277 ////////////////////////////////////////////////////////////////////////////////
273 // DragDropController, private: 278 // DragDropController, private:
274 279
275 void DragDropController::OnImplicitAnimationsCompleted() { 280 void DragDropController::OnImplicitAnimationsCompleted() {
276 DCHECK(drag_image_.get()); 281 DCHECK(drag_image_.get());
277 282
278 // By the time we finish animation, another drag/drop session may have 283 // By the time we finish animation, another drag/drop session may have
279 // started. We do not want to destroy the drag image in that case. 284 // started. We do not want to destroy the drag image in that case.
280 if (!drag_drop_in_progress_) 285 if (!IsDragDropInProgress())
281 drag_image_.reset(); 286 drag_image_.reset();
282 } 287 }
283 288
284 void DragDropController::StartCanceledAnimation() { 289 void DragDropController::StartCanceledAnimation() {
285 aura::Window* window = drag_image_->GetWidget()->GetNativeView(); 290 aura::Window* window = drag_image_->GetWidget()->GetNativeView();
286 ui::LayerAnimator* animator = window->layer()->GetAnimator(); 291 ui::LayerAnimator* animator = window->layer()->GetAnimator();
287 animator->set_preemption_strategy( 292 animator->set_preemption_strategy(
288 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 293 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
289 294
290 // Stop waiting for any as yet unfinished implicit animations. 295 // Stop waiting for any as yet unfinished implicit animations.
291 StopObservingImplicitAnimations(); 296 StopObservingImplicitAnimations();
292 297
293 ui::ScopedLayerAnimationSettings animation_setter(animator); 298 ui::ScopedLayerAnimationSettings animation_setter(animator);
294 animation_setter.SetTransitionDuration(kDragDropAnimationDuration); 299 animation_setter.SetTransitionDuration(kDragDropAnimationDuration);
295 animation_setter.AddObserver(this); 300 animation_setter.AddObserver(this);
296 window->SetBounds(gfx::Rect(drag_start_location_, window->bounds().size())); 301 window->SetBounds(gfx::Rect(drag_start_location_, window->bounds().size()));
297 } 302 }
298 303
299 void DragDropController::Cleanup() { 304 void DragDropController::Cleanup() {
300 if (drag_window_) 305 if (drag_window_)
301 drag_window_->RemoveObserver(this); 306 drag_window_->RemoveObserver(this);
302 drag_window_ = NULL; 307 drag_window_ = NULL;
303 drag_data_ = NULL; 308 drag_data_ = NULL;
304 drag_drop_in_progress_ = false; 309 // Cleanup can be called again while deleting DragDropTracker, so use Pass
310 // instead of reset to avoid double free.
311 drag_drop_tracker_.Pass();
danakj 2014/09/27 01:15:04 This is not going to work with unique_ptr, we shou
305 } 312 }
306 313
307 } // namespace internal 314 } // namespace internal
308 } // namespace ash 315 } // namespace ash
OLDNEW
« no previous file with comments | « ash/drag_drop/drag_drop_controller.h ('k') | ash/drag_drop/drag_drop_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698