From d5081e3f93a3283ca7e73358d24d76d110ea962f Mon Sep 17 00:00:00 2001 From: sharmander Date: Fri, 19 Feb 2021 19:34:41 -0500 Subject: [PATCH] Make windows DPI aware to display properly on high-resolution screens. (#1983) * Make Windows DPI aware to display properly on high-resolution screens. * remove empty line * Don't use app manifest, set process dpi aware programatically. Store variables in Program.cs for use instead of re-creating them per class/ method. * Fix for linux/osx * Add braces * Re-use manifest. It appears to be required on linux. * Undo previous commit -- it appears linux was simply never affected. * Addressed AcK's comments * Remove unused usings * Address comments by AcK #2 * Re-order * Move FromHwnd call to ForceDpiAware class. Wrap in Try-Catch to prevent crashes on systems that don't support it. * Additional code cleanup * Remove "global::" reference. --- Ryujinx.Common/Ryujinx.Common.csproj | 1 + Ryujinx.Common/System/ForceDpiAware.cs | 45 ++++++++++++++++++++++++++ Ryujinx/Program.cs | 8 ++++- Ryujinx/Ui/MainWindow.cs | 10 ++++-- Ryujinx/Ui/Windows/SettingsWindow.cs | 5 ++- 5 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 Ryujinx.Common/System/ForceDpiAware.cs diff --git a/Ryujinx.Common/Ryujinx.Common.csproj b/Ryujinx.Common/Ryujinx.Common.csproj index 4bb52c6d2f..a7e9c66c93 100644 --- a/Ryujinx.Common/Ryujinx.Common.csproj +++ b/Ryujinx.Common/Ryujinx.Common.csproj @@ -7,6 +7,7 @@ + diff --git a/Ryujinx.Common/System/ForceDpiAware.cs b/Ryujinx.Common/System/ForceDpiAware.cs new file mode 100644 index 0000000000..81c69376cb --- /dev/null +++ b/Ryujinx.Common/System/ForceDpiAware.cs @@ -0,0 +1,45 @@ +using Ryujinx.Common.Logging; +using System; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace Ryujinx.Common.System +{ + public static class ForceDpiAware + { + [DllImport("user32.dll")] + private static extern bool SetProcessDPIAware(); + + private static readonly double _standardDpiScale = 96.0; + private static readonly double _maxScaleFactor = 1.25; + + /// + /// Marks the application as DPI-Aware when running on the Windows operating system. + /// + public static void Windows() + { + // Make process DPI aware for proper window sizing on high-res screens. + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.OSVersion.Version.Major >= 6) + { + SetProcessDPIAware(); + } + } + + public static double GetWindowScaleFactor() + { + double userDpiScale; + + try + { + userDpiScale = Graphics.FromHwnd(IntPtr.Zero).DpiX; + } + catch (Exception e) + { + Logger.Warning?.Print(LogClass.Application, $"Couldn't determine monitor DPI: {e.Message}"); + userDpiScale = 96.0; + } + + return Math.Min(userDpiScale / _standardDpiScale, _maxScaleFactor); + } + } +} diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs index c6d3b1bd14..5d50e9d2a6 100644 --- a/Ryujinx/Program.cs +++ b/Ryujinx/Program.cs @@ -18,12 +18,14 @@ namespace Ryujinx { class Program { + public static double WindowScaleFactor { get; private set; } + public static string Version { get; private set; } public static string ConfigurationPath { get; set; } static void Main(string[] args) - { + { // Parse Arguments. string launchPathArg = null; string baseDirPathArg = null; @@ -54,6 +56,10 @@ namespace Ryujinx } } + // Make process DPI aware for proper window sizing on high-res screens. + ForceDpiAware.Windows(); + WindowScaleFactor = ForceDpiAware.GetWindowScaleFactor(); + // Delete backup files after updating. Task.Run(Updater.CleanupUpdate); diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index 92a2b4f1ca..2118076a78 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -1113,7 +1113,10 @@ namespace Ryujinx.Ui private void Settings_Pressed(object sender, EventArgs args) { - new SettingsWindow(this, _virtualFileSystem, _contentManager).Show(); + SettingsWindow settingsWindow = new SettingsWindow(this, _virtualFileSystem, _contentManager); + + settingsWindow.SetSizeRequest((int)(settingsWindow.DefaultWidth * Program.WindowScaleFactor), (int)(settingsWindow.DefaultHeight * Program.WindowScaleFactor)); + settingsWindow.Show(); } private void Simulate_WakeUp_Message_Pressed(object sender, EventArgs args) @@ -1134,7 +1137,10 @@ namespace Ryujinx.Ui private void About_Pressed(object sender, EventArgs args) { - new AboutWindow().Show(); + AboutWindow aboutWindow = new AboutWindow(); + + aboutWindow.SetSizeRequest((int)(aboutWindow.DefaultWidth * Program.WindowScaleFactor), (int)(aboutWindow.DefaultHeight * Program.WindowScaleFactor)); + aboutWindow.Show(); } private void Fav_Toggled(object sender, EventArgs args) diff --git a/Ryujinx/Ui/Windows/SettingsWindow.cs b/Ryujinx/Ui/Windows/SettingsWindow.cs index e839a366c6..0938783ff3 100644 --- a/Ryujinx/Ui/Windows/SettingsWindow.cs +++ b/Ryujinx/Ui/Windows/SettingsWindow.cs @@ -570,7 +570,10 @@ namespace Ryujinx.Ui.Windows { ((ToggleButton)sender).SetStateFlags(StateFlags.Normal, true); - new ControllerWindow(playerIndex).Show(); + ControllerWindow controllerWindow = new ControllerWindow(playerIndex); + + controllerWindow.SetSizeRequest((int)(controllerWindow.DefaultWidth * Program.WindowScaleFactor), (int)(controllerWindow.DefaultHeight * Program.WindowScaleFactor)); + controllerWindow.Show(); } private void SaveToggle_Activated(object sender, EventArgs args)