From ef08d06d022d4cd0894dcaf369d06d727d0ddcb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 30 Sep 2026 11:05:45 -0600 Subject: [PATCH] Achievements: Don't leave boot blocked after an aborted login or load rc_client doesn't call back for a game load aborted by unload, or for anything pending when the client is destroyed. g_isIdentifying or g_isLoggingIn then stayed set, and IsBlockingExecution kept every later boot on a black screen until restart. Quitting during identification, or disabling achievements during a token login, was enough. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/RetroAchievements.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Core/RetroAchievements.cpp b/Core/RetroAchievements.cpp index e0aa262d6a..c2c6853f2b 100644 --- a/Core/RetroAchievements.cpp +++ b/Core/RetroAchievements.cpp @@ -801,6 +801,9 @@ bool LoginAsync(const char *username, const char *password) { void Logout() { rc_client_logout(g_rcClient); + // An aborted login or game load doesn't always call back, so clear the flags here. + g_isLoggingIn = false; + g_isIdentifying = false; // remove secret from config NativeClearSecret(RA_TOKEN_SECRET_NAME); g_Config.Save("Achievements logout"); @@ -832,6 +835,9 @@ bool Shutdown() { g_rcClient = nullptr; INFO_LOG(Log::Achievements, "Achievements shut down."); } + // A destroyed client doesn't call back for pending logins or game loads. + g_isLoggingIn = false; + g_isIdentifying = false; return true; } @@ -1157,6 +1163,8 @@ void UnloadGame() { g_gamePath.clear(); s_game_hash.clear(); } + // Unloading aborts a pending load, and rc_client doesn't call back for an aborted load. + g_isIdentifying = false; } void change_media_callback(int result, const char *error_message, rc_client_t *client, void *userdata) {