mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-16 02:05:46 +00:00
Fix Windows fullscreen gap when toggling from maximized (#80)
This PR aims to Fix the Windows fullscreen gap when toggling from maximized state by using canonical Win32 fullscreen approach. When entering fullscreen, the window style is saved and replaced with WS_POPUP | WS_VISIBLE to remove all window chrome (title bar, borders), then SetWindowPos sizes the window to cover the full screen with SWP_FRAMECHANGED to force Win32 to recalculate the frame. On exit, the original window style is restored. This eliminates the few-pixel gap at the top that occurred because Avalonia's WindowState = FullScreen transition from a maximized state retained the title bar non-client area, leaving visible space at the top of the screen (Fullscreen resolution would be 1920 x 1072p on a 1080p monitor, it now correctly renders at 1920 x 1080p) Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/80
This commit is contained in:
@@ -5,6 +5,7 @@ using Avalonia.Input;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using System.Runtime.Versioning;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using DynamicData;
|
||||
@@ -2014,7 +2015,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
LastFullscreenToggle = Environment.TickCount64;
|
||||
|
||||
if (WindowState is not WindowState.Normal)
|
||||
if (WindowState is WindowState.FullScreen)
|
||||
{
|
||||
WindowState = WindowState.Normal;
|
||||
Window.TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowOldUI;
|
||||
@@ -2023,21 +2024,74 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
ShowMenuAndStatusBar = true;
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
RestoreWindowFromFullscreen();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowState = WindowState.FullScreen;
|
||||
Window.TitleBar.ExtendsContentIntoTitleBar = true;
|
||||
|
||||
if (IsGameRunning)
|
||||
{
|
||||
ShowMenuAndStatusBar = false;
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
MakeWindowFullscreen();
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowState = WindowState.FullScreen;
|
||||
}
|
||||
}
|
||||
|
||||
IsFullScreen = WindowState is WindowState.FullScreen;
|
||||
}
|
||||
|
||||
private nint _savedWindowStyle;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private void MakeWindowFullscreen()
|
||||
{
|
||||
nint hwnd = Window.TryGetPlatformHandle()?.Handle ?? nint.Zero;
|
||||
if (hwnd == nint.Zero) return;
|
||||
|
||||
// Save current style and placement
|
||||
_savedWindowStyle = Win32NativeInterop.GetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE);
|
||||
|
||||
// Remove window chrome: WS_OVERLAPPEDWINDOW -> WS_POPUP | WS_VISIBLE
|
||||
Win32NativeInterop.SetWindowLongPtrW(hwnd, Win32NativeInterop.GWL_STYLE,
|
||||
unchecked((nint)(Win32NativeInterop.WS_POPUP | Win32NativeInterop.WS_VISIBLE)));
|
||||
|
||||
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,
|
||||
Win32NativeInterop.SWP_NOZORDER | Win32NativeInterop.SWP_NOACTIVATE | Win32NativeInterop.SWP_FRAMECHANGED);
|
||||
|
||||
WindowState = WindowState.FullScreen;
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private void RestoreWindowFromFullscreen()
|
||||
{
|
||||
nint hwnd = Window.TryGetPlatformHandle()?.Handle ?? nint.Zero;
|
||||
if (hwnd == nint.Zero) return;
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
public static void SaveConfig()
|
||||
{
|
||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||
|
||||
Reference in New Issue
Block a user