diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/XamlWindowController.cs b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/XamlWindowController.cs index 2ebd955f..816af2c2 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/XamlWindowController.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/XamlWindowController.cs @@ -104,9 +104,7 @@ internal sealed class XamlWindowController args.Handled = true; window.Hide(); - RECT iconRect = serviceProvider.GetRequiredService().GetRect(); - RECT primaryRect = StructMarshal.RECT(DisplayArea.Primary.OuterBounds); - if (!IntersectRect(out _, in primaryRect, in iconRect)) + if (!IsNotifyIconVisible()) { new ToastContentBuilder() .AddText(SH.CoreWindowingNotifyIconPromotedHint) @@ -133,6 +131,28 @@ internal sealed class XamlWindowController } } + private unsafe bool IsNotifyIconVisible() + { + RECT iconRect = serviceProvider.GetRequiredService().GetRect(); + + if (UniversalApiContract.IsPresent(WindowsVersion.Windows11)) + { + RECT primaryRect = StructMarshal.RECT(DisplayArea.Primary.OuterBounds); + return IntersectRect(out _, in primaryRect, in iconRect); + } + + HWND shellTrayWnd = FindWindowExW(default, default, "Shell_TrayWnd", default); + HWND trayNotifyWnd = FindWindowExW(shellTrayWnd, default, "TrayNotifyWnd", default); + HWND button = FindWindowExW(trayNotifyWnd, default, "Button", default); + + if (GetWindowRect(button, out RECT buttonRect)) + { + return !EqualRect(in buttonRect, in iconRect); + } + + return false; + } + #region SystemBackdrop & ElementTheme private void OnOptionsPropertyChanged(object? sender, PropertyChangedEventArgs e) diff --git a/src/Snap.Hutao/Snap.Hutao/Win32/User32.cs b/src/Snap.Hutao/Snap.Hutao/Win32/User32.cs index 795ab2e1..e09b933a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Win32/User32.cs +++ b/src/Snap.Hutao/Snap.Hutao/Win32/User32.cs @@ -55,6 +55,22 @@ internal static class User32 [SupportedOSPlatform("windows5.0")] public static extern BOOL DestroyWindow(HWND hWnd); + [DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, ExactSpelling = true)] + [SupportedOSPlatform("windows5.0")] + public static unsafe extern BOOL EqualRect(RECT* lprc1, RECT* lprc2); + + [DebuggerStepThrough] + public static unsafe BOOL EqualRect(ref readonly RECT rc1, ref readonly RECT rc2) + { + fixed (RECT* lprc1 = &rc1) + { + fixed (RECT* lprc2 = &rc2) + { + return EqualRect(lprc1, lprc2); + } + } + } + [DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, ExactSpelling = true)] [SupportedOSPlatform("windows5.0")] public static extern HWND FindWindowExW([AllowNull] HWND hWndParent, [AllowNull] HWND hWndChildAfter, [AllowNull] PCWSTR lpszClass, [AllowNull] PCWSTR lpszWindow); @@ -112,6 +128,19 @@ internal static class User32 } } + [DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, ExactSpelling = true)] + [SupportedOSPlatform("windows5.0")] + public static unsafe extern BOOL GetWindowRect(HWND hWnd, RECT* lpRect); + + [DebuggerStepThrough] + public static unsafe BOOL GetWindowRect(HWND hWnd, out RECT rect) + { + fixed (RECT* lpRect = &rect) + { + return GetWindowRect(hWnd, lpRect); + } + } + [DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, ExactSpelling = true)] [SupportedOSPlatform("windows5.0")] public static unsafe extern uint GetWindowThreadProcessId(HWND hWnd, [MaybeNull] uint* lpdwProcessId);