diff options
Diffstat (limited to 'platform/macos/native_menu_macos.mm')
-rw-r--r-- | platform/macos/native_menu_macos.mm | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/platform/macos/native_menu_macos.mm b/platform/macos/native_menu_macos.mm index 1cf13a2d69..1ae1137ca0 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); @@ -436,7 +461,7 @@ int NativeMenuMacOS::add_icon_item(const RID &p_rid, const Ref<Texture2D> &p_ico obj->max_states = 0; obj->state = 0; DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); - if (ds && p_icon.is_valid()) { + if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) { obj->img = p_icon->get_image(); obj->img = obj->img->duplicate(); if (obj->img->is_compressed()) { @@ -467,7 +492,7 @@ int NativeMenuMacOS::add_icon_check_item(const RID &p_rid, const Ref<Texture2D> obj->max_states = 0; obj->state = 0; DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); - if (ds && p_icon.is_valid()) { + if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) { obj->img = p_icon->get_image(); obj->img = obj->img->duplicate(); if (obj->img->is_compressed()) { @@ -518,7 +543,7 @@ int NativeMenuMacOS::add_icon_radio_check_item(const RID &p_rid, const Ref<Textu obj->max_states = 0; obj->state = 0; DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); - if (ds && p_icon.is_valid()) { + if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) { obj->img = p_icon->get_image(); obj->img = obj->img->duplicate(); if (obj->img->is_compressed()) { @@ -1212,7 +1237,7 @@ void NativeMenuMacOS::set_item_icon(const RID &p_rid, int p_idx, const Ref<Textu GodotMenuItem *obj = [menu_item representedObject]; ERR_FAIL_NULL(obj); DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); - if (ds && p_icon.is_valid()) { + if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) { obj->img = p_icon->get_image(); obj->img = obj->img->duplicate(); if (obj->img->is_compressed()) { |