http://qs321.pair.com?node_id=11101747


in reply to Tk Windows 10 Scaling

There are a few ways that an application can tell Windows to not upscale/resample it for high-DPI displays (which it does for compatibility at the expense of appearance quality). Microsoft's recommended approach is to use an application manifest, rather than setting DPI awareness programmatically.

But for standalone scripts, setting DPI awareness programmatically seems easier—so much so that I haven't even attempted the application manifest approach :^). The simplest approach might be to invoke SetProcessDPIAware() from User32.dll, which is present in Vista and later. (Newer DPI awareness functions exist in Windows 8.1/10 which allow more specific settings, but I'm not sure Tk would take advantage of them.) That function can be invoked from XS, or from a Perl script by using a module like Win32::API:

# Make sure to do this **before** calling MainWindow->new
if ($^O eq 'MSWin32') {
    require Win32::API;
    # See https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiaware
    my $SetProcessDPIAware = Win32::API::More->new('User32', 'BOOL SetProcessDPIAware()');
    $SetProcessDPIAware->Call() or warn 'Failed to set process DPI awareness';
}

This approach works in Perl/Tk, as well as any of the wrappers for modern Tcl/Tk such as Tcl::pTk (disclaimer: I maintain this). There are very likely to be caveats to this approach; for example, although the value of $widget->scaling will be correctly updated, some elements like images will not be resized, and may appear smaller than expected.

Edit 2019-06-24: use Win32::API should instead be require Win32::API . Thanks vkon for catching this.

Replies are listed 'Best First'.
Re^2: Tk Windows 10 Scaling
by chrstphrchvz (Scribe) on Oct 24, 2020 at 18:43 UTC

    Something to be aware of: very recent versions of Windows support "per-monitor DPI awareness", meaning that separate displays can use different logical pixel densities; previously, all displays would use the same logical pixel density. Perl/Tk does not support per-monitor DPI awareness on Windows, and I believe adding support for it would be difficult. Rescaling (fuzziness) will be observed for Tk programs when toplevels are moved between displays with differing logical pixel densities. One issue encountered in upstream Tcl/Tk (and which likely affects Perl/Tk) is that this rescaling is not done correctly for overrideredirect toplevels (https://core.tcl-lang.org/tk/info/a9ee44102b); it is not clear if this is due to a Tk bug or a Windows bug.