Fix crash when switching menus in menubar

This commit is contained in:
Cheng Zhao 2017-08-28 18:59:06 +09:00
parent b2f3625eaa
commit 4febbec102
2 changed files with 18 additions and 8 deletions

View file

@ -97,6 +97,9 @@ void MenuDelegate::WillHideMenu(views::MenuItemView* menu) {
void MenuDelegate::OnMenuClosed(views::MenuItemView* menu,
views::MenuRunner::RunResult result) {
// Only switch to new menu when current menu is closed.
if (button_to_open_)
button_to_open_->Activate(nullptr);
delete this;
}
@ -106,18 +109,22 @@ views::MenuItemView* MenuDelegate::GetSiblingMenu(
views::MenuAnchorPosition* anchor,
bool* has_mnemonics,
views::MenuButton**) {
// TODO(zcbenz): We should follow Chromium's logics on implementing the
// sibling menu switches, this code is almost a hack.
views::MenuButton* button;
AtomMenuModel* model;
if (menu_bar_->GetMenuButtonFromScreenPoint(screen_point, &model, &button) &&
button->tag() != id_) {
DCHECK(menu_runner_->IsRunning());
menu_runner_->Cancel();
// After canceling the menu, we need to wait until next tick
// so we are out of nested message loop.
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(base::IgnoreResult(&views::MenuButton::Activate),
base::Unretained(button), nullptr));
bool switch_in_progress = !!button_to_open_;
// Always update target to open.
button_to_open_ = button;
// Switching menu asyncnously to avoid crash.
if (!switch_in_progress) {
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&views::MenuRunner::Cancel,
base::Unretained(menu_runner_.get())));
}
}
return nullptr;

View file

@ -55,6 +55,9 @@ class MenuDelegate : public views::MenuDelegate {
std::unique_ptr<views::MenuDelegate> adapter_;
std::unique_ptr<views::MenuRunner> menu_runner_;
// The menu button to switch to.
views::MenuButton* button_to_open_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(MenuDelegate);
};