summaryrefslogtreecommitdiff
path: root/FreeFileSync/Source/RealTimeSync/application.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'FreeFileSync/Source/RealTimeSync/application.cpp')
-rw-r--r--FreeFileSync/Source/RealTimeSync/application.cpp84
1 files changed, 33 insertions, 51 deletions
diff --git a/FreeFileSync/Source/RealTimeSync/application.cpp b/FreeFileSync/Source/RealTimeSync/application.cpp
index 6add53b9..1558ea33 100644
--- a/FreeFileSync/Source/RealTimeSync/application.cpp
+++ b/FreeFileSync/Source/RealTimeSync/application.cpp
@@ -27,6 +27,7 @@
using namespace zen;
using namespace rts;
+using fff::FfsExitCode;
#ifdef __WXGTK3__ //deprioritize Wayland: see FFS' application.cpp
GLOBAL_RUN_ONCE(::gdk_set_allowed_backends("x11,*")); //call *before* gtk_init()
@@ -37,29 +38,10 @@ IMPLEMENT_APP(Application)
namespace
{
-using fff::FfsExitCode;
-
-void notifyAppError(const std::wstring& msg, FfsExitCode rc)
+void notifyAppError(const std::wstring& msg)
{
- //raiseExitCode(exitCode_, rc);
-
- const std::wstring msgType = [&]
- {
- switch (rc)
- {
- //*INDENT-OFF*
- case FfsExitCode::success: break;
- case FfsExitCode::warning: return _("Warning");
- case FfsExitCode::error: return _("Error");
- case FfsExitCode::aborted: return _("Error");
- case FfsExitCode::exception: return _("An exception occurred");
- //*INDENT-ON*
- }
- assert(false);
- return std::wstring{};
- }();
//error handling strategy unknown and no sync log output available at this point!
- std::cerr << utfTo<std::string>(msgType + L": " + msg) + '\n';
+ std::cerr << utfTo<std::string>(_("Error") + L": " + msg) + '\n';
//alternative0: std::wcerr: cannot display non-ASCII at all, so why does it exist???
//alternative1: wxSafeShowMessage => NO console output on Debian x86, WTF!
//alternative2: wxMessageBox() => works, but we probably shouldn't block during command line usage
@@ -71,16 +53,24 @@ bool Application::OnInit()
{
//do not call wxApp::OnInit() to avoid using wxWidgets command line parser
+ initExtraLog([](const ErrorLog& log) //don't call functions depending on global state (which might be destroyed already!)
+ {
+ std::wstring msg;
+ for (const LogEntry& e : log)
+ msg += utfTo<std::wstring>(formatMessage(e));
+ trim(msg);
+ notifyAppError(msg);
+ });
+
try { imageResourcesInit(appendPath(fff::getResourceDirPath(), Zstr("Icons.zip"))); }
- catch (const FileError& e) { notifyAppError(e.toString(), FfsExitCode::warning); }
- //errors are not really critical in this context
+ catch (const FileError& e) { logExtraError(e.toString()); } //not critical in this context
//GTK should already have been initialized by wxWidgets (see \src\gtk\app.cpp:wxApp::Initialize)
#if GTK_MAJOR_VERSION == 2
::gtk_rc_parse(appendPath(fff::getResourceDirPath(), "Gtk2Styles.rc").c_str());
//fix hang on Ubuntu 19.10 (see FFS's application.cpp)
- g_vfs_get_default(); //returns unowned GVfs*
+ [[maybe_unused]] GVfs* defaultFs = ::g_vfs_get_default(); //not owned by us!
#elif GTK_MAJOR_VERSION == 3
auto loadCSS = [&](const char* fileName)
@@ -91,14 +81,14 @@ bool Application::OnInit()
GError* error = nullptr;
ZEN_ON_SCOPE_EXIT(if (error) ::g_error_free(error));
- ::gtk_css_provider_load_from_path(provider, //GtkCssProvider* css_provider,
- appendPath(fff::getResourceDirPath(), fileName).c_str(), //const gchar* path,
+ ::gtk_css_provider_load_from_path(provider, //GtkCssProvider* css_provider
+ appendPath(fff::getResourceDirPath(), fileName).c_str(), //const gchar* path
&error); //GError** error
if (error)
throw SysError(formatGlibError("gtk_css_provider_load_from_path", error));
- ::gtk_style_context_add_provider_for_screen(::gdk_screen_get_default(), //GdkScreen* screen,
- GTK_STYLE_PROVIDER(provider), //GtkStyleProvider* provider,
+ ::gtk_style_context_add_provider_for_screen(::gdk_screen_get_default(), //GdkScreen* screen
+ GTK_STYLE_PROVIDER(provider), //GtkStyleProvider* provider
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); //guint priority
};
try
@@ -112,30 +102,26 @@ bool Application::OnInit()
{
loadCSS("Gtk3Styles.old.css"); //throw SysError
}
- catch (const SysError& e2) { notifyAppError(e2.toString(), FfsExitCode::warning); }
+ catch (const SysError& e3) { logExtraError(_("Error during process initialization.") + L"\n\n" + e3.toString()); }
}
#else
#error unknown GTK version!
#endif
- try
- {
- /* we're a GUI app: ignore SIGHUP when the parent terminal quits! (or process is killed!)
+ /* we're a GUI app: ignore SIGHUP when the parent terminal quits! (or process is killed!)
=> the FFS launcher will still be killed => fine
=> macOS: apparently not needed! interestingly the FFS launcher does receive SIGHUP and *is* killed */
- if (sighandler_t oldHandler = ::signal(SIGHUP, SIG_IGN);
- oldHandler == SIG_ERR)
- THROW_LAST_SYS_ERROR("signal(SIGHUP)");
- else assert(!oldHandler);
- }
- catch (const SysError& e) { notifyAppError(e.toString(), FfsExitCode::warning); }
+ if (sighandler_t oldHandler = ::signal(SIGHUP, SIG_IGN);
+ oldHandler == SIG_ERR)
+ logExtraError(_("Error during process initialization.") + L"\n\n" + formatSystemError("signal(SIGHUP)", getLastError()));
+ else assert(!oldHandler);
//Windows User Experience Interaction Guidelines: tool tips should have 5s timeout, info tips no timeout => compromise:
wxToolTip::Enable(true); //wxWidgets screw-up: wxToolTip::SetAutoPop is no-op if global tooltip window is not yet constructed: wxToolTip::Enable creates it
wxToolTip::SetAutoPop(15'000); //https://docs.microsoft.com/en-us/windows/win32/uxguide/ctrl-tooltips-and-infotips
- SetAppName(L"RealTimeSync");
+ SetAppName(L"RealTimeSync"); //if not set, defaults to executable name
try
@@ -143,25 +129,21 @@ bool Application::OnInit()
fff::localizationInit(appendPath(fff::getResourceDirPath(), Zstr("Languages.zip"))); //throw FileError
fff::setLanguage(getProgramLanguage()); //throw FileError
}
- catch (const FileError& e) { notifyAppError(e.toString(), FfsExitCode::warning); }
+ catch (const FileError& e) { logExtraError(e.toString()); }
auto onSystemShutdown = [](int /*unused*/ = 0)
{
onSystemShutdownRunTasks();
//it's futile to try and clean up while the process is in full swing (CRASH!) => just terminate!
- terminateProcess(static_cast<int>(FfsExitCode::aborted));
+ terminateProcess(static_cast<int>(FfsExitCode::cancelled));
};
Bind(wxEVT_QUERY_END_SESSION, [onSystemShutdown](wxCloseEvent& event) { onSystemShutdown(); }); //can veto
Bind(wxEVT_END_SESSION, [onSystemShutdown](wxCloseEvent& event) { onSystemShutdown(); }); //can *not* veto
- try
- {
- if (auto /*sighandler_t n.a. on macOS*/ oldHandler = ::signal(SIGTERM, onSystemShutdown);//"graceful" exit requested, unlike SIGKILL
- oldHandler == SIG_ERR)
- THROW_LAST_SYS_ERROR("signal(SIGTERM)");
- else assert(!oldHandler);
- }
- catch (const SysError& e) { notifyAppError(e.toString(), FfsExitCode::warning); }
+ if (auto /*sighandler_t n.a. on macOS*/ oldHandler = ::signal(SIGTERM, onSystemShutdown);//"graceful" exit requested, unlike SIGKILL
+ oldHandler == SIG_ERR)
+ logExtraError(_("Error during process initialization.") + L"\n\n" + formatSystemError("signal(SIGTERM)", getLastError()));
+ else assert(!oldHandler);
//Note: app start is deferred: -> see FreeFileSync
CallAfter([&] { onEnterEventLoop(); });
@@ -207,7 +189,7 @@ void Application::onEnterEventLoop()
}
catch (const FileError& e)
{
- notifyAppError(e.toString(), FfsExitCode::exception);
+ notifyAppError(e.toString());
}
}
@@ -240,7 +222,7 @@ void Application::OnUnhandledException() //handles both wxApp::OnInit() + wxApp:
}
catch (const std::bad_alloc& e) //the only kind of exception we don't want crash dumps for
{
- notifyAppError(utfTo<std::wstring>(e.what()), FfsExitCode::exception);
+ notifyAppError(utfTo<std::wstring>(e.what()));
terminateProcess(static_cast<int>(FfsExitCode::exception));
}
//catch (...) -> Windows: let it crash and create mini dump!!! Linux/macOS: std::exception::what() logged to console
bgstack15