From 6cdcb8c14a41d272fd1114145bf027310fa32b1f Mon Sep 17 00:00:00 2001 From: Maia Everett Date: Sun, 21 Apr 2024 23:31:23 +0300 Subject: [PATCH] Fix HiDPI scaling on XWayland (#88) --- src/XIVLauncher.Core/Program.cs | 17 ++++++- src/XIVLauncher.Core/SdlHelpers.cs | 53 ++++++++++++++++++++ src/XIVLauncher.Core/XIVLauncher.Core.csproj | 4 +- 3 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 src/XIVLauncher.Core/SdlHelpers.cs diff --git a/src/XIVLauncher.Core/Program.cs b/src/XIVLauncher.Core/Program.cs index a8051724..9dabf1c4 100644 --- a/src/XIVLauncher.Core/Program.cs +++ b/src/XIVLauncher.Core/Program.cs @@ -255,8 +255,21 @@ private static void Main(string[] args) #endif // Create window, GraphicsDevice, and all resources necessary for the demo. + Sdl2Native.SDL_Init(SDLInitFlags.Video); + + float dpiScale = 1f; + + if (Environment.GetEnvironmentVariable("XDG_SESSION_TYPE") == "wayland" + && SdlHelpers.GetCurrentVideoDriver() == "x11") + { + dpiScale = SdlHelpers.GetDisplayDpiScale().Y; + } + + var windowWidth = (int) Math.Round(1280 * dpiScale); + var windowHeight = (int) Math.Round(800 * dpiScale); + VeldridStartup.CreateWindowAndGraphicsDevice( - new WindowCreateInfo(50, 50, 1280, 800, WindowState.Normal, $"XIVLauncher {version}"), + new WindowCreateInfo(50, 50, windowWidth, windowHeight, WindowState.Normal, $"XIVLauncher {version}"), new GraphicsDeviceOptions(false, null, true, ResourceBindingModel.Improved, true, true), out window, out gd); @@ -270,7 +283,7 @@ private static void Main(string[] args) cl = gd.ResourceFactory.CreateCommandList(); Log.Debug("Veldrid OK!"); - bindings = new ImGuiBindings(gd, gd.MainSwapchain.Framebuffer.OutputDescription, window.Width, window.Height, storage.GetFile("launcherUI.ini"), Config.FontPxSize ?? 21.0f); + bindings = new ImGuiBindings(gd, gd.MainSwapchain.Framebuffer.OutputDescription, window.Width, window.Height, storage.GetFile("launcherUI.ini"), (Config.FontPxSize ?? 21.0f) * dpiScale); Log.Debug("ImGui OK!"); StyleModelV1.DalamudStandard.Apply(); diff --git a/src/XIVLauncher.Core/SdlHelpers.cs b/src/XIVLauncher.Core/SdlHelpers.cs new file mode 100644 index 00000000..2c0bfc10 --- /dev/null +++ b/src/XIVLauncher.Core/SdlHelpers.cs @@ -0,0 +1,53 @@ +using System.Numerics; +using System.Runtime.InteropServices; +using System.Text; +using Serilog; +using Veldrid.Sdl2; + +namespace XIVLauncher.Core; + +public static unsafe partial class SdlHelpers +{ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate byte* SDL_GetCurrentVideoDriver_t(); + private static SDL_GetCurrentVideoDriver_t s_sdl_getCurrentVideoDriver = + Sdl2Native.LoadFunction("SDL_GetCurrentVideoDriver"); + private static byte* SDL_GetCurrentVideoDriver() => s_sdl_getCurrentVideoDriver(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int SDL_GetDisplayDPI_t(int displayIndex, float* ddpi, float* hdpi, float* vdpi); + private static SDL_GetDisplayDPI_t s_sdl_getDisplayDPI = + Sdl2Native.LoadFunction("SDL_GetDisplayDPI"); + private static int SDL_GetDisplayDPI(int displayIndex, float* ddpi, float* hdpi, float* vdpi) + => s_sdl_getDisplayDPI(displayIndex, ddpi, hdpi, vdpi); + + private static unsafe string GetString(byte* stringStart) + { + int characters = 0; + while (stringStart[characters] != 0) + { + characters++; + } + + return Encoding.UTF8.GetString(stringStart, characters); + } + + public static string GetCurrentVideoDriver() + { + return GetString(SDL_GetCurrentVideoDriver()); + } + + public static Vector2 GetDisplayDpiScale() + { + float ddpi, hdpi, vdpi; + + if (SDL_GetDisplayDPI(0, &ddpi, &hdpi, &vdpi) < 0) + { + Log.Warning("Cannot determine display DPI scale, defaulting to 1.0: {0}", + GetString(Sdl2Native.SDL_GetError())); + return new Vector2(1.0f, 1.0f); + } + + return new Vector2(hdpi / 96, vdpi / 96); + } +} diff --git a/src/XIVLauncher.Core/XIVLauncher.Core.csproj b/src/XIVLauncher.Core/XIVLauncher.Core.csproj index b6ad12d7..036d5702 100644 --- a/src/XIVLauncher.Core/XIVLauncher.Core.csproj +++ b/src/XIVLauncher.Core/XIVLauncher.Core.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 enable enable true @@ -13,7 +13,7 @@ $(Version) $(Version) - win10-x64;linux-x64;osx-x64 + linux-x64 true