summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorerg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-15 07:09:29 +0000
committererg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-15 07:09:29 +0000
commitd942722de9c44795be2e8ec37889ee31d973af13 (patch)
tree9e8b689e23b702311b1e31ca58e5b77cb6ffe5a1 /ui
parenta1de4cb35d3a7182e98311b7c78a671ffbe7f1aa (diff)
downloadchromium_src-d942722de9c44795be2e8ec37889ee31d973af13.zip
chromium_src-d942722de9c44795be2e8ec37889ee31d973af13.tar.gz
chromium_src-d942722de9c44795be2e8ec37889ee31d973af13.tar.bz2
linux_aura: Fix crash on drags from the omnibox.
When we receive a mouse move event, there may be more events behind it in the queue. Prevent those further mouse events from also triggering a nested drag message loop. BUG=268797 Review URL: https://chromiumcodereview.appspot.com/22934007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217757 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/views/view.cc11
-rw-r--r--ui/views/view.h5
2 files changed, 16 insertions, 0 deletions
diff --git a/ui/views/view.cc b/ui/views/view.cc
index 080df12..73b1e4e 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -9,6 +9,7 @@
#include <algorithm>
#include <cmath>
+#include "base/auto_reset.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
@@ -185,6 +186,7 @@ View::View()
accessibility_focusable_(false),
context_menu_controller_(NULL),
drag_controller_(NULL),
+ currently_dragging_(false),
post_dispatch_handler_(new internal::PostEventDispatchHandler(this)),
native_view_accessibility_(NULL) {
AddPostTargetHandler(post_dispatch_handler_.get());
@@ -194,6 +196,10 @@ View::~View() {
if (parent_)
parent_->RemoveChildView(this);
+ // If we destroy the view during a drag, AutoReset will probably write to
+ // freed memory.
+ DCHECK(!currently_dragging_);
+
for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) {
(*i)->parent_ = NULL;
if (!(*i)->owned_by_client_)
@@ -2318,10 +2324,14 @@ bool View::DoDrag(const ui::LocatedEvent& event,
const gfx::Point& press_pt,
ui::DragDropTypes::DragEventSource source) {
#if !defined(OS_MACOSX)
+ if (currently_dragging_)
+ return false;
+
int drag_operations = GetDragOperations(press_pt);
if (drag_operations == ui::DragDropTypes::DRAG_NONE)
return false;
+ base::AutoReset<bool> updating_focus(&currently_dragging_, true);
OSExchangeData data;
WriteDragData(press_pt, &data);
@@ -2331,6 +2341,7 @@ bool View::DoDrag(const ui::LocatedEvent& event,
ConvertPointToWidget(this, &widget_location);
GetWidget()->RunShellDrag(this, data, widget_location, drag_operations,
source);
+
return true;
#else
return false;
diff --git a/ui/views/view.h b/ui/views/view.h
index 2ffc620..337012c 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -1540,6 +1540,11 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
DragController* drag_controller_;
+ // True while we're performing DoDrag(). On X11, we can have multiple mouse
+ // move events in our event queue when we start a drag, so we need a way to
+ // ignore events after the first one.
+ bool currently_dragging_;
+
// Input --------------------------------------------------------------------
scoped_ptr<internal::PostEventDispatchHandler> post_dispatch_handler_;