Index: ui/views/view.cc |
diff --git a/ui/views/view.cc b/ui/views/view.cc |
index 080df12881d63898fafcc4bb54ed63f7f78764f3..73b1e4ef2f2d39d7a6ae94fe98f7e566a12e75d2 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; |