From 010fbded1ad5030ba0d9a78067453cee49c84261 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 11 Jan 2022 13:53:25 +0100 Subject: [PATCH] Added "Restore window position on start" option to the "Preferences > General" + added crash detection for the cases, when PrusaSlicer is started from secondary display Possible fix for part of: #2939 - PrusaSlic3r freezing at startup (Win 10) and #5573 - PrusaSlicer won't launch on secondary monitor. Nahimic? --- src/libslic3r/AppConfig.cpp | 3 +++ src/slic3r/GUI/GUI_App.cpp | 49 +++++++++++++++++++++++++++++++--- src/slic3r/GUI/Preferences.cpp | 7 +++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index ec5ce37023..5b4bb34a3c 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -175,6 +175,9 @@ void AppConfig::set_defaults() if (get("show_splash_screen").empty()) set("show_splash_screen", "1"); + if (get("restore_win_position").empty()) + set("restore_win_position", "1"); // allowed values - "1", "0", "crashed_at_..." + if (get("show_hints").empty()) set("show_hints", "1"); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 1858044ae8..429e022253 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1143,15 +1143,25 @@ bool GUI_App::on_init_inner() // Detect position (display) to show the splash screen // Now this position is equal to the mainframe position wxPoint splashscreen_pos = wxDefaultPosition; - if (app_config->has("window_mainframe")) { + bool default_splashscreen_pos = true; + if (app_config->has("window_mainframe") && app_config->get("restore_win_position") == "1") { auto metrics = WindowMetrics::deserialize(app_config->get("window_mainframe")); - if (metrics) + default_splashscreen_pos = metrics == boost::none; + if (!default_splashscreen_pos) splashscreen_pos = metrics->get_rect().GetPosition(); } + if (!default_splashscreen_pos) + // workaround for crash related to the positioning of the window on secondary monitor + get_app_config()->set("restore_win_position", "crashed_at_splashscreen_pos"); + // create splash screen with updated bmp scrn = new SplashScreen(bmp.IsOk() ? bmp : create_scaled_bitmap("PrusaSlicer", nullptr, 400), wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT, 4000, splashscreen_pos); + + if (!default_splashscreen_pos) + // revert "restore_win_position" value if application wasn't crashed + get_app_config()->set("restore_win_position", "1"); #ifndef __linux__ wxYield(); #endif @@ -1308,6 +1318,23 @@ bool GUI_App::on_init_inner() }); m_initialized = true; + + if (const std::string& crash_reason = app_config->get("restore_win_position"); + crash_reason._Starts_with("crashed")) + { + MessageDialog dialog(mainframe, + format_wxstr(_L("PrusaSlicer was crashed during a previous start due to \"%1%\".\n" + "PrusaSlicer works in save mode now.\n" + "To avoid a next application crash you have to disable\n" + "\"%2%\" in \"Preferences\""), from_u8(crash_reason), _L("Restore window position on start")) + + "\n\n" + + format_wxstr(_L("Do you want to disable \"%1%\"?"), _L("Restore window position on start")), + _L("Start PrusaSlicer in save mode"), + wxICON_QUESTION | wxYES_NO); + if (dialog.ShowModal() == wxID_YES) + app_config->set("restore_win_position", "0"); + } + return true; } @@ -2937,8 +2964,22 @@ void GUI_App::window_pos_restore(wxTopLevelWindow* window, const std::string &na } const wxRect& rect = metrics->get_rect(); - window->SetPosition(rect.GetPosition()); - window->SetSize(rect.GetSize()); + + if (app_config->get("restore_win_position") == "1") { + // workaround for crash related to the positioning of the window on secondary monitor + app_config->set("restore_win_position", (boost::format("crashed_at_%1%_pos") % name).str()); + window->SetPosition(rect.GetPosition()); + + // workaround for crash related to the positioning of the window on secondary monitor + app_config->set("restore_win_position", (boost::format("crashed_at_%1%_size") % name).str()); + window->SetSize(rect.GetSize()); + + // revert "restore_win_position" value if application wasn't crashed + app_config->set("restore_win_position", "1"); + } + else + window->CenterOnScreen(); + window->Maximize(metrics->get_maximized()); } diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 7668ec3603..996d6b2c2e 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -284,6 +284,13 @@ void PreferencesDialog::build(size_t selected_tab) option = Option(def, "show_splash_screen"); m_optgroup_general->append_single_option_line(option); + def.label = L("Restore window position on start"); + def.type = coBool; + def.tooltip = L("If enabled, PrusaSlicer will be open at the position it was closed"); + def.set_default_value(new ConfigOptionBool{ app_config->get("restore_win_position") == "1" }); + option = Option(def, "restore_win_position"); + m_optgroup_general->append_single_option_line(option); + // Clear Undo / Redo stack on new project def.label = L("Clear Undo / Redo stack on new project"); def.type = coBool;