lua: Handle file dialogs completely on main gui thread

wx doesn't seem to like the dialogs being created on some other worker
thread, which makes file dialogs opened by lua scripts crash in various
ways on Linux. Doing everything on the main thread hopefully fixes this.

Fixes TypesettingTools/Aegisub#51 .
This commit is contained in:
arch1t3cht 2023-02-25 02:22:13 +01:00
parent 1734f00d8a
commit 7f52346f06
3 changed files with 24 additions and 32 deletions

View file

@ -221,13 +221,6 @@ namespace Automation4 {
}); });
} }
int ProgressSink::ShowDialog(wxDialog *dialog)
{
int ret = 0;
agi::dispatch::Main().Sync([&] { ret = dialog->ShowModal(); });
return ret;
}
BackgroundScriptRunner::BackgroundScriptRunner(wxWindow *parent, std::string const& title) BackgroundScriptRunner::BackgroundScriptRunner(wxWindow *parent, std::string const& title)
: impl(new DialogProgress(parent, to_wx(title))) : impl(new DialogProgress(parent, to_wx(title)))
{ {

View file

@ -132,7 +132,6 @@ namespace Automation4 {
/// Show the passed dialog on the GUI thread, blocking the calling /// Show the passed dialog on the GUI thread, blocking the calling
/// thread until it closes /// thread until it closes
void ShowDialog(ScriptDialog *config_dialog); void ShowDialog(ScriptDialog *config_dialog);
int ShowDialog(wxDialog *dialog);
wxWindow *GetParentWindow() const { return bsr->GetParentWindow(); } wxWindow *GetParentWindow() const { return bsr->GetParentWindow(); }
/// Get the current automation trace level /// Get the current automation trace level

View file

@ -36,6 +36,7 @@
#include "compat.h" #include "compat.h"
#include <libaegisub/dispatch.h>
#include <libaegisub/lua/utils.h> #include <libaegisub/lua/utils.h>
#include <wx/filedlg.h> #include <wx/filedlg.h>
@ -197,7 +198,6 @@ namespace Automation4 {
int LuaProgressSink::LuaDisplayOpenDialog(lua_State *L) int LuaProgressSink::LuaDisplayOpenDialog(lua_State *L)
{ {
ProgressSink *ps = GetObjPointer(L, lua_upvalueindex(1));
wxString message(check_wxstring(L, 1)); wxString message(check_wxstring(L, 1));
wxString dir(check_wxstring(L, 2)); wxString dir(check_wxstring(L, 2));
wxString file(check_wxstring(L, 3)); wxString file(check_wxstring(L, 3));
@ -211,26 +211,24 @@ namespace Automation4 {
if (must_exist) if (must_exist)
flags |= wxFD_FILE_MUST_EXIST; flags |= wxFD_FILE_MUST_EXIST;
wxFileDialog diag(nullptr, message, dir, file, wildcard, flags); agi::dispatch::Main().Sync([&] {
if (ps->ShowDialog(&diag) == wxID_CANCEL) { wxFileDialog diag(nullptr, message, dir, file, wildcard, flags);
lua_pushnil(L); if (diag.ShowModal() == wxID_CANCEL) {
return 1; lua_pushnil(L);
} } else if (multiple) {
wxArrayString files;
diag.GetPaths(files);
if (multiple) { lua_createtable(L, files.size(), 0);
wxArrayString files; for (size_t i = 0; i < files.size(); ++i) {
diag.GetPaths(files); lua_pushstring(L, files[i].utf8_str());
lua_rawseti(L, -2, i + 1);
lua_createtable(L, files.size(), 0); }
for (size_t i = 0; i < files.size(); ++i) { } else {
lua_pushstring(L, files[i].utf8_str()); lua_pushstring(L, diag.GetPath().utf8_str());
lua_rawseti(L, -2, i + 1);
} }
});
return 1;
}
lua_pushstring(L, diag.GetPath().utf8_str());
return 1; return 1;
} }
@ -247,13 +245,15 @@ namespace Automation4 {
if (prompt_overwrite) if (prompt_overwrite)
flags |= wxFD_OVERWRITE_PROMPT; flags |= wxFD_OVERWRITE_PROMPT;
wxFileDialog diag(ps->GetParentWindow(), message, dir, file, wildcard, flags); agi::dispatch::Main().Sync([&] {
if (ps->ShowDialog(&diag) == wxID_CANCEL) { wxFileDialog diag(ps->GetParentWindow(), message, dir, file, wildcard, flags);
lua_pushnil(L); if (diag.ShowModal() == wxID_CANCEL) {
return 1; lua_pushnil(L);
} } else {
lua_pushstring(L, diag.GetPath().utf8_str());
}
});
lua_pushstring(L, diag.GetPath().utf8_str());
return 1; return 1;
} }
} }