summaryrefslogtreecommitdiffstats
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/macos/godot_menu_delegate.mm9
-rw-r--r--platform/macos/native_menu_macos.h5
-rw-r--r--platform/macos/native_menu_macos.mm41
-rw-r--r--platform/windows/native_menu_windows.cpp5
-rw-r--r--platform/windows/native_menu_windows.h2
5 files changed, 53 insertions, 9 deletions
diff --git a/platform/macos/godot_menu_delegate.mm b/platform/macos/godot_menu_delegate.mm
index 5c1e849715..3f7dfac3de 100644
--- a/platform/macos/godot_menu_delegate.mm
+++ b/platform/macos/godot_menu_delegate.mm
@@ -40,13 +40,20 @@
- (void)doNothing:(id)sender {
}
-- (void)menuNeedsUpdate:(NSMenu *)menu {
+- (void)menuWillOpen:(NSMenu *)menu {
if (NativeMenu::get_singleton()) {
NativeMenuMacOS *nmenu = (NativeMenuMacOS *)NativeMenu::get_singleton();
nmenu->_menu_open(menu);
}
}
+- (void)menuNeedsUpdate:(NSMenu *)menu {
+ if (NativeMenu::get_singleton()) {
+ NativeMenuMacOS *nmenu = (NativeMenuMacOS *)NativeMenu::get_singleton();
+ nmenu->_menu_need_update(menu);
+ }
+}
+
- (void)menuDidClose:(NSMenu *)menu {
if (NativeMenu::get_singleton()) {
NativeMenuMacOS *nmenu = (NativeMenuMacOS *)NativeMenu::get_singleton();
diff --git a/platform/macos/native_menu_macos.h b/platform/macos/native_menu_macos.h
index b5dbb8b9b0..42cf6740d9 100644
--- a/platform/macos/native_menu_macos.h
+++ b/platform/macos/native_menu_macos.h
@@ -73,8 +73,11 @@ class NativeMenuMacOS : public NativeMenu {
public:
void _register_system_menus(NSMenu *p_main_menu, NSMenu *p_application_menu, NSMenu *p_window_menu, NSMenu *p_help_menu, NSMenu *p_dock_menu);
NSMenu *_get_dock_menu();
+
+ void _menu_need_update(NSMenu *p_menu);
void _menu_open(NSMenu *p_menu);
void _menu_close(NSMenu *p_menu);
+ void _menu_close_cb(const RID &p_rid);
virtual bool has_feature(Feature p_feature) const override;
@@ -98,6 +101,8 @@ public:
virtual void set_minimum_width(const RID &p_rid, float p_width) override;
virtual float get_minimum_width(const RID &p_rid) const override;
+ virtual bool is_opened(const RID &p_rid) const override;
+
virtual int add_submenu_item(const RID &p_rid, const String &p_label, const RID &p_submenu_rid, const Variant &p_tag = Variant(), int p_index = -1) override;
virtual int add_item(const RID &p_rid, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override;
virtual int add_check_item(const RID &p_rid, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override;
diff --git a/platform/macos/native_menu_macos.mm b/platform/macos/native_menu_macos.mm
index 1cf13a2d69..97e8b6a7f1 100644
--- a/platform/macos/native_menu_macos.mm
+++ b/platform/macos/native_menu_macos.mm
@@ -91,11 +91,22 @@ void NativeMenuMacOS::_menu_open(NSMenu *p_menu) {
if (menu_lookup.has(p_menu)) {
MenuData *md = menus.get_or_null(menu_lookup[p_menu]);
if (md) {
+ // Note: Set "is_open" flag, but do not call callback, menu items can't be modified during this call and "_menu_need_update" will be called right before it.
md->is_open = true;
+ }
+ }
+}
+
+void NativeMenuMacOS::_menu_need_update(NSMenu *p_menu) {
+ if (menu_lookup.has(p_menu)) {
+ MenuData *md = menus.get_or_null(menu_lookup[p_menu]);
+ if (md) {
+ // Note: "is_open" flag is set by "_menu_open", this method is always called before menu is shown, but might be called for the other reasons as well.
if (md->open_cb.is_valid()) {
Variant ret;
Callable::CallError ce;
+ // Callback is called directly, since it's expected to modify menu items before it's shown.
md->open_cb.callp(nullptr, 0, ret, ce);
if (ce.error != Callable::CallError::CALL_OK) {
ERR_PRINT(vformat("Failed to execute menu open callback: %s.", Variant::get_callable_error_text(md->open_cb, nullptr, 0, ce)));
@@ -110,15 +121,22 @@ void NativeMenuMacOS::_menu_close(NSMenu *p_menu) {
MenuData *md = menus.get_or_null(menu_lookup[p_menu]);
if (md) {
md->is_open = false;
- if (md->close_cb.is_valid()) {
- Variant ret;
- Callable::CallError ce;
- md->close_cb.callp(nullptr, 0, ret, ce);
- if (ce.error != Callable::CallError::CALL_OK) {
- ERR_PRINT(vformat("Failed to execute menu close callback: %s.", Variant::get_callable_error_text(md->close_cb, nullptr, 0, ce)));
- }
- }
+ // Callback called deferred, since it should not modify menu items during "_menu_close" call.
+ callable_mp(this, &NativeMenuMacOS::_menu_close_cb).call_deferred(menu_lookup[p_menu]);
+ }
+ }
+}
+
+void NativeMenuMacOS::_menu_close_cb(const RID &p_rid) {
+ MenuData *md = menus.get_or_null(p_rid);
+ if (md->close_cb.is_valid()) {
+ Variant ret;
+ Callable::CallError ce;
+
+ md->close_cb.callp(nullptr, 0, ret, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_PRINT(vformat("Failed to execute menu close callback: %s.", Variant::get_callable_error_text(md->close_cb, nullptr, 0, ce)));
}
}
}
@@ -328,6 +346,13 @@ float NativeMenuMacOS::get_minimum_width(const RID &p_rid) const {
return md->menu.minimumWidth * DisplayServer::get_singleton()->screen_get_max_scale();
}
+bool NativeMenuMacOS::is_opened(const RID &p_rid) const {
+ const MenuData *md = menus.get_or_null(p_rid);
+ ERR_FAIL_NULL_V(md, false);
+
+ return md->is_open;
+}
+
int NativeMenuMacOS::add_submenu_item(const RID &p_rid, const String &p_label, const RID &p_submenu_rid, const Variant &p_tag, int p_index) {
MenuData *md = menus.get_or_null(p_rid);
MenuData *md_sub = menus.get_or_null(p_submenu_rid);
diff --git a/platform/windows/native_menu_windows.cpp b/platform/windows/native_menu_windows.cpp
index 40a08f87df..cc96d3f5de 100644
--- a/platform/windows/native_menu_windows.cpp
+++ b/platform/windows/native_menu_windows.cpp
@@ -231,6 +231,11 @@ float NativeMenuWindows::get_minimum_width(const RID &p_rid) const {
return 0.f;
}
+bool NativeMenuWindows::is_opened(const RID &p_rid) const {
+ // Not supported.
+ return false;
+}
+
int NativeMenuWindows::add_submenu_item(const RID &p_rid, const String &p_label, const RID &p_submenu_rid, const Variant &p_tag, int p_index) {
MenuData *md = menus.get_or_null(p_rid);
MenuData *md_sub = menus.get_or_null(p_submenu_rid);
diff --git a/platform/windows/native_menu_windows.h b/platform/windows/native_menu_windows.h
index 74fd231903..5c4aaa52c8 100644
--- a/platform/windows/native_menu_windows.h
+++ b/platform/windows/native_menu_windows.h
@@ -90,6 +90,8 @@ public:
virtual void set_minimum_width(const RID &p_rid, float p_width) override;
virtual float get_minimum_width(const RID &p_rid) const override;
+ virtual bool is_opened(const RID &p_rid) const override;
+
virtual int add_submenu_item(const RID &p_rid, const String &p_label, const RID &p_submenu_rid, const Variant &p_tag = Variant(), int p_index = -1) override;
virtual int add_item(const RID &p_rid, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override;
virtual int add_check_item(const RID &p_rid, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override;