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

Skip to content

Commit 0e3cce3

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 b151072 commit 0e3cce3

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

lib/matplotlib/backends/_backend_tk.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class FigureCanvasTk(FigureCanvasBase):
166166
def __init__(self, figure, 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, 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_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,20 @@ def filter_destroy(event):
209210
self._master = master
210211
self._tkcanvas.focus_set()
211212

213+
def _update_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+
current_pixel_ratio = round(
218+
self._master.call('tk', 'scaling') / (96 / 72), 2)
219+
if self.pixel_ratio != current_pixel_ratio:
220+
self.pixel_ratio = current_pixel_ratio
221+
# The easiest way to resize the canvas is to resize the canvas
222+
# widget itself, since we implement all the logic for resizing the
223+
# canvas backing store on that event.
224+
w, h = self.get_width_height(physical=True)
225+
self._tkcanvas.configure(width=w, height=h)
226+
212227
def resize(self, event):
213228
width, height = event.width, event.height
214229
if self._resize_callback is not None:

setupext.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,8 @@ def get_extensions(self):
411411
],
412412
include_dirs=["src"],
413413
# psapi library needed for finding Tcl/Tk at run time.
414-
libraries=({"linux": ["dl"], "win32": ["psapi"],
415-
"cygwin": ["psapi"]}.get(sys.platform, [])),
414+
libraries=({"linux": ["dl"], "win32": ["psapi", "user32"],
415+
"cygwin": ["psapi", "user32"]}.get(sys.platform, [])),
416416
extra_link_args={"win32": ["-mwindows"]}.get(sys.platform, []))
417417
add_numpy_flags(ext)
418418
add_libagg_flags(ext)

src/_tkagg.cpp

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

206206
PyMODINIT_FUNC PyInit__tkagg(void)
207207
{
208+
#ifdef WIN32_DLL
209+
SetProcessDPIAware(); // Ignore errors in case we are embedded.
210+
#endif
208211
load_tkinter_funcs();
209212
if (PyErr_Occurred()) {
210213
return NULL;

0 commit comments

Comments
 (0)
0