From 7f52346f06231af2b1998bbdd513a0dfe3d471c3 Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Sat, 25 Feb 2023 02:22:13 +0100 Subject: [PATCH] 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 . --- src/auto4_base.cpp | 7 ----- src/auto4_base.h | 1 - src/auto4_lua_progresssink.cpp | 48 +++++++++++++++++----------------- 3 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/auto4_base.cpp b/src/auto4_base.cpp index e3a796f73..0b9c292bd 100644 --- a/src/auto4_base.cpp +++ b/src/auto4_base.cpp @@ -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) : impl(new DialogProgress(parent, to_wx(title))) { diff --git a/src/auto4_base.h b/src/auto4_base.h index 5f645ccd0..c18aa9488 100644 --- a/src/auto4_base.h +++ b/src/auto4_base.h @@ -132,7 +132,6 @@ namespace Automation4 { /// Show the passed dialog on the GUI thread, blocking the calling /// thread until it closes void ShowDialog(ScriptDialog *config_dialog); - int ShowDialog(wxDialog *dialog); wxWindow *GetParentWindow() const { return bsr->GetParentWindow(); } /// Get the current automation trace level diff --git a/src/auto4_lua_progresssink.cpp b/src/auto4_lua_progresssink.cpp index 026cb9583..856912131 100644 --- a/src/auto4_lua_progresssink.cpp +++ b/src/auto4_lua_progresssink.cpp @@ -36,6 +36,7 @@ #include "compat.h" +#include #include #include @@ -197,7 +198,6 @@ namespace Automation4 { int LuaProgressSink::LuaDisplayOpenDialog(lua_State *L) { - ProgressSink *ps = GetObjPointer(L, lua_upvalueindex(1)); wxString message(check_wxstring(L, 1)); wxString dir(check_wxstring(L, 2)); wxString file(check_wxstring(L, 3)); @@ -211,26 +211,24 @@ namespace Automation4 { if (must_exist) flags |= wxFD_FILE_MUST_EXIST; - wxFileDialog diag(nullptr, message, dir, file, wildcard, flags); - if (ps->ShowDialog(&diag) == wxID_CANCEL) { - lua_pushnil(L); - return 1; - } + agi::dispatch::Main().Sync([&] { + wxFileDialog diag(nullptr, message, dir, file, wildcard, flags); + if (diag.ShowModal() == wxID_CANCEL) { + lua_pushnil(L); + } else if (multiple) { + wxArrayString files; + diag.GetPaths(files); - if (multiple) { - wxArrayString files; - diag.GetPaths(files); - - lua_createtable(L, files.size(), 0); - for (size_t i = 0; i < files.size(); ++i) { - 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) { + lua_pushstring(L, files[i].utf8_str()); + lua_rawseti(L, -2, i + 1); + } + } else { + lua_pushstring(L, diag.GetPath().utf8_str()); } + }); - return 1; - } - - lua_pushstring(L, diag.GetPath().utf8_str()); return 1; } @@ -247,13 +245,15 @@ namespace Automation4 { if (prompt_overwrite) flags |= wxFD_OVERWRITE_PROMPT; - wxFileDialog diag(ps->GetParentWindow(), message, dir, file, wildcard, flags); - if (ps->ShowDialog(&diag) == wxID_CANCEL) { - lua_pushnil(L); - return 1; - } + agi::dispatch::Main().Sync([&] { + wxFileDialog diag(ps->GetParentWindow(), message, dir, file, wildcard, flags); + if (diag.ShowModal() == wxID_CANCEL) { + lua_pushnil(L); + } else { + lua_pushstring(L, diag.GetPath().utf8_str()); + } + }); - lua_pushstring(L, diag.GetPath().utf8_str()); return 1; } }