[App] Ensure profile state is reloaded on child process exit.

If the game was started logged out but the user logs in during the
game we want that to be reflected in the main game list windows.
This commit is contained in:
Herman S.
2025-11-01 14:16:31 +09:00
parent 12bdb0a96b
commit 99361c54e5
3 changed files with 42 additions and 16 deletions
+14 -4
View File
@@ -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");
}
+27 -11
View File
@@ -162,30 +162,46 @@ void ProfileManager::SyncProfilesWithConfig() {
LoadAccount(account_xuid);
}
// Then logout all currently logged in profiles
std::vector<uint8_t> 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<uint8_t, uint64_t> desired_profiles;
for (uint8_t slot = 0; slot < 4; slot++) {
if (!profile_cvars[slot]->empty()) {
uint64_t xuid =
xe::string_util::from_string<uint64_t>(*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<uint8_t> 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());
+1 -1
View File
@@ -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;