diff options
-rw-r--r-- | app/os_exchange_data_gtk.cc | 75 | ||||
-rw-r--r-- | app/os_exchange_data_provider_gtk.cc | 99 | ||||
-rw-r--r-- | app/os_exchange_data_provider_gtk.h | 10 | ||||
-rw-r--r-- | views/controls/menu/menu_controller.cc | 18 | ||||
-rw-r--r-- | views/controls/menu/menu_host_gtk.cc | 11 | ||||
-rw-r--r-- | views/controls/menu/menu_host_gtk.h | 2 | ||||
-rw-r--r-- | views/view.cc | 14 | ||||
-rw-r--r-- | views/view_gtk.cc | 4 | ||||
-rw-r--r-- | views/view_win.cc | 18 | ||||
-rw-r--r-- | views/widget/root_view.h | 17 | ||||
-rw-r--r-- | views/widget/root_view_gtk.cc | 16 | ||||
-rw-r--r-- | views/widget/root_view_win.cc | 9 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 90 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 30 |
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); }; |