diff --git a/atom/browser/api/atom_api_menu.h b/atom/browser/api/atom_api_menu.h index 97b63600492c..772b2f3c088d 100644 --- a/atom/browser/api/atom_api_menu.h +++ b/atom/browser/api/atom_api_menu.h @@ -53,9 +53,8 @@ class Menu : public mate::TrackableObject, void ExecuteCommand(int command_id, int event_flags) override; void MenuWillShow(ui::SimpleMenuModel* source) override; - virtual void PopupAt(Window* window, - int x = -1, int y = -1, - int positioning_item = 0) = 0; + virtual void PopupAt(Window* window, int x, int y, int positioning_item, + bool async) = 0; std::unique_ptr model_; Menu* parent_; diff --git a/atom/browser/api/atom_api_menu_mac.h b/atom/browser/api/atom_api_menu_mac.h index 4539efb26ce1..0c5c7f7f98c4 100644 --- a/atom/browser/api/atom_api_menu_mac.h +++ b/atom/browser/api/atom_api_menu_mac.h @@ -19,9 +19,10 @@ class MenuMac : public Menu { protected: MenuMac(v8::Isolate* isolate, v8::Local wrapper); - void PopupAt(Window* window, int x, int y, int positioning_item) override; + void PopupAt( + Window* window, int x, int y, int positioning_item, bool async) override; void PopupOnUI(const base::WeakPtr& native_window, - int x, int y, int positioning_item); + int x, int y, int positioning_item, bool async); base::scoped_nsobject menu_controller_; diff --git a/atom/browser/api/atom_api_menu_mac.mm b/atom/browser/api/atom_api_menu_mac.mm index ed4dae372ee6..84a6b8d9df5b 100644 --- a/atom/browser/api/atom_api_menu_mac.mm +++ b/atom/browser/api/atom_api_menu_mac.mm @@ -16,6 +16,8 @@ #include "atom/common/node_includes.h" +using content::BrowserThread; + namespace atom { namespace api { @@ -25,18 +27,23 @@ MenuMac::MenuMac(v8::Isolate* isolate, v8::Local wrapper) weak_factory_(this) { } -void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { +void MenuMac::PopupAt( + Window* window, int x, int y, int positioning_item, bool async) { NativeWindow* native_window = window->window(); if (!native_window) return; - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(), - native_window->GetWeakPtr(), x, y, positioning_item)); + auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(), + native_window->GetWeakPtr(), x, y, positioning_item, + async); + if (async) + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup); + else + popup.Run(); } void MenuMac::PopupOnUI(const base::WeakPtr& native_window, - int x, int y, int positioning_item) { + int x, int y, int positioning_item, bool async) { if (!native_window) return; brightray::InspectableWebContents* web_contents = @@ -82,7 +89,8 @@ void MenuMac::PopupOnUI(const base::WeakPtr& native_window, if (rightmostMenuPoint > screenRight) position.x = position.x - [menu size].width; - { + + if (async) { // Make sure events can be pumped while the menu is up. base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoop::current()); @@ -96,8 +104,10 @@ void MenuMac::PopupOnUI(const base::WeakPtr& native_window, // Don't emit unresponsive event when showing menu. atom::UnresponsiveSuppressor suppressor; - - // Show the menu. + [menu popUpMenuPositioningItem:item atLocation:position inView:view]; + } else { + // Don't emit unresponsive event when showing menu. + atom::UnresponsiveSuppressor suppressor; [menu popUpMenuPositioningItem:item atLocation:position inView:view]; } } diff --git a/atom/browser/api/atom_api_menu_views.h b/atom/browser/api/atom_api_menu_views.h index c17dee353628..5e5dc8e93dc9 100644 --- a/atom/browser/api/atom_api_menu_views.h +++ b/atom/browser/api/atom_api_menu_views.h @@ -19,7 +19,8 @@ class MenuViews : public Menu { MenuViews(v8::Isolate* isolate, v8::Local wrapper); protected: - void PopupAt(Window* window, int x, int y, int positioning_item) override; + void PopupAt( + Window* window, int x, int y, int positioning_item, bool async) override; void OnMenuClosed(); private: diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index 167e9a744ec0..e4fda6d5b070 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -144,6 +144,9 @@ Menu.prototype._init = function () { } Menu.prototype.popup = function (window, x, y, positioningItem) { + let asyncPopup = false + + // menu.popup(x, y, positioningItem) if (typeof window !== 'object' || window.constructor !== BrowserWindow) { // Shift. positioningItem = y @@ -152,6 +155,15 @@ Menu.prototype.popup = function (window, x, y, positioningItem) { window = BrowserWindow.getFocusedWindow() } + // menu.popup(window, {}) + if (typeof x === 'object') { + const options = x + x = options.x + y = options.y + positioningItem = options.positioningItem + asyncPopup = options.async + } + // Default to showing under mouse location. if (typeof x !== 'number') x = -1 if (typeof y !== 'number') y = -1 @@ -159,7 +171,7 @@ Menu.prototype.popup = function (window, x, y, positioningItem) { // Default to not highlighting any item. if (typeof positioningItem !== 'number') positioningItem = -1 - this.popupAt(window, x, y, positioningItem) + this.popupAt(window, x, y, positioningItem, asyncPopup) } Menu.prototype.append = function (item) {