diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-08 18:39:52 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-08 18:39:52 +0000 |
commit | d02a21b84b9829a46e22466ebcd64da93c9479de (patch) | |
tree | 31974a653f6a0e5e90c3ec3bf066a6c9e5d17204 | |
parent | 9d05f7f84520083b1ac0afb85733ba5d32e89f50 (diff) | |
download | chromium_src-d02a21b84b9829a46e22466ebcd64da93c9479de.zip chromium_src-d02a21b84b9829a46e22466ebcd64da93c9479de.tar.gz chromium_src-d02a21b84b9829a46e22466ebcd64da93c9479de.tar.bz2 |
GTK: slightly change how we display drag images.
We use a popup window for the drag because in many window managers it looks better.
Ideally we would implement the alpha-channel fading that some other WebKit ports use, but gtk_drag_set_icon_* don't seem to support transparency (dragged tabs can be transparent because they use a different approach that avoids this problem, but is more complicated in other ways).
BUG=none
TEST=manual
Review URL: http://codereview.chromium.org/1519019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43976 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/tab_contents_drag_source.cc | 34 | ||||
-rw-r--r-- | chrome/browser/gtk/tab_contents_drag_source.h | 44 |
2 files changed, 38 insertions, 40 deletions
diff --git a/chrome/browser/gtk/tab_contents_drag_source.cc b/chrome/browser/gtk/tab_contents_drag_source.cc index fc5ffd5..8e285d1 100644 --- a/chrome/browser/gtk/tab_contents_drag_source.cc +++ b/chrome/browser/gtk/tab_contents_drag_source.cc @@ -31,7 +31,8 @@ TabContentsDragSource::TabContentsDragSource( TabContentsView* tab_contents_view) : tab_contents_view_(tab_contents_view), drag_failed_(false), - drag_widget_(NULL) { + drag_widget_(NULL), + drag_icon_(NULL) { drag_widget_ = gtk_invisible_new(); g_signal_connect(drag_widget_, "drag-failed", G_CALLBACK(OnDragFailedThunk), this); @@ -162,7 +163,7 @@ void TabContentsDragSource::DidProcessEvent(GdkEvent* event) { } } -void TabContentsDragSource::OnDragDataGet( +void TabContentsDragSource::OnDragDataGet(GtkWidget* sender, GdkDragContext* context, GtkSelectionData* selection_data, guint target_type, guint time) { const int kBitsPerByte = 8; @@ -268,7 +269,9 @@ void TabContentsDragSource::OnDragDataGet( } } -gboolean TabContentsDragSource::OnDragFailed() { +gboolean TabContentsDragSource::OnDragFailed(GtkWidget* sender, + GdkDragContext* context, + GtkDragResult result) { drag_failed_ = true; gfx::Point root = gtk_util::ScreenPoint(GetContentNativeView()); @@ -284,7 +287,8 @@ gboolean TabContentsDragSource::OnDragFailed() { return FALSE; } -void TabContentsDragSource::OnDragBegin(GdkDragContext* drag_context) { +void TabContentsDragSource::OnDragBegin(GtkWidget* sender, + GdkDragContext* drag_context) { if (!download_url_.is_empty()) { // Generate the file name based on both mime type and proposed file name. std::string download_mime_type = UTF16ToUTF8(wide_download_mime_type_); @@ -313,15 +317,25 @@ void TabContentsDragSource::OnDragBegin(GdkDragContext* drag_context) { if (!drag_image_.isNull()) { GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&drag_image_); - gtk_drag_set_icon_pixbuf(drag_context, pixbuf, - image_offset_.x(), image_offset_.y()); - // Let the drag take ownership. + GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); + gtk_widget_show(image); g_object_unref(pixbuf); + drag_icon_ = gtk_window_new(GTK_WINDOW_POPUP); + g_object_ref_sink(drag_icon_); + gtk_container_add(GTK_CONTAINER(drag_icon_), image); + + gtk_drag_set_icon_widget(drag_context, drag_icon_, + image_offset_.x(), image_offset_.y()); } } -void TabContentsDragSource::OnDragEnd(GdkDragContext* drag_context, - GdkDragAction action) { +void TabContentsDragSource::OnDragEnd(GtkWidget* sender, + GdkDragContext* drag_context) { + if (drag_icon_) { + g_object_unref(drag_icon_); + drag_icon_ = NULL; + } + MessageLoopForUI::current()->RemoveObserver(this); if (!download_url_.is_empty()) { @@ -337,7 +351,7 @@ void TabContentsDragSource::OnDragEnd(GdkDragContext* drag_context, if (tab_contents()->render_view_host()) { tab_contents()->render_view_host()->DragSourceEndedAt( client.x(), client.y(), root.x(), root.y(), - gtk_dnd_util::GdkDragActionToWebDragOp(action)); + gtk_dnd_util::GdkDragActionToWebDragOp(drag_context->action)); } } diff --git a/chrome/browser/gtk/tab_contents_drag_source.h b/chrome/browser/gtk/tab_contents_drag_source.h index 423f895..fbfaeee 100644 --- a/chrome/browser/gtk/tab_contents_drag_source.h +++ b/chrome/browser/gtk/tab_contents_drag_source.h @@ -7,6 +7,7 @@ #include <gtk/gtk.h> +#include "app/gtk_signal.h" #include "base/basictypes.h" #include "base/file_path.h" #include "base/message_loop.h" @@ -43,36 +44,14 @@ class TabContentsDragSource : public MessageLoopForUI::Observer { virtual void DidProcessEvent(GdkEvent* event); private: - static gboolean OnDragFailedThunk(GtkWidget* widget, - GdkDragContext* drag_context, - GtkDragResult result, - TabContentsDragSource* handler) { - return handler->OnDragFailed(); - } - gboolean OnDragFailed(); - static void OnDragBeginThunk(GtkWidget* widget, - GdkDragContext* drag_context, - TabContentsDragSource* handler) { - handler->OnDragBegin(drag_context); - } - void OnDragBegin(GdkDragContext* drag_context); - static void OnDragEndThunk(GtkWidget* widget, - GdkDragContext* drag_context, - TabContentsDragSource* handler) { - handler->OnDragEnd(drag_context, drag_context->action); - } - void OnDragEnd(GdkDragContext* drag_context, - GdkDragAction operation); - static void OnDragDataGetThunk(GtkWidget* drag_widget, - GdkDragContext* context, - GtkSelectionData* selection_data, - guint target_type, - guint time, - TabContentsDragSource* handler) { - handler->OnDragDataGet(context, selection_data, target_type, time); - } - void OnDragDataGet(GdkDragContext* context, GtkSelectionData* selection_data, - guint target_type, guint time); + CHROMEGTK_CALLBACK_2(TabContentsDragSource, gboolean, OnDragFailed, + GdkDragContext*, GtkDragResult); + CHROMEGTK_CALLBACK_1(TabContentsDragSource, void, OnDragBegin, + GdkDragContext*); + CHROMEGTK_CALLBACK_1(TabContentsDragSource, void, OnDragEnd, + GdkDragContext*); + CHROMEGTK_CALLBACK_4(TabContentsDragSource, void, OnDragDataGet, + GdkDragContext*, GtkSelectionData*, guint, guint); gfx::NativeView GetContentNativeView() const; @@ -109,6 +88,11 @@ class TabContentsDragSource : public MessageLoopForUI::Observer { // The URL to download from for a drag-out download. GURL download_url_; + // The widget that provides visual feedback for the drag. We use this instead + // of gtk_drag_set_icon_pixbuf() because some window managers will use shadows + // or other visual effects on top level windows. + GtkWidget* drag_icon_; + DISALLOW_COPY_AND_ASSIGN(TabContentsDragSource); }; |