diff --git a/src/Ryujinx/UI/Helpers/Win32NativeInterop.cs b/src/Ryujinx/UI/Helpers/Win32NativeInterop.cs index adfa899ed..65fa74297 100644 --- a/src/Ryujinx/UI/Helpers/Win32NativeInterop.cs +++ b/src/Ryujinx/UI/Helpers/Win32NativeInterop.cs @@ -63,6 +63,18 @@ namespace Ryujinx.Ava.UI.Helpers } } + [StructLayout(LayoutKind.Sequential)] + public struct NativeRect + { + public int Left; + public int Top; + public int Right; + public int Bottom; + + public int Width => Right - Left; + public int Height => Bottom - Top; + } + public static nint CreateEmptyCursor() { return CreateCursor(nint.Zero, 0, 0, 1, 1, [0xFF], [0x00]); @@ -119,6 +131,10 @@ namespace Ryujinx.Ava.UI.Helpers [LibraryImport("user32.dll", SetLastError = true)] public static partial nint SetWindowLongPtrW(nint hWnd, int nIndex, nint value); + [LibraryImport("user32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static partial bool GetWindowRect(nint hWnd, out NativeRect lpRect); + [LibraryImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static partial bool SetWindowPos( diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 44e22f812..6b780ee14 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -2053,6 +2053,12 @@ namespace Ryujinx.Ava.UI.ViewModels } private nint _savedWindowStyle; + private WindowState _savedWindowState; + private PixelPoint _savedWindowPosition; + private double _savedWindowWidth; + private double _savedWindowHeight; + private Win32NativeInterop.NativeRect _savedWindowRect; + private bool _savedWindowRectValid; [SupportedOSPlatform("windows")] private void MakeWindowFullscreen() @@ -2076,6 +2082,11 @@ namespace Ryujinx.Ava.UI.ViewModels // Save current style and placement _savedWindowStyle = Win32NativeInterop.GetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE); + _savedWindowState = WindowState; + _savedWindowPosition = Window.Position; + _savedWindowWidth = Window.Width; + _savedWindowHeight = Window.Height; + _savedWindowRectValid = Win32NativeInterop.GetWindowRect(hwnd, out _savedWindowRect); // Remove window chrome: WS_OVERLAPPEDWINDOW -> WS_POPUP | WS_VISIBLE Win32NativeInterop.SetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE, @@ -2099,10 +2110,34 @@ namespace Ryujinx.Ava.UI.ViewModels // Restore original window style Win32NativeInterop.SetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE, _savedWindowStyle); - Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, 0, 0, 0, 0, - Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE | - Win32NativeInterop.SWP_FRAMECHANGED | Win32NativeInterop.SWP_NOMOVE | Win32NativeInterop.SWP_NOSIZE); + if (_savedWindowState is WindowState.Maximized) + { + Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, 0, 0, 0, 0, + Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE | + Win32NativeInterop.SWP_FRAMECHANGED | Win32NativeInterop.SWP_NOMOVE | Win32NativeInterop.SWP_NOSIZE); + } + else if (_savedWindowRectValid) + { + Dispatcher.UIThread.Post(() => RestoreSavedWindowRect(hwnd), DispatcherPriority.Background); + } + else + { + Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, 0, 0, 0, 0, + Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE | + Win32NativeInterop.SWP_FRAMECHANGED | Win32NativeInterop.SWP_NOMOVE | Win32NativeInterop.SWP_NOSIZE); + } + } + [SupportedOSPlatform("windows")] + private void RestoreSavedWindowRect(nint hwnd) + { + Window.Position = _savedWindowPosition; + Window.Width = _savedWindowWidth; + Window.Height = _savedWindowHeight; + + Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, _savedWindowRect.Left, _savedWindowRect.Top, + _savedWindowRect.Width, _savedWindowRect.Height, + Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE | Win32NativeInterop.SWP_FRAMECHANGED); } public static void SaveConfig()