From 7a121533434527ec3d7ec9b5e66e9e12b8fb49a3 Mon Sep 17 00:00:00 2001 From: "j.foucher" Date: Sat, 2 May 2026 12:41:54 +0200 Subject: [PATCH] LaunchVersion: restore launcher window when Proserve exits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After clicking Lancer, the launcher minimizes to the taskbar so Proserve has the foreground. Add an Exited event handler on the launched Process that brings the launcher back from the taskbar once the game closes. EnableRaisingEvents is required (false by default) to receive Exited. The handler runs on a worker thread so we marshal back to the UI via Dispatcher.Invoke before touching WindowState. A brief Topmost=true / false toggle nudges the window to the foreground without permanently locking it on top. Wrapped in try/catch — some ShellExecute spawns return a Process with limited access (no event support), in which case we just log and let the user click the taskbar icon manually. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../ViewModels/MainViewModel.cs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/PSLauncher.App/ViewModels/MainViewModel.cs b/src/PSLauncher.App/ViewModels/MainViewModel.cs index b1ac8b6..fe1fb0e 100644 --- a/src/PSLauncher.App/ViewModels/MainViewModel.cs +++ b/src/PSLauncher.App/ViewModels/MainViewModel.cs @@ -424,13 +424,41 @@ public sealed partial class MainViewModel : ObservableObject if (row.Installed is null) return; try { - _processLauncher.Launch(row.Installed); + var proc = _processLauncher.Launch(row.Installed); _config.LastLaunchedVersion = row.Version; _configStore.Save(_config); // Réduit la fenêtre du launcher pour ne pas gêner Proserve qui démarre if (Application.Current.MainWindow is { } mw) mw.WindowState = WindowState.Minimized; + + // Quand Proserve se termine, on remet la fenêtre du launcher au premier plan. + // EnableRaisingEvents est requis pour recevoir l'event Exited. + try + { + proc.EnableRaisingEvents = true; + proc.Exited += (_, _) => + { + _logger.LogInformation("Proserve v{Version} a quitté — restauration du launcher", row.Version); + Application.Current?.Dispatcher.Invoke(() => + { + if (Application.Current.MainWindow is { } main) + { + if (main.WindowState == WindowState.Minimized) + main.WindowState = WindowState.Normal; + main.Activate(); + // Pop temporaire pour amener la fenêtre au premier plan + main.Topmost = true; + main.Topmost = false; + } + }); + }; + } + catch (Exception ex) + { + // ShellExecute peut renvoyer un Process sans accès aux events — non bloquant + _logger.LogDebug(ex, "Could not hook Exited on launched process"); + } } catch (Exception ex) {