| Index: ui/views/controls/menu/menu_controller.cc
|
| diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
|
| index aa002f26882d79ca43b067baf83c580db4b26f93..a3b11ed50d04a03382598f71d5f036597a9bed71 100644
|
| --- a/ui/views/controls/menu/menu_controller.cc
|
| +++ b/ui/views/controls/menu/menu_controller.cc
|
| @@ -522,8 +522,11 @@ void MenuController::Cancel(ExitType type) {
|
| // triggers deleting us.
|
| DCHECK(selected);
|
| showing_ = false;
|
| - delegate_->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
|
| - selected->GetRootMenuItem(), accept_event_flags_);
|
| + // Verify that the delegate was not destroyed.
|
| + if (delegate_) {
|
| + delegate_->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
|
| + selected->GetRootMenuItem(), accept_event_flags_);
|
| + }
|
| // WARNING: the call to MenuClosed deletes us.
|
| return;
|
| }
|
| @@ -544,8 +547,8 @@ void MenuController::Cancel(ExitType type) {
|
|
|
| void MenuController::AddNestedDelegate(
|
| internal::MenuControllerDelegate* delegate) {
|
| - delegate_stack_.push_back(std::make_pair(delegate, async_run_));
|
| - delegate_ = delegate;
|
| + delegate_stack_.push_back(std::make_pair(delegate->AsWeakPtr(), async_run_));
|
| + delegate_ = delegate->AsWeakPtr();
|
| }
|
|
|
| void MenuController::SetAsyncRun(bool is_async) {
|
| @@ -978,7 +981,7 @@ int MenuController::OnPerformDrop(SubmenuView* source,
|
| if (drop_target->id() == MenuItemView::kEmptyMenuItemViewID)
|
| drop_target = drop_target->GetParentMenuItem();
|
|
|
| - if (!IsBlockingRun()) {
|
| + if (!IsBlockingRun() && delegate_) {
|
| delegate_->OnMenuClosed(
|
| internal::MenuControllerDelegate::DONT_NOTIFY_DELEGATE,
|
| item->GetRootMenuItem(), accept_event_flags_);
|
| @@ -1395,7 +1398,7 @@ MenuController::MenuController(bool blocking,
|
| showing_submenu_(false),
|
| active_mouse_view_id_(ViewStorage::GetInstance()->CreateStorageID()),
|
| hot_button_(nullptr),
|
| - delegate_(delegate),
|
| + delegate_(delegate->AsWeakPtr()),
|
| message_loop_depth_(0),
|
| async_run_(false),
|
| is_combobox_(false),
|
| @@ -1522,7 +1525,8 @@ bool MenuController::ShowSiblingMenu(SubmenuView* source,
|
| if (!alt_menu || (state_.item && state_.item->GetRootMenuItem() == alt_menu))
|
| return false;
|
|
|
| - delegate_->SiblingMenuCreated(alt_menu);
|
| + if (delegate_)
|
| + delegate_->SiblingMenuCreated(alt_menu);
|
|
|
| if (!button) {
|
| // If the delegate returns a menu, they must also return a button.
|
| @@ -2585,15 +2589,18 @@ void MenuController::ExitAsyncRun() {
|
| return;
|
| bool nested = delegate_stack_.size() > 1;
|
| // ExitMenuRun unwinds nested delegates
|
| - internal::MenuControllerDelegate* delegate = delegate_;
|
| + base::WeakPtr<internal::MenuControllerDelegate> delegate = delegate_;
|
| // MenuController may have been deleted when releasing ViewsDelegate ref.
|
| // However as |delegate| can outlive this, it must still be notified of the
|
| // menu closing so that it can perform teardown.
|
| int accept_event_flags = accept_event_flags_;
|
| base::WeakPtr<MenuController> this_ref = AsWeakPtr();
|
| MenuItemView* result = ExitMenuRun();
|
| - delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
|
| - result, accept_event_flags);
|
| + // The delegate may have been deleted.
|
| + if (delegate) {
|
| + delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
|
| + result, accept_event_flags);
|
| + }
|
| // |delegate| may have deleted this.
|
| if (this_ref && nested && exit_type_ == EXIT_ALL)
|
| ExitAsyncRun();
|
|
|