diff --git a/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/LoadingWindow.xaml.cs b/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/LoadingWindow.xaml.cs index fc98b46..805870d 100644 --- a/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/LoadingWindow.xaml.cs +++ b/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/LoadingWindow.xaml.cs @@ -7,6 +7,8 @@ using System.Windows.Threading; using System.Windows.Controls; using System.Windows.Media; +using System.Threading; +using System.Windows.Input; namespace Community.PowerToys.Run.Plugin.SpeedTest { @@ -15,6 +17,7 @@ public partial class LoadingWindow : Window private TestStage _currentStage = TestStage.Connecting; private DispatcherTimer _dotAnimationTimer; private bool _isCompleted = false; + private readonly CancellationTokenSource _cancellationTokenSource; public enum TestStage { @@ -26,10 +29,22 @@ public enum TestStage Error = 5 } - public LoadingWindow() + public LoadingWindow(CancellationTokenSource cancellationTokenSource = null) { InitializeComponent(); + _cancellationTokenSource = cancellationTokenSource; Loaded += LoadingWindow_Loaded; + PreviewKeyDown += LoadingWindow_PreviewKeyDown; + } + + private void LoadingWindow_PreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.Escape) + { + _cancellationTokenSource?.Cancel(); + CloseWithAnimation(); + e.Handled = true; + } } private void LoadingWindow_Loaded(object sender, RoutedEventArgs e) diff --git a/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/Main.cs b/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/Main.cs index 793bf1c..2c2d52d 100644 --- a/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/Main.cs +++ b/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/Main.cs @@ -335,7 +335,7 @@ private async Task RunSpeedTestAsync() LoadingWindow loadingWindow = null; Application.Current.Dispatcher.Invoke(() => { - loadingWindow = new LoadingWindow(); + loadingWindow = new LoadingWindow(_cancellationTokenSource); _currentLoadingWindow = loadingWindow; loadingWindow.Show(); loadingWindow.UpdateStage(LoadingWindow.TestStage.Connecting); @@ -349,7 +349,13 @@ private async Task RunSpeedTestAsync() if (token.IsCancellationRequested) { - Application.Current.Dispatcher.Invoke(() => loadingWindow?.CloseWithAnimation()); + Application.Current.Dispatcher.Invoke(() => + { + if (loadingWindow?.IsVisible == true) + { + loadingWindow.CloseWithAnimation(); + } + }); if (_showNotifications) { _context.API.ShowMsg("Speed Test", "🛑 Test was canceled", _iconPath); @@ -361,7 +367,10 @@ private async Task RunSpeedTestAsync() { Application.Current.Dispatcher.Invoke(() => { - loadingWindow?.CloseWithAnimation(); + if (loadingWindow?.IsVisible == true) + { + loadingWindow.CloseWithAnimation(); + } try { @@ -388,7 +397,13 @@ private async Task RunSpeedTestAsync() } catch (OperationCanceledException) { - Application.Current.Dispatcher.Invoke(() => loadingWindow?.CloseWithAnimation()); + Application.Current.Dispatcher.Invoke(() => + { + if (loadingWindow?.IsVisible == true) + { + loadingWindow.CloseWithAnimation(); + } + }); if (_showNotifications) { _context.API.ShowMsg("Speed Test", "🛑 Test was canceled", _iconPath); @@ -404,11 +419,14 @@ private async Task RunSpeedTestAsync() { Interval = TimeSpan.FromSeconds(3) }; - timer.Tick += (s, e) => - { - timer.Stop(); - loadingWindow?.CloseWithAnimation(); - }; + timer.Tick += (s, e) => + { + timer.Stop(); + if (loadingWindow?.IsVisible == true) + { + loadingWindow.CloseWithAnimation(); + } + }; timer.Start(); }); @@ -458,6 +476,19 @@ private async Task ExecuteSpeedTestCLI(bool showUI = true, Load }; using var process = new Process { StartInfo = psi }; + using var _ = token.Register(() => + { + try + { + if (!process.HasExited) + { + process.Kill(true); + } + } + catch + { + } + }); process.OutputDataReceived += (sender, e) => { diff --git a/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/ResultsWindow.xaml.cs b/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/ResultsWindow.xaml.cs index 2c38b61..a108520 100644 --- a/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/ResultsWindow.xaml.cs +++ b/SpeedTest/Community.PowerToys.Run.Plugin.SpeedTest/ResultsWindow.xaml.cs @@ -7,6 +7,7 @@ using System; using System.Windows.Interop; using System.Runtime.InteropServices; +using System.Windows.Input; namespace Community.PowerToys.Run.Plugin.SpeedTest { @@ -30,6 +31,7 @@ public ResultsWindow(SpeedTestResult result) // Flash the window when it's loaded this.Loaded += (s, e) => FlashWindow(new WindowInteropHelper(this).Handle, true); + PreviewKeyDown += ResultsWindow_PreviewKeyDown; #if DEBUG // Log the result data for debugging purposes. @@ -38,6 +40,15 @@ public ResultsWindow(SpeedTestResult result) #endif } + private void ResultsWindow_PreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.Escape) + { + Close(); + e.Handled = true; + } + } + private void ApplyTheme() { bool isDarkTheme = false; diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 3005ebc..a917e15 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to the PowerToys Run SpeedTest Plugin will be documented in The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added +- Pressing `Esc` now cancels a running speed test or closes the results window + ## [1.0.5] - 2025-01-14 ### Added diff --git a/docs/README.md b/docs/README.md index d0c74e2..7100d77 100644 --- a/docs/README.md +++ b/docs/README.md @@ -109,10 +109,11 @@ - Configure clipboard settings in PowerToys settings if needed ## 🚀 Usage -- Open PowerToys Run (`Alt+Space`) +- Open PowerToys Run (`Alt+Space`) - Type `spt` and select `Run Speed Test` - Enjoy the beautiful loading animation and view real-time progress - Results window will flash when complete to get your attention +- Press `Esc` at any time to cancel the test or close the results window - Configure clipboard settings in PowerToys settings - Click the result URL to view/share your result online