.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
- .SetMethod("popupAt", &Menu::PopupAt);
+ .SetMethod("popupAt", &Menu::PopupAt)
+ .SetMethod("closePopupAt", &Menu::ClosePopupAt);
}
} // namespace api
virtual void PopupAt(Window* window, int x, int y, int positioning_item,
bool async) = 0;
+ virtual void ClosePopupAt(int32_t window_id) = 0;
std::unique_ptr<AtomMenuModel> model_;
Menu* parent_;
#include "atom/browser/api/atom_api_menu.h"
+#include <map>
#include <string>
#import "atom/browser/ui/cocoa/atom_menu_controller.h"
+using base::scoped_nsobject;
+
namespace atom {
namespace api {
void PopupAt(
Window* window, int x, int y, int positioning_item, bool async) override;
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
- int x, int y, int positioning_item, bool async);
+ int32_t window_id, int x, int y, int positioning_item,
+ bool async);
+ void ClosePopupAt(int32_t window_id) override;
- base::scoped_nsobject<AtomMenuController> menu_controller_;
+ scoped_nsobject<AtomMenuController> menu_controller_;
+ std::map<int32_t, scoped_nsobject<AtomMenuController>> popup_controllers_;
private:
friend class Menu;
return;
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
- native_window->GetWeakPtr(), x, y, positioning_item,
- async);
+ native_window->GetWeakPtr(), window->ID(), x, y,
+ positioning_item, async);
if (async)
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
else
}
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
- int x, int y, int positioning_item, bool async) {
+ int32_t window_id, int x, int y, int positioning_item,
+ bool async) {
if (!native_window)
return;
brightray::InspectableWebContents* web_contents =
if (!web_contents)
return;
- base::scoped_nsobject<AtomMenuController> menu_controller(
- [[AtomMenuController alloc] initWithModel:model_.get()
+ auto close_callback = base::Bind(&MenuMac::ClosePopupAt,
+ weak_factory_.GetWeakPtr(), window_id);
+ popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>(
+ [[AtomMenuController alloc] initWithModel:model()
useDefaultAccelerator:NO]);
- NSMenu* menu = [menu_controller menu];
+ NSMenu* menu = [popup_controllers_[window_id] menu];
NSView* view = web_contents->GetView()->GetNativeView();
// Which menu item to show.
if (async) {
+ [popup_controllers_[window_id] setCloseCallback:close_callback];
// Make sure events can be pumped while the menu is up.
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
+ close_callback.Run();
}
}
+void MenuMac::ClosePopupAt(int32_t window_id) {
+ popup_controllers_.erase(window_id);
+}
+
// static
void Menu::SetApplicationMenu(Menu* base_menu) {
MenuMac* menu = static_cast<MenuMac*>(base_menu);
NativeWindow* window() const { return window_.get(); }
+ int32_t ID() const;
+
protected:
Window(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
void SetVibrancy(mate::Arguments* args);
- int32_t ID() const;
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
// Remove this window from parent window's |child_windows_|.
#import <Cocoa/Cocoa.h>
+#include "base/callback.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/string16.h"
base::scoped_nsobject<NSMenu> menu_;
BOOL isMenuOpen_;
BOOL useDefaultAccelerator_;
+ base::Callback<void()> closeCallback;
}
@property(nonatomic, assign) atom::AtomMenuModel* model;
// to the contents of the model after calling this will not be noticed.
- (id)initWithModel:(atom::AtomMenuModel*)model useDefaultAccelerator:(BOOL)use;
+- (void)setCloseCallback:(const base::Callback<void()>&)callback;
+
// Populate current NSMenu with |model|.
- (void)populateWithModel:(atom::AtomMenuModel*)model;
[super dealloc];
}
+- (void)setCloseCallback:(const base::Callback<void()>&)callback {
+ closeCallback = callback;
+}
+
- (void)populateWithModel:(atom::AtomMenuModel*)model {
if (!menu_)
return;
- (void)menuDidClose:(NSMenu*)menu {
if (isMenuOpen_) {
- model_->MenuWillClose();
isMenuOpen_ = NO;
+ model_->MenuWillClose();
+ if (!closeCallback.is_null())
+ closeCallback.Run();
}
}
this.popupAt(window, x, y, positioningItem, asyncPopup)
}
+Menu.prototype.closePopup = function (window) {
+ if (window == null || window.constructor !== BrowserWindow) {
+ window = BrowserWindow.getFocusedWindow()
+ }
+ if (window != null) {
+ this.closePopupAt(window.id)
+ }
+}
+
Menu.prototype.append = function (item) {
return this.insert(this.getItemCount(), item)
}