Chromium Code Reviews| 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 bc718eff70ce3a0ed357e28858ec1ca18f9dcf2f..f764cf735dd581d4a33edb992c9060cb0ff99fdf 100644 |
| --- a/ui/views/controls/menu/menu_controller.cc |
| +++ b/ui/views/controls/menu/menu_controller.cc |
| @@ -416,12 +416,7 @@ void MenuController::Cancel(ExitType type) { |
| // WARNING: the call to MenuClosed deletes us. |
| return; |
| } |
| - if (async_run_) { |
| - internal::MenuControllerDelegate* delegate = delegate_; |
| - MenuItemView* result = ExitMenuRun(); |
| - delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
| - result, accept_event_flags_); |
| - } |
| + ExitAsyncRun(); |
| } |
| void MenuController::AddNestedDelegate( |
| @@ -816,6 +811,11 @@ int MenuController::OnPerformDrop(SubmenuView* source, |
| // WARNING: the call to MenuClosed deletes us. |
| + // ExitAsyncRun can delete us, however CloseAllNestedMenus enqueues work which |
|
sky
2015/12/11 18:37:46
I'm nervous of posting the task. What work is caus
jonross
2016/01/06 21:18:31
The shutdown enqueues the closing the current widg
sky
2016/01/06 22:20:56
What do you mean by 'corrupted buffer that is rele
jonross
2016/01/08 20:52:01
I'm seeing a few memory errors:
- Found a corru
|
| + // our deletion interferes with. Perform exit afterwards. |
| + base::MessageLoopForUI::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&MenuController::ExitAsyncRun, weak_factory_.GetWeakPtr())); |
| return drop_target->GetDelegate()->OnPerformDrop( |
| drop_target, drop_position, event); |
| } |
| @@ -854,7 +854,13 @@ void MenuController::OnDragComplete(bool should_close) { |
| current_mouse_event_target_ = nullptr; |
| if (showing_ && should_close && GetActiveInstance() == this) { |
| CloseAllNestedMenus(); |
| - Cancel(EXIT_ALL); |
| + if (async_run_) { |
| + base::MessageLoopForUI::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&MenuController::CancelAll, weak_factory_.GetWeakPtr())); |
| + } else { |
| + Cancel(EXIT_ALL); |
| + } |
| } |
| } |
| @@ -1197,7 +1203,8 @@ MenuController::MenuController(bool blocking, |
| item_selected_by_touch_(false), |
| current_mouse_event_target_(nullptr), |
| current_mouse_pressed_state_(0), |
| - message_loop_(MenuMessageLoop::Create()) { |
| + message_loop_(MenuMessageLoop::Create()), |
| + weak_factory_(this) { |
| delegate_stack_.push_back(std::make_pair(delegate_, async_run_)); |
| active_instance_ = this; |
| } |
| @@ -1274,12 +1281,7 @@ void MenuController::Accept(MenuItemView* item, int event_flags) { |
| SetExitType(EXIT_ALL); |
| } |
| accept_event_flags_ = event_flags; |
| - if (async_run_) { |
| - internal::MenuControllerDelegate* delegate = delegate_; |
| - MenuItemView* result = ExitMenuRun(); |
| - delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
| - result, accept_event_flags_); |
| - } |
| + ExitAsyncRun(); |
| } |
| bool MenuController::ShowSiblingMenu(SubmenuView* source, |
| @@ -2417,6 +2419,19 @@ void MenuController::TerminateNestedMessageLoop() { |
| message_loop_->QuitNow(); |
| } |
| +void MenuController::ExitAsyncRun() { |
| + if (!async_run_) |
| + return; |
| + bool nested = delegate_stack_.size() > 1; |
| + // ExitMenuRun unwinds nested delegates |
| + internal::MenuControllerDelegate* delegate = delegate_; |
| + MenuItemView* result = ExitMenuRun(); |
| + delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
| + result, accept_event_flags_); |
| + if (nested && exit_type_ == EXIT_ALL) |
| + ExitAsyncRun(); |
| +} |
| + |
| MenuItemView* MenuController::ExitMenuRun() { |
| // Release the lock which prevents Chrome from shutting down while the menu is |
| // showing. |