From b52826bf5593c8095e7ffa429e604089e9a1b584 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Thu, 12 Oct 2023 08:27:40 +0300 Subject: [PATCH] Add error messages to the native menu and file dialogs callback. --- .../linuxbsd/freedesktop_portal_desktop.cpp | 17 ++- .../linuxbsd/freedesktop_portal_desktop.h | 4 +- platform/macos/display_server_macos.mm | 103 +++++++++++++++--- platform/macos/godot_menu_delegate.mm | 18 ++- platform/windows/display_server_windows.cpp | 24 +++- 5 files changed, 142 insertions(+), 24 deletions(-) diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp index cf4354139ac0..d9aa98ba7060 100644 --- a/platform/linuxbsd/freedesktop_portal_desktop.cpp +++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp @@ -427,6 +427,17 @@ Error FreeDesktopPortalDesktop::file_dialog_show(DisplayServer::WindowID p_windo return OK; } +void FreeDesktopPortalDesktop::_file_dialog_callback(const Callable &p_callable, const Variant &p_status, const Variant &p_list, const Variant &p_index) { + Variant ret; + Callable::CallError ce; + const Variant *args[3] = { &p_status, &p_list, &p_index }; + + p_callable.callp(args, 3, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute file dialogs callback: %s."), Variant::get_callable_error_text(p_callable, args, 3, ce))); + } +} + void FreeDesktopPortalDesktop::_thread_file_dialog_monitor(void *p_ud) { FreeDesktopPortalDesktop *portal = (FreeDesktopPortalDesktop *)p_ud; @@ -451,11 +462,7 @@ void FreeDesktopPortalDesktop::_thread_file_dialog_monitor(void *p_ud) { file_chooser_parse_response(&iter, fd.filter_names, cancel, uris, index); if (fd.callback.is_valid()) { - Variant v_status = !cancel; - Variant v_files = uris; - Variant v_index = index; - Variant *v_args[3] = { &v_status, &v_files, &v_index }; - fd.callback.call_deferredp((const Variant **)&v_args, 3); + callable_mp(portal, &FreeDesktopPortalDesktop::_file_dialog_callback).call_deferred(fd.callback, !cancel, uris, index); } if (fd.prev_focus != DisplayServer::INVALID_WINDOW_ID) { callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(fd.prev_focus); diff --git a/platform/linuxbsd/freedesktop_portal_desktop.h b/platform/linuxbsd/freedesktop_portal_desktop.h index 503c3822077c..71e9812ea9fe 100644 --- a/platform/linuxbsd/freedesktop_portal_desktop.h +++ b/platform/linuxbsd/freedesktop_portal_desktop.h @@ -40,7 +40,7 @@ struct DBusMessage; struct DBusConnection; struct DBusMessageIter; -class FreeDesktopPortalDesktop { +class FreeDesktopPortalDesktop : public Object { private: bool unsupported = false; @@ -54,6 +54,8 @@ class FreeDesktopPortalDesktop { static void append_dbus_dict_bool(DBusMessageIter *p_iter, const String &p_key, bool p_value); static bool file_chooser_parse_response(DBusMessageIter *p_iter, const Vector &p_names, bool &r_cancel, Vector &r_urls, int &r_index); + void _file_dialog_callback(const Callable &p_callable, const Variant &p_status, const Variant &p_list, const Variant &p_index); + struct FileDialogData { Vector filter_names; DBusConnection *connection = nullptr; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 0d4a5e784dda..53db9a5abf01 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -611,7 +611,13 @@ MenuData &md = submenu[submenu_inv[p_menu]]; md.is_open = true; if (md.open.is_valid()) { - md.open.call(); + Variant ret; + Callable::CallError ce; + + md.open.callp(nullptr, 0, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute menu open callback: %s."), Variant::get_callable_error_text(md.open, nullptr, 0, ce))); + } } } } @@ -621,7 +627,13 @@ MenuData &md = submenu[submenu_inv[p_menu]]; md.is_open = false; if (md.close.is_valid()) { - md.close.call(); + Variant ret; + Callable::CallError ce; + + md.close.callp(nullptr, 0, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute menu close callback: %s."), Variant::get_callable_error_text(md.close, nullptr, 0, ce))); + } } } } @@ -1978,20 +1990,27 @@ [window setInformativeText:ns_description]; [window setAlertStyle:NSAlertStyleInformational]; - int button_pressed; + Variant button_pressed; NSInteger ret = [window runModal]; if (ret == NSAlertFirstButtonReturn) { - button_pressed = 0; + button_pressed = int64_t(0); } else if (ret == NSAlertSecondButtonReturn) { - button_pressed = 1; + button_pressed = int64_t(1); } else if (ret == NSAlertThirdButtonReturn) { - button_pressed = 2; + button_pressed = int64_t(2); } else { - button_pressed = 2 + (ret - NSAlertThirdButtonReturn); + button_pressed = int64_t(2 + (ret - NSAlertThirdButtonReturn)); } if (!p_callback.is_null()) { - p_callback.call(button_pressed); + Variant ret; + Callable::CallError ce; + const Variant *args[1] = { &button_pressed }; + + p_callback.callp(args, 1, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute dialog callback: %s."), Variant::get_callable_error_text(p_callback, args, 1, ce))); + } } return OK; @@ -2166,11 +2185,31 @@ - (void)popupAction:(id)sender { url.parse_utf8([[[panel URL] path] UTF8String]); files.push_back(url); if (!callback.is_null()) { - callback.call(true, files, [handler getIndex]); + Variant v_result = true; + Variant v_files = files; + Variant v_index = [handler getIndex]; + Variant ret; + Callable::CallError ce; + const Variant *args[3] = { &v_result, &v_files, &v_index }; + + callback.callp(args, 3, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute file dialog callback: %s."), Variant::get_callable_error_text(callback, args, 3, ce))); + } } } else { if (!callback.is_null()) { - callback.call(false, Vector(), [handler getIndex]); + Variant v_result = false; + Variant v_files = Vector(); + Variant v_index = [handler getIndex]; + Variant ret; + Callable::CallError ce; + const Variant *args[3] = { &v_result, &v_files, &v_index }; + + callback.callp(args, 3, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute file dialogs callback: %s."), Variant::get_callable_error_text(callback, args, 3, ce))); + } } } if (prev_focus != INVALID_WINDOW_ID) { @@ -2231,11 +2270,31 @@ - (void)popupAction:(id)sender { files.push_back(url); } if (!callback.is_null()) { - callback.call(true, files, [handler getIndex]); + Variant v_result = true; + Variant v_files = files; + Variant v_index = [handler getIndex]; + Variant ret; + Callable::CallError ce; + const Variant *args[3] = { &v_result, &v_files, &v_index }; + + callback.callp(args, 3, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute file dialog callback: %s."), Variant::get_callable_error_text(callback, args, 3, ce))); + } } } else { if (!callback.is_null()) { - callback.call(false, Vector(), [handler getIndex]); + Variant v_result = false; + Variant v_files = Vector(); + Variant v_index = [handler getIndex]; + Variant ret; + Callable::CallError ce; + const Variant *args[3] = { &v_result, &v_files, &v_index }; + + callback.callp(args, 3, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute file dialogs callback: %s."), Variant::get_callable_error_text(callback, args, 3, ce))); + } } } if (prev_focus != INVALID_WINDOW_ID) { @@ -2269,7 +2328,15 @@ - (void)popupAction:(id)sender { ret.parse_utf8([[input stringValue] UTF8String]); if (!p_callback.is_null()) { - p_callback.call(ret); + Variant v_result = ret; + Variant ret; + Callable::CallError ce; + const Variant *args[1] = { &v_result }; + + p_callback.callp(args, 1, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute input dialog callback: %s."), Variant::get_callable_error_text(p_callback, args, 1, ce))); + } } return OK; @@ -4020,7 +4087,15 @@ - (void)popupAction:(id)sender { while (List::Element *call_p = deferred_menu_calls.front()) { MenuCall call = call_p->get(); deferred_menu_calls.pop_front(); // Remove before call to avoid infinite loop in case callback is using `process_events` (e.g. EditorProgress). - call.callback.call(call.tag); + + Variant ret; + Callable::CallError ce; + const Variant *args[1] = { &call.tag }; + + call.callback.callp(args, 1, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute menu callback: %s."), Variant::get_callable_error_text(call.callback, args, 1, ce))); + } } if (!drop_events) { diff --git a/platform/macos/godot_menu_delegate.mm b/platform/macos/godot_menu_delegate.mm index a34094edd734..844fd27f0128 100644 --- a/platform/macos/godot_menu_delegate.mm +++ b/platform/macos/godot_menu_delegate.mm @@ -58,7 +58,14 @@ - (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item { GodotMenuItem *value = [item representedObject]; if (value && value->hover_callback.is_valid()) { // If custom callback is set, use it. - value->hover_callback.call(value->meta); + Variant ret; + Callable::CallError ce; + const Variant *args[1] = { &value->meta }; + + value->hover_callback.callp(args, 1, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute menu hover callback: %s."), Variant::get_callable_error_text(value->hover_callback, args, 1, ce))); + } } } } @@ -76,7 +83,14 @@ - (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id if (value) { if (value->key_callback.is_valid()) { // If custom callback is set, use it. - value->key_callback.call(value->meta); + Variant ret; + Callable::CallError ce; + const Variant *args[1] = { &value->meta }; + + value->key_callback.callp(args, 1, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute menu key callback: %s."), Variant::get_callable_error_text(value->key_callback, args, 1, ce))); + } } else { // Otherwise redirect event to the engine. if (DisplayServer::get_singleton()) { diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index cc5ae9ad45a1..bb0b64ba10d2 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -346,11 +346,31 @@ Error DisplayServerWindows::file_dialog_show(const String &p_title, const String } } if (!p_callback.is_null()) { - p_callback.call(true, file_names, index); + Variant v_result = true; + Variant v_files = file_names; + Variant v_index = index; + Variant ret; + Callable::CallError ce; + const Variant *args[3] = { &v_result, &v_files, &v_index }; + + p_callback.callp(args, 3, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute file dialogs callback: %s."), Variant::get_callable_error_text(p_callback, args, 3, ce))); + } } } else { if (!p_callback.is_null()) { - p_callback.call(false, Vector(), index); + Variant v_result = false; + Variant v_files = Vector(); + Variant v_index = index; + Variant ret; + Callable::CallError ce; + const Variant *args[3] = { &v_result, &v_files, &v_index }; + + p_callback.callp(args, 3, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat(RTR("Failed to execute file dialogs callback: %s."), Variant::get_callable_error_text(p_callback, args, 3, ce))); + } } } pfd->Release();