summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-08 18:39:52 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-08 18:39:52 +0000
commitd02a21b84b9829a46e22466ebcd64da93c9479de (patch)
tree31974a653f6a0e5e90c3ec3bf066a6c9e5d17204
parent9d05f7f84520083b1ac0afb85733ba5d32e89f50 (diff)
downloadchromium_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.cc34
-rw-r--r--chrome/browser/gtk/tab_contents_drag_source.h44
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);
};