make windows transient

This commit is contained in:
qhy040404
2024-06-13 19:48:06 +08:00
committed by DismissedLight
parent 99f35ca6db
commit 3a57d55c62
8 changed files with 68 additions and 19 deletions

View File

@@ -31,6 +31,12 @@ internal static class WindowExtension
return WindowControllers.TryGetValue(window, out _);
}
public static void UninitializeController<TWindow>(this TWindow window)
where TWindow : Window
{
WindowControllers.Remove(window);
}
public static DesktopWindowXamlSource? GetDesktopWindowXamlSource(this Window window)
{
if (window.SystemBackdrop is SystemBackdropDesktopWindowXamlSourceAccess access)

View File

@@ -13,6 +13,7 @@ using Snap.Hutao.Core.LifeCycle;
using Snap.Hutao.Core.Setting;
using Snap.Hutao.Core.Windowing.Abstraction;
using Snap.Hutao.Core.Windowing.NotifyIcon;
using Snap.Hutao.Factory.ContentDialog;
using Snap.Hutao.Service;
using Snap.Hutao.Win32;
using Snap.Hutao.Win32.Foundation;
@@ -99,11 +100,11 @@ internal sealed class XamlWindowController
private void OnWindowClosed(object sender, WindowEventArgs args)
{
IContentDialogFactory contentDialogFactory = serviceProvider.GetRequiredService<IContentDialogFactory>();
contentDialogFactory.HideAllDialogs();
if (XamlLifetime.ApplicationLaunchedWithNotifyIcon && !XamlLifetime.ApplicationExiting)
{
args.Handled = true;
window.Hide();
if (!IsNotifyIconVisible())
{
new ToastContentBuilder()
@@ -119,16 +120,15 @@ internal sealed class XamlWindowController
GC.Collect(GC.MaxGeneration);
}
else
{
if (window is IXamlWindowRectPersisted rectPersisted)
{
SaveOrSkipWindowSize(rectPersisted);
}
subclass?.Dispose();
windowNonRudeHWND?.Dispose();
if (window is IXamlWindowRectPersisted rectPersisted)
{
SaveOrSkipWindowSize(rectPersisted);
}
subclass?.Dispose();
windowNonRudeHWND?.Dispose();
window.UninitializeController();
}
private bool IsNotifyIconVisible()

View File

@@ -18,10 +18,14 @@ internal sealed partial class ContentDialogFactory : IContentDialogFactory
private readonly ITaskContext taskContext;
private readonly AppOptions appOptions;
private Microsoft.UI.Xaml.Controls.ContentDialog? currentContentDialog;
/// <inheritdoc/>
public async ValueTask<ContentDialogResult> CreateForConfirmAsync(string title, string content)
{
await HideAllDialogsAsync().ConfigureAwait(false);
await taskContext.SwitchToMainThreadAsync();
Microsoft.UI.Xaml.Controls.ContentDialog dialog = new()
{
XamlRoot = currentWindowReference.GetXamlRoot(),
@@ -32,13 +36,17 @@ internal sealed partial class ContentDialogFactory : IContentDialogFactory
RequestedTheme = appOptions.ElementTheme,
};
dialog.Closed += OnContentDialogClosed;
currentContentDialog = dialog;
return await dialog.ShowAsync();
}
/// <inheritdoc/>
public async ValueTask<ContentDialogResult> CreateForConfirmCancelAsync(string title, string content, ContentDialogButton defaultButton = ContentDialogButton.Close)
{
await HideAllDialogsAsync().ConfigureAwait(false);
await taskContext.SwitchToMainThreadAsync();
Microsoft.UI.Xaml.Controls.ContentDialog dialog = new()
{
XamlRoot = currentWindowReference.GetXamlRoot(),
@@ -50,13 +58,17 @@ internal sealed partial class ContentDialogFactory : IContentDialogFactory
RequestedTheme = appOptions.ElementTheme,
};
dialog.Closed += OnContentDialogClosed;
currentContentDialog = dialog;
return await dialog.ShowAsync();
}
/// <inheritdoc/>
public async ValueTask<Microsoft.UI.Xaml.Controls.ContentDialog> CreateForIndeterminateProgressAsync(string title)
{
await HideAllDialogsAsync().ConfigureAwait(false);
await taskContext.SwitchToMainThreadAsync();
Microsoft.UI.Xaml.Controls.ContentDialog dialog = new()
{
XamlRoot = currentWindowReference.GetXamlRoot(),
@@ -65,25 +77,54 @@ internal sealed partial class ContentDialogFactory : IContentDialogFactory
RequestedTheme = appOptions.ElementTheme,
};
dialog.Closed += OnContentDialogClosed;
currentContentDialog = dialog;
return dialog;
}
public async ValueTask<TContentDialog> CreateInstanceAsync<TContentDialog>(params object[] parameters)
where TContentDialog : Microsoft.UI.Xaml.Controls.ContentDialog
{
await HideAllDialogsAsync().ConfigureAwait(false);
await taskContext.SwitchToMainThreadAsync();
TContentDialog contentDialog = serviceProvider.CreateInstance<TContentDialog>(parameters);
contentDialog.XamlRoot = currentWindowReference.GetXamlRoot();
contentDialog.RequestedTheme = appOptions.ElementTheme;
contentDialog.Closed += OnContentDialogClosed;
currentContentDialog = contentDialog;
return contentDialog;
}
public TContentDialog CreateInstance<TContentDialog>(params object[] parameters)
where TContentDialog : Microsoft.UI.Xaml.Controls.ContentDialog
{
HideAllDialogs();
TContentDialog contentDialog = serviceProvider.CreateInstance<TContentDialog>(parameters);
contentDialog.XamlRoot = currentWindowReference.GetXamlRoot();
contentDialog.RequestedTheme = appOptions.ElementTheme;
contentDialog.Closed += OnContentDialogClosed;
currentContentDialog = contentDialog;
return contentDialog;
}
public void HideAllDialogs()
{
currentContentDialog?.Hide();
}
public async ValueTask HideAllDialogsAsync()
{
await taskContext.SwitchToMainThreadAsync();
currentContentDialog?.Hide();
}
private void OnContentDialogClosed(Microsoft.UI.Xaml.Controls.ContentDialog sender, ContentDialogClosedEventArgs args)
{
currentContentDialog = null;
sender.Closed -= OnContentDialogClosed;
}
}

View File

@@ -40,4 +40,8 @@ internal interface IContentDialogFactory
ValueTask<TContentDialog> CreateInstanceAsync<TContentDialog>(params object[] parameters)
where TContentDialog : Microsoft.UI.Xaml.Controls.ContentDialog;
void HideAllDialogs();
ValueTask HideAllDialogsAsync();
}

View File

@@ -13,7 +13,7 @@ using Windows.Graphics;
namespace Snap.Hutao;
[HighQuality]
[Injection(InjectAs.Singleton)]
[Injection(InjectAs.Transient)]
internal sealed partial class LaunchGameWindow : Window,
IDisposable,
IXamlWindowExtendContentIntoTitleBar,

View File

@@ -14,7 +14,7 @@ namespace Snap.Hutao;
/// 主窗体
/// </summary>
[HighQuality]
[Injection(InjectAs.Singleton)]
[Injection(InjectAs.Transient)]
internal sealed partial class MainWindow : Window,
IXamlWindowExtendContentIntoTitleBar,
IXamlWindowRectPersisted,

View File

@@ -17,10 +17,7 @@
mc:Ignorable="d">
<mxi:Interaction.Behaviors>
<shcb:PeriodicInvokeCommandOrOnActualThemeChangedBehavior
Command="{Binding UpdateBackgroundCommand}"
CommandParameter="{x:Bind BackgroundImagePresenter}"
Period="0:5:0"/>
<shcb:PeriodicInvokeCommandOrOnActualThemeChangedBehavior Command="{Binding UpdateBackgroundCommand}" Period="0:5:0"/>
</mxi:Interaction.Behaviors>
<UserControl.Resources>

View File

@@ -31,6 +31,7 @@ internal sealed partial class MainViewModel : Abstraction.ViewModel, IMainViewMo
public void Initialize(IBackgroundImagePresenterAccessor accessor)
{
backgroundImagePresenter = accessor.BackgroundImagePresenter;
UpdateBackgroundAsync(true).SafeForget();
}
public void Receive(BackgroundImageTypeChangedMessage message)
@@ -39,14 +40,14 @@ internal sealed partial class MainViewModel : Abstraction.ViewModel, IMainViewMo
}
[Command("UpdateBackgroundCommand")]
private async Task UpdateBackgroundAsync()
private async Task UpdateBackgroundAsync(bool forceRefresh = false)
{
if (backgroundImagePresenter is null)
{
return;
}
(bool shouldRefresh, BackgroundImage? backgroundImage) = await backgroundImageService.GetNextBackgroundImageAsync(previousBackgroundImage).ConfigureAwait(false);
(bool shouldRefresh, BackgroundImage? backgroundImage) = await backgroundImageService.GetNextBackgroundImageAsync(forceRefresh ? default : previousBackgroundImage).ConfigureAwait(false);
if (shouldRefresh)
{