diff --git a/atom/browser/api/atom_api_menu_views.cc b/atom/browser/api/atom_api_menu_views.cc index 0a3b161830..2511f9765e 100644 --- a/atom/browser/api/atom_api_menu_views.cc +++ b/atom/browser/api/atom_api_menu_views.cc @@ -48,7 +48,7 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { // Show the menu. int32_t window_id = window->ID(); auto close_callback = base::Bind( - &MenuViews::ClosePopupAt, weak_factory_.GetWeakPtr(), window_id); + &MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id); menu_runners_[window_id] = std::unique_ptr(new MenuRunner( model(), flags, close_callback)); menu_runners_[window_id]->RunMenuAt( @@ -60,12 +60,23 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { } void MenuViews::ClosePopupAt(int32_t window_id) { - if (menu_runners_[window_id]) { - menu_runners_[window_id]->Cancel(); - menu_runners_.erase(window_id); + auto runner = menu_runners_.find(window_id); + if (runner != menu_runners_.end()) { + // Close the runner for the window. + runner->second->Cancel(); + } else if (window_id == -1) { + // Or just close all opened runners. + for (auto it = menu_runners_.begin(); it != menu_runners_.end();) { + // The iterator is invalidated after the call. + (it++)->second->Cancel(); + } } } +void MenuViews::OnClosed(int32_t window_id) { + menu_runners_.erase(window_id); +} + // static mate::WrappableBase* Menu::New(mate::Arguments* args) { return new MenuViews(args->isolate(), args->GetThis()); diff --git a/atom/browser/api/atom_api_menu_views.h b/atom/browser/api/atom_api_menu_views.h index d0c33b3960..190e7d1cdf 100644 --- a/atom/browser/api/atom_api_menu_views.h +++ b/atom/browser/api/atom_api_menu_views.h @@ -25,6 +25,8 @@ class MenuViews : public Menu { void ClosePopupAt(int32_t window_id) override; private: + void OnClosed(int32_t window_id); + // window ID -> open context menu std::map> menu_runners_; diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index bd3427bcd6..4713d62194 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -94,10 +94,13 @@ Menu.prototype.popup = function (window, x, y, positioningItem) { } Menu.prototype.closePopup = function (window) { - if (!window || window.constructor !== BrowserWindow) { - window = BrowserWindow.getFocusedWindow() + if (window && window.constructor !== BrowserWindow) { + this.closePopupAt(window.id) + } else { + // Passing -1 (invalid) would make closePopupAt close the all menu runners + // belong to this menu. + this.closePopupAt(-1) } - if (window) this.closePopupAt(window.id) } Menu.prototype.getMenuItemById = function (id) {