summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-29 23:36:13 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-29 23:36:13 +0000
commitbe61b42e45eb49e26789aaa4bb74763a61b26593 (patch)
treeec1f5847261b531913ecb7a4b3c8920d81a88d0d /chrome
parent00c2ecbccaf81b313c9f2a74354012452db65642 (diff)
downloadchromium_src-be61b42e45eb49e26789aaa4bb74763a61b26593.zip
chromium_src-be61b42e45eb49e26789aaa4bb74763a61b26593.tar.gz
chromium_src-be61b42e45eb49e26789aaa4bb74763a61b26593.tar.bz2
More web contents dragging.
TEST=drag an image (such as the google logo from google.com) into gimp or onto the desktop. BUG=http://crbug.com/15429 Review URL: http://codereview.chromium.org/151033 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19553 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/gtk/bookmark_bar_gtk.cc13
-rw-r--r--chrome/browser/gtk/bookmark_manager_gtk.cc18
-rw-r--r--chrome/browser/gtk/bookmark_menu_controller_gtk.cc6
-rw-r--r--chrome/browser/gtk/bookmark_utils_gtk.cc6
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.cc15
-rw-r--r--chrome/browser/gtk/dnd_registry.cc47
-rw-r--r--chrome/browser/gtk/dnd_registry.h36
-rw-r--r--chrome/browser/gtk/gtk_dnd_util.cc80
-rw-r--r--chrome/browser/gtk/gtk_dnd_util.h43
-rw-r--r--chrome/browser/gtk/tabs/tab_gtk.cc5
-rwxr-xr-xchrome/browser/gtk/tabs/tab_strip_gtk.cc10
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.cc71
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.h2
-rw-r--r--chrome/chrome.gyp4
14 files changed, 226 insertions, 130 deletions
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc
index 959586d..1965a1b 100644
--- a/chrome/browser/gtk/bookmark_bar_gtk.cc
+++ b/chrome/browser/gtk/bookmark_bar_gtk.cc
@@ -20,8 +20,8 @@
#include "chrome/browser/gtk/bookmark_utils_gtk.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/custom_button.h"
-#include "chrome/browser/gtk/dnd_registry.h"
#include "chrome/browser/gtk/gtk_chrome_button.h"
+#include "chrome/browser/gtk/gtk_dnd_util.h"
#include "chrome/browser/gtk/nine_box.h"
#include "chrome/browser/gtk/tabs/tab_strip_gtk.h"
#include "chrome/browser/metrics/user_metrics.h"
@@ -134,8 +134,8 @@ void BookmarkBarGtk::Init(Profile* profile) {
gtk_drag_dest_set(bookmark_toolbar_.get(), GTK_DEST_DEFAULT_DROP,
NULL, 0, GDK_ACTION_MOVE);
- dnd::SetDestTargetListFromCodeMask(bookmark_toolbar_.get(),
- dnd::X_CHROME_BOOKMARK_ITEM);
+ GtkDndUtil::SetDestTargetListFromCodeMask(bookmark_toolbar_.get(),
+ GtkDndUtil::X_CHROME_BOOKMARK_ITEM);
g_signal_connect(bookmark_toolbar_.get(), "drag-motion",
G_CALLBACK(&OnToolbarDragMotion), this);
g_signal_connect(bookmark_toolbar_.get(), "drag-leave",
@@ -367,7 +367,8 @@ GtkWidget* BookmarkBarGtk::CreateBookmarkButton(const BookmarkNode* node) {
// The tool item is also a source for dragging
gtk_drag_source_set(button, GDK_BUTTON1_MASK,
NULL, 0, GDK_ACTION_MOVE);
- dnd::SetSourceTargetListFromCodeMask(button, dnd::X_CHROME_BOOKMARK_ITEM);
+ GtkDndUtil::SetSourceTargetListFromCodeMask(
+ button, GtkDndUtil::X_CHROME_BOOKMARK_ITEM);
g_signal_connect(G_OBJECT(button), "drag-begin",
G_CALLBACK(&OnButtonDragBegin), this);
g_signal_connect(G_OBJECT(button), "drag-end",
@@ -690,8 +691,8 @@ gboolean BookmarkBarGtk::OnToolbarDragDrop(
if (context->targets) {
GdkAtom target_type =
- GDK_POINTER_TO_ATOM(g_list_nth_data(context->targets,
- dnd::X_CHROME_BOOKMARK_ITEM));
+ GDK_POINTER_TO_ATOM(g_list_nth_data(
+ context->targets, GtkDndUtil::X_CHROME_BOOKMARK_ITEM));
gtk_drag_get_data(widget, context, target_type, time);
is_valid_drop_site = TRUE;
diff --git a/chrome/browser/gtk/bookmark_manager_gtk.cc b/chrome/browser/gtk/bookmark_manager_gtk.cc
index bd781a1..a385426 100644
--- a/chrome/browser/gtk/bookmark_manager_gtk.cc
+++ b/chrome/browser/gtk/bookmark_manager_gtk.cc
@@ -17,7 +17,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/gtk/bookmark_tree_model.h"
#include "chrome/browser/gtk/bookmark_utils_gtk.h"
-#include "chrome/browser/gtk/dnd_registry.h"
+#include "chrome/browser/gtk/gtk_dnd_util.h"
#include "chrome/browser/importer/importer.h"
#include "chrome/browser/profile.h"
#include "chrome/common/chrome_paths.h"
@@ -381,8 +381,8 @@ GtkWidget* BookmarkManagerGtk::MakeLeftPane() {
// The left side is only a drag destination (not a source).
gtk_drag_dest_set(left_tree_view_, GTK_DEST_DEFAULT_DROP,
NULL, 0, GDK_ACTION_MOVE);
- dnd::SetDestTargetListFromCodeMask(left_tree_view_,
- dnd::X_CHROME_BOOKMARK_ITEM);
+ GtkDndUtil::SetDestTargetListFromCodeMask(left_tree_view_,
+ GtkDndUtil::X_CHROME_BOOKMARK_ITEM);
g_signal_connect(left_tree_view_, "drag-data-received",
G_CALLBACK(&OnLeftTreeViewDragReceived), this);
@@ -447,8 +447,8 @@ GtkWidget* BookmarkManagerGtk::MakeRightPane() {
gtk_drag_source_set(right_tree_view_,
GDK_BUTTON1_MASK,
NULL, 0, GDK_ACTION_MOVE);
- dnd::SetSourceTargetListFromCodeMask(right_tree_view_,
- dnd::X_CHROME_BOOKMARK_ITEM);
+ GtkDndUtil::SetSourceTargetListFromCodeMask(
+ right_tree_view_, GtkDndUtil::X_CHROME_BOOKMARK_ITEM);
// We connect to drag dest signals, but we don't actually enable the widget
// as a drag destination unless it corresponds to the contents of a folder.
@@ -533,8 +533,8 @@ void BookmarkManagerGtk::BuildRightStore() {
gtk_drag_dest_set(right_tree_view_, GTK_DEST_DEFAULT_ALL, NULL, 0,
GDK_ACTION_MOVE);
- dnd::SetDestTargetListFromCodeMask(right_tree_view_,
- dnd::X_CHROME_BOOKMARK_ITEM);
+ GtkDndUtil::SetDestTargetListFromCodeMask(right_tree_view_,
+ GtkDndUtil::X_CHROME_BOOKMARK_ITEM);
} else {
gtk_tree_view_column_set_visible(path_column_, TRUE);
@@ -1019,8 +1019,8 @@ gboolean BookmarkManagerGtk::OnRightTreeViewMotion(GtkWidget* tree_view,
if (gtk_drag_check_threshold(tree_view,
bm->mousedown_event_.x, bm->mousedown_event_.y, event->x, event->y)) {
bm->delaying_mousedown_ = false;
- GtkTargetList* targets =
- dnd::GetTargetListFromCodeMask(dnd::X_CHROME_BOOKMARK_ITEM);
+ GtkTargetList* targets = GtkDndUtil::GetTargetListFromCodeMask(
+ GtkDndUtil::X_CHROME_BOOKMARK_ITEM);
gtk_drag_begin(tree_view, targets, GDK_ACTION_MOVE,
1, reinterpret_cast<GdkEvent*>(event));
// The drag adds a ref; let it own the list.
diff --git a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc
index af9e97f..1c54508 100644
--- a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc
+++ b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc
@@ -12,7 +12,7 @@
#include "base/string_util.h"
#include "chrome/browser/gtk/bookmark_context_menu.h"
#include "chrome/browser/gtk/bookmark_utils_gtk.h"
-#include "chrome/browser/gtk/dnd_registry.h"
+#include "chrome/browser/gtk/gtk_dnd_util.h"
#include "chrome/browser/gtk/menu_gtk.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/page_navigator.h"
@@ -135,8 +135,8 @@ void BookmarkMenuController::BuildMenu(const BookmarkNode* parent,
gtk_drag_source_set(menu_item, GDK_BUTTON1_MASK,
NULL, 0, GDK_ACTION_MOVE);
- dnd::SetSourceTargetListFromCodeMask(menu_item,
- dnd::X_CHROME_BOOKMARK_ITEM);
+ GtkDndUtil::SetSourceTargetListFromCodeMask(
+ menu_item, GtkDndUtil::X_CHROME_BOOKMARK_ITEM);
g_signal_connect(G_OBJECT(menu_item), "drag-begin",
G_CALLBACK(&OnMenuItemDragBegin), this);
g_signal_connect(G_OBJECT(menu_item), "drag-end",
diff --git a/chrome/browser/gtk/bookmark_utils_gtk.cc b/chrome/browser/gtk/bookmark_utils_gtk.cc
index 7486f1b..e66adff 100644
--- a/chrome/browser/gtk/bookmark_utils_gtk.cc
+++ b/chrome/browser/gtk/bookmark_utils_gtk.cc
@@ -10,8 +10,8 @@
#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/gtk/dnd_registry.h"
#include "chrome/browser/gtk/gtk_chrome_button.h"
+#include "chrome/browser/gtk/gtk_dnd_util.h"
#include "chrome/browser/profile.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
@@ -186,7 +186,7 @@ void WriteBookmarksToSelection(const std::vector<const BookmarkNode*>& nodes,
guint target_type,
Profile* profile) {
switch (target_type) {
- case dnd::X_CHROME_BOOKMARK_ITEM: {
+ case GtkDndUtil::X_CHROME_BOOKMARK_ITEM: {
BookmarkDragData data(nodes);
Pickle pickle;
data.WriteToPickle(profile, &pickle);
@@ -219,7 +219,7 @@ std::vector<const BookmarkNode*> GetNodesFromSelection(
}
switch (target_type) {
- case dnd::X_CHROME_BOOKMARK_ITEM: {
+ case GtkDndUtil::X_CHROME_BOOKMARK_ITEM: {
*dnd_success = TRUE;
Pickle pickle(reinterpret_cast<char*>(selection_data->data),
selection_data->length);
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc
index 31f2888..d7fddfd 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_toolbar_gtk.cc
@@ -18,9 +18,9 @@
#include "chrome/browser/gtk/back_forward_button_gtk.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/custom_button.h"
-#include "chrome/browser/gtk/dnd_registry.h"
#include "chrome/browser/gtk/go_button_gtk.h"
#include "chrome/browser/gtk/gtk_chrome_button.h"
+#include "chrome/browser/gtk/gtk_dnd_util.h"
#include "chrome/browser/gtk/location_bar_view_gtk.h"
#include "chrome/browser/gtk/nine_box.h"
#include "chrome/browser/gtk/standard_menus.h"
@@ -349,9 +349,9 @@ void BrowserToolbarGtk::SetUpDragForHomeButton() {
// prefer URIs over plain text when both are available.
gtk_drag_dest_set(home_->widget(), GTK_DEST_DEFAULT_ALL,
NULL, 0, GDK_ACTION_COPY);
- dnd::SetDestTargetListFromCodeMask(home_->widget(),
- dnd::X_CHROME_TEXT_PLAIN |
- dnd::X_CHROME_TEXT_URI_LIST);
+ GtkDndUtil::SetDestTargetListFromCodeMask(home_->widget(),
+ GtkDndUtil::X_CHROME_TEXT_PLAIN |
+ GtkDndUtil::X_CHROME_TEXT_URI_LIST);
g_signal_connect(home_->widget(), "drag-data-received",
G_CALLBACK(OnDragDataReceived), this);
@@ -423,17 +423,14 @@ void BrowserToolbarGtk::OnDragDataReceived(GtkWidget* widget,
GdkDragContext* drag_context, gint x, gint y,
GtkSelectionData* data, guint info, guint time,
BrowserToolbarGtk* toolbar) {
- if (info != dnd::X_CHROME_TEXT_PLAIN) {
+ if (info != GtkDndUtil::X_CHROME_TEXT_PLAIN) {
NOTIMPLEMENTED() << "Only support plain text drops for now, sorry!";
return;
}
GURL url(reinterpret_cast<char*>(data->data));
- if (!url.is_valid()) {
- // FIXME: remove this
- NOTIMPLEMENTED() << "invalid url: " << url.spec();
+ if (!url.is_valid())
return;
- }
bool url_is_newtab = url.spec() == chrome::kChromeUINewTabURL;
toolbar->profile_->GetPrefs()->SetBoolean(prefs::kHomePageIsNewTabPage,
diff --git a/chrome/browser/gtk/dnd_registry.cc b/chrome/browser/gtk/dnd_registry.cc
deleted file mode 100644
index 42e935a..0000000
--- a/chrome/browser/gtk/dnd_registry.cc
+++ /dev/null
@@ -1,47 +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 "dnd_registry.h"
-
-namespace dnd {
-
-GtkTargetList* GetTargetListFromCodeMask(int code_mask) {
- GtkTargetList* targets = gtk_target_list_new(NULL, 0);
-
- if (code_mask & X_CHROME_TAB) {
- GdkAtom tab_atom = gdk_atom_intern(
- const_cast<char*>("application/x-chrome-tab"), false);
- gtk_target_list_add(targets, tab_atom, GTK_TARGET_SAME_APP,
- X_CHROME_TAB);
- }
-
- if (code_mask & X_CHROME_TEXT_PLAIN)
- gtk_target_list_add_text_targets(targets, X_CHROME_TEXT_PLAIN);
-
- if (code_mask & X_CHROME_TEXT_URI_LIST)
- gtk_target_list_add_uri_targets(targets, X_CHROME_TEXT_URI_LIST);
-
- if (code_mask & X_CHROME_BOOKMARK_ITEM) {
- GdkAtom bookmark_atom = gdk_atom_intern(
- const_cast<char*>("application/x-chrome-bookmark-item"), false);
- gtk_target_list_add(targets, bookmark_atom, GTK_TARGET_SAME_APP,
- X_CHROME_BOOKMARK_ITEM);
- }
-
- return targets;
-}
-
-void SetDestTargetListFromCodeMask(GtkWidget* dest, int code_mask) {
- GtkTargetList* targets = GetTargetListFromCodeMask(code_mask);
- gtk_drag_dest_set_target_list(dest, targets);
- gtk_target_list_unref(targets);
-}
-
-void SetSourceTargetListFromCodeMask(GtkWidget* source, int code_mask) {
- GtkTargetList* targets = GetTargetListFromCodeMask(code_mask);
- gtk_drag_source_set_target_list(source, targets);
- gtk_target_list_unref(targets);
-}
-
-} // namespace dnd
diff --git a/chrome/browser/gtk/dnd_registry.h b/chrome/browser/gtk/dnd_registry.h
deleted file mode 100644
index e177a3f..0000000
--- a/chrome/browser/gtk/dnd_registry.h
+++ /dev/null
@@ -1,36 +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.
-
-#ifndef CHROME_BROWSER_GTK_DND_REGISTRY_H_
-#define CHROME_BROWSER_GTK_DND_REGISTRY_H_
-
-#include <gtk/gtk.h>
-
-// We wrap all of these constants in a namespace to prevent pollution.
-namespace dnd {
-
-// Registry of all internal int codes for drag and drop.
-//
-// These ids need to be unique app wide. Simply adding a GtkTargetEntry with an
-// id of 0 should be an error and it will conflict with X_CHROME_TAB below.
-enum {
- X_CHROME_TAB = 1 << 0,
- X_CHROME_TEXT_PLAIN = 1 << 1,
- X_CHROME_TEXT_URI_LIST = 1 << 2,
- X_CHROME_BOOKMARK_ITEM = 1 << 3,
-};
-
-// Creates a target list from the given mask. The mask should be an OR of
-// X_CHROME_* values. The target list is returned with ref count 1; the caller
-// is responsible for unreffing it when it is no longer needed.
-GtkTargetList* GetTargetListFromCodeMask(int code_mask);
-
-// Set the drag target list for |dest| or |source| with the target list that
-// corresponds to |code_mask|.
-void SetDestTargetListFromCodeMask(GtkWidget* dest, int code_mask);
-void SetSourceTargetListFromCodeMask(GtkWidget* source, int code_mask);
-
-} // namespace dnd
-
-#endif // CHROME_BROWSER_GTK_DND_REGISTRY_H_
diff --git a/chrome/browser/gtk/gtk_dnd_util.cc b/chrome/browser/gtk/gtk_dnd_util.cc
new file mode 100644
index 0000000..88668f3
--- /dev/null
+++ b/chrome/browser/gtk/gtk_dnd_util.cc
@@ -0,0 +1,80 @@
+// 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 "chrome/browser/gtk/gtk_dnd_util.h"
+
+#include "base/logging.h"
+
+// static
+GdkAtom GtkDndUtil::GetAtomForTarget(int target) {
+ switch (target) {
+ case X_CHROME_TAB:
+ static GdkAtom tab_atom = gdk_atom_intern(
+ const_cast<char*>("application/x-chrome-tab"), false);
+ return tab_atom;
+
+ case X_CHROME_TEXT_HTML:
+ static GdkAtom html_atom = gdk_atom_intern(
+ const_cast<char*>("text/html"), false);
+ return html_atom;
+
+ case X_CHROME_BOOKMARK_ITEM:
+ static GdkAtom bookmark_atom = gdk_atom_intern(
+ const_cast<char*>("application/x-chrome-bookmark-item"), false);
+ return bookmark_atom;
+
+ case X_CHROME_TEXT_PLAIN:
+ case X_CHROME_TEXT_URI_LIST:
+ return NULL;
+
+ default:
+ NOTREACHED();
+ }
+
+ return NULL;
+}
+
+// static
+GtkTargetList* GtkDndUtil::GetTargetListFromCodeMask(int code_mask) {
+ GtkTargetList* targets = gtk_target_list_new(NULL, 0);
+
+ if (code_mask & X_CHROME_TAB) {
+ gtk_target_list_add(targets, GetAtomForTarget(X_CHROME_TAB),
+ GTK_TARGET_SAME_APP, X_CHROME_TAB);
+ }
+
+ if (code_mask & X_CHROME_TEXT_PLAIN)
+ gtk_target_list_add_text_targets(targets, X_CHROME_TEXT_PLAIN);
+
+ if (code_mask & X_CHROME_TEXT_URI_LIST)
+ gtk_target_list_add_uri_targets(targets, X_CHROME_TEXT_URI_LIST);
+
+ if (code_mask & X_CHROME_TEXT_HTML) {
+ gtk_target_list_add(targets, GetAtomForTarget(X_CHROME_TEXT_PLAIN),
+ 0, X_CHROME_TEXT_HTML);
+ }
+
+ if (code_mask & X_CHROME_BOOKMARK_ITEM) {
+ gtk_target_list_add(targets, GetAtomForTarget(X_CHROME_BOOKMARK_ITEM),
+ GTK_TARGET_SAME_APP, X_CHROME_BOOKMARK_ITEM);
+ }
+
+ return targets;
+}
+
+// static
+void GtkDndUtil::SetDestTargetListFromCodeMask(GtkWidget* dest,
+ int code_mask) {
+ GtkTargetList* targets = GetTargetListFromCodeMask(code_mask);
+ gtk_drag_dest_set_target_list(dest, targets);
+ gtk_target_list_unref(targets);
+}
+
+// static
+void GtkDndUtil::SetSourceTargetListFromCodeMask(GtkWidget* source,
+ int code_mask) {
+ GtkTargetList* targets = GetTargetListFromCodeMask(code_mask);
+ gtk_drag_source_set_target_list(source, targets);
+ gtk_target_list_unref(targets);
+}
diff --git a/chrome/browser/gtk/gtk_dnd_util.h b/chrome/browser/gtk/gtk_dnd_util.h
new file mode 100644
index 0000000..38036f8
--- /dev/null
+++ b/chrome/browser/gtk/gtk_dnd_util.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef CHROME_BROWSER_GTK_GTK_DND_UTIL_H_
+#define CHROME_BROWSER_GTK_GTK_DND_UTIL_H_
+
+#include <gtk/gtk.h>
+
+class GtkDndUtil {
+ public:
+ // Registry of all internal int codes for drag and drop.
+ enum {
+ X_CHROME_TAB = 1 << 0,
+ X_CHROME_TEXT_PLAIN = 1 << 1,
+ X_CHROME_TEXT_URI_LIST = 1 << 2,
+ X_CHROME_TEXT_HTML = 1 << 3,
+ X_CHROME_BOOKMARK_ITEM = 1 << 4,
+ X_CHROME_WEBDROP_FILE_CONTENTS = 1 << 5,
+ };
+
+ // Get the atom for a given target (of the above enum type). Will return NULL
+ // for non-custom targets, such as X_CHROME_TEXT_PLAIN.
+ static GdkAtom GetAtomForTarget(int target);
+
+ // Creates a target list from the given mask. The mask should be an OR of
+ // X_CHROME_* values. The target list is returned with ref count 1; the caller
+ // is responsible for unreffing it when it is no longer needed.
+ // Since the MIME type for WEBDROP_FILE_CONTENTS depends on the file's
+ // contents, that flag is ignored by this function. It is the responsibility
+ // of the client code to do the right thing.
+ static GtkTargetList* GetTargetListFromCodeMask(int code_mask);
+
+ // Set the drag target list for |dest| or |source| with the target list that
+ // corresponds to |code_mask|.
+ static void SetDestTargetListFromCodeMask(GtkWidget* dest, int code_mask);
+ static void SetSourceTargetListFromCodeMask(GtkWidget* source, int code_mask);
+
+ private:
+ GtkDndUtil();
+};
+
+#endif // CHROME_BROWSER_GTK_GTK_DND_UTIL_H_
diff --git a/chrome/browser/gtk/tabs/tab_gtk.cc b/chrome/browser/gtk/tabs/tab_gtk.cc
index 10583e0..54f6428 100644
--- a/chrome/browser/gtk/tabs/tab_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_gtk.cc
@@ -7,7 +7,7 @@
#include "app/gfx/path.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
-#include "chrome/browser/gtk/dnd_registry.h"
+#include "chrome/browser/gtk/gtk_dnd_util.h"
#include "chrome/browser/gtk/menu_gtk.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -108,7 +108,8 @@ TabGtk::TabGtk(TabDelegate* delegate)
gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_), FALSE);
gtk_drag_source_set(event_box_, GDK_BUTTON1_MASK,
NULL, 0, GDK_ACTION_MOVE);
- dnd::SetSourceTargetListFromCodeMask(event_box_, dnd::X_CHROME_TAB);
+ GtkDndUtil::SetSourceTargetListFromCodeMask(event_box_,
+ GtkDndUtil::X_CHROME_TAB);
g_signal_connect(G_OBJECT(event_box_), "button-press-event",
G_CALLBACK(OnMousePress), this);
g_signal_connect(G_OBJECT(event_box_), "button-release-event",
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
index 944323f..e25fd0d 100755
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
@@ -14,7 +14,7 @@
#include "base/gfx/point.h"
#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/gtk/custom_button.h"
-#include "chrome/browser/gtk/dnd_registry.h"
+#include "chrome/browser/gtk/gtk_dnd_util.h"
#include "chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
@@ -477,9 +477,9 @@ void TabStripGtk::Init() {
NULL, 0,
static_cast<GdkDragAction>(
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK));
- dnd::SetDestTargetListFromCodeMask(tabstrip_.get(),
- dnd::X_CHROME_TEXT_URI_LIST |
- dnd::X_CHROME_TEXT_PLAIN);
+ GtkDndUtil::SetDestTargetListFromCodeMask(tabstrip_.get(),
+ GtkDndUtil::X_CHROME_TEXT_URI_LIST |
+ GtkDndUtil::X_CHROME_TEXT_PLAIN);
g_signal_connect(G_OBJECT(tabstrip_.get()), "expose-event",
G_CALLBACK(OnExpose), this);
@@ -1553,7 +1553,7 @@ gboolean TabStripGtk::OnDragDataReceived(GtkWidget* widget,
guint info, guint time,
TabStripGtk* tabstrip) {
// TODO(jhawkins): Parse URI lists.
- if (info == dnd::X_CHROME_TEXT_PLAIN) {
+ if (info == GtkDndUtil::X_CHROME_TEXT_PLAIN) {
tabstrip->CompleteDrop(data->data);
gtk_drag_finish(context, TRUE, TRUE, time);
}
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
index 1c853bd..84aa955 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
@@ -7,6 +7,7 @@
#include <gdk/gdk.h>
#include <gtk/gtk.h>
+#include "base/mime_util.h"
#include "base/gfx/point.h"
#include "base/gfx/rect.h"
#include "base/gfx/size.h"
@@ -16,7 +17,7 @@
#include "chrome/browser/gtk/blocked_popup_container_view_gtk.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/constrained_window_gtk.h"
-#include "chrome/browser/gtk/dnd_registry.h"
+#include "chrome/browser/gtk/gtk_dnd_util.h"
#include "chrome/browser/gtk/gtk_floating_container.h"
#include "chrome/browser/gtk/sad_tab_gtk.h"
#include "chrome/browser/renderer_host/render_view_host.h"
@@ -364,16 +365,33 @@ void TabContentsViewGtk::DragEnded() {
void TabContentsViewGtk::StartDragging(const WebDropData& drop_data) {
DCHECK(GetContentNativeView());
- if (drop_data.plain_text.empty()) {
- NOTIMPLEMENTED() << "Only plain text drags supported, sorry!";
+ int targets_mask = 0;
+
+ if (!drop_data.plain_text.empty())
+ targets_mask |= GtkDndUtil::X_CHROME_TEXT_PLAIN;
+ if (drop_data.url.is_valid())
+ targets_mask |= GtkDndUtil::X_CHROME_TEXT_URI_LIST;
+ if (!drop_data.text_html.empty())
+ targets_mask |= GtkDndUtil::X_CHROME_TEXT_HTML;
+ if (!drop_data.file_contents.empty())
+ targets_mask |= GtkDndUtil::X_CHROME_WEBDROP_FILE_CONTENTS;
+
+ if (targets_mask == 0) {
+ NOTIMPLEMENTED();
DragEnded();
return;
}
drop_data_.reset(new WebDropData(drop_data));
- GtkTargetList* list = gtk_target_list_new(NULL, 0);
- gtk_target_list_add_text_targets(list, dnd::X_CHROME_TEXT_PLAIN);
+ GtkTargetList* list = GtkDndUtil::GetTargetListFromCodeMask(targets_mask);
+ if (targets_mask & GtkDndUtil::X_CHROME_WEBDROP_FILE_CONTENTS) {
+ drag_file_mime_type_ = gdk_atom_intern(
+ mime_util::GetDataMimeType(drop_data.file_contents).c_str(), FALSE);
+ gtk_target_list_add(list, drag_file_mime_type_,
+ 0, GtkDndUtil::X_CHROME_WEBDROP_FILE_CONTENTS);
+ }
+
gtk_drag_begin(GetContentNativeView(), list, GDK_ACTION_COPY, 1, NULL);
// The drag adds a ref; let it own the list.
gtk_target_list_unref(list);
@@ -384,9 +402,46 @@ void TabContentsViewGtk::OnDragDataGet(
GtkWidget* drag_widget,
GdkDragContext* context, GtkSelectionData* selection_data,
guint target_type, guint time, TabContentsViewGtk* view) {
- std::string utf8_text(UTF16ToUTF8(view->drop_data_->plain_text));
- gtk_selection_data_set_text(selection_data, utf8_text.c_str(),
- utf8_text.length());
+ const int bits_per_byte = 8;
+ // We must make this initialization here or gcc complains about jumping past
+ // it in the switch statement.
+ std::string utf8_text;
+
+ switch (target_type) {
+ case GtkDndUtil::X_CHROME_TEXT_PLAIN:
+ utf8_text = UTF16ToUTF8(view->drop_data_->plain_text);
+ gtk_selection_data_set_text(selection_data, utf8_text.c_str(),
+ utf8_text.length());
+ break;
+ case GtkDndUtil::X_CHROME_TEXT_URI_LIST:
+ gchar* uri_array[2];
+ uri_array[0] = strdup(view->drop_data_->url.spec().c_str());
+ uri_array[1] = NULL;
+ gtk_selection_data_set_uris(selection_data, uri_array);
+ free(uri_array[0]);
+ break;
+ case GtkDndUtil::X_CHROME_TEXT_HTML:
+ // TODO(estade): change relative links to be absolute using
+ // |html_base_url|.
+ utf8_text = UTF16ToUTF8(view->drop_data_->text_html);
+ gtk_selection_data_set(selection_data,
+ GtkDndUtil::GetAtomForTarget(GtkDndUtil::X_CHROME_TEXT_HTML),
+ bits_per_byte,
+ reinterpret_cast<const guchar*>(utf8_text.c_str()),
+ utf8_text.length());
+ break;
+
+ case GtkDndUtil::X_CHROME_WEBDROP_FILE_CONTENTS:
+ gtk_selection_data_set(selection_data,
+ view->drag_file_mime_type_, bits_per_byte,
+ reinterpret_cast<const guchar*>(
+ view->drop_data_->file_contents.data()),
+ view->drop_data_->file_contents.length());
+ break;
+
+ default:
+ NOTREACHED();
+ }
}
// static
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h
index 46cfc50..be2b74d 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.h
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h
@@ -138,6 +138,8 @@ class TabContentsViewGtk : public TabContentsView,
// The drop data for the current drag (for drags that originate in the render
// view).
scoped_ptr<WebDropData> drop_data_;
+ // The mime type for the file contents of the current drag (if any).
+ GdkAtom drag_file_mime_type_;
DISALLOW_COPY_AND_ASSIGN(TabContentsViewGtk);
};
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 5039e50..a94f441 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -970,8 +970,6 @@
'browser/gtk/custom_button.cc',
'browser/gtk/custom_button.h',
'browser/gtk/dialogs_gtk.cc',
- 'browser/gtk/dnd_registry.cc',
- 'browser/gtk/dnd_registry.h',
'browser/gtk/download_item_gtk.cc',
'browser/gtk/download_item_gtk.h',
'browser/gtk/download_shelf_gtk.cc',
@@ -985,6 +983,8 @@
'browser/gtk/gtk_chrome_button.h',
'browser/gtk/gtk_chrome_link_button.cc',
'browser/gtk/gtk_chrome_link_button.h',
+ 'browser/gtk/gtk_dnd_util.cc',
+ 'browser/gtk/gtk_dnd_util.h',
'browser/gtk/gtk_floating_container.cc',
'browser/gtk/gtk_floating_container.h',
'browser/gtk/hung_renderer_dialog_gtk.cc',