From 347f4387f4babda5349a994566652f583f35e63d Mon Sep 17 00:00:00 2001 From: Bagus Nur Listiyono Date: Sun, 21 Dec 2025 02:52:55 +0700 Subject: [PATCH] [INTERIM] fix(ui): Fix carousel still running after using StartOnTray This is interim commit before @neon-nyan take precedence over at fecc199d91dbac8a1340399ec3683ec92895ad0a 1. Move CTSW creator outside while loop to prevent self recreation 2. Always pause carousel when window is not in foreground 3. Properly break the for loop when CTS is called 4. Delay stop scroller to wait for scroller to initialize 5. Pause/resume carousel on tray activity --- .../XAMLs/MainApp/Pages/HomePage.xaml.cs | 17 +++++++++++++++-- CollapseLauncher/XAMLs/MainApp/TrayIcon.xaml.cs | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml.cs b/CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml.cs index 8fbba9fdb..a15f4fd13 100644 --- a/CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml.cs +++ b/CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml.cs @@ -436,6 +436,7 @@ await ImageLoaderHelper.GetConvertedImageAsPng(outStream, #endregion #region Carousel + private bool _isCarouselInitialized = false; private async Task StartCarouselAutoScroll(int delaySeconds = 5) { @@ -444,11 +445,11 @@ private async Task StartCarouselAutoScroll(int delaySeconds = 5) try { + CarouselToken ??= new CancellationTokenSourceWrapper(); while (true) { - CarouselToken ??= new CancellationTokenSourceWrapper(); - await Task.Delay(TimeSpan.FromSeconds(delaySeconds), CarouselToken.Token); + _isCarouselInitialized = true; if (!IsCarouselPanelAvailable) return; if (ImageCarousel.SelectedIndex != GameCarouselData?.Count - 1 && ImageCarousel.SelectedIndex < ImageCarousel.Items.Count - 1) @@ -456,6 +457,10 @@ private async Task StartCarouselAutoScroll(int delaySeconds = 5) else for (int i = GameCarouselData?.Count ?? 0; i > 0; i--) { + while (!WindowUtility.IsCurrentWindowInFocus()) + { + await Task.Delay(RefreshRate, CarouselToken.Token); + } if (i - 1 >= 0 && i - 1 < ImageCarousel.Items.Count) { ImageCarousel.SelectedIndex = i - 1; @@ -464,7 +469,9 @@ private async Task StartCarouselAutoScroll(int delaySeconds = 5) { await Task.Delay(100, CarouselToken.Token); } + else break; } + break; } } catch (TaskCanceledException) @@ -496,6 +503,12 @@ public async Task CarouselRestartScroll(int delaySeconds = 5) public async ValueTask CarouselStopScroll() { + // Wait until Carousel is fully initialized to invoke the cts cancellation + while (!_isCarouselInitialized) + { + await Task.Delay(500); + } + if (CarouselToken is { IsCancellationRequested: false, IsDisposed: false, IsCancelled: false }) { await CarouselToken.CancelAsync(); diff --git a/CollapseLauncher/XAMLs/MainApp/TrayIcon.xaml.cs b/CollapseLauncher/XAMLs/MainApp/TrayIcon.xaml.cs index cb3cf13a1..1dce200a8 100644 --- a/CollapseLauncher/XAMLs/MainApp/TrayIcon.xaml.cs +++ b/CollapseLauncher/XAMLs/MainApp/TrayIcon.xaml.cs @@ -292,6 +292,7 @@ public void ToggleMainVisibility(bool forceShow = false) MainTaskbarToggle.Text = _showApp; // Increase refresh rate to 1000ms when main window is hidden RefreshRate = RefreshRateSlow; + m_homePage?.CarouselStopScroll(); LogWriteLine("Main window is hidden!"); // Spawn the hidden to tray toast notification @@ -307,6 +308,7 @@ public void ToggleMainVisibility(bool forceShow = false) EfficiencyModeWrapper(false); PInvoke.SetForegroundWindow(mainWindowHandle); MainTaskbarToggle.Text = _hideApp; + m_homePage?.CarouselRestartScroll(); // Revert refresh rate to its default RefreshRate = RefreshRateDefault; LogWriteLine("Main window is shown!");