From f15a692f03dbef063880edecaf4386b264923784 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Thu, 16 May 2024 11:11:49 +0800 Subject: [PATCH] fix window state --- .../Core/Windowing/WindowExtension.cs | 20 +++++++++++++++++++ .../Core/Windowing/XamlWindowController.cs | 9 +++------ .../Snap.Hutao/Properties/launchSettings.json | 2 +- .../ViewModel/NotifyIconViewModel.cs | 6 +++--- .../Win32/Registry/RegistryWatcher.cs | 7 +++++-- src/Snap.Hutao/Snap.Hutao/Win32/User32.cs | 8 ++++++++ 6 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowExtension.cs b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowExtension.cs index 7fb76a91..8b754758 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowExtension.cs @@ -56,6 +56,21 @@ internal static class WindowExtension ShowWindow(GetWindowHandle(window), SHOW_WINDOW_CMD.SW_NORMAL); } + public static void SwitchTo(this Window window) + { + HWND hwnd = GetWindowHandle(window); + if (!IsWindowVisible(hwnd)) + { + ShowWindow(hwnd, SHOW_WINDOW_CMD.SW_SHOW); + } + else if (IsIconic(hwnd)) + { + ShowWindow(hwnd, SHOW_WINDOW_CMD.SW_RESTORE); + } + + SetForegroundWindow(hwnd); + } + public static void Hide(this Window window) { ShowWindow(GetWindowHandle(window), SHOW_WINDOW_CMD.SW_HIDE); @@ -92,6 +107,11 @@ internal static class WindowExtension public static double GetRasterizationScale(this Window window) { + if (window is { Content.XamlRoot: { } xamlRoot }) + { + return xamlRoot.RasterizationScale; + } + uint dpi = GetDpiForWindow(window.GetWindowHandle()); return Math.Round(dpi / 96D, 2, MidpointRounding.AwayFromZero); } diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/XamlWindowController.cs b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/XamlWindowController.cs index 1c41628d..6ce3ac93 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/XamlWindowController.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/XamlWindowController.cs @@ -4,6 +4,7 @@ using Microsoft.UI; using Microsoft.UI.Composition.SystemBackdrops; using Microsoft.UI.Content; +using Microsoft.UI.Input; using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Media; @@ -281,13 +282,9 @@ internal sealed class XamlWindowController return; } - AppWindowTitleBar appTitleBar = window.AppWindow.TitleBar; - - double scale = window.GetRasterizationScale(); - // 48 is the navigation button leftInset - RectInt32 dragRect = StructMarshal.RectInt32(48, 0, xamlWindow.TitleBarAccess.ActualSize).Scale(scale); - appTitleBar.SetDragRectangles([dragRect]); + RectInt32 dragRect = StructMarshal.RectInt32(48, 0, xamlWindow.TitleBarAccess.ActualSize).Scale(window.GetRasterizationScale()); + window.GetInputNonClientPointerSource().SetRegionRects(NonClientRegionKind.Caption, [dragRect]); } #endregion } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Properties/launchSettings.json b/src/Snap.Hutao/Snap.Hutao/Properties/launchSettings.json index 36a6b395..a5fb2a14 100644 --- a/src/Snap.Hutao/Snap.Hutao/Properties/launchSettings.json +++ b/src/Snap.Hutao/Snap.Hutao/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Snap.Hutao": { "commandName": "MsixPackage", - "nativeDebugging": true, + "nativeDebugging": false, "doNotLaunchApp": false, "allowLocalNetworkLoopbackProperty": true }, diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/NotifyIconViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/NotifyIconViewModel.cs index 49003411..e413b5db 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/NotifyIconViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/NotifyIconViewModel.cs @@ -48,7 +48,7 @@ internal sealed partial class NotifyIconViewModel : ObservableObject case MainWindow mainWindow: { // MainWindow is activated, bring to foreground - mainWindow.Show(); + mainWindow.SwitchTo(); mainWindow.BringToForeground(); return; } @@ -60,14 +60,14 @@ internal sealed partial class NotifyIconViewModel : ObservableObject currentXamlWindowReference.Window = mainWindow; // TODO: Can actually be no any window is initialized - mainWindow.Show(); + mainWindow.SwitchTo(); mainWindow.BringToForeground(); break; } case Window otherWindow: { - otherWindow.Show(); + otherWindow.SwitchTo(); otherWindow.BringToForeground(); return; } diff --git a/src/Snap.Hutao/Snap.Hutao/Win32/Registry/RegistryWatcher.cs b/src/Snap.Hutao/Snap.Hutao/Win32/Registry/RegistryWatcher.cs index 5454eb49..9f04ccac 100644 --- a/src/Snap.Hutao/Snap.Hutao/Win32/Registry/RegistryWatcher.cs +++ b/src/Snap.Hutao/Snap.Hutao/Win32/Registry/RegistryWatcher.cs @@ -29,6 +29,7 @@ internal sealed partial class RegistryWatcher : IDisposable private readonly Action valueChangedCallback; private readonly object syncRoot = new(); private bool disposed; + private bool disposing; public RegistryWatcher(string keyName, Action valueChangedCallback) { @@ -69,6 +70,8 @@ internal sealed partial class RegistryWatcher : IDisposable return; } + disposing = true; + // First cancel the outer while loop cancellationTokenSource.Cancel(); @@ -104,11 +107,11 @@ internal sealed partial class RegistryWatcher : IDisposable try { - // If terminateEvent is signaled, the Dispose method + // If disposeEvent is signaled, the Dispose method // has been called and the object is shutting down. // The outer token has already canceled, so we can // skip both loops and exit the method. - while (!disposeEvent.WaitOne(0, true)) + while (!disposing && !disposeEvent.WaitOne(0, true)) { HRESULT hRESULT = HRESULT_FROM_WIN32(RegNotifyChangeKeyValue(registryKey, true, RegNotifyFilters, hEvent, true)); Marshal.ThrowExceptionForHR(hRESULT); diff --git a/src/Snap.Hutao/Snap.Hutao/Win32/User32.cs b/src/Snap.Hutao/Snap.Hutao/Win32/User32.cs index 87962e2a..b33df772 100644 --- a/src/Snap.Hutao/Snap.Hutao/Win32/User32.cs +++ b/src/Snap.Hutao/Snap.Hutao/Win32/User32.cs @@ -101,6 +101,14 @@ internal static class User32 } } + [DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, ExactSpelling = true)] + [SupportedOSPlatform("windows5.0")] + public static extern BOOL IsIconic(HWND hWnd); + + [DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, ExactSpelling = true)] + [SupportedOSPlatform("windows5.0")] + public static extern BOOL IsWindowVisible(HWND hWnd); + [DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, ExactSpelling = true, SetLastError = true)] [SupportedOSPlatform("windows5.0")] public static unsafe extern ushort RegisterClassW(WNDCLASSW* lpWndClass);