[Windows] Emit native file dialog callback from event loop, fix selected options not saved.

This commit is contained in:
bruvzg 2024-08-23 09:53:16 +03:00
parent 568589c9d8
commit ea252675aa
4 changed files with 71 additions and 51 deletions

View File

@ -115,6 +115,8 @@ void EditorFileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_file
file_name = ProjectSettings::get_singleton()->localize_path(file_name); file_name = ProjectSettings::get_singleton()->localize_path(file_name);
} }
} }
selected_options = p_selected_options;
String f = files[0]; String f = files[0];
if (mode == FILE_MODE_OPEN_FILES) { if (mode == FILE_MODE_OPEN_FILES) {
emit_signal(SNAME("files_selected"), files); emit_signal(SNAME("files_selected"), files);
@ -146,7 +148,6 @@ void EditorFileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_file
} }
file->set_text(f); file->set_text(f);
dir->set_text(f.get_base_dir()); dir->set_text(f.get_base_dir());
selected_options = p_selected_options;
filter->select(p_filter); filter->select(p_filter);
} }

View File

@ -519,7 +519,7 @@ void DisplayServerWindows::_thread_fd_monitor(void *p_ud) {
if (!item.has("name") || !item.has("values") || !item.has("default")) { if (!item.has("name") || !item.has("values") || !item.has("default")) {
continue; continue;
} }
event_handler->add_option(pfdc, item["name"], item["values"], item["default_idx"]); event_handler->add_option(pfdc, item["name"], item["values"], item["default"]);
} }
event_handler->set_root(fd->root); event_handler->set_root(fd->root);
@ -603,62 +603,41 @@ void DisplayServerWindows::_thread_fd_monitor(void *p_ud) {
} }
} }
if (fd->callback.is_valid()) { if (fd->callback.is_valid()) {
if (fd->options_in_cb) { MutexLock lock(ds->file_dialog_mutex);
Variant v_result = true; FileDialogCallback cb;
Variant v_files = file_names; cb.callback = fd->callback;
Variant v_index = index; cb.status = true;
Variant v_opt = options; cb.files = file_names;
const Variant *cb_args[4] = { &v_result, &v_files, &v_index, &v_opt }; cb.index = index;
cb.options = options;
fd->callback.call_deferredp(cb_args, 4); cb.opt_in_cb = fd->options_in_cb;
} else { ds->pending_cbs.push_back(cb);
Variant v_result = true;
Variant v_files = file_names;
Variant v_index = index;
const Variant *cb_args[3] = { &v_result, &v_files, &v_index };
fd->callback.call_deferredp(cb_args, 3);
}
} }
} else { } else {
if (fd->callback.is_valid()) { if (fd->callback.is_valid()) {
if (fd->options_in_cb) { MutexLock lock(ds->file_dialog_mutex);
Variant v_result = false; FileDialogCallback cb;
Variant v_files = Vector<String>(); cb.callback = fd->callback;
Variant v_index = 0; cb.status = false;
Variant v_opt = Dictionary(); cb.files = Vector<String>();
const Variant *cb_args[4] = { &v_result, &v_files, &v_index, &v_opt }; cb.index = index;
cb.options = options;
fd->callback.call_deferredp(cb_args, 4); cb.opt_in_cb = fd->options_in_cb;
} else { ds->pending_cbs.push_back(cb);
Variant v_result = false;
Variant v_files = Vector<String>();
Variant v_index = 0;
const Variant *cb_args[3] = { &v_result, &v_files, &v_index };
fd->callback.call_deferredp(cb_args, 3);
}
} }
} }
pfd->Release(); pfd->Release();
} else { } else {
if (fd->callback.is_valid()) { if (fd->callback.is_valid()) {
if (fd->options_in_cb) { MutexLock lock(ds->file_dialog_mutex);
Variant v_result = false; FileDialogCallback cb;
Variant v_files = Vector<String>(); cb.callback = fd->callback;
Variant v_index = 0; cb.status = false;
Variant v_opt = Dictionary(); cb.files = Vector<String>();
const Variant *cb_args[4] = { &v_result, &v_files, &v_index, &v_opt }; cb.index = 0;
cb.options = Dictionary();
fd->callback.call_deferredp(cb_args, 4); cb.opt_in_cb = fd->options_in_cb;
} else { ds->pending_cbs.push_back(cb);
Variant v_result = false;
Variant v_files = Vector<String>();
Variant v_index = 0;
const Variant *cb_args[3] = { &v_result, &v_files, &v_index };
fd->callback.call_deferredp(cb_args, 3);
}
} }
} }
{ {
@ -746,6 +725,34 @@ Error DisplayServerWindows::_file_dialog_with_options_show(const String &p_title
return OK; return OK;
} }
void DisplayServerWindows::process_file_dialog_callbacks() {
MutexLock lock(file_dialog_mutex);
while (!pending_cbs.is_empty()) {
FileDialogCallback cb = pending_cbs.front()->get();
pending_cbs.pop_front();
if (cb.opt_in_cb) {
Variant ret;
Callable::CallError ce;
const Variant *args[4] = { &cb.status, &cb.files, &cb.index, &cb.options };
cb.callback.callp(args, 4, ret, ce);
if (ce.error != Callable::CallError::CALL_OK) {
ERR_PRINT(vformat("Failed to execute file dialog callback: %s.", Variant::get_callable_error_text(cb.callback, args, 4, ce)));
}
} else {
Variant ret;
Callable::CallError ce;
const Variant *args[3] = { &cb.status, &cb.files, &cb.index };
cb.callback.callp(args, 3, ret, ce);
if (ce.error != Callable::CallError::CALL_OK) {
ERR_PRINT(vformat("Failed to execute file dialog callback: %s.", Variant::get_callable_error_text(cb.callback, args, 3, ce)));
}
}
}
}
void DisplayServerWindows::mouse_set_mode(MouseMode p_mode) { void DisplayServerWindows::mouse_set_mode(MouseMode p_mode) {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
@ -3168,6 +3175,7 @@ void DisplayServerWindows::process_events() {
memdelete(E->get()); memdelete(E->get());
E->erase(); E->erase();
} }
process_file_dialog_callbacks();
} }
void DisplayServerWindows::force_process_and_drop_events() { void DisplayServerWindows::force_process_and_drop_events() {

View File

@ -572,6 +572,16 @@ class DisplayServerWindows : public DisplayServer {
Mutex file_dialog_mutex; Mutex file_dialog_mutex;
List<FileDialogData *> file_dialogs; List<FileDialogData *> file_dialogs;
HashMap<HWND, FileDialogData *> file_dialog_wnd; HashMap<HWND, FileDialogData *> file_dialog_wnd;
struct FileDialogCallback {
Callable callback;
Variant status;
Variant files;
Variant index;
Variant options;
bool opt_in_cb = false;
};
List<FileDialogCallback> pending_cbs;
void process_file_dialog_callbacks();
static void _thread_fd_monitor(void *p_ud); static void _thread_fd_monitor(void *p_ud);

View File

@ -124,6 +124,8 @@ void FileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_files, int
file_name = ProjectSettings::get_singleton()->localize_path(file_name); file_name = ProjectSettings::get_singleton()->localize_path(file_name);
} }
} }
selected_options = p_selected_options;
String f = files[0]; String f = files[0];
if (mode == FILE_MODE_OPEN_FILES) { if (mode == FILE_MODE_OPEN_FILES) {
emit_signal(SNAME("files_selected"), files); emit_signal(SNAME("files_selected"), files);
@ -155,7 +157,6 @@ void FileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_files, int
} }
file->set_text(f); file->set_text(f);
dir->set_text(f.get_base_dir()); dir->set_text(f.get_base_dir());
selected_options = p_selected_options;
filter->select(p_filter); filter->select(p_filter);
} }