Index: ui/views/widget/widget.cc |
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc |
index 7178e37ebef7611dff99032116ecad027523d809..f1f748ff60f31af54bccebf756190e0b86e7e640 100644 |
--- a/ui/views/widget/widget.cc |
+++ b/ui/views/widget/widget.cc |
@@ -1151,17 +1151,23 @@ void Widget::OnMouseEvent(ui::MouseEvent* event) { |
ScopedEvent scoped(this, *event); |
View* root_view = GetRootView(); |
switch (event->type()) { |
- case ui::ET_MOUSE_PRESSED: |
+ case ui::ET_MOUSE_PRESSED: { |
last_mouse_event_was_move_ = false; |
+ |
+ // We may get deleted by the time we return from OnMousePressed. So we |
+ // use an observer to make sure we are still alive. |
+ WidgetDeletionObserver widget_deletion_observer(this); |
// Make sure we're still visible before we attempt capture as the mouse |
// press processing may have made the window hide (as happens with menus). |
- if (root_view && root_view->OnMousePressed(*event) && IsVisible()) { |
+ if (root_view && root_view->OnMousePressed(*event) && |
+ widget_deletion_observer.IsWidgetAlive() && IsVisible()) { |
is_mouse_button_pressed_ = true; |
if (!native_widget_->HasCapture()) |
native_widget_->SetCapture(); |
event->SetHandled(); |
} |
return; |
+ } |
case ui::ET_MOUSE_RELEASED: |
last_mouse_event_was_move_ = false; |
is_mouse_button_pressed_ = false; |
@@ -1425,6 +1431,34 @@ void Widget::ReplaceInputMethod(InputMethod* input_method) { |
input_method->Init(this); |
} |
+//////////////////////////////////////////////////////////////////////////////// |
+// WidgetDeletionObserver: |
+ |
+WidgetDeletionObserver::WidgetDeletionObserver(Widget* widget) |
+ : widget_(widget) { |
+ if (widget_) |
+ widget_->AddObserver(this); |
+} |
+ |
+WidgetDeletionObserver::~WidgetDeletionObserver() { |
+ CleanupWidget(); |
+} |
+ |
+bool WidgetDeletionObserver::IsWidgetAlive() { |
+ return widget_; |
+} |
+ |
+void WidgetDeletionObserver::OnWidgetDestroying(Widget* widget) { |
+ CleanupWidget(); |
+} |
+ |
+void WidgetDeletionObserver::CleanupWidget() { |
+ if (widget_) { |
+ widget_->RemoveObserver(this); |
+ widget_ = NULL; |
+ } |
+} |
+ |
namespace internal { |
//////////////////////////////////////////////////////////////////////////////// |