Index: content/browser/web_contents/web_drag_dest_gtk.cc |
diff --git a/content/browser/web_contents/web_drag_dest_gtk.cc b/content/browser/web_contents/web_drag_dest_gtk.cc |
deleted file mode 100644 |
index 2fae6863b6386edbf9f793aec857e3aa31d19113..0000000000000000000000000000000000000000 |
--- a/content/browser/web_contents/web_drag_dest_gtk.cc |
+++ /dev/null |
@@ -1,345 +0,0 @@ |
-// Copyright (c) 2012 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 "content/browser/web_contents/web_drag_dest_gtk.h" |
- |
-#include <string> |
- |
-#include "base/bind.h" |
-#include "base/files/file_path.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "content/browser/renderer_host/render_view_host_impl.h" |
-#include "content/browser/web_contents/drag_utils_gtk.h" |
-#include "content/browser/web_contents/web_contents_impl.h" |
-#include "content/public/browser/web_contents_delegate.h" |
-#include "content/public/browser/web_drag_dest_delegate.h" |
-#include "content/public/common/url_constants.h" |
-#include "net/base/filename_util.h" |
-#include "third_party/WebKit/public/web/WebInputEvent.h" |
-#include "ui/base/clipboard/custom_data_helper.h" |
-#include "ui/base/dragdrop/gtk_dnd_util.h" |
-#include "ui/base/gtk/gtk_screen_util.h" |
- |
-using blink::WebDragOperation; |
-using blink::WebDragOperationNone; |
- |
-namespace content { |
- |
-namespace { |
-const int kNumGtkHandlers = 5; |
- |
-int GetModifierFlags(GtkWidget* widget) { |
- int modifier_state = 0; |
- GdkModifierType state; |
- gdk_window_get_pointer(gtk_widget_get_window(widget), NULL, NULL, &state); |
- |
- if (state & GDK_SHIFT_MASK) |
- modifier_state |= blink::WebInputEvent::ShiftKey; |
- if (state & GDK_CONTROL_MASK) |
- modifier_state |= blink::WebInputEvent::ControlKey; |
- if (state & GDK_MOD1_MASK) |
- modifier_state |= blink::WebInputEvent::AltKey; |
- if (state & GDK_META_MASK) |
- modifier_state |= blink::WebInputEvent::MetaKey; |
- return modifier_state; |
-} |
- |
-} // namespace |
- |
-WebDragDestGtk::WebDragDestGtk(WebContents* web_contents, GtkWidget* widget) |
- : web_contents_(web_contents), |
- widget_(widget), |
- context_(NULL), |
- data_requests_(0), |
- delegate_(NULL), |
- canceled_(false), |
- method_factory_(this) { |
- gtk_drag_dest_set(widget, static_cast<GtkDestDefaults>(0), |
- NULL, 0, |
- static_cast<GdkDragAction>(GDK_ACTION_COPY | |
- GDK_ACTION_LINK | |
- GDK_ACTION_MOVE)); |
- |
- // If adding a handler, make sure to update kNumGtkHandlers and add it to the |
- // |handlers_| array so that it can be disconnected later on. |
- handlers_.reset(new int[kNumGtkHandlers]); |
- handlers_.get()[0] = g_signal_connect( |
- widget, "drag-motion", G_CALLBACK(OnDragMotionThunk), this); |
- handlers_.get()[1] = g_signal_connect( |
- widget, "drag-leave", G_CALLBACK(OnDragLeaveThunk), this); |
- handlers_.get()[2] = g_signal_connect( |
- widget, "drag-drop", G_CALLBACK(OnDragDropThunk), this); |
- handlers_.get()[3] = g_signal_connect( |
- widget, "drag-data-received", G_CALLBACK(OnDragDataReceivedThunk), this); |
- // TODO(tony): Need a drag-data-delete handler for moving content out of |
- // the WebContents. http://crbug.com/38989 |
- |
- handlers_.get()[4] = g_signal_connect( |
- widget, "destroy", G_CALLBACK(gtk_widget_destroyed), &widget_); |
-} |
- |
-WebDragDestGtk::~WebDragDestGtk() { |
- if (widget_) { |
- gtk_drag_dest_unset(widget_); |
- for (int i = 0; i < kNumGtkHandlers; ++i) |
- g_signal_handler_disconnect(widget_, handlers_.get()[i]); |
- } |
-} |
- |
-void WebDragDestGtk::UpdateDragStatus(WebDragOperation operation) { |
- if (context_) { |
- is_drop_target_ = operation != WebDragOperationNone; |
- gdk_drag_status(context_, WebDragOpToGdkDragAction(operation), |
- drag_over_time_); |
- } |
-} |
- |
-void WebDragDestGtk::DragLeave() { |
- GetRenderViewHost()->DragTargetDragLeave(); |
- if (delegate()) |
- delegate()->OnDragLeave(); |
- |
- drop_data_.reset(); |
-} |
- |
-gboolean WebDragDestGtk::OnDragMotion(GtkWidget* sender, |
- GdkDragContext* context, |
- gint x, gint y, |
- guint time) { |
- if (context_ != context) { |
- context_ = context; |
- drop_data_.reset(new DropData); |
- is_drop_target_ = false; |
- |
- if (delegate()) |
- delegate()->DragInitialize(web_contents_); |
- |
- // text/plain must come before text/uri-list. This is a hack that works in |
- // conjunction with OnDragDataReceived. Since some file managers populate |
- // text/plain with file URLs when dragging files, we want to handle |
- // text/uri-list after text/plain so that the plain text can be cleared if |
- // it's a file drag. |
- // Similarly, renderer taint must occur before anything else so we can |
- // ignore potentially forged filenames when handling text/uri-list. |
- static int supported_targets[] = { |
- ui::RENDERER_TAINT, |
- ui::TEXT_PLAIN, |
- ui::TEXT_URI_LIST, |
- ui::TEXT_HTML, |
- ui::NETSCAPE_URL, |
- ui::CHROME_NAMED_URL, |
- // TODO(estade): support image drags? |
- ui::CUSTOM_DATA, |
- }; |
- |
- // Add the delegate's requested target if applicable. Need to do this here |
- // since gtk_drag_get_data will dispatch to our drag-data-received. |
- data_requests_ = arraysize(supported_targets) + (delegate() ? 1 : 0); |
- for (size_t i = 0; i < arraysize(supported_targets); ++i) { |
- gtk_drag_get_data(widget_, context, |
- ui::GetAtomForTarget(supported_targets[i]), |
- time); |
- } |
- |
- if (delegate()) { |
- gtk_drag_get_data(widget_, context, delegate()->GetBookmarkTargetAtom(), |
- time); |
- } |
- } else if (data_requests_ == 0) { |
- if (canceled_) |
- return FALSE; |
- |
- GetRenderViewHost()->DragTargetDragOver( |
- ui::ClientPoint(widget_), |
- ui::ScreenPoint(widget_), |
- GdkDragActionToWebDragOp(context->actions), |
- GetModifierFlags(widget_)); |
- |
- if (delegate()) |
- delegate()->OnDragOver(); |
- |
- drag_over_time_ = time; |
- } |
- |
- // Pretend we are a drag destination because we don't want to wait for |
- // the renderer to tell us if we really are or not. |
- return TRUE; |
-} |
- |
-void WebDragDestGtk::OnDragDataReceived( |
- GtkWidget* sender, GdkDragContext* context, gint x, gint y, |
- GtkSelectionData* data, guint info, guint time) { |
- // We might get the data from an old get_data() request that we no longer |
- // care about. |
- if (context != context_) |
- return; |
- |
- data_requests_--; |
- |
- // Decode the data. |
- gint data_length = gtk_selection_data_get_length(data); |
- const guchar* raw_data = gtk_selection_data_get_data(data); |
- GdkAtom target = gtk_selection_data_get_target(data); |
- if (raw_data && data_length > 0) { |
- // If the source can't provide us with valid data for a requested target, |
- // raw_data will be NULL. |
- if (target == ui::GetAtomForTarget(ui::RENDERER_TAINT)) { |
- drop_data_->did_originate_from_renderer = true; |
- } else if (target == ui::GetAtomForTarget(ui::TEXT_PLAIN)) { |
- guchar* text = gtk_selection_data_get_text(data); |
- if (text) { |
- drop_data_->text = base::NullableString16( |
- base::UTF8ToUTF16(std::string(reinterpret_cast<const char*>(text))), |
- false); |
- g_free(text); |
- } |
- } else if (target == ui::GetAtomForTarget(ui::TEXT_URI_LIST)) { |
- gchar** uris = gtk_selection_data_get_uris(data); |
- if (uris) { |
- drop_data_->url = GURL(); |
- for (gchar** uri_iter = uris; *uri_iter; uri_iter++) { |
- // Most file managers populate text/uri-list with file URLs when |
- // dragging files. To avoid exposing file system paths to web content, |
- // file URLs are never set as the URL content for the drop. |
- // TODO(estade): Can the filenames have a non-UTF8 encoding? |
- GURL url(*uri_iter); |
- base::FilePath file_path; |
- if (url.SchemeIs(kFileScheme) && |
- net::FileURLToFilePath(url, &file_path)) { |
- drop_data_->filenames.push_back( |
- ui::FileInfo(file_path, base::FilePath())); |
- // This is a hack. Some file managers also populate text/plain with |
- // a file URL when dragging files, so we clear it to avoid exposing |
- // it to the web content. |
- drop_data_->text = base::NullableString16(); |
- } else if (!drop_data_->url.is_valid()) { |
- // Also set the first non-file URL as the URL content for the drop. |
- drop_data_->url = url; |
- } |
- } |
- g_strfreev(uris); |
- } |
- } else if (target == ui::GetAtomForTarget(ui::TEXT_HTML)) { |
- // TODO(estade): Can the html have a non-UTF8 encoding? |
- drop_data_->html = base::NullableString16( |
- base::UTF8ToUTF16(std::string(reinterpret_cast<const char*>(raw_data), |
- data_length)), |
- false); |
- // We leave the base URL empty. |
- } else if (target == ui::GetAtomForTarget(ui::NETSCAPE_URL)) { |
- std::string netscape_url(reinterpret_cast<const char*>(raw_data), |
- data_length); |
- size_t split = netscape_url.find_first_of('\n'); |
- if (split != std::string::npos) { |
- drop_data_->url = GURL(netscape_url.substr(0, split)); |
- if (split < netscape_url.size() - 1) { |
- drop_data_->url_title = |
- base::UTF8ToUTF16(netscape_url.substr(split + 1)); |
- } |
- } |
- } else if (target == ui::GetAtomForTarget(ui::CHROME_NAMED_URL)) { |
- ui::ExtractNamedURL(data, &drop_data_->url, &drop_data_->url_title); |
- } else if (target == ui::GetAtomForTarget(ui::CUSTOM_DATA)) { |
- ui::ReadCustomDataIntoMap( |
- raw_data, data_length, &drop_data_->custom_data); |
- } |
- } |
- |
- if (data_requests_ == 0) { |
- // Give the delegate an opportunity to cancel the drag. |
- canceled_ = !web_contents_->GetDelegate()->CanDragEnter( |
- web_contents_, |
- *drop_data_, |
- GdkDragActionToWebDragOp(context->actions)); |
- if (canceled_) { |
- drag_over_time_ = time; |
- UpdateDragStatus(WebDragOperationNone); |
- drop_data_.reset(); |
- return; |
- } |
- } |
- |
- // For CHROME_BOOKMARK_ITEM, we have to handle the case where the drag source |
- // doesn't have any data available for us. In this case we try to synthesize a |
- // URL bookmark. |
- // Note that bookmark drag data is encoded in the same format for both |
- // GTK and Views, hence we can share the same logic here. |
- if (delegate() && target == delegate()->GetBookmarkTargetAtom()) { |
- if (raw_data && data_length > 0) { |
- delegate()->OnReceiveDataFromGtk(data); |
- } else { |
- delegate()->OnReceiveProcessedData(drop_data_->url, |
- drop_data_->url_title); |
- } |
- } |
- |
- if (data_requests_ == 0) { |
- // Tell the renderer about the drag. |
- // |x| and |y| are seemingly arbitrary at this point. |
- GetRenderViewHost()->DragTargetDragEnter( |
- *drop_data_.get(), |
- ui::ClientPoint(widget_), |
- ui::ScreenPoint(widget_), |
- GdkDragActionToWebDragOp(context->actions), |
- GetModifierFlags(widget_)); |
- |
- if (delegate()) |
- delegate()->OnDragEnter(); |
- |
- drag_over_time_ = time; |
- } |
-} |
- |
-// The drag has left our widget; forward this information to the renderer. |
-void WebDragDestGtk::OnDragLeave(GtkWidget* sender, GdkDragContext* context, |
- guint time) { |
- // Set |context_| to NULL to make sure we will recognize the next DragMotion |
- // as an enter. |
- context_ = NULL; |
- |
- if (canceled_) |
- return; |
- |
- // Sometimes we get a drag-leave event before getting a drag-data-received |
- // event. In that case, we don't want to bother the renderer with a |
- // DragLeave event. |
- if (data_requests_ != 0) |
- return; |
- |
- // When GTK sends us a drag-drop signal, it is shortly (and synchronously) |
- // preceded by a drag-leave. The renderer doesn't like getting the signals |
- // in this order so delay telling it about the drag-leave till we are sure |
- // we are not getting a drop as well. |
- base::MessageLoop::current()->PostTask( |
- FROM_HERE, |
- base::Bind(&WebDragDestGtk::DragLeave, method_factory_.GetWeakPtr())); |
-} |
- |
-// Called by GTK when the user releases the mouse, executing a drop. |
-gboolean WebDragDestGtk::OnDragDrop(GtkWidget* sender, GdkDragContext* context, |
- gint x, gint y, guint time) { |
- // Cancel that drag leave! |
- method_factory_.InvalidateWeakPtrs(); |
- |
- GetRenderViewHost()-> |
- DragTargetDrop(ui::ClientPoint(widget_), ui::ScreenPoint(widget_), |
- GetModifierFlags(widget_)); |
- |
- if (delegate()) |
- delegate()->OnDrop(); |
- |
- // The second parameter is just an educated guess as to whether or not the |
- // drag succeeded, but at least we will get the drag-end animation right |
- // sometimes. |
- gtk_drag_finish(context, is_drop_target_, FALSE, time); |
- |
- return TRUE; |
-} |
- |
-RenderViewHostImpl* WebDragDestGtk::GetRenderViewHost() const { |
- return static_cast<RenderViewHostImpl*>(web_contents_->GetRenderViewHost()); |
-} |
- |
-} // namespace content |