Index: ash/drag_drop/drag_drop_controller.cc |
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc |
index c273bf09623bb54c149753992ff82f8da3c1f7bb..5d4408555ed23ce4cb945288cede3bc2e8de39a9 100644 |
--- a/ash/drag_drop/drag_drop_controller.cc |
+++ b/ash/drag_drop/drag_drop_controller.cc |
@@ -4,6 +4,7 @@ |
#include "ash/drag_drop/drag_drop_controller.h" |
+#include "ash/drag_drop/drag_drop_tracker.h" |
#include "ash/drag_drop/drag_image_view.h" |
#include "ash/shell.h" |
#include "ash/wm/coordinate_conversion.h" |
@@ -44,7 +45,6 @@ DragDropController::DragDropController() |
drag_data_(NULL), |
drag_operation_(0), |
drag_window_(NULL), |
- drag_drop_in_progress_(false), |
should_block_during_drag_drop_(true) { |
Shell::GetInstance()->AddEnvEventFilter(this); |
} |
@@ -57,16 +57,13 @@ DragDropController::~DragDropController() { |
} |
int DragDropController::StartDragAndDrop(const ui::OSExchangeData& data, |
+ aura::RootWindow* root_window, |
const gfx::Point& root_location, |
int operation) { |
- DCHECK(!drag_drop_in_progress_); |
- // TODO(oshima): Add CaptureClient client API. |
- aura::Window* capture_window = |
- aura::client::GetCaptureWindow(Shell::GetPrimaryRootWindow()); |
- if (capture_window) |
- capture_window->ReleaseCapture(); |
- drag_drop_in_progress_ = true; |
+ DCHECK(!IsDragDropInProgress()); |
+ |
drag_cursor_ = ui::kCursorPointer; |
+ drag_drop_tracker_.reset(new DragDropTracker(root_window)); |
drag_data_ = &data; |
drag_operation_ = operation; |
@@ -197,7 +194,7 @@ void DragDropController::DragCancel() { |
} |
bool DragDropController::IsDragDropInProgress() { |
- return drag_drop_in_progress_; |
+ return !!drag_drop_tracker_.get(); |
} |
gfx::NativeCursor DragDropController::GetDragCursor() { |
@@ -206,7 +203,7 @@ gfx::NativeCursor DragDropController::GetDragCursor() { |
bool DragDropController::PreHandleKeyEvent(aura::Window* target, |
ui::KeyEvent* event) { |
- if (drag_drop_in_progress_ && event->key_code() == ui::VKEY_ESCAPE) { |
+ if (IsDragDropInProgress() && event->key_code() == ui::VKEY_ESCAPE) { |
DragCancel(); |
return true; |
} |
@@ -215,17 +212,23 @@ bool DragDropController::PreHandleKeyEvent(aura::Window* target, |
bool DragDropController::PreHandleMouseEvent(aura::Window* target, |
ui::MouseEvent* event) { |
- if (!drag_drop_in_progress_) |
+ if (!IsDragDropInProgress()) |
return false; |
- switch (event->type()) { |
+ aura::Window* translated_target = drag_drop_tracker_->GetTarget(*event); |
+ if (!translated_target) { |
+ DragCancel(); |
+ return true; |
+ } |
+ scoped_ptr<ui::MouseEvent> translated_event( |
+ drag_drop_tracker_->ConvertMouseEvent(translated_target, *event)); |
+ switch (translated_event->type()) { |
case ui::ET_MOUSE_DRAGGED: |
- DragUpdate(target, *event); |
+ DragUpdate(translated_target, *translated_event.get()); |
break; |
case ui::ET_MOUSE_RELEASED: |
- Drop(target, *event); |
+ Drop(translated_target, *translated_event.get()); |
break; |
default: |
- // We could reach here if the user drops outside the root window. |
// We could also reach here because RootWindow may sometimes generate a |
// bunch of fake mouse events |
// (aura::RootWindow::PostMouseMoveEventAfterWindowChange). |
@@ -238,7 +241,9 @@ ui::TouchStatus DragDropController::PreHandleTouchEvent( |
aura::Window* target, |
ui::TouchEvent* event) { |
// TODO(sad): Also check for the touch-id. |
- if (!drag_drop_in_progress_) |
+ // TODO(varunjain): Add code for supporting drag-and-drop across displays |
+ // (http://crbug.com/114755). |
+ if (!IsDragDropInProgress()) |
return ui::TOUCH_STATUS_UNKNOWN; |
switch (event->type()) { |
case ui::ET_TOUCH_MOVED: |
@@ -277,7 +282,7 @@ void DragDropController::OnImplicitAnimationsCompleted() { |
// By the time we finish animation, another drag/drop session may have |
// started. We do not want to destroy the drag image in that case. |
- if (!drag_drop_in_progress_) |
+ if (!IsDragDropInProgress()) |
drag_image_.reset(); |
} |
@@ -301,7 +306,9 @@ void DragDropController::Cleanup() { |
drag_window_->RemoveObserver(this); |
drag_window_ = NULL; |
drag_data_ = NULL; |
- drag_drop_in_progress_ = false; |
+ // Cleanup can be called again while deleting DragDropTracker, so use Pass |
+ // instead of reset to avoid double free. |
+ drag_drop_tracker_.Pass(); |
danakj
2014/09/27 01:15:04
This is not going to work with unique_ptr, we shou
|
} |
} // namespace internal |