From 6c48bd8f93fee36cafa4438d8bd262673191c437 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Mon, 16 Mar 2026 08:08:36 +0100 Subject: [PATCH] Fix callback initialization order We need to initialize the emu callbacks before creating the main window. Otherwise CallFromMainThread segs since call_from_main_thread is null. The same goes for the CallFromMainThread connect in gui_application. If we create the connection too late, we will simply never wake up the caller and therefore softlock eventually. --- rpcs3/Emu/System.cpp | 4 ++- rpcs3/rpcs3qt/gui_application.cpp | 45 +++++++++++++++---------------- rpcs3/rpcs3qt/gui_settings.h | 2 +- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 3548df869d..85b753d130 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -166,6 +166,8 @@ void fmt_class_string::format(std::string& out, u64 arg) void Emulator::CallFromMainThread(std::function&& func, atomic_t* wake_up, bool track_emu_state, u64 stop_ctr, std::source_location src_loc) const { + ensure(func); + std::function final_func = [this, before = IsStopped(true), track_emu_state, thread_name = thread_ctrl::get_name(), src = src_loc , count = (stop_ctr == umax ? +m_stop_ctr : stop_ctr), func = std::move(func)] { @@ -179,7 +181,7 @@ void Emulator::CallFromMainThread(std::function&& func, atomic_t* w } }; - m_cb.call_from_main_thread(std::move(final_func), wake_up); + ensure(m_cb.call_from_main_thread)(std::move(final_func), wake_up); } void Emulator::BlockingCallFromMainThread(std::function&& func, bool track_emu_state, std::source_location src_loc) const diff --git a/rpcs3/rpcs3qt/gui_application.cpp b/rpcs3/rpcs3qt/gui_application.cpp index 113f5a6ebb..606a081fff 100644 --- a/rpcs3/rpcs3qt/gui_application.cpp +++ b/rpcs3/rpcs3qt/gui_application.cpp @@ -154,6 +154,12 @@ bool gui_application::Init() // Force init the emulator InitializeEmulator(m_active_user, m_show_gui); + // Create callbacks from the emulator, which reference the handlers. + InitializeCallbacks(); + + // Create connects to propagate events throughout Gui. + InitializeConnects(); + // Create the main window if (m_show_gui) { @@ -164,14 +170,23 @@ bool gui_application::Init() const auto index = codes.indexOf(language); LoadLanguage(index < 0 ? QLocale(QLocale::English).bcp47Name() : ::at32(codes, index)); + + connect(m_main_window, &main_window::RequestLanguageChange, this, &gui_application::LoadLanguage); + connect(m_main_window, &main_window::RequestGlobalStylesheetChange, this, &gui_application::OnChangeStyleSheetRequest); + connect(m_main_window, &main_window::NotifyEmuSettingsChange, this, [this](){ OnEmuSettingsChange(); }); + connect(m_main_window, &main_window::NotifyShortcutHandlers, this, &gui_application::OnShortcutChange); + + connect(this, &gui_application::OnEmulatorRun, m_main_window, &main_window::OnEmuRun); + connect(this, &gui_application::OnEmulatorStop, m_main_window, &main_window::OnEmuStop); + connect(this, &gui_application::OnEmulatorPause, m_main_window, &main_window::OnEmuPause); + connect(this, &gui_application::OnEmulatorResume, m_main_window, &main_window::OnEmuResume); + connect(this, &gui_application::OnEmulatorReady, m_main_window, &main_window::OnEmuReady); + connect(this, &gui_application::OnEnableDiscEject, m_main_window, &main_window::OnEnableDiscEject); + connect(this, &gui_application::OnEnableDiscInsert, m_main_window, &main_window::OnEnableDiscInsert); + + connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, [this](){ OnChangeStyleSheetRequest(); }); } - // Create callbacks from the emulator, which reference the handlers. - InitializeCallbacks(); - - // Create connects to propagate events throughout Gui. - InitializeConnects(); - if (m_gui_settings->GetValue(gui::ib_show_welcome).toBool()) { welcome_dialog* welcome = new welcome_dialog(m_gui_settings, false); @@ -438,24 +453,6 @@ void gui_application::InitializeConnects() connect(this, &gui_application::OnEmulatorResume, this, &gui_application::StartPlaytime); connect(this, &QGuiApplication::applicationStateChanged, this, &gui_application::OnAppStateChanged); - if (m_main_window) - { - connect(m_main_window, &main_window::RequestLanguageChange, this, &gui_application::LoadLanguage); - connect(m_main_window, &main_window::RequestGlobalStylesheetChange, this, &gui_application::OnChangeStyleSheetRequest); - connect(m_main_window, &main_window::NotifyEmuSettingsChange, this, [this](){ OnEmuSettingsChange(); }); - connect(m_main_window, &main_window::NotifyShortcutHandlers, this, &gui_application::OnShortcutChange); - - connect(this, &gui_application::OnEmulatorRun, m_main_window, &main_window::OnEmuRun); - connect(this, &gui_application::OnEmulatorStop, m_main_window, &main_window::OnEmuStop); - connect(this, &gui_application::OnEmulatorPause, m_main_window, &main_window::OnEmuPause); - connect(this, &gui_application::OnEmulatorResume, m_main_window, &main_window::OnEmuResume); - connect(this, &gui_application::OnEmulatorReady, m_main_window, &main_window::OnEmuReady); - connect(this, &gui_application::OnEnableDiscEject, m_main_window, &main_window::OnEnableDiscEject); - connect(this, &gui_application::OnEnableDiscInsert, m_main_window, &main_window::OnEnableDiscInsert); - - connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, [this](){ OnChangeStyleSheetRequest(); }); - } - #ifdef WITH_DISCORD_RPC connect(this, &gui_application::OnEmulatorRun, [this](bool /*start_playtime*/) { diff --git a/rpcs3/rpcs3qt/gui_settings.h b/rpcs3/rpcs3qt/gui_settings.h index 21a46259c2..bdc6401031 100644 --- a/rpcs3/rpcs3qt/gui_settings.h +++ b/rpcs3/rpcs3qt/gui_settings.h @@ -315,7 +315,7 @@ namespace gui const gui_save sc_shortcuts = gui_save(sc, "shortcuts", QVariantMap()); - const gui_save nav_enabled = gui_save(navigation, "pad_input_enabled", false); + const gui_save nav_enabled = gui_save(navigation, "pad_input_enabled", true); const gui_save nav_global = gui_save(navigation, "allow_global_pad_input", false); }