Add async option to menu.popup

This commit is contained in:
Kevin Sawicki 2017-02-15 15:57:36 -08:00
parent b091d104f5
commit 4430927f98
5 changed files with 38 additions and 15 deletions

View file

@ -53,9 +53,8 @@ class Menu : public mate::TrackableObject<Menu>,
void ExecuteCommand(int command_id, int event_flags) override; void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override; void MenuWillShow(ui::SimpleMenuModel* source) override;
virtual void PopupAt(Window* window, virtual void PopupAt(Window* window, int x, int y, int positioning_item,
int x = -1, int y = -1, bool async) = 0;
int positioning_item = 0) = 0;
std::unique_ptr<AtomMenuModel> model_; std::unique_ptr<AtomMenuModel> model_;
Menu* parent_; Menu* parent_;

View file

@ -19,9 +19,10 @@ class MenuMac : public Menu {
protected: protected:
MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper); MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> 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<NativeWindow>& native_window, void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
int x, int y, int positioning_item); int x, int y, int positioning_item, bool async);
base::scoped_nsobject<AtomMenuController> menu_controller_; base::scoped_nsobject<AtomMenuController> menu_controller_;

View file

@ -16,6 +16,8 @@
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
using content::BrowserThread;
namespace atom { namespace atom {
namespace api { namespace api {
@ -25,18 +27,23 @@ MenuMac::MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
weak_factory_(this) { 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(); NativeWindow* native_window = window->window();
if (!native_window) if (!native_window)
return; return;
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(), native_window->GetWeakPtr(), x, y, positioning_item,
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<NativeWindow>& native_window, void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
int x, int y, int positioning_item) { int x, int y, int positioning_item, bool async) {
if (!native_window) if (!native_window)
return; return;
brightray::InspectableWebContents* web_contents = brightray::InspectableWebContents* web_contents =
@ -82,7 +89,8 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
if (rightmostMenuPoint > screenRight) if (rightmostMenuPoint > screenRight)
position.x = position.x - [menu size].width; position.x = position.x - [menu size].width;
{
if (async) {
// Make sure events can be pumped while the menu is up. // Make sure events can be pumped while the menu is up.
base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current()); base::MessageLoop::current());
@ -96,8 +104,10 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
// Don't emit unresponsive event when showing menu. // Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor; atom::UnresponsiveSuppressor suppressor;
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
// Show the menu. } else {
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
[menu popUpMenuPositioningItem:item atLocation:position inView:view]; [menu popUpMenuPositioningItem:item atLocation:position inView:view];
} }
} }

View file

@ -19,7 +19,8 @@ class MenuViews : public Menu {
MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper); MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
protected: 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(); void OnMenuClosed();
private: private:

View file

@ -144,6 +144,9 @@ Menu.prototype._init = function () {
} }
Menu.prototype.popup = function (window, x, y, positioningItem) { Menu.prototype.popup = function (window, x, y, positioningItem) {
let asyncPopup = false
// menu.popup(x, y, positioningItem)
if (typeof window !== 'object' || window.constructor !== BrowserWindow) { if (typeof window !== 'object' || window.constructor !== BrowserWindow) {
// Shift. // Shift.
positioningItem = y positioningItem = y
@ -152,6 +155,15 @@ Menu.prototype.popup = function (window, x, y, positioningItem) {
window = BrowserWindow.getFocusedWindow() 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. // Default to showing under mouse location.
if (typeof x !== 'number') x = -1 if (typeof x !== 'number') x = -1
if (typeof y !== 'number') y = -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. // Default to not highlighting any item.
if (typeof positioningItem !== 'number') positioningItem = -1 if (typeof positioningItem !== 'number') positioningItem = -1
this.popupAt(window, x, y, positioningItem) this.popupAt(window, x, y, positioningItem, asyncPopup)
} }
Menu.prototype.append = function (item) { Menu.prototype.append = function (item) {