This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: tkinter breaks on high resolution screen after ctypes SetProcessDPIAware()
Type: behavior Stage:
Components: Tkinter, Windows Versions: Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: GabeMillikan, epaine, paul.moore, serhiy.storchaka, steve.dower, terry.reedy, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2021-10-31 12:12 by GabeMillikan, last changed 2022-04-11 14:59 by admin.

Files
File name Uploaded Description Edit
KwUqCTWl58.gif GabeMillikan, 2021-10-31 12:12
Messages (5)
msg405401 - (view) Author: Gabe (GabeMillikan) Date: 2021-10-31 12:12
In the following code: 
```py
import tkinter as tk
from tkinter import ttk

import ctypes
ctypes.windll.user32.SetProcessDPIAware()

w = tk.Tk()
ttk.Checkbutton(w, text = "Checkbox").grid()
w.mainloop()
```

The checkbox begins as normal size, but after hovering over it, it becomes small. See attached gif.

The issue does not occur without the SetProcessDPIAware call. 

I am running Windows 11, and my screen resolution is 2560x1440. My Settings>System>Display>Custom Scaling is set to 150%. I believe that this is relevant because SetProcessDPIAware() directly affects the dpi awareness (aka 'custom scaling') of the program, according to Microsoft documentation.
msg405438 - (view) Author: E. Paine (epaine) * Date: 2021-11-01 12:15
What happens if you use `ctypes.windll.user32.SetProcessDPIAware(1)` (note the 1)? Also, are the checkboxes on the IDLE config dialog affected (since IDLE also sets the dpi awareness: see https://github.com/python/cpython/blob/main/Lib/idlelib/pyshell.py#L14-L22)?
msg405450 - (view) Author: Gabe (GabeMillikan) Date: 2021-11-01 16:40
The exact same effect happens with SetProcessDPIAware(1). The IDLE checkboxes are in fact affected; they're tiny. I discovered that I was able to prevent the issue by using `ctypes.windll.shcore.SetProcessDpiAwareness(0)`. This prevents the issue only if it is called prior to the SetProcessDPIAware call.

This code does not have any issues (everything is correctly scaled)

```
import tkinter as tk
from tkinter import ttk

import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(0)
ctypes.windll.user32.SetProcessDPIAware()

w = tk.Tk()
ttk.Checkbutton(w, text = "Checkbox").grid()
w.mainloop()
```

If the SetProcessDpiAwareness call comes after the SetProcessDPIAware call, then the error persists. I believe that this is because Windows only listens to the first DPI configuration call, so it ignores subsequent calls. I was unable to find documentation to support this though.
msg405452 - (view) Author: Gabe (GabeMillikan) Date: 2021-11-01 16:55
I should add - the reason why this is an issue is because pyautogui calls this function, and I would like to use pyautogui in my tkinter app, but I currently cannot without sacrificing my checkbuttons. (Well, pyautogui uses pyscreeze for screenshots and pyscreeze calls it: https://github.com/asweigart/pyscreeze/blob/master/pyscreeze/__init__.py#L69)
msg405454 - (view) Author: E. Paine (epaine) * Date: 2021-11-01 17:15
This is definitely a Tk issue, but it is resolved as of Tk 8.6.11. I assume this is similar to #41969.

Strangely, the Windows installers for 3.10 and 3.11 appear to still be using Tk 8.6.10 despite PR-25170, rather than 8.6.11. I'll raise it on #43652.
History
Date User Action Args
2022-04-11 14:59:51adminsetgithub: 89844
2021-11-01 22:43:16terry.reedysetnosy: + paul.moore, tim.golden, zach.ware, steve.dower
components: + Windows
2021-11-01 17:15:22epainesetmessages: + msg405454
2021-11-01 16:55:19GabeMillikansetmessages: + msg405452
2021-11-01 16:40:07GabeMillikansetmessages: + msg405450
2021-11-01 12:15:22epainesetnosy: + terry.reedy, serhiy.storchaka, epaine
messages: + msg405438
2021-10-31 12:12:02GabeMillikancreate