8000 Add initial support for HiDPI in TkAgg on Windows. · matplotlib/matplotlib@5f1b3d1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5f1b3d1

Browse files
committed
Add initial support for HiDPI in TkAgg on Windows.
At the moment, Tk does not support updating the 'scaling' value when the monitor pixel ratio changes, or the window is moved to a different one.
1 parent dca7536 commit 5f1b3d1

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

lib/matplotlib/backends/_backend_tk.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class FigureCanvasTk(FigureCanvasBase):
166166
def __init__(self, figure=None, master=None, resize_callback=None):
167167
super().__init__(figure)
168168
self._idle_draw_id = None
169-
w, h = self.figure.bbox.size.astype(int)
169+
w, h = self.get_width_height(physical=True)
170170
self._tkcanvas = tk.Canvas(
171171
master=master, background="white",
172172
width=w, height=h, borderwidth=0, highlightthickness=0)
@@ -175,6 +175,7 @@ def __init__(self, figure=None, master=None, resize_callback=None):
175175
self._tkcanvas.create_image(w//2, h//2, image=self._tkphoto)
176176
self._resize_callback = resize_callback
177177
self._tkcanvas.bind("<Configure>", self.resize)
178+
self._tkcanvas.bind("<Map>", self._update_device_pixel_ratio)
178179
self._tkcanvas.bind("<Key>", self.key_press)
179180
self._tkcanvas.bind("<Motion>", self.motion_notify_event)
180181
self._tkcanvas.bind("<Enter>", self.enter_notify_event)
@@ -209,6 +210,18 @@ def filter_destroy(event):
209210
self._master = master
210211
self._tkcanvas.focus_set()
211212

213+
def _update_device_pixel_ratio(self, event=None):
214+
# Tk gives scaling with respect to 72 DPI, but most (all?) screens are
215+
# scaled vs 96 dpi, and pixel ratio settings are given in whole
216+
# percentages, so round to 2 digits.
217+
ratio = round(self._master.call('tk', 'scaling') / (96 / 72), 2)
218+
if self._set_device_pixel_ratio(ratio):
219+
# The easiest way to resize the canvas is to resize the canvas
220+
# widget itself, since we implement all the logic for resizing the
221+
# canvas backing store on that event.
222+
w, h = self.get_width_height(physical=True)
223+
self._tkcanvas.configure(width=w, height=h)
224+
212225
def resize(self, event):
213226
width, height = event.width, event.height
214227
if self._resize_callback is not None:

setupext.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,8 +444,8 @@ def get_extensions(self):
444444
],
445445
include_dirs=["src"],
446446
# psapi library needed for finding Tcl/Tk at run time.
447-
libraries=({"linux": ["dl"], "win32": ["psapi"],
448-
"cygwin": ["psapi"]}.get(sys.platform, [])),
447+
libraries=({"linux": ["dl"], "win32": ["psapi", "user32"],
448+
"cygwin": ["psapi", "user32"]}.get(sys.platform, [])),
449449
extra_link_args={"win32": ["-mwindows"]}.get(sys.platform, []))
450450
add_numpy_flags(ext)
451451
add_libagg_flags(ext)

src/_tkagg.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ static PyModuleDef _tkagg_module = {
208208

209209
PyMODINIT_FUNC PyInit__tkagg(void)
210210
{
211+
#ifdef WIN32_DLL
212+
SetProcessDPIAware(); // Ignore errors in case we are embedded.
213+
#endif
211214
load_tkinter_funcs();
212215
if (PyErr_Occurred()) {
213216
return NULL;

0 commit comments

Comments
 (0)
0