Windows Fullscreen Fixes (#87)

This PR fixes two bugs introduced in #80 :
- Exiting fullscreen could exit the Ryujinx window  (https://github.com/Ryubing/Issues/issues/415)
- Toggling fullscreen on would move the window to the primary monitor

And two other bugs related to input view :
- Exiting fullscreen when window was previously in a non maximized state now conserves the window coordinates and size properly (https://github.com/Ryubing/Issues/issues/425)
- Opening the ryujinx app no makes the app grow slightly larger vertically on each launch (+31px on my 1080p monitor) (https://github.com/Ryubing/Issues/issues/425)

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/87
This commit is contained in:
Babib3l
2026-05-25 12:09:00 +00:00
committed by sh0inx
parent b62c58c2fe
commit b2310823c9
3 changed files with 79 additions and 11 deletions

View File

@@ -2060,6 +2060,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()
@@ -2067,19 +2073,36 @@ namespace Ryujinx.Ava.UI.ViewModels
nint hwnd = Window.TryGetPlatformHandle()?.Handle ?? nint.Zero;
if (hwnd == nint.Zero) return;
PixelPoint windowCenter = new(
Window.Position.X + (int)(Window.Bounds.Width / 2),
Window.Position.Y + (int)(Window.Bounds.Height / 2));
Avalonia.Platform.Screen? screen =
Window.Screens.ScreenFromVisual(Window) ??
Window.Screens.ScreenFromPoint(windowCenter) ??
Window.Screens.Primary;
if (screen == null)
{
return; // Can't determine screen size, don't attempt fullscreen
}
// 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,
unchecked((nint)(Win32NativeInterop.WS_POPUP | Win32NativeInterop.WS_VISIBLE)));
// TODO: why is this nullable
Avalonia.Platform.Screen? screen = Window.Screens.ScreenFromVisual(Window);
int w = screen?.Bounds.Width ?? 0;
int h = screen?.Bounds.Height ?? 0;
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, 0, 0, w, h,
int w = screen.Bounds.Width;
int h = screen.Bounds.Height;
Win32NativeInterop.SetWindowPos(hwnd, nint.Zero, screen.Bounds.X, screen.Bounds.Y, w, h,
Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE | Win32NativeInterop.SWP_FRAMECHANGED);
WindowState = WindowState.FullScreen;
@@ -2094,10 +2117,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()