summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/os_exchange_data_gtk.cc75
-rw-r--r--app/os_exchange_data_provider_gtk.cc99
-rw-r--r--app/os_exchange_data_provider_gtk.h10
-rw-r--r--views/controls/menu/menu_controller.cc18
-rw-r--r--views/controls/menu/menu_host_gtk.cc11
-rw-r--r--views/controls/menu/menu_host_gtk.h2
-rw-r--r--views/view.cc14
-rw-r--r--views/view_gtk.cc4
-rw-r--r--views/view_win.cc18
-rw-r--r--views/widget/root_view.h17
-rw-r--r--views/widget/root_view_gtk.cc16
-rw-r--r--views/widget/root_view_win.cc9
-rw-r--r--views/widget/widget_gtk.cc90
-rw-r--r--views/widget/widget_gtk.h30
14 files changed, 272 insertions, 141 deletions
diff --git a/app/os_exchange_data_gtk.cc b/app/os_exchange_data_gtk.cc
deleted file mode 100644
index b599470..0000000
--- a/app/os_exchange_data_gtk.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2009 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 "app/os_exchange_data.h"
-
-#include "base/logging.h"
-
-OSExchangeData::OSExchangeData() {
-}
-
-OSExchangeData::~OSExchangeData() {
-}
-
-void OSExchangeData::SetString(const std::wstring& data) {
- NOTIMPLEMENTED();
-}
-
-void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) {
- NOTIMPLEMENTED();
-}
-
-void OSExchangeData::SetFilename(const std::wstring& full_path) {
- NOTIMPLEMENTED();
-}
-
-void OSExchangeData::SetFileContents(const std::wstring& filename,
- const std::string& file_contents) {
- NOTIMPLEMENTED();
-}
-
-void OSExchangeData::SetHtml(const std::wstring& html, const GURL& base_url) {
- NOTIMPLEMENTED();
-}
-
-bool OSExchangeData::GetString(std::wstring* data) const {
- NOTIMPLEMENTED();
- return false;
-}
-
-bool OSExchangeData::GetURLAndTitle(GURL* url, std::wstring* title) const {
- NOTIMPLEMENTED();
- return false;
-}
-
-bool OSExchangeData::GetFilename(std::wstring* full_path) const {
- NOTIMPLEMENTED();
- return false;
-}
-
-bool OSExchangeData::GetFileContents(std::wstring* filename,
- std::string* file_contents) const {
- NOTIMPLEMENTED();
- return false;
-}
-
-bool OSExchangeData::GetHtml(std::wstring* html, GURL* base_url) const {
- NOTIMPLEMENTED();
- return false;
-}
-
-bool OSExchangeData::HasString() const {
- NOTIMPLEMENTED();
- return false;
-}
-
-bool OSExchangeData::HasURL() const {
- NOTIMPLEMENTED();
- return false;
-}
-
-bool OSExchangeData::HasFile() const {
- NOTIMPLEMENTED();
- return false;
-}
diff --git a/app/os_exchange_data_provider_gtk.cc b/app/os_exchange_data_provider_gtk.cc
index 5aaa414..f432c7c 100644
--- a/app/os_exchange_data_provider_gtk.cc
+++ b/app/os_exchange_data_provider_gtk.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "app/gtk_dnd_util.h"
#include "base/string_util.h"
OSExchangeDataProviderGtk::OSExchangeDataProviderGtk(
@@ -29,9 +30,99 @@ bool OSExchangeDataProviderGtk::HasDataForAllFormats(
const std::set<GdkAtom>& custom_formats) const {
if ((formats_ & formats) != formats)
return false;
- return std::includes(custom_formats_.begin(),
- custom_formats_.end(),
- custom_formats.begin(), custom_formats.end());
+ for (std::set<GdkAtom>::iterator i = custom_formats.begin();
+ i != custom_formats.end(); ++i) {
+ if (pickle_data_.find(*i) == pickle_data_.end())
+ return false;
+ }
+ return true;
+}
+
+GtkTargetList* OSExchangeDataProviderGtk::GetTargetList() const {
+ GtkTargetList* targets = gtk_target_list_new(NULL, 0);
+
+ if ((formats_ & OSExchangeData::STRING) != 0)
+ gtk_target_list_add_text_targets(targets, OSExchangeData::STRING);
+
+ if ((formats_ & OSExchangeData::URL) != 0) {
+ gtk_target_list_add_uri_targets(targets, OSExchangeData::URL);
+ gtk_target_list_add(
+ targets,
+ GtkDndUtil::GetAtomForTarget(GtkDndUtil::CHROME_NAMED_URL),
+ 0,
+ OSExchangeData::URL);
+ }
+
+ if ((formats_ & OSExchangeData::FILE_CONTENTS) != 0)
+ NOTIMPLEMENTED();
+
+ if ((formats_ & OSExchangeData::FILE_NAME) != 0)
+ NOTIMPLEMENTED();
+
+ if ((formats_ & OSExchangeData::HTML) != 0)
+ NOTIMPLEMENTED();
+
+
+ for (PickleData::const_iterator i = pickle_data_.begin();
+ i != pickle_data_.end(); ++i) {
+ gtk_target_list_add(targets, i->first, 0, OSExchangeData::PICKLED_DATA);
+ }
+
+ return targets;
+}
+
+void OSExchangeDataProviderGtk::WriteFormatToSelection(
+ int format,
+ GtkSelectionData* selection) const {
+ if ((format & OSExchangeData::STRING) != 0) {
+ gtk_selection_data_set_text(
+ selection,
+ reinterpret_cast<const gchar*>(string_.c_str()),
+ -1);
+ }
+
+ if ((format & OSExchangeData::URL) != 0) {
+ // TODO: this should be pulled out of TabContentsDragSource into a common
+ // place.
+ Pickle pickle;
+ pickle.WriteString(UTF16ToUTF8(title_));
+ pickle.WriteString(url_.spec());
+ gtk_selection_data_set(
+ selection,
+ GtkDndUtil::GetAtomForTarget(GtkDndUtil::CHROME_NAMED_URL),
+ 8,
+ reinterpret_cast<const guchar*>(pickle.data()),
+ pickle.size());
+
+ gchar* uri_array[2];
+ uri_array[0] = strdup(url_.spec().c_str());
+ uri_array[1] = NULL;
+ gtk_selection_data_set_uris(selection, uri_array);
+ free(uri_array[0]);
+ }
+
+ if ((format & OSExchangeData::FILE_CONTENTS) != 0)
+ NOTIMPLEMENTED();
+
+ if ((format & OSExchangeData::FILE_NAME) != 0)
+ NOTIMPLEMENTED();
+
+ if ((format & OSExchangeData::HTML) != 0)
+ NOTIMPLEMENTED();
+
+
+ if ((format & OSExchangeData::PICKLED_DATA) != 0) {
+ for (PickleData::const_iterator i = pickle_data_.begin();
+ i != pickle_data_.end(); ++i) {
+ const Pickle& data = i->second;
+ gtk_selection_data_set(
+ selection,
+ i->first,
+ 8,
+ reinterpret_cast<const guchar*>(data.data()),
+ data.size());
+ }
+ }
}
void OSExchangeDataProviderGtk::SetString(const std::wstring& data) {
@@ -154,7 +245,7 @@ bool OSExchangeDataProviderGtk::HasHtml() const {
bool OSExchangeDataProviderGtk::HasCustomFormat(GdkAtom format) const {
return known_custom_formats_.find(format) != known_custom_formats_.end() ||
- custom_formats_.find(format) != custom_formats_.end();
+ pickle_data_.find(format) != pickle_data_.end();
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/app/os_exchange_data_provider_gtk.h b/app/os_exchange_data_provider_gtk.h
index dd9c009..5974cde 100644
--- a/app/os_exchange_data_provider_gtk.h
+++ b/app/os_exchange_data_provider_gtk.h
@@ -44,6 +44,15 @@ class OSExchangeDataProviderGtk : public OSExchangeData::Provider {
bool HasDataForAllFormats(int formats,
const std::set<GdkAtom>& custom_formats) const;
+ // Returns the set of formats available as a GtkTargetList. It is up to the
+ // caller to free (gtk_target_list_unref) the returned list.
+ GtkTargetList* GetTargetList() const;
+
+ // Writes the data to |selection|. |format| is any combination of
+ // OSExchangeData::Formats.
+ void WriteFormatToSelection(int format,
+ GtkSelectionData* selection) const;
+
// Provider methods.
virtual void SetString(const std::wstring& data);
virtual void SetURL(const GURL& url, const std::wstring& title);
@@ -80,7 +89,6 @@ class OSExchangeDataProviderGtk : public OSExchangeData::Provider {
// Actual formats that have been set. See comment above |known_formats_|
// for details.
int formats_;
- std::set<GdkAtom> custom_formats_;
// String contents.
string16 string_;
diff --git a/views/controls/menu/menu_controller.cc b/views/controls/menu/menu_controller.cc
index 7f19592..8016868 100644
--- a/views/controls/menu/menu_controller.cc
+++ b/views/controls/menu/menu_controller.cc
@@ -13,13 +13,9 @@
#include "views/controls/menu/submenu_view.h"
#include "views/drag_utils.h"
#include "views/view_constants.h"
+#include "views/widget/root_view.h"
#include "views/widget/widget.h"
-#if defined(OS_WIN)
-#include "app/os_exchange_data_provider_win.h"
-#include "base/base_drag_source.h"
-#endif
-
using base::Time;
using base::TimeDelta;
@@ -406,18 +402,10 @@ void MenuController::OnMouseDragged(SubmenuView* source,
drag_utils::SetDragImageOnDataObject(canvas, item->width(),
item->height(), press_loc.x(),
press_loc.y(), &data);
-
StopScrolling();
-#if defined(OS_WIN)
int drag_ops = item->GetDelegate()->GetDragOperations(item);
- scoped_refptr<BaseDragSource> drag_source(new BaseDragSource);
- DWORD effects;
- DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source,
- DragDropTypes::DragOperationToDropEffect(drag_ops),
- &effects);
-#else
- NOTIMPLEMENTED();
-#endif
+ item->GetRootView()->StartDragForViewFromMouseEvent(
+ NULL, data, drag_ops);
if (GetActiveInstance() == this) {
if (showing_) {
// We're still showing, close all menus.
diff --git a/views/controls/menu/menu_host_gtk.cc b/views/controls/menu/menu_host_gtk.cc
index 9990aab..f79f3363b 100644
--- a/views/controls/menu/menu_host_gtk.cc
+++ b/views/controls/menu/menu_host_gtk.cc
@@ -101,17 +101,12 @@ RootView* MenuHost::CreateRootView() {
}
gboolean MenuHost::OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event) {
- if (!closed_)
- submenu_->GetMenuItem()->GetMenuController()->Cancel(true);
+ // Grab breaking only happens when drag and drop starts. So, we don't try
+ // and ungrab or cancel the menu.
+ did_pointer_grab_ = false;
return WidgetGtk::OnGrabBrokeEvent(widget, event);
}
-void MenuHost::OnGrabNotify(GtkWidget* widget, gboolean was_grabbed) {
- if (!closed_ && (widget != window_contents() || !was_grabbed))
- submenu_->GetMenuItem()->GetMenuController()->Cancel(true);
- WidgetGtk::OnGrabNotify(widget, was_grabbed);
-}
-
// Overriden to return false, we do NOT want to release capture on mouse
// release.
bool MenuHost::ReleaseCaptureOnMouseReleased() {
diff --git a/views/controls/menu/menu_host_gtk.h b/views/controls/menu/menu_host_gtk.h
index 6e70bc9..b3e1f75 100644
--- a/views/controls/menu/menu_host_gtk.h
+++ b/views/controls/menu/menu_host_gtk.h
@@ -30,9 +30,7 @@ class MenuHost : public WidgetGtk {
protected:
virtual RootView* CreateRootView();
- // If the grab breaks we cancel the menu.
virtual gboolean OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event);
- virtual void OnGrabNotify(GtkWidget* widget, gboolean was_grabbed);
// Overriden to return false, we do NOT want to release capture on mouse
// release.
diff --git a/views/view.cc b/views/view.cc
index 30a6e74..65e642e 100644
--- a/views/view.cc
+++ b/views/view.cc
@@ -554,6 +554,20 @@ void View::RemoveAllChildViews(bool delete_views) {
UpdateTooltip();
}
+void View::DoDrag(const MouseEvent& e, int press_x, int press_y) {
+ int drag_operations = GetDragOperations(press_x, press_y);
+ if (drag_operations == DragDropTypes::DRAG_NONE)
+ return;
+
+ OSExchangeData data;
+ WriteDragData(press_x, press_y, &data);
+
+ // Message the RootView to do the drag and drop. That way if we're removed
+ // the RootView can detect it and avoid calling us back.
+ RootView* root_view = GetRootView();
+ root_view->StartDragForViewFromMouseEvent(this, data, drag_operations);
+}
+
void View::DoRemoveChildView(View* a_view,
bool update_focus_cycle,
bool update_tool_tip,
diff --git a/views/view_gtk.cc b/views/view_gtk.cc
index 941908f..f04818d 100644
--- a/views/view_gtk.cc
+++ b/views/view_gtk.cc
@@ -10,10 +10,6 @@
namespace views {
-void View::DoDrag(const MouseEvent& e, int press_x, int press_y) {
- NOTIMPLEMENTED();
-}
-
ViewAccessibilityWrapper* View::GetViewAccessibilityWrapper() {
NOTIMPLEMENTED();
return NULL;
diff --git a/views/view_win.cc b/views/view_win.cc
index f0d71c4..c03e908 100644
--- a/views/view_win.cc
+++ b/views/view_win.cc
@@ -7,9 +7,6 @@
#include "app/drag_drop_types.h"
#include "app/gfx/canvas.h"
#include "app/gfx/path.h"
-#include "app/os_exchange_data.h"
-#include "app/os_exchange_data_provider_win.h"
-#include "base/scoped_handle.h"
#include "base/string_util.h"
#include "views/accessibility/view_accessibility_wrapper.h"
#include "views/border.h"
@@ -18,21 +15,6 @@
namespace views {
-void View::DoDrag(const MouseEvent& e, int press_x, int press_y) {
- int drag_operations = GetDragOperations(press_x, press_y);
- if (drag_operations == DragDropTypes::DRAG_NONE)
- return;
-
- OSExchangeData data;
- WriteDragData(press_x, press_y, &data);
-
- // Message the RootView to do the drag and drop. That way if we're removed
- // the RootView can detect it and avoid calling us back.
- RootView* root_view = GetRootView();
- root_view->StartDragForViewFromMouseEvent(
- this, OSExchangeDataProviderWin::GetIDataObject(data), drag_operations);
-}
-
ViewAccessibilityWrapper* View::GetViewAccessibilityWrapper() {
if (accessibility_.get() == NULL) {
accessibility_.reset(new ViewAccessibilityWrapper(this));
diff --git a/views/widget/root_view.h b/views/widget/root_view.h
index b3c43d8..25ca7a2 100644
--- a/views/widget/root_view.h
+++ b/views/widget/root_view.h
@@ -166,6 +166,14 @@ class RootView : public View,
void OnPaint(GdkEventExpose* event);
#endif
+ // Starts a drag operation for the specified view. This blocks until done.
+ // If the view has not been deleted during the drag, OnDragDone is invoked
+ // on the view.
+ // NOTE: |view| may be null.
+ void StartDragForViewFromMouseEvent(View* view,
+ const OSExchangeData& data,
+ int operation);
+
// Accessibility accessors/mutators, overridden from View.
virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
virtual bool GetAccessibleName(std::wstring* name);
@@ -242,15 +250,6 @@ class RootView : public View,
// Updates the last_mouse_* fields from e.
void SetMouseLocationAndFlags(const MouseEvent& e);
-#if defined(OS_WIN)
- // Starts a drag operation for the specified view. This blocks until done.
- // If the view has not been deleted during the drag, OnDragDone is invoked
- // on the view.
- void StartDragForViewFromMouseEvent(View* view,
- IDataObject* data,
- int operation);
-#endif
-
// If a view is dragging, this returns it. Otherwise returns NULL.
View* GetDragView();
diff --git a/views/widget/root_view_gtk.cc b/views/widget/root_view_gtk.cc
index 6984429..290203f 100644
--- a/views/widget/root_view_gtk.cc
+++ b/views/widget/root_view_gtk.cc
@@ -36,4 +36,20 @@ void RootView::OnPaint(GdkEventExpose* event) {
}
}
+void RootView::StartDragForViewFromMouseEvent(
+ View* view,
+ const OSExchangeData& data,
+ int operation) {
+ // NOTE: view may be null.
+ drag_view_ = view;
+ static_cast<WidgetGtk*>(GetWidget())->DoDrag(data, operation);
+ // If the view is removed during the drag operation, drag_view_ is set to
+ // NULL.
+ if (view && drag_view_ == view) {
+ View* drag_view = drag_view_;
+ drag_view_ = NULL;
+ drag_view->OnDragDone();
+ }
+}
+
}
diff --git a/views/widget/root_view_win.cc b/views/widget/root_view_win.cc
index fedb40d..65aa1b7 100644
--- a/views/widget/root_view_win.cc
+++ b/views/widget/root_view_win.cc
@@ -6,6 +6,8 @@
#include "app/drag_drop_types.h"
#include "app/gfx/canvas_paint.h"
+#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "base/base_drag_source.h"
#include "base/logging.h"
@@ -33,16 +35,17 @@ void RootView::OnPaint(HWND hwnd) {
void RootView::StartDragForViewFromMouseEvent(
View* view,
- IDataObject* data,
+ const OSExchangeData& data,
int operation) {
+ // NOTE: view may be null.
drag_view_ = view;
scoped_refptr<BaseDragSource> drag_source(new BaseDragSource);
DWORD effects;
- DoDragDrop(data, drag_source,
+ DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source,
DragDropTypes::DragOperationToDropEffect(operation), &effects);
// If the view is removed during the drag operation, drag_view_ is set to
// NULL.
- if (drag_view_ == view) {
+ if (view && drag_view_ == view) {
View* drag_view = drag_view_;
drag_view_ = NULL;
drag_view->OnDragDone();
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index a2044221..91b7e5c 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -4,8 +4,12 @@
#include "views/widget/widget_gtk.h"
+#include "app/drag_drop_types.h"
#include "app/gfx/path.h"
+#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_gtk.h"
#include "base/compiler_specific.h"
+#include "base/message_loop.h"
#include "views/widget/default_theme_provider.h"
#include "views/widget/drop_target_gtk.h"
#include "views/widget/root_view.h"
@@ -102,7 +106,8 @@ WidgetGtk::WidgetGtk(Type type)
delete_on_destroy_(true),
transparent_(false),
ignore_drag_leave_(false),
- opacity_(255) {
+ opacity_(255),
+ drag_data_(NULL) {
static bool installed_message_loop_observer = false;
if (!installed_message_loop_observer) {
installed_message_loop_observer = true;
@@ -163,6 +168,27 @@ void WidgetGtk::PositionChild(GtkWidget* child, int x, int y, int w, int h) {
gtk_fixed_move(GTK_FIXED(window_contents_), child, x, y);
}
+void WidgetGtk::DoDrag(const OSExchangeData& data, int operation) {
+ const OSExchangeDataProviderGtk& data_provider =
+ static_cast<const OSExchangeDataProviderGtk&>(data.provider());
+ GtkTargetList* targets = data_provider.GetTargetList();
+ GdkEvent* current_event = gtk_get_current_event();
+ DCHECK(current_event);
+ gtk_drag_begin(window_contents_, targets,
+ static_cast<GdkDragAction>(
+ DragDropTypes::DragOperationToGdkDragAction(operation)),
+ 1, current_event);
+ gdk_event_free(current_event);
+ gtk_target_list_unref(targets);
+
+ drag_data_ = &data_provider;
+
+ // Block the caller until drag is done by running a nested message loop.
+ MessageLoopForUI::current()->Run(NULL);
+
+ drag_data_ = NULL;
+}
+
////////////////////////////////////////////////////////////////////////////////
// WidgetGtk, Widget implementation:
@@ -256,6 +282,12 @@ void WidgetGtk::Init(GtkWidget* parent,
G_CALLBACK(CallDragDrop), this);
g_signal_connect(G_OBJECT(window_contents_), "drag_leave",
G_CALLBACK(CallDragLeave), this);
+ g_signal_connect(G_OBJECT(window_contents_), "drag_data_get",
+ G_CALLBACK(CallDragDataGet), this);
+ g_signal_connect(G_OBJECT(window_contents_), "drag_end",
+ G_CALLBACK(CallDragEnd), this);
+ g_signal_connect(G_OBJECT(window_contents_), "drag_failed",
+ G_CALLBACK(CallDragFailed), this);
tooltip_manager_.reset(new TooltipManagerGtk(this));
@@ -546,6 +578,17 @@ void WidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) {
root_view_->OnPaint(event);
}
+void WidgetGtk::OnDragDataGet(GdkDragContext* context,
+ GtkSelectionData* data,
+ guint info,
+ guint time) {
+ if (!drag_data_) {
+ NOTREACHED();
+ return;
+ }
+ drag_data_->WriteFormatToSelection(info, data);
+}
+
void WidgetGtk::OnDragDataReceived(GdkDragContext* context,
gint x,
gint y,
@@ -566,6 +609,22 @@ gboolean WidgetGtk::OnDragDrop(GdkDragContext* context,
return FALSE;
}
+void WidgetGtk::OnDragEnd(GdkDragContext* context) {
+ if (!drag_data_) {
+ // This indicates we didn't start a drag operation, and should never
+ // happen.
+ NOTREACHED();
+ return;
+ }
+ // Quit the nested message loop we spawned in DoDrag.
+ MessageLoop::current()->Quit();
+}
+
+gboolean WidgetGtk::OnDragFailed(GdkDragContext* context,
+ GtkDragResult result) {
+ return FALSE;
+}
+
void WidgetGtk::OnDragLeave(GdkDragContext* context,
guint time) {
if (ignore_drag_leave_) {
@@ -705,7 +764,9 @@ void WidgetGtk::ProcessMouseReleased(GdkEventButton* event) {
if (has_capture_ && ReleaseCaptureOnMouseReleased())
ReleaseGrab();
is_mouse_down_ = false;
- root_view_->OnMouseReleased(mouse_up, false);
+ // GTK generates a mouse release at the end of dnd. We need to ignore it.
+ if (!drag_data_)
+ root_view_->OnMouseReleased(mouse_up, false);
}
// static
@@ -761,6 +822,16 @@ gboolean WidgetGtk::CallWindowPaint(GtkWidget* widget,
}
// static
+void WidgetGtk::CallDragDataGet(GtkWidget* widget,
+ GdkDragContext* context,
+ GtkSelectionData* data,
+ guint info,
+ guint time,
+ WidgetGtk* host) {
+ host->OnDragDataGet(context, data, info, time);
+}
+
+// static
void WidgetGtk::CallDragDataReceived(GtkWidget* widget,
GdkDragContext* context,
gint x,
@@ -783,6 +854,21 @@ gboolean WidgetGtk::CallDragDrop(GtkWidget* widget,
}
// static
+void WidgetGtk::CallDragEnd(GtkWidget* widget,
+ GdkDragContext* context,
+ WidgetGtk* host) {
+ host->OnDragEnd(context);
+}
+
+// static
+gboolean WidgetGtk::CallDragFailed(GtkWidget* widget,
+ GdkDragContext* context,
+ GtkDragResult result,
+ WidgetGtk* host) {
+ return host->OnDragFailed(context, result);
+}
+
+// static
void WidgetGtk::CallDragLeave(GtkWidget* widget,
GdkDragContext* context,
guint time,
diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h
index 7de1492..a7e905e 100644
--- a/views/widget/widget_gtk.h
+++ b/views/widget/widget_gtk.h
@@ -10,6 +10,9 @@
#include "base/message_loop.h"
#include "views/widget/widget.h"
+class OSExchangeData;
+class OSExchangeDataProviderGtk;
+
namespace gfx {
class Rect;
}
@@ -72,6 +75,9 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer {
// |widget_|.
GtkWidget* window_contents() const { return window_contents_; }
+ // Starts a drag on this widget. This blocks until the drag is done.
+ void DoDrag(const OSExchangeData& data, int operation);
+
// Overridden from Widget:
virtual void Init(gfx::NativeView parent, const gfx::Rect& bounds);
virtual void SetContentsView(View* view);
@@ -114,6 +120,10 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer {
protected:
virtual void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation);
virtual void OnPaint(GtkWidget* widget, GdkEventExpose* event);
+ virtual void OnDragDataGet(GdkDragContext* context,
+ GtkSelectionData* data,
+ guint info,
+ guint time);
virtual void OnDragDataReceived(GdkDragContext* context,
gint x,
gint y,
@@ -124,6 +134,9 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer {
gint x,
gint y,
guint time);
+ virtual void OnDragEnd(GdkDragContext* context);
+ virtual gboolean OnDragFailed(GdkDragContext* context,
+ GtkDragResult result);
virtual void OnDragLeave(GdkDragContext* context,
guint time);
virtual gboolean OnDragMotion(GdkDragContext* context,
@@ -201,6 +214,12 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer {
static gboolean CallWindowPaint(GtkWidget* widget,
GdkEventExpose* event,
WidgetGtk* widget_gtk);
+ static void CallDragDataGet(GtkWidget* widget,
+ GdkDragContext* context,
+ GtkSelectionData* data,
+ guint info,
+ guint time,
+ WidgetGtk* host);
static void CallDragDataReceived(GtkWidget* widget,
GdkDragContext* context,
gint x,
@@ -215,6 +234,13 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer {
gint y,
guint time,
WidgetGtk* host);
+ static void CallDragEnd(GtkWidget* widget,
+ GdkDragContext* context,
+ WidgetGtk* host);
+ static gboolean CallDragFailed(GtkWidget* widget,
+ GdkDragContext* context,
+ GtkDragResult result,
+ WidgetGtk* host);
static void CallDragLeave(GtkWidget* widget,
GdkDragContext* context,
guint time,
@@ -319,6 +345,10 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer {
unsigned char opacity_;
+ // This is non-null during the life of DoDrag and contains the actual data
+ // for the drag.
+ const OSExchangeDataProviderGtk* drag_data_;
+
DISALLOW_COPY_AND_ASSIGN(WidgetGtk);
};