summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-10 18:11:07 +0000
committertsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-10 18:11:07 +0000
commitea2dc8e2fcef3218ffd9560adb053842fb025e41 (patch)
tree1dcaf3f7bc5f73655cc5ee7eff6eed47a2a0fa97
parent66194b10c48282e9e074cec1010adda45814b6f4 (diff)
downloadchromium_src-ea2dc8e2fcef3218ffd9560adb053842fb025e41.zip
chromium_src-ea2dc8e2fcef3218ffd9560adb053842fb025e41.tar.gz
chromium_src-ea2dc8e2fcef3218ffd9560adb053842fb025e41.tar.bz2
Fix situation where a new drag could start before previous one completes.
BUG=61094 TEST=manually select a region of text and repeatedly drag it into an inactive portion of the screen. Review URL: http://codereview.chromium.org/5981011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70906 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/tab_contents_drag_source.cc19
-rw-r--r--chrome/browser/gtk/tab_contents_drag_source.h4
2 files changed, 19 insertions, 4 deletions
diff --git a/chrome/browser/gtk/tab_contents_drag_source.cc b/chrome/browser/gtk/tab_contents_drag_source.cc
index 13e2196..eedfe83 100644
--- a/chrome/browser/gtk/tab_contents_drag_source.cc
+++ b/chrome/browser/gtk/tab_contents_drag_source.cc
@@ -33,6 +33,7 @@ TabContentsDragSource::TabContentsDragSource(
drag_pixbuf_(NULL),
drag_failed_(false),
drag_widget_(gtk_invisible_new()),
+ drag_context_(NULL),
drag_icon_(gtk_window_new(GTK_WINDOW_POPUP)) {
signals_.Connect(drag_widget_, "drag-failed",
G_CALLBACK(OnDragFailedThunk), this);
@@ -70,6 +71,14 @@ void TabContentsDragSource::StartDragging(const WebDropData& drop_data,
GdkEventButton* last_mouse_down,
const SkBitmap& image,
const gfx::Point& image_offset) {
+ // Guard against re-starting before previous drag completed.
+ if (drag_context_) {
+ NOTREACHED();
+ if (tab_contents()->render_view_host())
+ tab_contents()->render_view_host()->DragSourceSystemDragEnded();
+ return;
+ }
+
int targets_mask = 0;
if (!drop_data.plain_text.empty())
@@ -91,10 +100,11 @@ void TabContentsDragSource::StartDragging(const WebDropData& drop_data,
targets_mask |= gtk_dnd_util::DIRECT_SAVE_FILE;
}
+ // Short-circuit execution if no targets present.
if (targets_mask == 0) {
- NOTIMPLEMENTED();
if (tab_contents()->render_view_host())
tab_contents()->render_view_host()->DragSourceSystemDragEnded();
+ return;
}
drop_data_.reset(new WebDropData(drop_data));
@@ -122,8 +132,7 @@ void TabContentsDragSource::StartDragging(const WebDropData& drop_data,
// and holds and doesn't start dragging for a long time. I doubt it matters
// much, but we should probably look into the possibility of getting the
// initiating event from webkit.
- GdkDragContext* context = gtk_drag_begin(
- drag_widget_, list,
+ drag_context_ = gtk_drag_begin(drag_widget_, list,
gtk_util::WebDragOpToGdkDragAction(allowed_ops),
1, // Drags are always initiated by the left button.
reinterpret_cast<GdkEvent*>(last_mouse_down));
@@ -132,7 +141,8 @@ void TabContentsDragSource::StartDragging(const WebDropData& drop_data,
// Sometimes the drag fails to start; |context| will be NULL and we won't
// get a drag-end signal.
- if (!context) {
+ if (!drag_context_) {
+ drag_failed_ = true;
drop_data_.reset();
if (tab_contents()->render_view_host())
tab_contents()->render_view_host()->DragSourceSystemDragEnded();
@@ -362,6 +372,7 @@ void TabContentsDragSource::OnDragEnd(GtkWidget* sender,
tab_contents()->render_view_host()->DragSourceSystemDragEnded();
drop_data_.reset();
+ drag_context_ = NULL;
}
gfx::NativeView TabContentsDragSource::GetContentNativeView() const {
diff --git a/chrome/browser/gtk/tab_contents_drag_source.h b/chrome/browser/gtk/tab_contents_drag_source.h
index 261c677..e1eb56e 100644
--- a/chrome/browser/gtk/tab_contents_drag_source.h
+++ b/chrome/browser/gtk/tab_contents_drag_source.h
@@ -84,6 +84,10 @@ class TabContentsDragSource : public MessageLoopForUI::Observer {
// initialization code sinks the reference.
GtkWidget* drag_widget_;
+ // Context created once drag starts. A NULL value indicates that there is
+ // no drag currently in progress.
+ GdkDragContext* drag_context_;
+
// The file mime type for a drag-out download.
string16 wide_download_mime_type_;