classification
Title: IDLE: scale font to Windows' "zoom" factor
Type: enhancement Stage: resolved
Components: IDLE Versions: Python 3.10, Python 3.9, Python 3.8
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: terry.reedy Nosy List: epaine, eryksun, taleinat, terry.reedy
Priority: normal Keywords:

Created on 2020-09-11 15:39 by epaine, last changed 2020-09-14 15:21 by epaine. This issue is now closed.

Messages (3)
msg376733 - (view) Author: E. Paine (epaine) * Date: 2020-09-11 15:39
Following #33656, IDLE now "lies" to Windows and declares it has system DPI awareness to achieve a *sharper* look. System dpi is in effect:
DPI_AWARENESS_UNAWARE * Windows' zoom factor

Therefore, for IDLE to scale to the Windows' zoom/scale factor (System > Display > Scale and layout > Change the size of text, apps and other items), we need multiply the user's chosen font size by the zoom factor.

Unfortunately I cannot quote the docs about the multiplication I gave above but have extensively tested and found this to hold true (the docs are not very explanatory but a link and small snippet can be found below):

DPI_AWARENESS                Return value
DPI_AWARENESS_UNAWARE        96
DPI_AWARENESS_SYSTEM_AWARE   The system DPI.
[https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiforwindow]

We can use the GetDpiForWindow function to get the system dpi and divide it by 96 (DPI_AWARENESS_UNAWARE) to get the scale factor for the font. This keeps IDLE sharp while allowing it to respect the user's scaling preferences.

I was not intending for this to not be an option (it would happen on any Windows system unless the user digs through the source), though appreciate that it could cause a significant change on first-load.

I considered adding this logic to the idlelib.run.fix_scaling method (which already modifies tkinter font size) but thought that users would not want this if their application was not set as DPI aware so settled on extending the idlelib.config.IdleConf.GetFont method instead.

My motivation for this is that currently that the user has to manually change their font size to match their Windows zoom factor (IDLE, without the user changing their font size, remains the same size regardless of what setting the user chooses as their scale factor). I have prepared a branch if this change is something that would interest you Terry.

Eryk, I have nosied you as I believe you are the person for Windows API calls (please do remove yourself if I am wrong).
msg376775 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-09-12 05:40
Are you the Elisha Paine that suggested the original fix?

I am still interested in the subject, but there are a lot of factors to consider.

Rereading #33656, I disagree that IDLE is lying; tk scales on startup and others agreed with the current setting, and even thought it should be made part of the Python install.

I did a *lot* of testing, using a magnifier looking at IDLE, Firefox, and Command Prompt, and changing the properties settings.

The minimum client for GetDpiForWindow is Windows 10, version 1607, whereas the current solution works for all Win 10 and likely Win 8, so it cannot replace the latter.

Currently, when I change Settings / Display / Scale and layout, which is what I presume you mean by 'zoom factor' (100%, 125%, ...), IDLE 3.9 changes too, as I would expect.  The text window change is not exactly in proportion to the Display dialog change, but the difference might be the layout white space.  This is contrary to what you report.  I have Win 10 2004 with Sept updates.

When I downscale the resolution, the type for both the dialog and IDLE enlarges.  I presume that this is to keep it smooth rather than becoming pixelated.

I have access to system with 2 4k monitors.  When I downscaled one, and moved Windows between them, the physical height was sometimes maintained, but sometimes changed.  I will probably install Python on that system to see how IDLE and tkinter and turtledemo (without the fix) look, and repeat the above experiment.

If people changes font face, they may need to adjust the 'size', and the physical size for a given 'size' varies between fonts.
msg376882 - (view) Author: E. Paine (epaine) * Date: 2020-09-14 15:21
Firstly, apologies about the original message: rereading it, it was a bit random and written in a very illogical order.

> Are you the Elisha Paine that suggested the original fix?

Yes (though I like to think I have somewhat progressed in 2 years!). The reason I am E. Paine here is solely because I prefer if Google did not index my entire life ;-) On the subject, I would like to thank you Terry 1. for all your work on IDLE and CPython more generally and 2. because you were my first experience of the devs and were very patient despite my clear incompetence (now and then!)

> tk scales on startup

When first writing this issue I saw that Tk was calling GetDeviceCaps for LOGPIXELSX/LOGPIXELSY. The Windows docs say this:
"Number of pixels per logical inch along the screen width..."

I (incorrectly) took this to mean it disregards the system dpi and returns the dpi for the monitor. In reality, increasing the zoom factor causes this value to increase, meaning Windows (in effect) declares a smaller monitor size (certainly in later versions of Windows - whether this is true in older versions I don't know).

I have checked and the scale value increases correctly with a change in system dpi (hence meaning IDLE also scales correctly).

> IDLE ... remains the same size regardless of what setting the user chooses as their scale factor

Apologies, this is complete rubbish (I think I was comparing it to the increase in size on the settings window rather than actually paying proper attention to IDLE).

I have closed this issue as not a bug.
History
Date User Action Args
2020-09-14 15:21:45epainesetstatus: open -> closed
resolution: not a bug
messages: + msg376882

stage: resolved
2020-09-12 05:40:08terry.reedysetmessages: + msg376775
2020-09-11 15:39:13epainecreate