diff --git a/src/xenia/app/emulator_window.cc b/src/xenia/app/emulator_window.cc index beacaa11f..7162c4f4b 100644 --- a/src/xenia/app/emulator_window.cc +++ b/src/xenia/app/emulator_window.cc @@ -2394,16 +2394,25 @@ void EmulatorWindow::CheckChildProcessStatus() { // Detect transition from having child to no child if (had_child_last_check && !has_child_now) { - XELOGI("Child process exited, remounting profiles and reloading GPDs"); + XELOGI("Child process exited, reloading config and profile state"); - // Remount VFS for all logged-in profiles to pick up file changes from game - // process + // Reload config from disk to pick up any profile login changes made by + // child process + config::ReloadConfig(); + XELOGI("Config reloaded from disk"); + + // Sync profile login state with the reloaded config if (emulator_ && emulator_->kernel_state() && emulator_->kernel_state()->xam_state()) { auto profile_manager = emulator_->kernel_state()->xam_state()->profile_manager(); if (profile_manager) { - // Remount VFS for each logged-in profile + // Sync profiles with config: logout current profiles and login based on + // config cvars + profile_manager->SyncProfilesWithConfig(); + XELOGI("Profile login state synced with config"); + + // Remount VFS for all newly logged-in profiles for (uint8_t i = 0; i < 4; i++) { auto profile = profile_manager->GetProfile(i); if (profile) { @@ -2427,6 +2436,7 @@ void EmulatorWindow::CheckChildProcessStatus() { // Reload the game list dialog if it's open if (game_list_dialog_qt_) { game_list_dialog_qt_->LoadGameList(); + game_list_dialog_qt_->UpdateProfileButtonState(); XELOGI("Game list dialog refreshed"); } diff --git a/src/xenia/kernel/xam/profile_manager.cc b/src/xenia/kernel/xam/profile_manager.cc index 1035a9351..427d381c8 100644 --- a/src/xenia/kernel/xam/profile_manager.cc +++ b/src/xenia/kernel/xam/profile_manager.cc @@ -162,30 +162,46 @@ void ProfileManager::SyncProfilesWithConfig() { LoadAccount(account_xuid); } - // Then logout all currently logged in profiles - std::vector slots_to_logout; - for (const auto& [slot, profile] : logged_profiles_) { - slots_to_logout.push_back(slot); - } - for (uint8_t slot : slots_to_logout) { - Logout(slot, false); - } - - // Now login profiles based on the current cvar values + // Build desired login state from current cvar values const std::string* profile_cvars[4] = { &cvars::logged_profile_slot_0_xuid, &cvars::logged_profile_slot_1_xuid, &cvars::logged_profile_slot_2_xuid, &cvars::logged_profile_slot_3_xuid}; + std::map desired_profiles; for (uint8_t slot = 0; slot < 4; slot++) { if (!profile_cvars[slot]->empty()) { uint64_t xuid = xe::string_util::from_string(*profile_cvars[slot], true); if (xuid != 0) { - Login(xuid, slot, false); + desired_profiles[slot] = xuid; } } } + // Logout profiles that shouldn't be logged in anymore + std::vector slots_to_logout; + for (const auto& [slot, profile] : logged_profiles_) { + auto desired_it = desired_profiles.find(slot); + if (desired_it == desired_profiles.end() || + desired_it->second != profile->xuid()) { + // This slot should be logged out (either empty or different profile) + slots_to_logout.push_back(slot); + } + } + for (uint8_t slot : slots_to_logout) { + Logout(slot, false); + } + + // Login profiles that aren't already logged in + for (const auto& [slot, xuid] : desired_profiles) { + auto current_profile = logged_profiles_.find(slot); + if (current_profile == logged_profiles_.end() || + current_profile->second->xuid() != xuid) { + // This slot needs to be logged in (either empty or different profile) + Login(xuid, slot, false); + } + } + // Send a single notification after all changes kernel_state_->BroadcastNotification(kXNotificationSystemSignInChanged, GetUsedUserSlots().to_ulong()); diff --git a/src/xenia/ui/game_list_dialog_qt.h b/src/xenia/ui/game_list_dialog_qt.h index c2d70f836..338d3f591 100644 --- a/src/xenia/ui/game_list_dialog_qt.h +++ b/src/xenia/ui/game_list_dialog_qt.h @@ -56,6 +56,7 @@ class GameListDialogQt : public QWidget { void LoadGameList(); void RefreshIcons(); + void UpdateProfileButtonState(); private slots: void OnFilterTextChanged(const QString& text); @@ -67,7 +68,6 @@ class GameListDialogQt : public QWidget { void OnProfileContextMenu(const QPoint& pos); void OnSelectionChanged(); void UpdatePlayButtonState(); - void UpdateProfileButtonState(); protected: bool eventFilter(QObject* obj, QEvent* event) override;