From 65129d2aa286c03eef9f177868f9136b44ce64ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:47:23 +0300 Subject: [PATCH] [macOS] Fix native menu submenu items have wrong action and accelerators set. --- platform/macos/godot_menu_item.h | 1 + platform/macos/godot_menu_item.mm | 1 + platform/macos/native_menu_macos.mm | 30 +++++++++++++++++++++++------ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/platform/macos/godot_menu_item.h b/platform/macos/godot_menu_item.h index ed63e78ec86..95cc91f3114 100644 --- a/platform/macos/godot_menu_item.h +++ b/platform/macos/godot_menu_item.h @@ -50,6 +50,7 @@ enum GlobalMenuCheckType { Callable key_callback; Callable hover_callback; Variant meta; + Key accel; GlobalMenuCheckType checkable_type; bool checked; int max_states; diff --git a/platform/macos/godot_menu_item.mm b/platform/macos/godot_menu_item.mm index 687b4e85a99..49495676271 100644 --- a/platform/macos/godot_menu_item.mm +++ b/platform/macos/godot_menu_item.mm @@ -41,6 +41,7 @@ self->checked = false; self->max_states = 0; self->state = 0; + self->accel = Key::NONE; return self; } diff --git a/platform/macos/native_menu_macos.mm b/platform/macos/native_menu_macos.mm index bd3ccf25f5c..33bfb210ffd 100644 --- a/platform/macos/native_menu_macos.mm +++ b/platform/macos/native_menu_macos.mm @@ -415,6 +415,7 @@ int NativeMenuMacOS::add_item(const RID &p_rid, const String &p_label, const Cal obj->callback = p_callback; obj->key_callback = p_key_callback; obj->meta = p_tag; + obj->accel = p_accel; [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } @@ -433,6 +434,7 @@ int NativeMenuMacOS::add_check_item(const RID &p_rid, const String &p_label, con obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX; + obj->accel = p_accel; [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } @@ -450,6 +452,7 @@ int NativeMenuMacOS::add_icon_item(const RID &p_rid, const Ref &p_ico obj->callback = p_callback; obj->key_callback = p_key_callback; obj->meta = p_tag; + obj->accel = p_accel; DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); 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(); @@ -479,6 +482,7 @@ int NativeMenuMacOS::add_icon_check_item(const RID &p_rid, const Ref obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX; + obj->accel = p_accel; DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); 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(); @@ -508,6 +512,7 @@ int NativeMenuMacOS::add_radio_check_item(const RID &p_rid, const String &p_labe obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON; + obj->accel = p_accel; [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } @@ -526,6 +531,7 @@ int NativeMenuMacOS::add_icon_radio_check_item(const RID &p_rid, const Refkey_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON; + obj->accel = p_accel; DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); 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(); @@ -556,6 +562,7 @@ int NativeMenuMacOS::add_multistate_item(const RID &p_rid, const String &p_label obj->meta = p_tag; obj->max_states = p_max_states; obj->state = p_default_state; + obj->accel = p_accel; [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } @@ -1096,6 +1103,8 @@ void NativeMenuMacOS::set_item_submenu(const RID &p_rid, int p_idx, const RID &p NSMenuItem *menu_item = [md->menu itemAtIndex:p_idx]; if (menu_item) { [md->menu setSubmenu:md_sub->menu forItem:menu_item]; + [menu_item setAction:nil]; + [menu_item setKeyEquivalent:@""]; } } else { int item_start = _get_system_menu_start(md->menu); @@ -1108,7 +1117,11 @@ void NativeMenuMacOS::set_item_submenu(const RID &p_rid, int p_idx, const RID &p ERR_PRINT("Can't remove open menu!"); return; } + GodotMenuItem *obj = [menu_item representedObject]; + String keycode = KeyMappingMacOS::keycode_get_native_string(obj->accel & KeyModifierMask::CODE_MASK); [md->menu setSubmenu:nil forItem:menu_item]; + [menu_item setAction:@selector(globalMenuCallback:)]; + [menu_item setKeyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]]; } } } @@ -1124,12 +1137,17 @@ void NativeMenuMacOS::set_item_accelerator(const RID &p_rid, int p_idx, Key p_ke ERR_FAIL_COND(p_idx >= item_start + item_count); NSMenuItem *menu_item = [md->menu itemAtIndex:p_idx]; if (menu_item) { - if (p_keycode == Key::NONE) { - [menu_item setKeyEquivalent:@""]; - } else { - [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_keycode)]; - String keycode = KeyMappingMacOS::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK); - [menu_item setKeyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]]; + GodotMenuItem *obj = [menu_item representedObject]; + obj->accel = p_keycode; + NSMenu *sub_menu = [menu_item submenu]; + if (!sub_menu) { + if (p_keycode == Key::NONE) { + [menu_item setKeyEquivalent:@""]; + } else { + [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_keycode)]; + String keycode = KeyMappingMacOS::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK); + [menu_item setKeyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]]; + } } } }