From 0fa669c09727df15b10eccb9ab220230891488f8 Mon Sep 17 00:00:00 2001
From: bruvzg <7645683+bruvzg@users.noreply.github.com>
Date: Mon, 30 Sep 2024 12:19:48 +0300
Subject: [PATCH] [macOS] Add native "Edit" menu.
---
doc/classes/NativeMenu.xml | 33 +++++++++
editor/editor_node.cpp | 3 +
platform/macos/display_server_macos.h | 2 +
platform/macos/display_server_macos.mm | 67 +++++++++++++++++-
platform/macos/godot_content_view.h | 1 +
platform/macos/godot_content_view.mm | 60 ++++++++++++++++
platform/macos/godot_menu_delegate.mm | 6 +-
platform/macos/native_menu_macos.h | 12 +++-
platform/macos/native_menu_macos.mm | 98 +++++++++++++++++++++++---
scene/gui/popup_menu.cpp | 10 +++
servers/display/native_menu.cpp | 22 ++++++
servers/display/native_menu.h | 6 ++
12 files changed, 308 insertions(+), 12 deletions(-)
diff --git a/doc/classes/NativeMenu.xml b/doc/classes/NativeMenu.xml
index 2b9e4141068..bc261e20020 100644
--- a/doc/classes/NativeMenu.xml
+++ b/doc/classes/NativeMenu.xml
@@ -401,6 +401,14 @@
[b]Note:[/b] This method is implemented only on macOS.
+
+
+
+
+ Returns [code]true[/code] if system menu has no default items.
+ [b]Note:[/b] This method is implemented only on macOS.
+
+
@@ -720,6 +728,25 @@
[b]Note:[/b] This method is implemented only on macOS.
+
+
+
+
+
+ Hides/shows the system menu. Only system menus with no default items can be hidden. When it is hidden, an item does not appear in a menu and its action cannot be invoked.
+ [b]Note:[/b] This method is implemented only on macOS.
+
+
+
+
+
+
+
+ Sets system menu name. If set to empty string, default menu name is restored.
+ [b]Note:[/b] On macOS, only [constant FILE_MENU_ID] can be renamed.
+ [b]Note:[/b] This method is implemented only on macOS.
+
+
@@ -755,5 +782,11 @@
Dock icon right-click menu ID (on macOS this menu include standard application control items and a list of open windows).
+
+ "Edit" menu ID (on macOS this menu includes "Cut", "Copy", and "Paste" items).
+
+
+ "File" menu ID (on macOS this menu is empty and is hidden by default, this menu is shown before "Edit" menu).
+
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 665255b9b24..fb681121053 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -7168,6 +7168,9 @@ EditorNode::EditorNode() {
file_menu = memnew(PopupMenu);
file_menu->set_name(TTR("Scene"));
+ if (global_menu && NativeMenu::get_singleton()->has_system_menu(NativeMenu::FILE_MENU_ID)) {
+ file_menu->set_system_menu(NativeMenu::FILE_MENU_ID);
+ }
main_menu->add_child(file_menu);
main_menu->set_menu_tooltip(0, TTR("Operations with scene files."));
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index 97af6d0a5a2..0087cb0c47e 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -217,6 +217,8 @@ private:
WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect);
void _update_window_style(WindowData p_wd);
+ void _get_action_key(const StringName &p_name, String &r_keycode, unsigned int &r_keymask) const;
+
void _update_displays_arrangement();
Point2i _get_native_screen_position(int p_screen) const;
static void _displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info);
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index f6c1d11028d..38a6b54e23a 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -43,6 +43,7 @@
#include "tts_macos.h"
#include "core/config/project_settings.h"
+#include "core/input/input_map.h"
#include "core/io/marshalls.h"
#include "core/math/geometry_2d.h"
#include "core/os/keyboard.h"
@@ -3471,6 +3472,34 @@ bool DisplayServerMacOS::mouse_process_popups(bool p_close) {
return closed;
}
+void DisplayServerMacOS::_get_action_key(const StringName &p_name, String &r_keycode, unsigned int &r_keymask) const {
+ r_keycode = String();
+ r_keymask = 0;
+
+ const List[> *events = InputMap::get_singleton()->action_get_events(p_name);
+ if (!events) {
+ return;
+ }
+ const List][>::Element *first_event = events->front();
+ if (!first_event) {
+ return;
+ }
+ const Ref event = first_event->get();
+ if (event.is_null()) {
+ return;
+ }
+ if (event->get_keycode() != Key::NONE) {
+ r_keycode = KeyMappingMacOS::keycode_get_native_string(event->get_keycode() & KeyModifierMask::CODE_MASK);
+ r_keymask = KeyMappingMacOS::keycode_get_native_mask(event->get_keycode_with_modifiers());
+ } else if (event->get_physical_keycode() != Key::NONE) {
+ r_keycode = KeyMappingMacOS::keycode_get_native_string(event->get_physical_keycode() & KeyModifierMask::CODE_MASK);
+ r_keymask = KeyMappingMacOS::keycode_get_native_mask(event->get_physical_keycode_with_modifiers());
+ } else if (event->get_key_label() != Key::NONE) {
+ r_keycode = KeyMappingMacOS::keycode_get_native_string(event->get_key_label() & KeyModifierMask::CODE_MASK);
+ r_keymask = KeyMappingMacOS::keycode_get_native_mask(event->get_key_label_with_modifiers());
+ }
+}
+
DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {
KeyMappingMacOS::initialize();
@@ -3558,6 +3587,35 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
title = [NSString stringWithFormat:NSLocalizedString(@"Quit %@", nil), nsappname];
[application_menu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
+ NSMenu *file_menu = [[NSMenu alloc] initWithTitle:NSLocalizedString(@"File", nil)];
+ menu_item = [file_menu addItemWithTitle:@"_start_" action:nil keyEquivalent:@""];
+ menu_item.hidden = YES;
+ menu_item.tag = MENU_TAG_START;
+ menu_item = [file_menu addItemWithTitle:@"_end_" action:nil keyEquivalent:@""];
+ menu_item.hidden = YES;
+ menu_item.tag = MENU_TAG_END;
+
+ NSMenu *edit_menu = [[NSMenu alloc] initWithTitle:NSLocalizedString(@"Edit", nil)];
+ String keycode;
+ unsigned int keymask = 0;
+
+ _get_action_key("ui_cut", keycode, keymask);
+ menu_item = [edit_menu addItemWithTitle:NSLocalizedString(@"Cut", nil) action:@selector(cut:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
+ [menu_item setKeyEquivalentModifierMask:keymask];
+ _get_action_key("ui_copy", keycode, keymask);
+ menu_item = [edit_menu addItemWithTitle:NSLocalizedString(@"Copy", nil) action:@selector(copy:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
+ [menu_item setKeyEquivalentModifierMask:keymask];
+ _get_action_key("ui_paste", keycode, keymask);
+ menu_item = [edit_menu addItemWithTitle:NSLocalizedString(@"Paste", nil) action:@selector(paste:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
+ [menu_item setKeyEquivalentModifierMask:keymask];
+ [edit_menu addItem:[NSMenuItem separatorItem]];
+ menu_item = [edit_menu addItemWithTitle:@"_start_" action:nil keyEquivalent:@""];
+ menu_item.hidden = YES;
+ menu_item.tag = MENU_TAG_START;
+ menu_item = [edit_menu addItemWithTitle:@"_end_" action:nil keyEquivalent:@""];
+ menu_item.hidden = YES;
+ menu_item.tag = MENU_TAG_END;
+
NSMenu *window_menu = [[NSMenu alloc] initWithTitle:NSLocalizedString(@"Window", nil)];
[window_menu addItemWithTitle:NSLocalizedString(@"Minimize", nil) action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[window_menu addItemWithTitle:NSLocalizedString(@"Zoom", nil) action:@selector(performZoom:) keyEquivalent:@""];
@@ -3587,6 +3645,13 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
menu_item = [main_menu addItemWithTitle:@"" action:nil keyEquivalent:@""];
[main_menu setSubmenu:application_menu forItem:menu_item];
+ NSMenuItem *file_menu_item = [main_menu addItemWithTitle:NSLocalizedString(@"File", nil) action:nil keyEquivalent:@""];
+ file_menu_item.hidden = YES;
+ [main_menu setSubmenu:file_menu forItem:file_menu_item];
+
+ menu_item = [main_menu addItemWithTitle:NSLocalizedString(@"Edit", nil) action:nil keyEquivalent:@""];
+ [main_menu setSubmenu:edit_menu forItem:menu_item];
+
menu_item = [main_menu addItemWithTitle:NSLocalizedString(@"Window", nil) action:nil keyEquivalent:@""];
[main_menu setSubmenu:window_menu forItem:menu_item];
@@ -3595,7 +3660,7 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
[main_menu setAutoenablesItems:NO];
- native_menu->_register_system_menus(main_menu, application_menu, window_menu, help_menu, dock_menu);
+ native_menu->_register_system_menus(main_menu, application_menu, window_menu, help_menu, dock_menu, edit_menu, file_menu, file_menu_item);
//!!!!!!!!!!!!!!!!!!!!!!!!!!
//TODO - do Vulkan and OpenGL support checks, driver selection and fallback
diff --git a/platform/macos/godot_content_view.h b/platform/macos/godot_content_view.h
index dc8d11be541..cf8e79991fd 100644
--- a/platform/macos/godot_content_view.h
+++ b/platform/macos/godot_content_view.h
@@ -76,6 +76,7 @@
- (void)setWindowID:(DisplayServer::WindowID)wid;
- (void)updateLayerDelegate;
- (void)cancelComposition;
+- (void)processUIEvent:(const StringName &)name;
@end
diff --git a/platform/macos/godot_content_view.mm b/platform/macos/godot_content_view.mm
index 7d43ac9fe61..886d3068720 100644
--- a/platform/macos/godot_content_view.mm
+++ b/platform/macos/godot_content_view.mm
@@ -33,6 +33,7 @@
#include "display_server_macos.h"
#include "key_mapping_macos.h"
+#include "core/input/input_map.h"
#include "main/main.h"
@implementation GodotContentLayerDelegate
@@ -337,6 +338,65 @@
return NO;
}
+// MARK: Edit menu actions
+
+- (void)processUIEvent:(const StringName &)name {
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
+ if (!ds || !ds->has_window(window_id)) {
+ return;
+ }
+ const List][> *events = InputMap::get_singleton()->action_get_events(name);
+ if (!events) {
+ return;
+ }
+ const List][>::Element *first_event = events->front();
+ if (!first_event) {
+ return;
+ }
+
+ const Ref event = first_event->get();
+ if (event.is_null()) {
+ return;
+ }
+
+ DisplayServerMacOS::KeyEvent ke;
+ ke.window_id = window_id;
+ ke.macos_state = 0;
+ if (event->is_ctrl_pressed()) {
+ ke.macos_state |= NSEventModifierFlagControl;
+ }
+ if (event->is_shift_pressed()) {
+ ke.macos_state |= NSEventModifierFlagShift;
+ }
+ if (event->is_alt_pressed()) {
+ ke.macos_state |= NSEventModifierFlagOption;
+ }
+ if (event->is_meta_pressed()) {
+ ke.macos_state |= NSEventModifierFlagCommand;
+ }
+ ke.pressed = true;
+ ke.echo = false;
+ ke.raw = false;
+ ke.keycode = event->get_keycode();
+ ke.physical_keycode = event->get_physical_keycode();
+ ke.key_label = event->get_key_label();
+ ke.unicode = event->get_unicode();
+
+ ds->push_to_key_event_buffer(ke);
+}
+
+- (void)copy:(id)sender {
+ [self processUIEvent:"ui_copy"];
+}
+
+- (void)cut:(id)sender {
+ [self processUIEvent:"ui_cut"];
+}
+
+- (void)paste:(id)sender {
+ [self processUIEvent:"ui_paste"];
+}
+
// MARK: Focus
- (BOOL)canBecomeKeyView {
diff --git a/platform/macos/godot_menu_delegate.mm b/platform/macos/godot_menu_delegate.mm
index 3f7dfac3dec..16fdd0d189a 100644
--- a/platform/macos/godot_menu_delegate.mm
+++ b/platform/macos/godot_menu_delegate.mm
@@ -102,7 +102,11 @@
} else {
// Otherwise redirect event to the engine.
if (DisplayServer::get_singleton()) {
- [[[NSApplication sharedApplication] keyWindow] sendEvent:event];
+ if ([[NSApplication sharedApplication] keyWindow].sheet) {
+ [[[[NSApplication sharedApplication] keyWindow] sheetParent] sendEvent:event];
+ } else {
+ [[[NSApplication sharedApplication] keyWindow] sendEvent:event];
+ }
}
}
diff --git a/platform/macos/native_menu_macos.h b/platform/macos/native_menu_macos.h
index 42cf6740d90..b9e6bd7f5fa 100644
--- a/platform/macos/native_menu_macos.h
+++ b/platform/macos/native_menu_macos.h
@@ -58,12 +58,18 @@ class NativeMenuMacOS : public NativeMenu {
NSMenu *window_menu_ns = nullptr;
NSMenu *help_menu_ns = nullptr;
NSMenu *dock_menu_ns = nullptr;
+ NSMenu *edit_menu_ns = nullptr;
+ NSMenu *file_menu_ns = nullptr;
+
+ NSMenuItem *file_menu_item = nullptr;
RID main_menu;
RID application_menu;
RID window_menu;
RID help_menu;
RID dock_menu;
+ RID edit_menu;
+ RID file_menu;
int _get_system_menu_start(const NSMenu *p_menu) const;
int _get_system_menu_count(const NSMenu *p_menu) const;
@@ -71,7 +77,7 @@ class NativeMenuMacOS : public NativeMenu {
NSMenuItem *_menu_add_item(NSMenu *p_menu, const String &p_label, Key p_accel, int p_index, int *r_out);
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);
+ 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 *p_edit_menu, NSMenu *p_file_menu, NSMenuItem *p_file_menu_item);
NSMenu *_get_dock_menu();
void _menu_need_update(NSMenu *p_menu);
@@ -84,6 +90,10 @@ public:
virtual bool has_system_menu(SystemMenus p_menu_id) const override;
virtual RID get_system_menu(SystemMenus p_menu_id) const override;
+ virtual bool get_system_menu_no_default_items(SystemMenus p_menu_id) const override;
+ virtual void set_system_menu_name(SystemMenus p_menu_id, const String &p_string) override;
+ virtual void set_system_menu_hidden(SystemMenus p_menu_id, bool p_hidden) override;
+
virtual RID create_menu() override;
virtual bool has_menu(const RID &p_rid) const override;
virtual void free_menu(const RID &p_rid) override;
diff --git a/platform/macos/native_menu_macos.mm b/platform/macos/native_menu_macos.mm
index 802d58dc269..e26ba33ce0c 100644
--- a/platform/macos/native_menu_macos.mm
+++ b/platform/macos/native_menu_macos.mm
@@ -36,7 +36,7 @@
#include "scene/resources/image_texture.h"
-void NativeMenuMacOS::_register_system_menus(NSMenu *p_main_menu, NSMenu *p_application_menu, NSMenu *p_window_menu, NSMenu *p_help_menu, NSMenu *p_dock_menu) {
+void NativeMenuMacOS::_register_system_menus(NSMenu *p_main_menu, NSMenu *p_application_menu, NSMenu *p_window_menu, NSMenu *p_help_menu, NSMenu *p_dock_menu, NSMenu *p_edit_menu, NSMenu *p_file_menu, NSMenuItem *p_file_menu_item) {
{
MenuData *md = memnew(MenuData);
md->menu = p_main_menu;
@@ -45,6 +45,24 @@ void NativeMenuMacOS::_register_system_menus(NSMenu *p_main_menu, NSMenu *p_appl
main_menu_ns = p_main_menu;
menu_lookup[md->menu] = main_menu;
}
+ {
+ MenuData *md = memnew(MenuData);
+ md->menu = p_file_menu;
+ md->is_system = true;
+ file_menu = menus.make_rid(md);
+ file_menu_ns = p_file_menu;
+ menu_lookup[md->menu] = file_menu;
+
+ file_menu_item = p_file_menu_item;
+ }
+ {
+ MenuData *md = memnew(MenuData);
+ md->menu = p_edit_menu;
+ md->is_system = true;
+ edit_menu = menus.make_rid(md);
+ edit_menu_ns = p_edit_menu;
+ menu_lookup[md->menu] = edit_menu;
+ }
{
MenuData *md = memnew(MenuData);
md->menu = p_application_menu;
@@ -160,10 +178,10 @@ bool NativeMenuMacOS::_is_menu_opened(NSMenu *p_menu) const {
}
int NativeMenuMacOS::_get_system_menu_start(const NSMenu *p_menu) const {
- if (p_menu == [NSApp mainMenu]) { // Skip Apple menu.
- return 1;
+ if (p_menu == [NSApp mainMenu]) { // Skip Apple, File and Edit menu.
+ return 3;
}
- if (p_menu == application_menu_ns || p_menu == window_menu_ns || p_menu == help_menu_ns) {
+ if (p_menu == application_menu_ns || p_menu == window_menu_ns || p_menu == help_menu_ns || p_menu == edit_menu_ns || p_menu == file_menu_ns) {
int count = [p_menu numberOfItems];
for (int i = 0; i < count; i++) {
NSMenuItem *menu_item = [p_menu itemAtIndex:i];
@@ -176,10 +194,10 @@ int NativeMenuMacOS::_get_system_menu_start(const NSMenu *p_menu) const {
}
int NativeMenuMacOS::_get_system_menu_count(const NSMenu *p_menu) const {
- if (p_menu == [NSApp mainMenu]) { // Skip Apple, Window and Help menu.
- return [p_menu numberOfItems] - 3;
+ if (p_menu == [NSApp mainMenu]) { // Skip Apple, File, Edit, Window and Help menu.
+ return [p_menu numberOfItems] - 5;
}
- if (p_menu == application_menu_ns || p_menu == window_menu_ns || p_menu == help_menu_ns) {
+ if (p_menu == application_menu_ns || p_menu == window_menu_ns || p_menu == help_menu_ns || p_menu == edit_menu_ns || p_menu == file_menu_ns) {
int start = 0;
int count = [p_menu numberOfItems];
for (int i = 0; i < count; i++) {
@@ -215,6 +233,8 @@ bool NativeMenuMacOS::has_system_menu(SystemMenus p_menu_id) const {
case WINDOW_MENU_ID:
case HELP_MENU_ID:
case DOCK_MENU_ID:
+ case EDIT_MENU_ID:
+ case FILE_MENU_ID:
return true;
default:
return false;
@@ -233,11 +253,37 @@ RID NativeMenuMacOS::get_system_menu(SystemMenus p_menu_id) const {
return help_menu;
case DOCK_MENU_ID:
return dock_menu;
+ case EDIT_MENU_ID:
+ return edit_menu;
+ case FILE_MENU_ID:
+ return file_menu;
default:
return RID();
}
}
+bool NativeMenuMacOS::get_system_menu_no_default_items(SystemMenus p_menu_id) const {
+ return p_menu_id == FILE_MENU_ID;
+}
+
+void NativeMenuMacOS::set_system_menu_name(SystemMenus p_menu_id, const String &p_string) {
+ if (p_menu_id == FILE_MENU_ID) {
+ if (p_string.is_empty()) {
+ [file_menu_item setTitle:NSLocalizedString(@"File", nil)];
+ [file_menu_ns setTitle:NSLocalizedString(@"File", nil)];
+ } else {
+ [file_menu_item setTitle:[NSString stringWithUTF8String:p_string.utf8().get_data()]];
+ [file_menu_ns setTitle:[NSString stringWithUTF8String:p_string.utf8().get_data()]];
+ }
+ }
+}
+
+void NativeMenuMacOS::set_system_menu_hidden(SystemMenus p_menu_id, bool p_hidden) {
+ if (p_menu_id == FILE_MENU_ID) {
+ file_menu_item.hidden = p_hidden;
+ }
+}
+
RID NativeMenuMacOS::create_menu() {
MenuData *md = memnew(MenuData);
md->menu = [[NSMenu alloc] initWithTitle:@""];
@@ -1291,7 +1337,7 @@ void NativeMenuMacOS::clear(const RID &p_rid) {
ERR_FAIL_NULL(md);
ERR_FAIL_COND_MSG(_is_menu_opened(md->menu), "Can't remove open menu!");
- if (p_rid == application_menu || p_rid == window_menu || p_rid == help_menu) {
+ if (p_rid == application_menu || p_rid == window_menu || p_rid == help_menu || p_rid == edit_menu || p_rid == file_menu) {
int start = _get_system_menu_start(md->menu);
int count = _get_system_menu_count(md->menu);
for (int i = start + count - 1; i >= start; i--) {
@@ -1302,12 +1348,24 @@ void NativeMenuMacOS::clear(const RID &p_rid) {
}
if (p_rid == main_menu) {
- // Restore Apple, Window and Help menu.
+ // Restore Apple, File, Edit, Window and Help menu.
MenuData *md_app = menus.get_or_null(application_menu);
if (md_app) {
NSMenuItem *menu_item = [md->menu addItemWithTitle:@"" action:nil keyEquivalent:@""];
[md->menu setSubmenu:md_app->menu forItem:menu_item];
}
+ MenuData *md_file = menus.get_or_null(file_menu);
+ if (md_file) {
+ NSMenuItem *menu_item = [md->menu addItemWithTitle:@"File" action:nil keyEquivalent:@""];
+ menu_item.hidden = YES;
+ [md->menu setSubmenu:md_file->menu forItem:menu_item];
+ file_menu_item = menu_item;
+ }
+ MenuData *md_edit = menus.get_or_null(edit_menu);
+ if (md_edit) {
+ NSMenuItem *menu_item = [md->menu addItemWithTitle:@"Edit" action:nil keyEquivalent:@""];
+ [md->menu setSubmenu:md_edit->menu forItem:menu_item];
+ }
MenuData *md_win = menus.get_or_null(window_menu);
if (md_win) {
NSMenuItem *menu_item = [md->menu addItemWithTitle:@"Window" action:nil keyEquivalent:@""];
@@ -1346,6 +1404,28 @@ NativeMenuMacOS::~NativeMenuMacOS() {
memdelete(md);
}
}
+ if (file_menu.is_valid()) {
+ MenuData *md = menus.get_or_null(file_menu);
+ if (md) {
+ clear(file_menu);
+ menus.free(file_menu);
+ menu_lookup.erase(md->menu);
+ md->menu = nullptr;
+ file_menu_ns = nullptr;
+ memdelete(md);
+ }
+ }
+ if (edit_menu.is_valid()) {
+ MenuData *md = menus.get_or_null(edit_menu);
+ if (md) {
+ clear(edit_menu);
+ menus.free(edit_menu);
+ menu_lookup.erase(md->menu);
+ md->menu = nullptr;
+ edit_menu_ns = nullptr;
+ memdelete(md);
+ }
+ }
if (window_menu.is_valid()) {
MenuData *md = menus.get_or_null(window_menu);
if (md) {
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 3c04094526d..e473fca3cf4 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -99,6 +99,10 @@ RID PopupMenu::bind_global_menu() {
} else {
system_menus[system_menu_id] = this;
system_menu = nmenu->get_system_menu(system_menu_id);
+ nmenu->set_system_menu_name(system_menu_id, get_name());
+ if (nmenu->get_system_menu_no_default_items(system_menu_id)) {
+ nmenu->set_system_menu_hidden(system_menu_id, false);
+ }
global_menu = system_menu;
}
} else {
@@ -154,6 +158,12 @@ void PopupMenu::unbind_global_menu() {
if (global_menu == system_menu && system_menus[system_menu_id] == this) {
system_menus.erase(system_menu_id);
+ NativeMenu *nmenu = NativeMenu::get_singleton();
+
+ nmenu->set_system_menu_name(system_menu_id, String());
+ if (nmenu->get_system_menu_no_default_items(system_menu_id)) {
+ nmenu->set_system_menu_hidden(system_menu_id, true);
+ }
}
for (int i = 0; i < items.size(); i++) {
diff --git a/servers/display/native_menu.cpp b/servers/display/native_menu.cpp
index c7346637d8c..966294df4df 100644
--- a/servers/display/native_menu.cpp
+++ b/servers/display/native_menu.cpp
@@ -41,6 +41,10 @@ void NativeMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_system_menu", "menu_id"), &NativeMenu::get_system_menu);
ClassDB::bind_method(D_METHOD("get_system_menu_name", "menu_id"), &NativeMenu::get_system_menu_name);
+ ClassDB::bind_method(D_METHOD("get_system_menu_no_default_items", "menu_id"), &NativeMenu::get_system_menu_no_default_items);
+ ClassDB::bind_method(D_METHOD("set_system_menu_name", "menu_id", "string"), &NativeMenu::set_system_menu_name);
+ ClassDB::bind_method(D_METHOD("set_system_menu_hidden", "menu_id", "hidden"), &NativeMenu::set_system_menu_hidden);
+
ClassDB::bind_method(D_METHOD("create_menu"), &NativeMenu::create_menu);
ClassDB::bind_method(D_METHOD("has_menu", "rid"), &NativeMenu::has_menu);
ClassDB::bind_method(D_METHOD("free_menu", "rid"), &NativeMenu::free_menu);
@@ -125,6 +129,8 @@ void NativeMenu::_bind_methods() {
BIND_ENUM_CONSTANT(WINDOW_MENU_ID);
BIND_ENUM_CONSTANT(HELP_MENU_ID);
BIND_ENUM_CONSTANT(DOCK_MENU_ID);
+ BIND_ENUM_CONSTANT(EDIT_MENU_ID);
+ BIND_ENUM_CONSTANT(FILE_MENU_ID);
}
bool NativeMenu::has_feature(Feature p_feature) const {
@@ -152,11 +158,27 @@ String NativeMenu::get_system_menu_name(SystemMenus p_menu_id) const {
return "Help menu";
case DOCK_MENU_ID:
return "Dock menu";
+ case EDIT_MENU_ID:
+ return "Edit menu";
+ case FILE_MENU_ID:
+ return "File menu";
default:
return "Invalid";
}
}
+bool NativeMenu::get_system_menu_no_default_items(SystemMenus p_menu_id) const {
+ return false;
+}
+
+void NativeMenu::set_system_menu_name(SystemMenus p_menu_id, const String &p_string) {
+ WARN_PRINT("Global menus are not supported on this platform.");
+}
+
+void NativeMenu::set_system_menu_hidden(SystemMenus p_menu_id, bool p_hidden) {
+ WARN_PRINT("Global menus are not supported on this platform.");
+}
+
RID NativeMenu::create_menu() {
WARN_PRINT("Global menus are not supported on this platform.");
return RID();
diff --git a/servers/display/native_menu.h b/servers/display/native_menu.h
index 29d22e03aa7..362d54e5784 100644
--- a/servers/display/native_menu.h
+++ b/servers/display/native_menu.h
@@ -66,6 +66,8 @@ public:
WINDOW_MENU_ID,
HELP_MENU_ID,
DOCK_MENU_ID,
+ EDIT_MENU_ID,
+ FILE_MENU_ID,
};
virtual bool has_feature(Feature p_feature) const;
@@ -74,6 +76,10 @@ public:
virtual RID get_system_menu(SystemMenus p_menu_id) const;
virtual String get_system_menu_name(SystemMenus p_menu_id) const;
+ virtual bool get_system_menu_no_default_items(SystemMenus p_menu_id) const;
+ virtual void set_system_menu_name(SystemMenus p_menu_id, const String &p_string);
+ virtual void set_system_menu_hidden(SystemMenus p_menu_id, bool p_hidden);
+
virtual RID create_menu();
virtual bool has_menu(const RID &p_rid) const;
virtual void free_menu(const RID &p_rid);
]