diff --git a/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs b/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs
index e4ee99f5d..eeeb6fa6d 100644
--- a/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs
+++ b/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs
@@ -18,8 +18,10 @@ namespace CollapseLauncher.Helper.Background
[SuppressMessage("ReSharper", "IdentifierTypo")]
[SuppressMessage("ReSharper", "PossibleNullReferenceException")]
[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
- internal static class BackgroundMediaUtility
+ internal class BackgroundMediaUtility : IDisposable
{
+ internal static BackgroundMediaUtility Current { get; private set; }
+
internal enum MediaType
{
Media,
@@ -36,30 +38,27 @@ internal enum MediaType
internal static readonly string[] SupportedMediaPlayerExt =
[".mp4", ".mov", ".mkv", ".webm", ".avi", ".gif"];
- private static FrameworkElement? _parentUI;
- private static ImageUI? _bgImageBackground;
- private static ImageUI? _bgImageBackgroundLast;
- private static MediaPlayerElement? _bgMediaPlayerBackground;
+ private FrameworkElement? _parentUI;
+ private ImageUI? _bgImageBackground;
+ private ImageUI? _bgImageBackgroundLast;
+ private MediaPlayerElement? _bgMediaPlayerBackground;
- private static Grid? _bgAcrylicMask;
- private static Grid? _bgOverlayTitleBar;
+ private Grid? _bgAcrylicMask;
+ private Grid? _bgOverlayTitleBar;
- private static Grid? _parentBgImageBackgroundGrid;
- #pragma warning disable CS0169 // Field is never used
- private static Grid? _parentBgImageForegroundGrid;
- #pragma warning restore CS0169 // Field is never used
- private static Grid? _parentBgMediaPlayerBackgroundGrid;
+ private Grid? _parentBgImageBackgroundGrid;
+ private Grid? _parentBgMediaPlayerBackgroundGrid;
- internal static MediaType CurrentAppliedMediaType = MediaType.Unknown;
+ internal MediaType CurrentAppliedMediaType = MediaType.Unknown;
- private static CancellationTokenSourceWrapper? _cancellationToken;
- private static StillImageLoader? _loaderStillImage;
- private static MediaPlayerLoader? _loaderMediaPlayer;
- private static IBackgroundMediaLoader? _currentMediaLoader;
+ private CancellationTokenSourceWrapper? _cancellationToken;
+ private StillImageLoader? _loaderStillImage;
+ private MediaPlayerLoader? _loaderMediaPlayer;
+ private IBackgroundMediaLoader? _currentMediaLoader;
- private static bool _isCurrentDimmAnimRun;
- private static bool _isCurrentUndimmAnimRun;
- private static bool _isCurrentRegistered;
+ private bool _isCurrentDimmAnimRun;
+ private bool _isCurrentUndimmAnimRun;
+ private bool _isCurrentRegistered;
private static FileStream? _alternativeFileStream;
@@ -75,61 +74,76 @@ internal enum MediaType
/// The parent for Background Image.
/// The parent for Background Media Player
internal static async Task RegisterCurrent(FrameworkElement? parentUI, Grid bgAcrylicMask,
- Grid bgOverlayTitleBar, Grid bgImageGridBackground,
- Grid bgMediaPlayerGrid)
+ Grid bgOverlayTitleBar, Grid bgImageGridBackground,
+ Grid bgMediaPlayerGrid)
{
// Set the parent UI
- _parentUI = parentUI;
-
- // Mask stuff
- _bgAcrylicMask = bgAcrylicMask;
- _bgOverlayTitleBar = bgOverlayTitleBar;
+ FrameworkElement? ui = parentUI;
// Initialize the background instances
- (_bgImageBackground, _bgImageBackgroundLast) =
+ var (bgImageBackground, bgImageBackgroundLast) =
await InitializeElementGrid(bgImageGridBackground, "ImageBackground", AssignDefaultImage);
- _bgMediaPlayerBackground =
+ var bgMediaPlayerBackground =
(await TryGetFirstGridElement(bgMediaPlayerGrid.WithOpacity(0), "MediaPlayer"))
.WithHorizontalAlignment(HorizontalAlignment.Center)
.WithVerticalAlignment(VerticalAlignment.Center)
.WithStretch(Stretch.UniformToFill);
- // Store the parent grid reference into this static variables
+ Current = new BackgroundMediaUtility(ui, bgAcrylicMask, bgOverlayTitleBar,
+ bgImageGridBackground, bgMediaPlayerGrid, bgImageBackground,
+ bgImageBackgroundLast, bgMediaPlayerBackground);
+ }
+
+ private BackgroundMediaUtility(FrameworkElement? parentUI, Grid bgAcrylicMask,
+ Grid bgOverlayTitleBar, Grid bgImageGridBackground,
+ Grid bgMediaPlayerGrid, ImageUI? bgImageBackground,
+ ImageUI? bgImageBackgroundLast, MediaPlayerElement? mediaPlayerElement)
+ {
+ _parentUI = parentUI;
+ _bgAcrylicMask = bgAcrylicMask;
+ _bgOverlayTitleBar = bgOverlayTitleBar;
_parentBgImageBackgroundGrid = bgImageGridBackground;
_parentBgMediaPlayerBackgroundGrid = bgMediaPlayerGrid;
+ _bgImageBackground = bgImageBackground;
+ _bgImageBackgroundLast = bgImageBackgroundLast;
+ _bgMediaPlayerBackground = mediaPlayerElement;
+
// Set that the current page has been registered
_isCurrentRegistered = true;
}
+ ~BackgroundMediaUtility() => Dispose();
+
///
- /// Detach the current background utility from the previously attached .
+ /// Detach and dispose the current background utility from the previously attached .
///
- internal static void DetachCurrent()
+ public void Dispose()
{
if (_cancellationToken is { IsCancellationRequested: false })
{
_cancellationToken.Cancel();
}
+ _cancellationToken?.Dispose();
_bgImageBackground = null;
_bgImageBackgroundLast = null;
_bgMediaPlayerBackground = null;
- _parentBgImageBackgroundGrid?.ClearChildren();
- _parentBgMediaPlayerBackgroundGrid?.ClearChildren();
-
_parentBgImageBackgroundGrid = null;
_parentBgMediaPlayerBackgroundGrid = null;
_bgAcrylicMask = null;
_bgOverlayTitleBar = null;
+ _loaderMediaPlayer?.Dispose();
_loaderMediaPlayer = null;
+ _loaderStillImage?.Dispose();
_loaderStillImage = null;
CurrentAppliedMediaType = MediaType.Unknown;
_isCurrentRegistered = false;
+ GC.SuppressFinalize(this);
}
///
@@ -237,7 +251,7 @@ internal static async ValueTask AssignDefaultImage(TElement element)
/// Ensure that the instance is already initialized
///
/// Throw if instance is not registered
- private static void EnsureCurrentImageRegistered()
+ private void EnsureCurrentImageRegistered()
{
if (_bgImageBackground == null || _bgImageBackgroundLast == null)
{
@@ -249,7 +263,7 @@ private static void EnsureCurrentImageRegistered()
/// Ensure that the instance is already initialized
///
/// Throw if instance is not registered
- private static void EnsureCurrentMediaPlayerRegistered()
+ private void EnsureCurrentMediaPlayerRegistered()
{
if (_bgMediaPlayerBackground == null)
{
@@ -265,12 +279,12 @@ private static void EnsureCurrentMediaPlayerRegistered()
/// Request a cache recreation if the background file properties have been cached
/// Throws if the background file is not supported
/// Throws if some instances aren't yet initialized
- internal static async Task LoadBackground(string mediaPath, bool isRequestInit = false,
+ internal async Task LoadBackground(string mediaPath, bool isRequestInit = false,
bool isForceRecreateCache = false)
{
while (!_isCurrentRegistered)
{
- await Task.Delay(250, _cancellationToken?.Token ?? default);
+ await Task.Delay(250, _cancellationToken?.Token ?? default);
}
EnsureCurrentImageRegistered();
@@ -348,7 +362,7 @@ await _currentMediaLoader.LoadAsync(mediaPath, isForceRecreateCache, isRequestIn
///
/// Dimming the current loaded background
///
- internal static async void Dimm()
+ internal async void Dimm()
{
while (_isCurrentDimmAnimRun || _isCurrentUndimmAnimRun)
{
@@ -375,7 +389,7 @@ internal static async void Dimm()
///
/// Undimming the current loaded background
///
- internal static async void Undimm()
+ internal async void Undimm()
{
while (_isCurrentDimmAnimRun || _isCurrentUndimmAnimRun)
{
@@ -402,7 +416,7 @@ internal static async void Undimm()
///
/// Mute the audio of the currently loaded background
///
- internal static void Mute()
+ internal void Mute()
{
_currentMediaLoader?.Mute();
}
@@ -410,7 +424,7 @@ internal static void Mute()
///
/// Unmute the audio of the currently loaded background
///
- internal static void Unmute()
+ internal void Unmute()
{
_currentMediaLoader?.Unmute();
}
@@ -418,7 +432,7 @@ internal static void Unmute()
///
/// Set the volume of the audio from the currently loaded background
///
- internal static void SetVolume(double value)
+ internal void SetVolume(double value)
{
_currentMediaLoader?.SetVolume(value);
}
@@ -426,7 +440,7 @@ internal static void SetVolume(double value)
///
/// Trigger the unfocused window event to the currently loaded background
///
- internal static void WindowUnfocused()
+ internal void WindowUnfocused()
{
_currentMediaLoader?.WindowUnfocused();
}
@@ -434,7 +448,7 @@ internal static void WindowUnfocused()
///
/// Trigger the focused window event to the currently loaded background
///
- internal static void WindowFocused()
+ internal void WindowFocused()
{
_currentMediaLoader?.WindowFocused();
}
@@ -442,7 +456,7 @@ internal static void WindowFocused()
///
/// Play/Resume the currently loaded background
///
- internal static void Play()
+ internal void Play()
{
_currentMediaLoader?.Play();
}
@@ -450,7 +464,7 @@ internal static void Play()
///
/// Pause the currently loaded background
///
- internal static void Pause()
+ internal void Pause()
{
_currentMediaLoader?.Pause();
}
@@ -467,7 +481,7 @@ public static void SetAlternativeFileStream(FileStream stream)
_alternativeFileStream = stream;
}
- private static IBackgroundMediaLoader? GetImageLoader(MediaType mediaType)
+ private IBackgroundMediaLoader? GetImageLoader(MediaType mediaType)
{
return mediaType switch
{
diff --git a/CollapseLauncher/Classes/Helper/Background/Loaders/MediaPlayerLoader.cs b/CollapseLauncher/Classes/Helper/Background/Loaders/MediaPlayerLoader.cs
index 398edf907..d1277790f 100644
--- a/CollapseLauncher/Classes/Helper/Background/Loaders/MediaPlayerLoader.cs
+++ b/CollapseLauncher/Classes/Helper/Background/Loaders/MediaPlayerLoader.cs
@@ -9,11 +9,8 @@
using Windows.Media.Playback;
using Windows.Storage;
using Windows.Storage.FileProperties;
-using Windows.UI;
using CollapseLauncher.Extension;
using CollapseLauncher.Helper.Animation;
-using ColorThiefDotNet;
-using CommunityToolkit.WinUI;
using CommunityToolkit.WinUI.Animations;
using Hi3Helper;
using Hi3Helper.Shared.Region;
@@ -24,8 +21,6 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using ImageUI = Microsoft.UI.Xaml.Controls.Image;
-using Microsoft.UI;
-using CollapseLauncher.Helper.Image;
#nullable enable
namespace CollapseLauncher.Helper.Background.Loaders
@@ -33,7 +28,7 @@ namespace CollapseLauncher.Helper.Background.Loaders
[SuppressMessage("ReSharper", "IdentifierTypo")]
[SuppressMessage("ReSharper", "PossibleNullReferenceException")]
[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
- internal class MediaPlayerLoader : IBackgroundMediaLoader
+ internal class MediaPlayerLoader : IBackgroundMediaLoader, IDisposable
{
private FrameworkElement ParentUI { get; }
private Compositor CurrentCompositor { get; }
@@ -56,8 +51,12 @@ internal class MediaPlayerLoader : IBackgroundMediaLoader
private SoftwareBitmap? CurrentFrameBitmap { get; set; }
private CanvasImageSource? CurrentCanvasImageSource { get; set; }
private CanvasDevice? CanvasDevice { get; set; }
+
+#if USEDYNAMICVIDEOPALETTE
private CanvasBitmap? CanvasBitmap { get; set; }
+#endif
+
internal MediaPlayerLoader(
FrameworkElement parentUI,
Grid acrylicMask, Grid overlayTitleBar,
@@ -82,6 +81,20 @@ internal MediaPlayerLoader(
IsMediaPlayerLoading = false;
}
+ ~MediaPlayerLoader() => Dispose();
+
+ public void Dispose()
+ {
+ CurrentMediaPlayer?.Dispose();
+ CurrentStopwatch?.Stop();
+ InnerCancellationToken?.Dispose();
+ CurrentFrameBitmap?.Dispose();
+ CanvasDevice?.Dispose();
+ CurrentMediaStream?.Dispose();
+
+ GC.SuppressFinalize(this);
+ }
+
public async ValueTask LoadAsync(string filePath, bool isImageLoadForFirstTime, bool isRequestInit,
CancellationToken token)
{
diff --git a/CollapseLauncher/Classes/Helper/Background/Loaders/StillImageLoader.cs b/CollapseLauncher/Classes/Helper/Background/Loaders/StillImageLoader.cs
index 620db2480..ea9260c02 100644
--- a/CollapseLauncher/Classes/Helper/Background/Loaders/StillImageLoader.cs
+++ b/CollapseLauncher/Classes/Helper/Background/Loaders/StillImageLoader.cs
@@ -20,7 +20,7 @@ namespace CollapseLauncher.Helper.Background.Loaders
[SuppressMessage("ReSharper", "IdentifierTypo")]
[SuppressMessage("ReSharper", "PossibleNullReferenceException")]
[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
- internal class StillImageLoader : IBackgroundMediaLoader
+ internal class StillImageLoader : IBackgroundMediaLoader, IDisposable
{
private FrameworkElement ParentUI { get; }
private Compositor CurrentCompositor { get; }
@@ -56,6 +56,13 @@ internal StillImageLoader(
IsImageLoading = false;
}
+ ~StillImageLoader() => Dispose();
+
+ public void Dispose()
+ {
+ GC.SuppressFinalize(this);
+ }
+
public async ValueTask LoadAsync(string filePath, bool isImageLoadForFirstTime, bool isRequestInit,
CancellationToken token)
{
diff --git a/CollapseLauncher/Classes/Helper/WindowUtility.cs b/CollapseLauncher/Classes/Helper/WindowUtility.cs
index 3eca361a7..25fe03deb 100644
--- a/CollapseLauncher/Classes/Helper/WindowUtility.cs
+++ b/CollapseLauncher/Classes/Helper/WindowUtility.cs
@@ -304,11 +304,11 @@ private static IntPtr WndProc(IntPtr hwnd, uint msg, UIntPtr wParam, IntPtr lPar
{
if (wParam == 1)
{
- BackgroundMediaUtility.WindowFocused();
+ BackgroundMediaUtility.Current.WindowFocused();
}
else
{
- BackgroundMediaUtility.WindowUnfocused();
+ BackgroundMediaUtility.Current.WindowUnfocused();
}
}
break;
@@ -335,7 +335,7 @@ private static IntPtr WndProc(IntPtr hwnd, uint msg, UIntPtr wParam, IntPtr lPar
}
case SC_MINIMIZE:
{
- BackgroundMediaUtility.WindowUnfocused();
+ BackgroundMediaUtility.Current.WindowUnfocused();
if (LauncherConfig.GetAppConfigValue("MinimizeToTray").ToBool())
{
// Carousel is handled inside WM_SHOWWINDOW message for minimize to tray
@@ -352,7 +352,7 @@ private static IntPtr WndProc(IntPtr hwnd, uint msg, UIntPtr wParam, IntPtr lPar
}
case SC_RESTORE:
{
- BackgroundMediaUtility.WindowFocused();
+ BackgroundMediaUtility.Current.WindowFocused();
InnerLauncherConfig.m_homePage?.CarouselRestartScroll();
break;
}
@@ -368,7 +368,7 @@ private static IntPtr WndProc(IntPtr hwnd, uint msg, UIntPtr wParam, IntPtr lPar
}
else
{
- BackgroundMediaUtility.WindowFocused();
+ BackgroundMediaUtility.Current.WindowFocused();
InnerLauncherConfig.m_homePage?.CarouselRestartScroll();
}
diff --git a/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs b/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs
index e111fc29f..e0403d977 100644
--- a/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs
+++ b/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs
@@ -98,7 +98,6 @@ private void Page_Unloaded(object sender, RoutedEventArgs e)
AppDiscordPresence.Dispose();
#endif
ImageLoaderHelper.DestroyWaifu2X();
- BackgroundMediaUtility.DetachCurrent();
}
private async void StartRoutine(object sender, RoutedEventArgs e)
@@ -427,8 +426,8 @@ private void BackgroundImg_IsImageHideEvent(object sender, bool e)
{
if (IsFirstStartup) return;
- if (e) BackgroundMediaUtility.Dimm();
- else BackgroundMediaUtility.Undimm();
+ if (e) BackgroundMediaUtility.Current.Dimm();
+ else BackgroundMediaUtility.Current.Undimm();
}
private async void CustomBackgroundChanger_Event(object sender, BackgroundImgProperty e)
@@ -448,7 +447,7 @@ private async void CustomBackgroundChanger_Event(object sender, BackgroundImgPro
try
{
- await BackgroundMediaUtility.LoadBackground(regionBackgroundProp.imgLocalPath, e.IsRequestInit, e.IsForceRecreateCache);
+ await BackgroundMediaUtility.Current.LoadBackground(regionBackgroundProp.imgLocalPath, e.IsRequestInit, e.IsForceRecreateCache);
}
catch (Exception ex)
{
diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml.cs b/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml.cs
index 6650a9abf..c296eecfe 100644
--- a/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml.cs
+++ b/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml.cs
@@ -606,9 +606,9 @@ private bool IsVideoBackgroundAudioMute
set
{
if (!value)
- BackgroundMediaUtility.Mute();
+ BackgroundMediaUtility.Current.Mute();
else
- BackgroundMediaUtility.Unmute();
+ BackgroundMediaUtility.Current.Unmute();
}
}
@@ -618,9 +618,9 @@ private double VideoBackgroundAudioVolume
{
double value = GetAppConfigValue("BackgroundAudioVolume").ToDouble();
if (value < 0)
- BackgroundMediaUtility.SetVolume(0d);
+ BackgroundMediaUtility.Current.SetVolume(0d);
if (value > 1)
- BackgroundMediaUtility.SetVolume(1d);
+ BackgroundMediaUtility.Current.SetVolume(1d);
return value * 100d;
}
@@ -628,7 +628,7 @@ private double VideoBackgroundAudioVolume
{
if (value < 0) return;
double downValue = value / 100d;
- BackgroundMediaUtility.SetVolume(downValue);
+ BackgroundMediaUtility.Current.SetVolume(downValue);
}
}
@@ -672,7 +672,7 @@ private bool IsAcrylicEffectEnabled
set
{
SetAndSaveConfigValue("EnableAcrylicEffect", value);
- if (BackgroundMediaUtility.CurrentAppliedMediaType == MediaType.StillImage)
+ if (BackgroundMediaUtility.Current.CurrentAppliedMediaType == MediaType.StillImage)
App.ToggleBlurBackdrop(value);
}
}