diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-15 07:09:29 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-15 07:09:29 +0000 |
commit | d942722de9c44795be2e8ec37889ee31d973af13 (patch) | |
tree | 9e8b689e23b702311b1e31ca58e5b77cb6ffe5a1 /ui | |
parent | a1de4cb35d3a7182e98311b7c78a671ffbe7f1aa (diff) | |
download | chromium_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.cc | 11 | ||||
-rw-r--r-- | ui/views/view.h | 5 |
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(¤tly_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_; |