summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/ash.gyp4
-rw-r--r--ash/drag_drop/drag_drop_controller.cc12
-rw-r--r--ash/drag_drop/drag_drop_controller_unittest.cc9
-rw-r--r--chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc2
-rw-r--r--chrome/test/base/view_event_test_base.cc26
-rw-r--r--content/browser/web_contents/web_contents_view_aura.cc31
-rw-r--r--ui/aura/ui_controls_win.cc8
-rw-r--r--ui/base/dragdrop/os_exchange_data.h12
-rw-r--r--ui/base/dragdrop/os_exchange_data_provider_win.cc22
-rw-r--r--ui/base/dragdrop/os_exchange_data_provider_win.h9
-rw-r--r--ui/ui.gyp5
-rw-r--r--ui/views/controls/textfield/native_textfield_views_unittest.cc4
-rw-r--r--ui/views/views.gyp8
-rw-r--r--ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc73
-rw-r--r--ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h59
-rw-r--r--ui/views/widget/desktop_aura/desktop_drop_target_win.cc139
-rw-r--r--ui/views/widget/desktop_aura/desktop_drop_target_win.h81
-rw-r--r--ui/views/widget/desktop_aura/desktop_native_widget_aura.cc47
-rw-r--r--ui/views/widget/desktop_aura/desktop_native_widget_aura.h14
-rw-r--r--ui/views/widget/desktop_aura/desktop_root_window_host_win.cc15
-rw-r--r--ui/views/widget/desktop_aura/desktop_root_window_host_win.h3
21 files changed, 529 insertions, 54 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 69a4917..d949329 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -603,8 +603,10 @@
],
}],
['OS=="win"', {
- # TODO(zork): fix this test to build on Windows. See: crosbug.com/26906
'sources/': [
+ # TODO(win_ash): implement DragDropController::StartDragAndDrop
+ ['exclude', 'drag_drop/drag_drop_controller_unittest.cc'],
+ # TODO(zork): fix this test to build on Windows. See: crosbug.com/26906
['exclude', 'focus_cycler_unittest.cc'],
],
}],
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index cf6135e..4248099 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -106,6 +106,17 @@ int DragDropController::StartDragAndDrop(
if (IsDragDropInProgress())
return 0;
+#if defined(OS_WIN)
+ // TODO(win_ash): need to figure out how this will work in Metro, since
+ // OSExchangeDataProviderAura isn't used in Windows builds. Two alternatives:
+ // 1) Use OSExchangeDataProviderAura in Ash and OSExchangeDataProviderWin
+ // elsewhere. This will complicate creating an ui::OSExchangeData to pass
+ // in more context.
+ // 2) Add methods to get the image and offset in the base interface of these
+ // implementations to get to this data here.
+ NOTIMPLEMENTED();
+ return 0;
+#else
const ui::OSExchangeDataProviderAura& provider =
static_cast<const ui::OSExchangeDataProviderAura&>(data.provider());
// We do not support touch drag/drop without a drag image.
@@ -180,6 +191,7 @@ int DragDropController::StartDragAndDrop(
drag_source_window_->RemoveObserver(this);
drag_source_window_ = NULL;
}
+#endif
return drag_operation_;
}
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc
index 14a25c6..06969eb 100644
--- a/ash/drag_drop/drag_drop_controller_unittest.cc
+++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -16,8 +16,8 @@
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/dragdrop/drag_drop_types.h"
+#include "ui/base/dragdrop/drag_utils.h"
#include "ui/base/dragdrop/os_exchange_data.h"
-#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
#include "ui/base/events/event.h"
#include "ui/base/gestures/gesture_types.h"
#include "ui/base/ui_base_switches.h"
@@ -73,12 +73,13 @@ class DragTestView : public views::View {
void WriteDragData(const gfx::Point& p, OSExchangeData* data) OVERRIDE {
data->SetString(UTF8ToUTF16("I am being dragged"));
- ui::OSExchangeDataProviderAura& provider =
- static_cast<ui::OSExchangeDataProviderAura&>(data->provider());
gfx::ImageSkiaRep* image = new gfx::ImageSkiaRep(
gfx::Size(10, 20), ui::SCALE_FACTOR_100P);
gfx::ImageSkia* image_skia = new gfx::ImageSkia(*image);
- provider.set_drag_image(*image_skia);
+
+ drag_utils::SetDragImageOnDataObject(
+ *image_skia, gfx::Size(image_skia->width(), image_skia->height()),
+ gfx::Vector2d(), data);
}
bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
index 6947e84..a88f550 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -546,7 +546,7 @@ class BookmarkBarViewTest5 : public BookmarkBarViewEventTestBase {
// Drop the item so that it's now the second item.
views::MenuItemView* target_menu =
bb_view_->GetMenu()->GetSubmenu()->GetMenuItemAt(1);
- gfx::Point loc(1, target_menu->height() - 1);
+ gfx::Point loc(1, target_menu->height() - 2);
views::View::ConvertPointToScreen(target_menu, &loc);
ui_controls::SendMouseMove(loc.x(), loc.y());
diff --git a/chrome/test/base/view_event_test_base.cc b/chrome/test/base/view_event_test_base.cc
index f3948d1..28a951e 100644
--- a/chrome/test/base/view_event_test_base.cc
+++ b/chrome/test/base/view_event_test_base.cc
@@ -8,12 +8,14 @@
#include "base/bind_helpers.h"
#include "base/message_loop.h"
#include "base/string_number_conversions.h"
+#include "chrome/browser/ui/views/chrome_views_delegate.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "ui/base/ime/text_input_test_support.h"
#include "ui/compositor/test/compositor_test_support.h"
#include "ui/ui_controls/ui_controls.h"
#include "ui/views/view.h"
+#include "ui/views/widget/desktop_aura/desktop_screen.h"
#include "ui/views/widget/widget.h"
#if defined(USE_ASH)
@@ -88,8 +90,17 @@ void ViewEventTestBase::SetUp() {
ui::TextInputTestSupport::Initialize();
ui::CompositorTestSupport::Initialize();
#if defined(USE_ASH)
+#if defined(OS_WIN)
+ // http://crbug.com/154081 use ash::Shell code path below on win_ash bots when
+ // interactive_ui_tests is brought up on that platform.
+ views::ViewsDelegate::views_delegate = new ChromeViewsDelegate;
+
+ gfx::Screen::SetScreenInstance(
+ gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen());
+#else
ash::Shell::CreateInstance(new ash::test::TestShellDelegate());
#endif
+#endif
window_ = views::Widget::CreateWindow(this);
}
@@ -104,8 +115,13 @@ void ViewEventTestBase::TearDown() {
window_ = NULL;
}
#if defined(USE_ASH)
+#if defined(OS_WIN)
+ delete views::ViewsDelegate::views_delegate;
+ views::ViewsDelegate::views_delegate = NULL;
+#else
ash::Shell::DeleteInstance();
#endif
+#endif
#if defined(USE_AURA)
aura::Env::DeleteInstance();
#endif
@@ -144,8 +160,14 @@ void ViewEventTestBase::StartMessageLoopAndRunTest() {
window_->Show();
// Make sure the window is the foreground window, otherwise none of the
// mouse events are going to be targeted correctly.
-#if defined(OS_WIN) && !defined(USE_AURA)
- SetForegroundWindow(window_->GetNativeWindow());
+#if defined(OS_WIN)
+#if defined(USE_AURA)
+ HWND window =
+ window_->GetNativeWindow()->GetRootWindow()->GetAcceleratedWidget();
+#else
+ HWND window = window_->GetNativeWindow();
+#endif
+ SetForegroundWindow(window);
#endif
// Flush any pending events to make sure we start with a clean slate.
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index bf881e3..dde8d86 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -33,16 +33,21 @@
#include "ui/aura/window_observer.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/dragdrop/drag_drop_types.h"
+#include "ui/base/dragdrop/drag_utils.h"
#include "ui/base/dragdrop/os_exchange_data.h"
-#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
#include "ui/base/events/event.h"
#include "ui/base/events/event_utils.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/screen.h"
#include "webkit/glue/webdropdata.h"
+#if defined(OS_WIN)
+#include "ui/base/clipboard/clipboard_util_win.h"
+#endif
+
namespace content {
WebContentsView* CreateWebContentsView(
WebContentsImpl* web_contents,
@@ -128,9 +133,9 @@ class WebDragSourceAura : public MessageLoopForUI::Observer,
DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura);
};
-// Utility to fill a ui::OSExchangeDataProviderAura object from WebDropData.
+// Utility to fill a ui::OSExchangeDataProvider object from WebDropData.
void PrepareDragData(const WebDropData& drop_data,
- ui::OSExchangeDataProviderAura* provider) {
+ ui::OSExchangeData::Provider* provider) {
if (!drop_data.text.string().empty())
provider->SetString(drop_data.text.string());
if (drop_data.url.is_valid())
@@ -152,8 +157,13 @@ void PrepareDragData(const WebDropData& drop_data,
if (!drop_data.custom_data.empty()) {
Pickle pickle;
ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle);
+#if defined(OS_WIN)
+ provider->SetPickledData(
+ ui::ClipboardUtil::GetWebCustomDataFormat()->cfFormat, pickle);
+#else
provider->SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(),
pickle);
+#endif
}
}
@@ -193,8 +203,13 @@ void PrepareWebDropData(WebDropData* drop_data,
}
Pickle pickle;
+#if defined(OS_WIN)
+ if (data.GetPickledData(ui::ClipboardUtil::GetWebCustomDataFormat()->cfFormat,
+ &pickle))
+#else
if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(),
&pickle))
+#endif
ui::ReadCustomDataIntoMap(pickle.data(), pickle.size(),
&drop_data->custom_data);
}
@@ -672,13 +687,15 @@ void WebContentsViewAura::StartDragging(
if (!aura::client::GetDragDropClient(root_window))
return;
- ui::OSExchangeDataProviderAura* provider = new ui::OSExchangeDataProviderAura;
+ ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider();
PrepareDragData(drop_data, provider);
+
+ ui::OSExchangeData data(provider); // takes ownership of |provider|.
+
if (!image.isNull()) {
- provider->set_drag_image(image);
- provider->set_drag_image_offset(image_offset);
+ drag_utils::SetDragImageOnDataObject(image,
+ gfx::Size(image.width(), image.height()), image_offset, &data);
}
- ui::OSExchangeData data(provider); // takes ownership of |provider|.
scoped_ptr<WebDragSourceAura> drag_source(
new WebDragSourceAura(GetNativeView(), web_contents_));
diff --git a/ui/aura/ui_controls_win.cc b/ui/aura/ui_controls_win.cc
index a28d553..49e5fe8 100644
--- a/ui/aura/ui_controls_win.cc
+++ b/ui/aura/ui_controls_win.cc
@@ -14,8 +14,7 @@ namespace aura {
namespace {
class UIControlsWin : public ui_controls::UIControlsAura {
public:
- UIControlsWin(RootWindow* root_window) : root_window_(root_window) {
- }
+ UIControlsWin() {}
// UIControlsAura overrides:
virtual bool SendKeyPress(gfx::NativeWindow native_window,
@@ -43,7 +42,6 @@ class UIControlsWin : public ui_controls::UIControlsAura {
}
virtual bool SendMouseMove(long x, long y) {
gfx::Point point(x, y);
- root_window_->ConvertPointToNativeScreen(&point);
return ui_controls::internal::SendMouseMoveImpl(
point.x(), point.y(), base::Closure());
}
@@ -51,7 +49,6 @@ class UIControlsWin : public ui_controls::UIControlsAura {
long y,
const base::Closure& task) {
gfx::Point point(x, y);
- root_window_->ConvertPointToNativeScreen(&point);
return ui_controls::internal::SendMouseMoveImpl(point.x(), point.y(), task);
}
virtual bool SendMouseEvents(ui_controls::MouseButton type, int state) {
@@ -72,14 +69,13 @@ class UIControlsWin : public ui_controls::UIControlsAura {
}
private:
- RootWindow* root_window_;
DISALLOW_COPY_AND_ASSIGN(UIControlsWin);
};
} // namespace
ui_controls::UIControlsAura* CreateUIControlsAura(RootWindow* root_window) {
- return new UIControlsWin(root_window);
+ return new UIControlsWin();
}
} // namespace aura
diff --git a/ui/base/dragdrop/os_exchange_data.h b/ui/base/dragdrop/os_exchange_data.h
index 92b6798..c99cf3a 100644
--- a/ui/base/dragdrop/os_exchange_data.h
+++ b/ui/base/dragdrop/os_exchange_data.h
@@ -49,12 +49,12 @@ class UI_EXPORT OSExchangeData {
public:
// CustomFormats are used for non-standard data types. For example, bookmark
// nodes are written using a CustomFormat.
-#if defined(USE_AURA)
+#if defined(OS_WIN)
+ typedef CLIPFORMAT CustomFormat;
+#elif defined(USE_AURA)
// Use the same type as the clipboard (why do we want two different
// definitions of this on other platforms?).
typedef Clipboard::FormatType CustomFormat;
-#elif defined(OS_WIN)
- typedef CLIPFORMAT CustomFormat;
#elif defined(TOOLKIT_GTK)
typedef GdkAtom CustomFormat;
#else
@@ -139,6 +139,9 @@ class UI_EXPORT OSExchangeData {
#endif
};
+ // Creates the platform specific Provider.
+ static Provider* CreateProvider();
+
OSExchangeData();
// Creates an OSExchangeData with the specified provider. OSExchangeData
// takes ownership of the supplied provider.
@@ -222,9 +225,6 @@ class UI_EXPORT OSExchangeData {
#endif
private:
- // Creates the platform specific Provider.
- static Provider* CreateProvider();
-
// Provides the actual data.
scoped_ptr<Provider> provider_;
diff --git a/ui/base/dragdrop/os_exchange_data_provider_win.cc b/ui/base/dragdrop/os_exchange_data_provider_win.cc
index fc4fc85..65922f8 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_win.cc
+++ b/ui/base/dragdrop/os_exchange_data_provider_win.cc
@@ -327,6 +327,16 @@ void OSExchangeDataProviderWin::SetFilename(const FilePath& path) {
data_->contents_.push_back(info);
}
+void OSExchangeDataProviderWin::SetFilenames(
+ const std::vector<OSExchangeData::FileInfo>& filenames) {
+ for (size_t i = 0; i < filenames.size(); ++i) {
+ STGMEDIUM* storage = GetStorageForFileName(filenames[i].path);
+ DataObjectImpl::StoredDataInfo* info =
+ new DataObjectImpl::StoredDataInfo(CF_HDROP, storage);
+ data_->contents_.push_back(info);
+ }
+}
+
void OSExchangeDataProviderWin::SetPickledData(CLIPFORMAT format,
const Pickle& data) {
STGMEDIUM* storage = GetStorageForBytes(static_cast<const char*>(data.data()),
@@ -395,6 +405,18 @@ bool OSExchangeDataProviderWin::GetFilename(FilePath* path) const {
return success;
}
+bool OSExchangeDataProviderWin::GetFilenames(
+ std::vector<OSExchangeData::FileInfo>* filenames) const {
+ std::vector<string16> filenames_local;
+ bool success = ClipboardUtil::GetFilenames(source_object_, &filenames_local);
+ if (success) {
+ for (size_t i = 0; i < filenames_local.size(); ++i)
+ filenames->push_back(
+ OSExchangeData::FileInfo(FilePath(filenames_local[i]), FilePath()));
+ }
+ return success;
+}
+
bool OSExchangeDataProviderWin::GetPickledData(CLIPFORMAT format,
Pickle* data) const {
DCHECK(data);
diff --git a/ui/base/dragdrop/os_exchange_data_provider_win.h b/ui/base/dragdrop/os_exchange_data_provider_win.h
index 576445f..9705d34 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_win.h
+++ b/ui/base/dragdrop/os_exchange_data_provider_win.h
@@ -161,9 +161,7 @@ class UI_EXPORT OSExchangeDataProviderWin : public OSExchangeData::Provider {
virtual void SetURL(const GURL& url, const string16& title);
virtual void SetFilename(const FilePath& path);
virtual void SetFilenames(
- const std::vector<OSExchangeData::FileInfo>& filenames) {
- NOTREACHED();
- }
+ const std::vector<OSExchangeData::FileInfo>& filenames);
virtual void SetPickledData(OSExchangeData::CustomFormat format,
const Pickle& data);
virtual void SetFileContents(const FilePath& filename,
@@ -174,10 +172,7 @@ class UI_EXPORT OSExchangeDataProviderWin : public OSExchangeData::Provider {
virtual bool GetURLAndTitle(GURL* url, string16* title) const;
virtual bool GetFilename(FilePath* path) const;
virtual bool GetFilenames(
- std::vector<OSExchangeData::FileInfo>* filenames) const {
- NOTREACHED();
- return false;
- }
+ std::vector<OSExchangeData::FileInfo>* filenames) const;
virtual bool GetPickledData(OSExchangeData::CustomFormat format,
Pickle* data) const;
virtual bool GetFileContents(FilePath* filename,
diff --git a/ui/ui.gyp b/ui/ui.gyp
index 7ed2833..a31f518 100644
--- a/ui/ui.gyp
+++ b/ui/ui.gyp
@@ -593,7 +593,6 @@
['exclude', 'gfx/screen_gtk.cc'],
['exclude', 'base/dialogs/select_file_dialog_mac.mm'],
['exclude', 'base/dialogs/select_file_dialog_win.cc'],
- ['exclude', 'base/dragdrop/drag_utils_win.cc'],
['exclude', 'base/work_area_watcher_observer.h'],
['exclude', 'base/x/active_window_watcher_x.cc'],
['exclude', 'base/x/active_window_watcher_x.h'],
@@ -616,8 +615,8 @@
}],
['use_aura==1 and OS=="win"', {
'sources/': [
- ['exclude', 'base/dragdrop/os_exchange_data_provider_win.cc'],
- ['exclude', 'base/dragdrop/os_exchange_data_provider_win.h'],
+ ['exclude', 'base/dragdrop/os_exchange_data_provider_aura.cc'],
+ ['exclude', 'base/dragdrop/drag_utils_aura.cc'],
],
}],
['use_aura==0 and toolkit_views==0', {
diff --git a/ui/views/controls/textfield/native_textfield_views_unittest.cc b/ui/views/controls/textfield/native_textfield_views_unittest.cc
index e599e7c..91ee81f 100644
--- a/ui/views/controls/textfield/native_textfield_views_unittest.cc
+++ b/ui/views/controls/textfield/native_textfield_views_unittest.cc
@@ -873,11 +873,7 @@ TEST_F(NativeTextfieldViewsTest, DragAndDrop_AcceptDrop) {
ui::OSExchangeData bad_data;
bad_data.SetFilename(FilePath(FILE_PATH_LITERAL("x")));
#if defined(OS_WIN)
-#if defined(USE_AURA)
- ui::OSExchangeData::CustomFormat fmt = ui::Clipboard::GetBitmapFormatType();
-#else
ui::OSExchangeData::CustomFormat fmt = CF_BITMAP;
-#endif
bad_data.SetPickledData(fmt, Pickle());
bad_data.SetFileContents(FilePath(L"x"), "x");
bad_data.SetHtml(string16(ASCIIToUTF16("x")), GURL("x.org"));
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index edc77d6..6bfd9f5 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -358,6 +358,10 @@
'widget/desktop_aura/desktop_cursor_client.h',
'widget/desktop_aura/desktop_dispatcher_client.cc',
'widget/desktop_aura/desktop_dispatcher_client.h',
+ 'widget/desktop_aura/desktop_drag_drop_client_win.cc',
+ 'widget/desktop_aura/desktop_drag_drop_client_win.h',
+ 'widget/desktop_aura/desktop_drop_target_win.cc',
+ 'widget/desktop_aura/desktop_drop_target_win.h',
'widget/desktop_aura/desktop_layout_manager.cc',
'widget/desktop_aura/desktop_layout_manager.h',
'widget/desktop_aura/desktop_native_widget_aura.cc',
@@ -474,9 +478,9 @@
['OS=="win"', {
'sources/': [
['include', 'widget/desktop_aura/desktop_screen_win.cc'],
- ['include', 'widget/desktop_aura/desktop_screen_win.h'],
+ ['include', 'widget/desktop_aura/desktop_drag_drop_client_win.cc'],
+ ['include', 'widget/desktop_aura/desktop_drop_target_win.cc'],
['include', 'widget/desktop_aura/desktop_root_window_host_win.cc'],
- ['include', 'widget/desktop_aura/desktop_root_window_host_win.h'],
],
}],
],
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc
new file mode 100644
index 0000000..08de103
--- /dev/null
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc
@@ -0,0 +1,73 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h"
+
+#include "ui/base/dragdrop/drag_drop_types.h"
+#include "ui/base/dragdrop/drag_source.h"
+#include "ui/base/dragdrop/os_exchange_data_provider_win.h"
+#include "ui/views/widget/desktop_aura/desktop_drop_target_win.h"
+#include "ui/views/widget/desktop_aura/desktop_root_window_host_win.h"
+#include "ui/views/widget/drop_target_win.h"
+
+namespace views {
+
+DesktopDragDropClientWin::DesktopDragDropClientWin(
+ aura::RootWindow* root_window,
+ HWND window)
+ : drag_drop_in_progress_(false),
+ drag_operation_(0) {
+ drop_target_ = new DesktopDropTargetWin(root_window, window);
+}
+
+DesktopDragDropClientWin::~DesktopDragDropClientWin() {
+}
+
+int DesktopDragDropClientWin::StartDragAndDrop(
+ const ui::OSExchangeData& data,
+ aura::RootWindow* root_window,
+ aura::Window* source_window,
+ const gfx::Point& root_location,
+ int operation,
+ ui::DragDropTypes::DragEventSource source) {
+ drag_drop_in_progress_ = true;
+ drag_operation_ = operation;
+
+ drag_source_ = new ui::DragSource;
+ DWORD effects;
+ DoDragDrop(ui::OSExchangeDataProviderWin::GetIDataObject(data),
+ drag_source_,
+ ui::DragDropTypes::DragOperationToDropEffect(operation),
+ &effects);
+
+ drag_drop_in_progress_ = false;
+
+ return drag_operation_;
+}
+
+void DesktopDragDropClientWin::DragUpdate(aura::Window* target,
+ const ui::LocatedEvent& event) {
+}
+
+void DesktopDragDropClientWin::Drop(aura::Window* target,
+ const ui::LocatedEvent& event) {
+}
+
+void DesktopDragDropClientWin::DragCancel() {
+ drag_source_->CancelDrag();
+ drag_operation_ = 0;
+}
+
+bool DesktopDragDropClientWin::IsDragDropInProgress() {
+ return drag_drop_in_progress_;
+}
+
+void DesktopDragDropClientWin::OnNativeWidgetDestroying(HWND window) {
+ if (drop_target_.get()) {
+ RevokeDragDrop(window);
+ drop_target_ = NULL;
+ }
+}
+
+} // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
new file mode 100644
index 0000000..852e7ab
--- /dev/null
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_WIN_H_
+#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_WIN_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "ui/aura/client/drag_drop_client.h"
+#include "ui/views/views_export.h"
+
+namespace ui {
+class DragSource;
+class RootWindow;
+}
+
+namespace views {
+class DesktopDragDragSourceWin;
+class DesktopDropTargetWin;
+
+class VIEWS_EXPORT DesktopDragDropClientWin
+ : public aura::client::DragDropClient {
+ public:
+ DesktopDragDropClientWin(aura::RootWindow* root_window, HWND window);
+ virtual ~DesktopDragDropClientWin();
+
+ // Overridden from aura::client::DragDropClient:
+ virtual int StartDragAndDrop(
+ const ui::OSExchangeData& data,
+ aura::RootWindow* root_window,
+ aura::Window* source_window,
+ const gfx::Point& root_location,
+ int operation,
+ ui::DragDropTypes::DragEventSource source) OVERRIDE;
+ virtual void DragUpdate(aura::Window* target,
+ const ui::LocatedEvent& event) OVERRIDE;
+ virtual void Drop(aura::Window* target,
+ const ui::LocatedEvent& event) OVERRIDE;
+ virtual void DragCancel() OVERRIDE;
+ virtual bool IsDragDropInProgress() OVERRIDE;
+
+ void OnNativeWidgetDestroying(HWND window);
+
+ private:
+ bool drag_drop_in_progress_;
+
+ int drag_operation_;
+
+ scoped_refptr<ui::DragSource> drag_source_;
+
+ scoped_refptr<DesktopDropTargetWin> drop_target_;
+
+ DISALLOW_COPY_AND_ASSIGN(DesktopDragDropClientWin);
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_WIN_H_
diff --git a/ui/views/widget/desktop_aura/desktop_drop_target_win.cc b/ui/views/widget/desktop_aura/desktop_drop_target_win.cc
new file mode 100644
index 0000000..4d0a8ea
--- /dev/null
+++ b/ui/views/widget/desktop_aura/desktop_drop_target_win.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/widget/desktop_aura/desktop_drop_target_win.h"
+
+#include "ui/aura/client/drag_drop_client.h"
+#include "ui/aura/client/drag_drop_delegate.h"
+#include "ui/aura/window.h"
+#include "ui/aura/root_window.h"
+#include "ui/base/dragdrop/drag_drop_types.h"
+#include "ui/base/dragdrop/os_exchange_data_provider_win.h"
+#include "ui/base/events/event.h"
+
+using aura::client::DragDropDelegate;
+using ui::OSExchangeData;
+using ui::OSExchangeDataProviderWin;
+
+namespace views {
+
+DesktopDropTargetWin::DesktopDropTargetWin(aura::RootWindow* root_window,
+ HWND window)
+ : ui::DropTarget(window),
+ root_window_(root_window),
+ target_window_(NULL) {
+}
+
+DesktopDropTargetWin::~DesktopDropTargetWin() {
+ if (target_window_)
+ target_window_->RemoveObserver(this);
+}
+
+DWORD DesktopDropTargetWin::OnDragEnter(IDataObject* data_object,
+ DWORD key_state,
+ POINT position,
+ DWORD effect) {
+ scoped_ptr<OSExchangeData> data;
+ scoped_ptr<ui::DropTargetEvent> event;
+ DragDropDelegate* delegate;
+ // Translate will call OnDragEntered.
+ Translate(data_object, key_state, position, effect, &data, &event, &delegate);
+ return ui::DragDropTypes::DragOperationToDropEffect(
+ ui::DragDropTypes::DRAG_NONE);
+}
+
+DWORD DesktopDropTargetWin::OnDragOver(IDataObject* data_object,
+ DWORD key_state,
+ POINT position,
+ DWORD effect) {
+ int drag_operation = ui::DragDropTypes::DRAG_NONE;
+ scoped_ptr<OSExchangeData> data;
+ scoped_ptr<ui::DropTargetEvent> event;
+ DragDropDelegate* delegate;
+ Translate(data_object, key_state, position, effect, &data, &event, &delegate);
+ if (delegate)
+ drag_operation = delegate->OnDragUpdated(*event);
+ return ui::DragDropTypes::DragOperationToDropEffect(drag_operation);
+}
+
+void DesktopDropTargetWin::OnDragLeave(IDataObject* data_object) {
+ NotifyDragLeave();
+}
+
+DWORD DesktopDropTargetWin::OnDrop(IDataObject* data_object,
+ DWORD key_state,
+ POINT position,
+ DWORD effect) {
+ int drag_operation = ui::DragDropTypes::DRAG_NONE;
+ scoped_ptr<OSExchangeData> data;
+ scoped_ptr<ui::DropTargetEvent> event;
+ DragDropDelegate* delegate;
+ Translate(data_object, key_state, position, effect, &data, &event, &delegate);
+ if (delegate)
+ drag_operation = delegate->OnPerformDrop(*event);
+ if (target_window_) {
+ target_window_->RemoveObserver(this);
+ target_window_ = NULL;
+ }
+ return ui::DragDropTypes::DragOperationToDropEffect(drag_operation);
+}
+
+void DesktopDropTargetWin::OnWindowDestroyed(aura::Window* window) {
+ DCHECK(window == target_window_);
+ target_window_ = NULL;
+}
+
+void DesktopDropTargetWin::Translate(
+ IDataObject* data_object,
+ DWORD key_state,
+ POINT position,
+ DWORD effect,
+ scoped_ptr<OSExchangeData>* data,
+ scoped_ptr<ui::DropTargetEvent>* event,
+ DragDropDelegate** delegate) {
+ gfx::Point location(position.x, position.y);
+ gfx::Point root_location = location;
+ root_window_->ConvertPointFromNativeScreen(&root_location);
+ aura::Window* target_window =
+ root_window_->GetEventHandlerForPoint(root_location);
+ bool target_window_changed = false;
+ if (target_window != target_window_) {
+ if (target_window_)
+ NotifyDragLeave();
+ target_window_ = target_window;
+ if (target_window_)
+ target_window_->AddObserver(this);
+ target_window_changed = true;
+ }
+ *delegate = NULL;
+ if (!target_window_)
+ return;
+ *delegate = aura::client::GetDragDropDelegate(target_window_);
+ if (!*delegate)
+ return;
+
+ data->reset(new OSExchangeData(new OSExchangeDataProviderWin(data_object)));
+ location = root_location;
+ aura::Window::ConvertPointToTarget(root_window_, target_window_, &location);
+ event->reset(new ui::DropTargetEvent(
+ *(data->get()),
+ location,
+ root_location,
+ ui::DragDropTypes::DropEffectToDragOperation(effect)));
+ if (target_window_changed)
+ (*delegate)->OnDragEntered(*event->get());
+}
+
+void DesktopDropTargetWin::NotifyDragLeave() {
+ if (!target_window_)
+ return;
+ DragDropDelegate* delegate =
+ aura::client::GetDragDropDelegate(target_window_);
+ if (delegate)
+ delegate->OnDragExited();
+ target_window_->RemoveObserver(this);
+ target_window_ = NULL;
+}
+
+} // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_drop_target_win.h b/ui/views/widget/desktop_aura/desktop_drop_target_win.h
new file mode 100644
index 0000000..bdb22bb8
--- /dev/null
+++ b/ui/views/widget/desktop_aura/desktop_drop_target_win.h
@@ -0,0 +1,81 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTIOP_DROP_TARGET_WIN_H_
+#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTIOP_DROP_TARGET_WIN_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "ui/base/dragdrop/drop_target.h"
+#include "ui/aura/window_observer.h"
+
+namespace aura {
+class RootWindow;
+namespace client {
+class DragDropDelegate;
+}
+}
+
+namespace ui {
+class DropTargetEvent;
+class OSExchangeData;
+}
+
+namespace views {
+
+// DesktopDropTargetWin takes care of managing drag and drop for
+// DesktopRootWindowHostWin. It converts Windows OLE drop messages into
+// aura::client::DragDropDelegate calls.
+class DesktopDropTargetWin : public ui::DropTarget,
+ public aura::WindowObserver {
+ public:
+ DesktopDropTargetWin(aura::RootWindow* root_window, HWND window);
+ virtual ~DesktopDropTargetWin();
+
+ private:
+ // ui::DropTarget implementation:
+ virtual DWORD OnDragEnter(IDataObject* data_object,
+ DWORD key_state,
+ POINT position,
+ DWORD effect) OVERRIDE;
+ virtual DWORD OnDragOver(IDataObject* data_object,
+ DWORD key_state,
+ POINT position,
+ DWORD effect) OVERRIDE;
+ virtual void OnDragLeave(IDataObject* data_object) OVERRIDE;
+ virtual DWORD OnDrop(IDataObject* data_object,
+ DWORD key_state,
+ POINT position,
+ DWORD effect) OVERRIDE;
+
+ // aura::WindowObserver implementation:
+ virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
+
+ // Common functionality for the ui::DropTarget methods to translate from COM
+ // data types to Aura ones.
+ void Translate(IDataObject* data_object,
+ DWORD key_state,
+ POINT cursor_position,
+ DWORD effect,
+ scoped_ptr<ui::OSExchangeData>* data,
+ scoped_ptr<ui::DropTargetEvent>* event,
+ aura::client::DragDropDelegate** delegate);
+
+ void NotifyDragLeave();
+
+ // The root window associated with this drop target.
+ aura::RootWindow* root_window_;
+
+ // The Aura window that is currently under the cursor. We need to manually
+ // keep track of this because Windows will only call our drag enter method
+ // once when the user enters the associated HWND. But inside that HWND there
+ // could be multiple aura windows, so we need to generate drag enter events
+ // for them.
+ aura::Window* target_window_;
+
+ DISALLOW_COPY_AND_ASSIGN(DesktopDropTargetWin);
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTIOP_DROP_TARGET_WIN_H_
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index 0a11531..0ac38a7 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -17,10 +17,13 @@
#include "ui/native_theme/native_theme.h"
#include "ui/views/corewm/compound_event_filter.h"
#include "ui/views/corewm/input_method_event_filter.h"
+#include "ui/views/drag_utils.h"
#include "ui/views/ime/input_method.h"
#include "ui/views/ime/input_method_bridge.h"
#include "ui/views/widget/desktop_aura/desktop_root_window_host.h"
+#include "ui/views/widget/drop_helper.h"
#include "ui/views/widget/native_widget_aura_window_observer.h"
+#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_aura_utils.h"
@@ -133,6 +136,9 @@ void DesktopNativeWidgetAura::InitNativeWidget(
desktop_root_window_host_->Init(window_, params));
stacking_client_.reset(
new DesktopNativeWidgetAuraStackingClient(root_window_.get()));
+ drop_helper_.reset(new DropHelper(
+ static_cast<internal::RootView*>(GetWidget()->GetRootView())));
+ aura::client::SetDragDropDelegate(window_, this);
aura::client::SetActivationDelegate(window_, this);
}
@@ -394,11 +400,13 @@ bool DesktopNativeWidgetAura::IsAccessibleWidget() const {
return false;
}
-void DesktopNativeWidgetAura::RunShellDrag(View* view,
- const ui::OSExchangeData& data,
- const gfx::Point& location,
- int operation,
- ui::DragDropTypes::DragEventSource source) {
+void DesktopNativeWidgetAura::RunShellDrag(
+ View* view,
+ const ui::OSExchangeData& data,
+ const gfx::Point& location,
+ int operation,
+ ui::DragDropTypes::DragEventSource source) {
+ views::RunShellDrag(window_, data, location, operation, source);
}
void DesktopNativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) {
@@ -522,7 +530,7 @@ void DesktopNativeWidgetAura::OnWindowDestroyed() {
window_ = NULL;
native_widget_delegate_->OnNativeWidgetDestroyed();
if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
- delete this;
+ delete this;
}
void DesktopNativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) {
@@ -633,4 +641,31 @@ void DesktopNativeWidgetAura::DispatchKeyEventPostIME(const ui::KeyEvent& key) {
focus_manager->OnKeyEvent(key);
}
+////////////////////////////////////////////////////////////////////////////////
+// DesktopNativeWidgetAura, aura::WindowDragDropDelegate implementation:
+
+void DesktopNativeWidgetAura::OnDragEntered(const ui::DropTargetEvent& event) {
+ DCHECK(drop_helper_.get() != NULL);
+ last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
+ event.location(), event.source_operations());
+}
+
+int DesktopNativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent& event) {
+ DCHECK(drop_helper_.get() != NULL);
+ last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
+ event.location(), event.source_operations());
+ return last_drop_operation_;
+}
+
+void DesktopNativeWidgetAura::OnDragExited() {
+ DCHECK(drop_helper_.get() != NULL);
+ drop_helper_->OnDragExit();
+}
+
+int DesktopNativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent& event) {
+ DCHECK(drop_helper_.get() != NULL);
+ return drop_helper_->OnDrop(event.data(), event.location(),
+ last_drop_operation_);
+}
+
} // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
index 63977a5..cbf8f56 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -7,6 +7,7 @@
#include "base/memory/weak_ptr.h"
#include "ui/aura/client/activation_delegate.h"
+#include "ui/aura/client/drag_drop_delegate.h"
#include "ui/aura/window_delegate.h"
#include "ui/views/ime/input_method_delegate.h"
#include "ui/views/widget/native_widget_private.h"
@@ -26,6 +27,7 @@ class InputMethodEventFilter;
}
class DesktopRootWindowHost;
+class DropHelper;
class NativeWidgetAuraWindowObserver;
// TODO(erg): May also need to be a DragDropDelegate
@@ -33,7 +35,8 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
: public internal::NativeWidgetPrivate,
public aura::WindowDelegate,
public aura::client::ActivationDelegate,
- public views::internal::InputMethodDelegate {
+ public views::internal::InputMethodDelegate,
+ public aura::client::DragDropDelegate {
public:
explicit DesktopNativeWidgetAura(internal::NativeWidgetDelegate* delegate);
virtual ~DesktopNativeWidgetAura();
@@ -180,6 +183,12 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
// Overridden from views::internal::InputMethodDelegate:
virtual void DispatchKeyEventPostIME(const ui::KeyEvent& key) OVERRIDE;
+ // Overridden from aura::client::DragDropDelegate:
+ virtual void OnDragEntered(const ui::DropTargetEvent& event) OVERRIDE;
+ virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE;
+ virtual void OnDragExited() OVERRIDE;
+ virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE;
+
private:
// See class documentation for Widget in widget.h for a note about ownership.
Widget::InitParams::Ownership ownership_;
@@ -209,6 +218,9 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
scoped_ptr<corewm::InputMethodEventFilter> input_method_event_filter_;
+ scoped_ptr<DropHelper> drop_helper_;
+ int last_drop_operation_;
+
DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetAura);
};
diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc
index a5b785c..ca19df0 100644
--- a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc
@@ -26,8 +26,10 @@
#include "ui/views/widget/desktop_aura/desktop_activation_client.h"
#include "ui/views/widget/desktop_aura/desktop_cursor_client.h"
#include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
+#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#include "ui/views/widget/desktop_aura/desktop_screen_position_client.h"
+#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/widget/widget_hwnd_utils.h"
#include "ui/views/win/fullscreen_handler.h"
@@ -130,13 +132,16 @@ aura::RootWindow* DesktopRootWindowHostWin::Init(
cursor_client_.reset(new DesktopCursorClient(root_window_));
aura::client::SetCursorClient(root_window_, cursor_client_.get());
-
position_client_.reset(new DesktopScreenPositionClient());
aura::client::SetScreenPositionClient(root_window_,
position_client_.get());
desktop_native_widget_aura_->InstallInputMethodEventFilter(root_window_);
+ drag_drop_client_.reset(new DesktopDragDropClientWin(root_window_,
+ GetHWND()));
+ aura::client::SetDragDropClient(root_window_, drag_drop_client_.get());
+
focus_client_->FocusWindow(content_window_, NULL);
root_window_->SetProperty(kContentWindowForRootWindow, content_window_);
@@ -373,7 +378,9 @@ void DesktopRootWindowHostWin::SetBounds(const gfx::Rect& bounds) {
}
gfx::Point DesktopRootWindowHostWin::GetLocationOnNativeScreen() const {
- return gfx::Point(1, 1);
+ RECT r;
+ GetWindowRect(GetHWND(), &r);
+ return gfx::Point(r.left, r.top);
}
void DesktopRootWindowHostWin::SetCapture() {
@@ -588,11 +595,11 @@ void DesktopRootWindowHostWin::HandleCreate() {
// 1. Window property association
// 2. MouseWheel.
- // 3. Drop target.
- // 4. Tooltip Manager.
+ // 3. Tooltip Manager.
}
void DesktopRootWindowHostWin::HandleDestroying() {
+ drag_drop_client_->OnNativeWidgetDestroying(GetHWND());
native_widget_delegate_->OnNativeWidgetDestroying();
}
diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_win.h b/ui/views/widget/desktop_aura/desktop_root_window_host_win.h
index 8ff793c..8dd59ae 100644
--- a/ui/views/widget/desktop_aura/desktop_root_window_host_win.h
+++ b/ui/views/widget/desktop_aura/desktop_root_window_host_win.h
@@ -22,6 +22,7 @@ namespace views {
class DesktopActivationClient;
class DesktopCursorClient;
class DesktopDispatcherClient;
+class DesktopDragDropClientWin;
class HWNDMessageHandler;
class VIEWS_EXPORT DesktopRootWindowHostWin
@@ -224,6 +225,8 @@ class VIEWS_EXPORT DesktopRootWindowHostWin
// A simple cursor client which just forwards events to the RootWindow.
scoped_ptr<DesktopCursorClient> cursor_client_;
+ scoped_ptr<DesktopDragDropClientWin> drag_drop_client_;
+
DISALLOW_COPY_AND_ASSIGN(DesktopRootWindowHostWin);
};