From 1271fd1a44574413743d58d4dafcfb713d6e82d1 Mon Sep 17 00:00:00 2001 From: MohandL3G Date: Mon, 29 Jun 2026 09:17:32 +0200 Subject: [PATCH] Dynamic Steam controls: show Restart/Close when running, Start when stopped --- ui/MainWindow.xaml | 13 ++++- ui/MainWindow.xaml.cs | 54 +++++++++++++++---- ui/Pages/DashboardPage.xaml | 13 ++++- ui/Pages/DashboardPage.xaml.cs | 96 ++++++++++++++++++++++++++++++++++ ui/Resources/Strings.resx | 12 +++++ 5 files changed, 175 insertions(+), 13 deletions(-) diff --git a/ui/MainWindow.xaml b/ui/MainWindow.xaml index 11825393..9434e9a2 100644 --- a/ui/MainWindow.xaml +++ b/ui/MainWindow.xaml @@ -116,7 +116,18 @@ + Click="SteamNav_Click" + Tag="restart" /> + + diff --git a/ui/MainWindow.xaml.cs b/ui/MainWindow.xaml.cs index 3ccc4934..52314728 100644 --- a/ui/MainWindow.xaml.cs +++ b/ui/MainWindow.xaml.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using System.Windows.Threading; using Wpf.Ui.Appearance; using Wpf.Ui.Controls; using TextBlock = System.Windows.Controls.TextBlock; @@ -14,6 +15,7 @@ public partial class MainWindow : FluentWindow { private Services.AppUpdater.CheckResult? _pendingUpdate; public bool AppUpdateAvailable { get; private set; } + private readonly DispatcherTimer _steamStateTimer = new() { Interval = TimeSpan.FromSeconds(5) }; public MainWindow() { @@ -40,6 +42,10 @@ public MainWindow() RootNavigation.Navigate(typeof(Pages.DashboardPage)); } catch { } + + UpdateSteamNavItem(); + _steamStateTimer.Tick += (_, _) => UpdateSteamNavItem(); + _steamStateTimer.Start(); }; } @@ -179,18 +185,42 @@ private void UpdateSkip_Click(object sender, RoutedEventArgs e) public void ShowRestartSteam() { - // Button is always visible now; kept for callers. + UpdateSteamNavItem(); + } + + private void UpdateSteamNavItem() + { + var running = Services.SteamDetector.IsSteamRunning(); + RestartSteamItem.Visibility = running ? Visibility.Visible : Visibility.Collapsed; + CloseSteamItem.Visibility = running ? Visibility.Visible : Visibility.Collapsed; + StartSteamItem.Visibility = running ? Visibility.Collapsed : Visibility.Visible; } - private async void RestartSteamItem_Click(object sender, RoutedEventArgs e) + private async void SteamNav_Click(object sender, RoutedEventArgs e) { + var tag = (sender as FrameworkElement)?.Tag as string; + var steamPath = Services.SteamDetector.FindSteamPath(); if (steamPath == null) return; var steamExe = Path.Combine(steamPath, "steam.exe"); if (!File.Exists(steamExe)) return; - // Graceful shutdown first + if (tag == "start") + { + try + { + Process.Start(new ProcessStartInfo + { + FileName = steamExe, + UseShellExecute = true + })?.Dispose(); + } + catch { } + return; + } + + // restart or close — shut down Steam first var procs = Process.GetProcessesByName("steam"); bool wasRunning = procs.Length > 0; foreach (var p in procs) p.Dispose(); @@ -204,7 +234,6 @@ private async void RestartSteamItem_Click(object sender, RoutedEventArgs e) UseShellExecute = true })?.Dispose(); - // Wait up to 15s for Steam to close for (int i = 0; i < 30; i++) { await Task.Delay(500); @@ -215,16 +244,19 @@ private async void RestartSteamItem_Click(object sender, RoutedEventArgs e) } } - try + if (tag == "restart") { - Process.Start(new ProcessStartInfo + try { - FileName = steamExe, - UseShellExecute = true - })?.Dispose(); + Process.Start(new ProcessStartInfo + { + FileName = steamExe, + UseShellExecute = true + })?.Dispose(); + } + catch { } } - catch { } - RestartSteamItem.Visibility = Visibility.Collapsed; + UpdateSteamNavItem(); } } diff --git a/ui/Pages/DashboardPage.xaml b/ui/Pages/DashboardPage.xaml index 45e7411e..4282ecd8 100644 --- a/ui/Pages/DashboardPage.xaml +++ b/ui/Pages/DashboardPage.xaml @@ -99,10 +99,21 @@ Icon="{ui:SymbolIcon Document24}" Margin="0,0,8,8" Click="OpenLog_Click" /> - + + diff --git a/ui/Pages/DashboardPage.xaml.cs b/ui/Pages/DashboardPage.xaml.cs index 1420a17b..b2d4541e 100644 --- a/ui/Pages/DashboardPage.xaml.cs +++ b/ui/Pages/DashboardPage.xaml.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using System.Windows.Threading; using CloudRedirect.Resources; namespace CloudRedirect.Pages; @@ -11,6 +12,7 @@ namespace CloudRedirect.Pages; public partial class DashboardPage : Page { private string? _steamPath; + private readonly DispatcherTimer _steamStateTimer = new() { Interval = TimeSpan.FromSeconds(5) }; public void HideDllUpdateBanner() { @@ -25,6 +27,10 @@ public DashboardPage() try { await LoadStatusAsync(); } catch { } + UpdateSteamButtons(); + _steamStateTimer.Tick += (_, _) => UpdateSteamButtons(); + _steamStateTimer.Start(); + // Give the app-level update check time to finish, then hide the // DLL banner if a full app update is available (avoids two banners). await Task.Delay(3000); @@ -268,6 +274,96 @@ await Task.Run(() => } } + private void UpdateSteamButtons() + { + var running = Services.SteamDetector.IsSteamRunning(); + RestartSteamBtn.Visibility = running ? Visibility.Visible : Visibility.Collapsed; + CloseSteamBtn.Visibility = running ? Visibility.Visible : Visibility.Collapsed; + StartSteamBtn.Visibility = running ? Visibility.Collapsed : Visibility.Visible; + } + + private async void CloseSteam_Click(object sender, RoutedEventArgs e) + { + var steamPath = Services.SteamDetector.FindSteamPath(); + if (steamPath == null) return; + + var steamExe = Path.Combine(steamPath, "steam.exe"); + if (!File.Exists(steamExe)) return; + + var button = (Wpf.Ui.Controls.Button)sender; + button.IsEnabled = false; + var originalContent = button.Content; + button.Content = S.Get("Dashboard_ShuttingDownSteam"); + + try + { + Process.Start(new ProcessStartInfo + { + FileName = steamExe, + Arguments = "-shutdown", + UseShellExecute = true + })?.Dispose(); + + bool exited = await Task.Run(async () => + { + for (int i = 0; i < 30; i++) + { + await Task.Delay(500); + var procs = Process.GetProcessesByName("steam"); + bool any = procs.Length > 0; + foreach (var p in procs) p.Dispose(); + if (!any) return true; + } + return false; + }); + + if (!exited) + { + button.Content = S.Get("Dashboard_ForceKilling"); + await Task.Run(() => + { + foreach (var proc in Process.GetProcessesByName("steam")) + { + try { proc.Kill(); } + catch { } + finally { proc.Dispose(); } + } + }); + await Task.Delay(1000); + } + } + catch { } + + button.Content = originalContent; + button.IsEnabled = true; + UpdateSteamButtons(); + } + + private async void StartSteam_Click(object sender, RoutedEventArgs e) + { + var steamPath = Services.SteamDetector.FindSteamPath(); + if (steamPath == null) return; + + var steamExe = Path.Combine(steamPath, "steam.exe"); + if (!File.Exists(steamExe)) return; + + var button = (Wpf.Ui.Controls.Button)sender; + button.IsEnabled = false; + + try + { + Process.Start(new ProcessStartInfo + { + FileName = steamExe, + UseShellExecute = true + })?.Dispose(); + } + catch { } + + button.IsEnabled = true; + UpdateSteamButtons(); + } + private async void UpdateDll_Click(object sender, RoutedEventArgs e) { if (_steamPath == null) return; diff --git a/ui/Resources/Strings.resx b/ui/Resources/Strings.resx index c695380d..ca246422 100644 --- a/ui/Resources/Strings.resx +++ b/ui/Resources/Strings.resx @@ -73,6 +73,12 @@ Restart Steam + + Close Steam + + + Start Steam + Mode @@ -518,6 +524,12 @@ If you skip this, saves will be stored locally in your Steam folder. Restart Steam + + Close Steam + + + Start Steam +