diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index d792e7caea..7494d512b9 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -966,6 +966,11 @@ game_boot_result Emulator::BootGame(const std::string& path, const std::string& std::tie(m_path, m_path_original, argv, envp, data, disc, klic, hdd1, m_config_mode, m_config_path) = std::move(save_args); }; } + + if (result != game_boot_result::no_errors) + { + GetCallbacks().close_gs_frame(); + } } return result; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 747d6d494b..fd48c199ae 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -86,6 +86,7 @@ struct EmuCallbacks std::function init_pad_handler; std::function update_emu_settings; std::function save_emu_settings; + std::function close_gs_frame; std::function()> get_gs_frame; std::function()> get_camera_handler; std::function()> get_music_handler; diff --git a/rpcs3/headless_application.cpp b/rpcs3/headless_application.cpp index b12b6d87e2..e82bcc12dc 100644 --- a/rpcs3/headless_application.cpp +++ b/rpcs3/headless_application.cpp @@ -120,6 +120,7 @@ void headless_application::InitializeCallbacks() return nullptr; }; + callbacks.close_gs_frame = [](){}; callbacks.get_gs_frame = []() -> std::unique_ptr { if (g_cfg.video.renderer != video_renderer::null) diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index ef4131c3b4..41421cfdcf 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -603,6 +603,11 @@ void gs_frame::close() gui_log.notice("Closing game window"); + if (m_ignore_stop_events) + { + return; + } + Emu.CallFromMainThread([this]() { // Hide window if necessary @@ -1139,6 +1144,11 @@ bool gs_frame::event(QEvent* ev) gui_log.notice("Game window close event issued"); + if (m_ignore_stop_events) + { + return QWindow::event(ev); + } + if (Emu.IsStopped()) { // This should be unreachable, but never say never. Properly close the window anyway. diff --git a/rpcs3/rpcs3qt/gs_frame.h b/rpcs3/rpcs3qt/gs_frame.h index a6d5f41b19..07f3527d61 100644 --- a/rpcs3/rpcs3qt/gs_frame.h +++ b/rpcs3/rpcs3qt/gs_frame.h @@ -45,6 +45,7 @@ private: u32 m_hide_mouse_idletime = 2000; // ms bool m_flip_showed_frame = false; bool m_start_games_fullscreen = false; + bool m_ignore_stop_events = false; std::shared_ptr m_video_encoder{}; @@ -52,6 +53,8 @@ public: explicit gs_frame(QScreen* screen, const QRect& geometry, const QIcon& appIcon, std::shared_ptr gui_settings, bool force_fullscreen); ~gs_frame(); + void ignore_stop_events() { m_ignore_stop_events = true; } + draw_context_t make_context() override; void set_current(draw_context_t context) override; void delete_context(draw_context_t context) override; diff --git a/rpcs3/rpcs3qt/gui_application.cpp b/rpcs3/rpcs3qt/gui_application.cpp index e16f97aff0..bacc530051 100644 --- a/rpcs3/rpcs3qt/gui_application.cpp +++ b/rpcs3/rpcs3qt/gui_application.cpp @@ -366,6 +366,9 @@ std::unique_ptr gui_application::get_gs_frame() } return std::unique_ptr(m_game_window); } + + // Clean-up old game window. This should only happen if there was an unexpected error during boot. + Emu.GetCallbacks().close_gs_frame(); } gui_log.notice("gui_application: Creating new game window"); @@ -564,6 +567,16 @@ void gui_application::InitializeCallbacks() return nullptr; }; + callbacks.close_gs_frame = [this]() + { + if (m_game_window) + { + gui_log.warning("gui_application: Closing old game window"); + m_game_window->ignore_stop_events(); + delete m_game_window; + m_game_window = nullptr; + } + }; callbacks.get_gs_frame = [this]() -> std::unique_ptr { return get_gs_frame(); }; callbacks.get_msg_dialog = [this]() -> std::shared_ptr { return m_show_gui ? std::make_shared() : nullptr; }; callbacks.get_osk_dialog = [this]() -> std::shared_ptr { return m_show_gui ? std::make_shared() : nullptr; };