diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-06-07 23:30:15 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-06-07 23:30:15 +0200 |
commit | ea7d988b72587c265726ccfdabd56b4083c4d2fc (patch) | |
tree | dc8b3af0c279bf98c7ac11fd885eec42943b8efa /platform/macos | |
parent | 54e09c31adadcf3603ba8c3e16a0e03a7560d908 (diff) | |
parent | 1f7bf27780931eef193866a501801f4a9b3067c9 (diff) | |
download | redot-engine-ea7d988b72587c265726ccfdabd56b4083c4d2fc.tar.gz |
Merge pull request #92781 from bruvzg/menu_open_close_imp
[macOS] Improve native menu open/close callbacks.
Diffstat (limited to 'platform/macos')
-rw-r--r-- | platform/macos/godot_menu_delegate.mm | 9 | ||||
-rw-r--r-- | platform/macos/native_menu_macos.h | 5 | ||||
-rw-r--r-- | platform/macos/native_menu_macos.mm | 41 |
3 files changed, 46 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); |