| Index: chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.cc
|
| diff --git a/chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.cc b/chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.cc
|
| index 5084ddbd5014464c6c8dfb82e1500e9c406ae98f..7fd5c80761d08aef223a16dfbd557709befa5b6d 100644
|
| --- a/chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.cc
|
| +++ b/chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.cc
|
| @@ -4,14 +4,123 @@
|
|
|
| #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.h"
|
|
|
| +#include "base/event_types.h"
|
| +#include "base/message_loop.h"
|
| #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_delegate.h"
|
| +#include "content/browser/renderer_host/render_view_host.h"
|
| #include "content/browser/renderer_host/render_widget_host_view_aura.h"
|
| #include "content/browser/tab_contents/tab_contents.h"
|
| #include "content/browser/tab_contents/tab_contents_view.h"
|
| +#include "ui/aura/client/aura_constants.h"
|
| +#include "ui/aura/client/drag_drop_client.h"
|
| +#include "ui/aura/desktop.h"
|
| #include "ui/aura/event.h"
|
| #include "ui/aura/window.h"
|
| +#include "ui/base/dragdrop/drag_drop_types.h"
|
| +#include "ui/base/dragdrop/os_exchange_data.h"
|
| +#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
|
| #include "ui/views/widget/widget.h"
|
| #include "views/views_delegate.h"
|
| +#include "webkit/glue/webdropdata.h"
|
| +
|
| +namespace {
|
| +
|
| +// Listens to all mouse drag events during a drag and drop and sends them to
|
| +// the renderer.
|
| +class WebDragSourceAura : public MessageLoopForUI::Observer {
|
| + public:
|
| + explicit WebDragSourceAura(NativeTabContentsViewAura* view)
|
| + : view_(view) {
|
| + MessageLoopForUI::current()->AddObserver(this);
|
| + }
|
| +
|
| + virtual ~WebDragSourceAura() {
|
| + MessageLoopForUI::current()->RemoveObserver(this);
|
| + }
|
| +
|
| + // MessageLoop::Observer implementation:
|
| + virtual base::EventStatus WillProcessEvent(
|
| + const base::NativeEvent& event) OVERRIDE {
|
| + return base::EVENT_CONTINUE;
|
| + }
|
| + virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE {
|
| + ui::EventType type = ui::EventTypeFromNative(event);
|
| + RenderViewHost* rvh = NULL;
|
| + switch (type) {
|
| + case ui::ET_MOUSE_DRAGGED:
|
| + rvh = view_->GetTabContents()->render_view_host();
|
| + if (rvh) {
|
| + gfx::Point screen_loc = ui::EventLocationFromNative(event);
|
| + gfx::Point client_loc = screen_loc;
|
| + aura::Window* window = rvh->view()->GetNativeView();
|
| + aura::Window::ConvertPointToWindow(aura::Desktop::GetInstance(),
|
| + window, &client_loc);
|
| + rvh->DragSourceMovedTo(client_loc.x(), client_loc.y(),
|
| + screen_loc.x(), screen_loc.y());
|
| + }
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + }
|
| +
|
| + private:
|
| + NativeTabContentsViewAura* view_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura);
|
| +};
|
| +
|
| +// Utility to fill a ui::OSExchangeDataProviderAura object from WebDropData.
|
| +void PrepareDragData(const WebDropData& drop_data,
|
| + ui::OSExchangeDataProviderAura* provider) {
|
| + if (!drop_data.plain_text.empty())
|
| + provider->SetString(drop_data.plain_text);
|
| + if (drop_data.url.is_valid())
|
| + provider->SetURL(drop_data.url, drop_data.url_title);
|
| + // TODO(varunjain): support other formats.
|
| +}
|
| +
|
| +// Utility to fill a WebDropData object from ui::OSExchangeData.
|
| +void PrepareWebDropData(WebDropData* drop_data,
|
| + const ui::OSExchangeData& data) {
|
| + string16 plain_text, url_title;
|
| + GURL url;
|
| + data.GetString(&plain_text);
|
| + if (!plain_text.empty())
|
| + drop_data->plain_text = plain_text;
|
| + data.GetURLAndTitle(&url, &url_title);
|
| + if (url.is_valid()) {
|
| + drop_data->url = url;
|
| + drop_data->url_title = url_title;
|
| + }
|
| + // TODO(varunjain): support other formats.
|
| +}
|
| +
|
| +// Utilities to convert between WebKit::WebDragOperationsMask and
|
| +// ui::DragDropTypes.
|
| +int ConvertFromWeb(WebKit::WebDragOperationsMask ops) {
|
| + int drag_op = ui::DragDropTypes::DRAG_NONE;
|
| + if (ops & WebKit::WebDragOperationCopy)
|
| + drag_op |= ui::DragDropTypes::DRAG_COPY;
|
| + if (ops & WebKit::WebDragOperationMove)
|
| + drag_op |= ui::DragDropTypes::DRAG_MOVE;
|
| + if (ops & WebKit::WebDragOperationLink)
|
| + drag_op |= ui::DragDropTypes::DRAG_LINK;
|
| + return drag_op;
|
| +}
|
| +
|
| +WebKit::WebDragOperationsMask ConvertToWeb(int drag_op) {
|
| + int web_drag_op = WebKit::WebDragOperationNone;
|
| + if (drag_op & ui::DragDropTypes::DRAG_COPY)
|
| + web_drag_op |= WebKit::WebDragOperationCopy;
|
| + if (drag_op & ui::DragDropTypes::DRAG_MOVE)
|
| + web_drag_op |= WebKit::WebDragOperationMove;
|
| + if (drag_op & ui::DragDropTypes::DRAG_LINK)
|
| + web_drag_op |= WebKit::WebDragOperationLink;
|
| + return (WebKit::WebDragOperationsMask) web_drag_op;
|
| +}
|
| +
|
| +} // namespace
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // NativeTabContentsViewAura, public:
|
| @@ -19,7 +128,8 @@
|
| NativeTabContentsViewAura::NativeTabContentsViewAura(
|
| internal::NativeTabContentsViewDelegate* delegate)
|
| : views::NativeWidgetAura(delegate->AsNativeWidgetDelegate()),
|
| - delegate_(delegate) {
|
| + delegate_(delegate),
|
| + current_drag_op_(WebKit::WebDragOperationNone) {
|
| }
|
|
|
| NativeTabContentsViewAura::~NativeTabContentsViewAura() {
|
| @@ -29,12 +139,6 @@ TabContents* NativeTabContentsViewAura::GetTabContents() const {
|
| return delegate_->GetTabContents();
|
| }
|
|
|
| -void NativeTabContentsViewAura::EndDragging() {
|
| - delegate_->OnNativeTabContentsViewDraggingEnded();
|
| - // TODO(beng):
|
| - NOTIMPLEMENTED();
|
| -}
|
| -
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // NativeTabContentsViewAura, NativeTabContentsView implementation:
|
|
|
| @@ -67,6 +171,12 @@ RenderWidgetHostView* NativeTabContentsViewAura::CreateRenderWidgetHostView(
|
| view->InitAsChild();
|
| GetNativeView()->AddChild(view->GetNativeView());
|
| view->Show();
|
| +
|
| + // We listen to drag drop events in the newly created view's window.
|
| + aura::Window* window = static_cast<aura::Window*>(view->GetNativeView());
|
| + DCHECK(window);
|
| + window->SetProperty(aura::kDragDropDelegateKey,
|
| + static_cast<aura::WindowDragDropDelegate*>(this));
|
| return view;
|
| }
|
|
|
| @@ -84,25 +194,51 @@ void NativeTabContentsViewAura::StartDragging(const WebDropData& drop_data,
|
| WebKit::WebDragOperationsMask ops,
|
| const SkBitmap& image,
|
| const gfx::Point& image_offset) {
|
| - // TODO(beng):
|
| - NOTIMPLEMENTED();
|
| + aura::DragDropClient* client = static_cast<aura::DragDropClient*>(
|
| + aura::Desktop::GetInstance()->GetProperty(
|
| + aura::kDesktopDragDropClientKey));
|
| + if (!client)
|
| + return;
|
| +
|
| + ui::OSExchangeDataProviderAura* provider = new ui::OSExchangeDataProviderAura;
|
| + PrepareDragData(drop_data, provider);
|
| + if (!image.isNull())
|
| + provider->set_drag_image(image);
|
| + ui::OSExchangeData data(provider); // takes ownership of |provider|.
|
| +
|
| + scoped_ptr<WebDragSourceAura> drag_source(new WebDragSourceAura(this));
|
| +
|
| + // We need to enable recursive tasks on the message loop so we can get
|
| + // updates while in the system DoDragDrop loop.
|
| + bool old_state = MessageLoop::current()->NestableTasksAllowed();
|
| + MessageLoop::current()->SetNestableTasksAllowed(true);
|
| + int result_op = client->StartDragAndDrop(data, ConvertFromWeb(ops));
|
| + MessageLoop::current()->SetNestableTasksAllowed(old_state);
|
| +
|
| + EndDrag(ConvertToWeb(result_op));
|
| + GetTabContents()->render_view_host()->DragSourceSystemDragEnded();
|
| }
|
|
|
| void NativeTabContentsViewAura::CancelDrag() {
|
| - // TODO(beng):
|
| - NOTIMPLEMENTED();
|
| + aura::DragDropClient* client = static_cast<aura::DragDropClient*>(
|
| + aura::Desktop::GetInstance()->GetProperty(
|
| + aura::kDesktopDragDropClientKey));
|
| + if (client)
|
| + client->DragCancel();
|
| }
|
|
|
| bool NativeTabContentsViewAura::IsDoingDrag() const {
|
| - // TODO(beng):
|
| - NOTIMPLEMENTED();
|
| + aura::DragDropClient* client = static_cast<aura::DragDropClient*>(
|
| + aura::Desktop::GetInstance()->GetProperty(
|
| + aura::kDesktopDragDropClientKey));
|
| + if (client)
|
| + return client->IsDragDropInProgress();
|
| return false;
|
| }
|
|
|
| void NativeTabContentsViewAura::SetDragCursor(
|
| WebKit::WebDragOperation operation) {
|
| - // TODO(beng):
|
| - NOTIMPLEMENTED();
|
| + current_drag_op_ = operation;
|
| }
|
|
|
| views::NativeWidget* NativeTabContentsViewAura::AsNativeWidget() {
|
| @@ -136,6 +272,51 @@ bool NativeTabContentsViewAura::OnMouseEvent(aura::MouseEvent* event) {
|
| return views::NativeWidgetAura::OnMouseEvent(event);
|
| }
|
|
|
| +void NativeTabContentsViewAura::OnDragEntered(
|
| + const aura::DropTargetEvent& event) {
|
| + WebDropData drop_data;
|
| + PrepareWebDropData(&drop_data, event.data());
|
| + WebKit::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
|
| +
|
| + gfx::Point screen_pt = aura::Desktop::GetInstance()->last_mouse_location();
|
| + GetTabContents()->render_view_host()->DragTargetDragEnter(
|
| + drop_data, event.location(), screen_pt, op);
|
| +}
|
| +
|
| +int NativeTabContentsViewAura::OnDragUpdated(
|
| + const aura::DropTargetEvent& event) {
|
| + WebKit::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
|
| + gfx::Point screen_pt = aura::Desktop::GetInstance()->last_mouse_location();
|
| + GetTabContents()->render_view_host()->DragTargetDragOver(
|
| + event.location(), screen_pt, op);
|
| + return ConvertFromWeb(current_drag_op_);
|
| +}
|
| +
|
| +void NativeTabContentsViewAura::OnDragExited() {
|
| + GetTabContents()->render_view_host()->DragTargetDragLeave();
|
| +}
|
| +
|
| +int NativeTabContentsViewAura::OnPerformDrop(
|
| + const aura::DropTargetEvent& event) {
|
| + GetTabContents()->render_view_host()->DragTargetDrop(
|
| + event.location(), aura::Desktop::GetInstance()->last_mouse_location());
|
| + return current_drag_op_;
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// NativeTabContentsViewAura, private:
|
| +
|
| +void NativeTabContentsViewAura::EndDrag(WebKit::WebDragOperationsMask ops) {
|
| + gfx::Point screen_loc = aura::Desktop::GetInstance()->last_mouse_location();
|
| + gfx::Point client_loc = screen_loc;
|
| + RenderViewHost* rvh = GetTabContents()->render_view_host();
|
| + aura::Window* window = rvh->view()->GetNativeView();
|
| + aura::Window::ConvertPointToWindow(aura::Desktop::GetInstance(),
|
| + window, &client_loc);
|
| + rvh->DragSourceEndedAt(client_loc.x(), client_loc.y(), screen_loc.x(),
|
| + screen_loc.y(), ops);
|
| +}
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // NativeTabContentsView, public:
|
|
|
|
|