Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add error messages to the native menu and file dialogs callback. #83181

Merged
merged 1 commit into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions platform/linuxbsd/freedesktop_portal_desktop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion platform/linuxbsd/freedesktop_portal_desktop.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct DBusMessage;
struct DBusConnection;
struct DBusMessageIter;

class FreeDesktopPortalDesktop {
class FreeDesktopPortalDesktop : public Object {
private:
bool unsupported = false;

Expand All @@ -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<String> &p_names, bool &r_cancel, Vector<String> &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<String> filter_names;
DBusConnection *connection = nullptr;
Expand Down
103 changes: 89 additions & 14 deletions platform/macos/display_server_macos.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}
}
}
}
Expand All @@ -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)));
}
}
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<String>(), [handler getIndex]);
Variant v_result = false;
Variant v_files = Vector<String>();
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) {
Expand Down Expand Up @@ -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<String>(), [handler getIndex]);
Variant v_result = false;
Variant v_files = Vector<String>();
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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -4020,7 +4087,15 @@ - (void)popupAction:(id)sender {
while (List<MenuCall>::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) {
Expand Down
18 changes: 16 additions & 2 deletions platform/macos/godot_menu_delegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}
}
}
}
Expand All @@ -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()) {
Expand Down
24 changes: 22 additions & 2 deletions platform/windows/display_server_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>(), index);
Variant v_result = false;
Variant v_files = Vector<String>();
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();
Expand Down
Loading