Skip to content

Commit

Permalink
Fix HiDPI scaling on XWayland (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
Maia-Everett committed Apr 21, 2024
1 parent 072480e commit 6936908
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/XIVLauncher.Core/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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();
Expand Down
53 changes: 53 additions & 0 deletions src/XIVLauncher.Core/SdlHelpers.cs
Original file line number Diff line number Diff line change
@@ -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_t>("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_t>("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);
}
}

0 comments on commit 6936908

Please sign in to comment.