Files
totk-pc-recomp/runtime/dpi_probe.c
T
Valiantsin DzerakhandClaude Opus 5.5 fcaecabad4 Make totk.exe per-monitor DPI aware so fullscreen and the window use physical pixels
The manifest declared no DPI awareness, so Windows ran the process DPI-unaware: on a 4K monitor at 150% scale the
fullscreen window and its swapchain were 2560x1440, the 4K game image was shrunk to it and Windows stretched the
result back up, blurred (issues #25, #56, #31).

The manifest now declares PerMonitorV2 (true/pm for older Windows 10). The window frame is measured at the window's
DPI, a framed window keeps its client size when it moves to a monitor at another scale, WM_DPICHANGED takes the
suggested rect or keeps fullscreen over the monitor, and window_size means screen pixels. The menu's minimum text
size follows the window's DPI, and the text entry dialog is measured at the game window's DPI. --probe-dpi prints
the process awareness and fails unless it is per-monitor v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 13:40:04 +03:00

34 lines
1.8 KiB
C

// --probe-dpi: the process DPI awareness that totk.manifest declares, and what the primary monitor reports under it.
// A DPI-unaware process gets every window and monitor size scaled down by the display scale and its output stretched
// back up by Windows; the probe fails unless the process is per-monitor aware (v2). Needs no game files and no GPU.
#include <stdio.h>
#include <windows.h>
#include "host.h"
static const char *awareness_name(DPI_AWARENESS_CONTEXT ctx) {
if (AreDpiAwarenessContextsEqual(ctx, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) return "per-monitor aware v2";
switch (GetAwarenessFromDpiAwarenessContext(ctx)) {
case DPI_AWARENESS_UNAWARE: return "unaware";
case DPI_AWARENESS_SYSTEM_AWARE: return "system aware";
case DPI_AWARENESS_PER_MONITOR_AWARE: return "per-monitor aware v1";
default: return "invalid";
}
}
int probe_dpi(void) {
DPI_AWARENESS_CONTEXT ctx = GetThreadDpiAwarenessContext();
MONITORINFO mi = {sizeof mi};
HMONITOR mon = MonitorFromPoint((POINT){0, 0}, MONITOR_DEFAULTTOPRIMARY);
int have = GetMonitorInfoW(mon, &mi);
printf("dpi: awareness %s\n", awareness_name(ctx));
printf("dpi: system dpi %u (scale %u%%)\n", GetDpiForSystem(), GetDpiForSystem() * 100 / 96);
if (have)
printf("dpi: primary monitor %ldx%ld at %ld,%ld; screen metrics %dx%d\n", mi.rcMonitor.right - mi.rcMonitor.left,
mi.rcMonitor.bottom - mi.rcMonitor.top, mi.rcMonitor.left, mi.rcMonitor.top, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
int ok = AreDpiAwarenessContextsEqual(ctx, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) && have;
printf("probe-dpi: %s\n", ok ? "PASS" : "FAIL (the process is not per-monitor aware v2)");
return ok ? 0 : 1;
}