summaryrefslogtreecommitdiffstats
path: root/platform
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2023-10-22 14:29:56 +0300
committerbruvzg <7645683+bruvzg@users.noreply.github.com>2024-02-13 18:37:37 +0200
commitdeffe6a3bee2bb15fbc7946711e073ab447e472a (patch)
treeb69f9694f318cf7db190ed16c4f355227b79e403 /platform
parente92d55bbf417aa9f4592a863cb5b2c7ba0740e21 (diff)
downloadredot-engine-deffe6a3bee2bb15fbc7946711e073ab447e472a.tar.gz
[macOS] Add support for native help menu search callbacks, integrate editor help.
Diffstat (limited to 'platform')
-rw-r--r--platform/macos/display_server_macos.h7
-rw-r--r--platform/macos/display_server_macos.mm14
-rw-r--r--platform/macos/godot_application_delegate.h2
-rw-r--r--platform/macos/godot_application_delegate.mm53
-rw-r--r--platform/macos/os_macos.mm1
5 files changed, 76 insertions, 1 deletions
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index 10c8abe663..84e863ad41 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -211,6 +211,9 @@ private:
IOPMAssertionID screen_keep_on_assertion = kIOPMNullAssertionID;
+ Callable help_search_callback;
+ Callable help_action_callback;
+
struct MenuCall {
Variant tag;
Callable callback;
@@ -282,6 +285,10 @@ public:
virtual bool has_feature(Feature p_feature) const override;
virtual String get_name() const override;
+ virtual void help_set_search_callbacks(const Callable &p_search_callback = Callable(), const Callable &p_action_callback = Callable()) override;
+ Callable _help_get_search_callback() const;
+ Callable _help_get_action_callback() const;
+
virtual void global_menu_set_popup_callbacks(const String &p_menu_root, const Callable &p_open_callback = Callable(), const Callable &p_close_callback = Callable()) override;
virtual int global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index = -1) override;
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 19632dd799..3c88b7af24 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -840,6 +840,7 @@ bool DisplayServerMacOS::has_feature(Feature p_feature) const {
case FEATURE_EXTEND_TO_TITLE:
case FEATURE_SCREEN_CAPTURE:
case FEATURE_STATUS_INDICATOR:
+ case FEATURE_NATIVE_HELP:
return true;
default: {
}
@@ -851,6 +852,19 @@ String DisplayServerMacOS::get_name() const {
return "macOS";
}
+void DisplayServerMacOS::help_set_search_callbacks(const Callable &p_search_callback, const Callable &p_action_callback) {
+ help_search_callback = p_search_callback;
+ help_action_callback = p_action_callback;
+}
+
+Callable DisplayServerMacOS::_help_get_search_callback() const {
+ return help_search_callback;
+}
+
+Callable DisplayServerMacOS::_help_get_action_callback() const {
+ return help_action_callback;
+}
+
bool DisplayServerMacOS::_is_menu_opened(NSMenu *p_menu) const {
if (submenu_inv.has(p_menu)) {
const MenuData &md = submenu[submenu_inv[p_menu]];
diff --git a/platform/macos/godot_application_delegate.h b/platform/macos/godot_application_delegate.h
index 2426fb0b1c..45bd85c45c 100644
--- a/platform/macos/godot_application_delegate.h
+++ b/platform/macos/godot_application_delegate.h
@@ -36,7 +36,7 @@
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
-@interface GodotApplicationDelegate : NSObject
+@interface GodotApplicationDelegate : NSObject <NSUserInterfaceItemSearching, NSApplicationDelegate>
- (void)forceUnbundledWindowActivationHackStep1;
- (void)forceUnbundledWindowActivationHackStep2;
- (void)forceUnbundledWindowActivationHackStep3;
diff --git a/platform/macos/godot_application_delegate.mm b/platform/macos/godot_application_delegate.mm
index c1de8ade58..c907e338ba 100644
--- a/platform/macos/godot_application_delegate.mm
+++ b/platform/macos/godot_application_delegate.mm
@@ -39,6 +39,59 @@
return YES;
}
+- (NSArray<NSString *> *)localizedTitlesForItem:(id)item {
+ NSArray *item_name = @[ item[1] ];
+ return item_name;
+}
+
+- (void)searchForItemsWithSearchString:(NSString *)searchString resultLimit:(NSInteger)resultLimit matchedItemHandler:(void (^)(NSArray *items))handleMatchedItems {
+ NSMutableArray *found_items = [[NSMutableArray alloc] init];
+
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
+ if (ds && ds->_help_get_search_callback().is_valid()) {
+ Callable cb = ds->_help_get_search_callback();
+
+ Variant ret;
+ Variant search_string = String::utf8([searchString UTF8String]);
+ Variant result_limit = (uint64_t)resultLimit;
+ Callable::CallError ce;
+ const Variant *args[2] = { &search_string, &result_limit };
+
+ cb.callp(args, 2, ret, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_PRINT(vformat(RTR("Failed to execute help search callback: %s."), Variant::get_callable_error_text(cb, args, 2, ce)));
+ }
+ Dictionary results = ret;
+ for (const Variant *E = results.next(); E; E = results.next(E)) {
+ const String &key = *E;
+ const String &value = results[*E];
+ if (key.length() > 0 && value.length() > 0) {
+ NSArray *item = @[ [NSString stringWithUTF8String:key.utf8().get_data()], [NSString stringWithUTF8String:value.utf8().get_data()] ];
+ [found_items addObject:item];
+ }
+ }
+ }
+
+ handleMatchedItems(found_items);
+}
+
+- (void)performActionForItem:(id)item {
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
+ if (ds && ds->_help_get_action_callback().is_valid()) {
+ Callable cb = ds->_help_get_action_callback();
+
+ Variant ret;
+ Variant item_string = String::utf8([item[0] UTF8String]);
+ Callable::CallError ce;
+ const Variant *args[1] = { &item_string };
+
+ cb.callp(args, 1, ret, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_PRINT(vformat(RTR("Failed to execute help action callback: %s."), Variant::get_callable_error_text(cb, args, 1, ce)));
+ }
+ }
+}
+
- (void)forceUnbundledWindowActivationHackStep1 {
// Step 1: Switch focus to macOS SystemUIServer process.
// Required to perform step 2, TransformProcessType will fail if app is already the in focus.
diff --git a/platform/macos/os_macos.mm b/platform/macos/os_macos.mm
index 000215ac46..80c9f1b422 100644
--- a/platform/macos/os_macos.mm
+++ b/platform/macos/os_macos.mm
@@ -830,6 +830,7 @@ OS_MacOS::OS_MacOS() {
id delegate = [[GodotApplicationDelegate alloc] init];
ERR_FAIL_NULL(delegate);
[NSApp setDelegate:delegate];
+ [NSApp registerUserInterfaceItemSearchHandler:delegate];
pre_wait_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, &pre_wait_observer_cb, nullptr);
CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);