diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index a692504afb23..25619104134f 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -30,14 +30,6 @@ def __init__(self, figure): FigureCanvasBase.__init__(self, figure) width, height = self.get_width_height() _macosx.FigureCanvas.__init__(self, width, height) - self._dpi_ratio = 1.0 - - def _set_device_scale(self, value): - if self._dpi_ratio != value: - # Need the new value in place before setting figure.dpi, which - # will trigger a resize - self._dpi_ratio, old_value = value, self._dpi_ratio - self.figure.dpi = self.figure.dpi / old_value * self._dpi_ratio def set_cursor(self, cursor): # docstring inherited @@ -60,12 +52,11 @@ def blit(self, bbox=None): self.draw_idle() def resize(self, width, height): - dpi = self.figure.dpi - width /= dpi - height /= dpi - self.figure.set_size_inches(width * self._dpi_ratio, - height * self._dpi_ratio, - forward=False) + # Size from macOS is logical pixels, dpi is physical. + scale = self.figure.dpi / self.device_pixel_ratio + width /= scale + height /= scale + self.figure.set_size_inches(width, height, forward=False) FigureCanvasBase.resize_event(self) self.draw_idle() diff --git a/src/_macosx.m b/src/_macosx.m index ef999ca9ea2d..9eeeab46eb5b 100755 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -237,6 +237,8 @@ @interface View : NSView } - (void)dealloc; - (void)drawRect:(NSRect)rect; +- (void)updateDevicePixelRatio:(double)scale; +- (void)windowDidChangeBackingProperties:(NSNotification*)notification; - (void)windowDidResize:(NSNotification*)notification; - (View*)initWithFrame:(NSRect)rect; - (void)setCanvas: (PyObject*)newCanvas; @@ -706,6 +708,7 @@ static CGFloat _get_device_scale(CGContextRef cr) [window setDelegate: view]; [window makeFirstResponder: view]; [[window contentView] addSubview: view]; + [view updateDevicePixelRatio: [window backingScaleFactor]]; return 0; } @@ -801,6 +804,9 @@ static CGFloat _get_device_scale(CGContextRef cr) Window* window = self->window; if(window) { + CGFloat device_pixel_ratio = [window backingScaleFactor]; + width /= device_pixel_ratio; + height /= device_pixel_ratio; // 36 comes from hard-coded size of toolbar later in code [window setContentSize: NSMakeSize(width, height + 36.)]; } @@ -1654,15 +1660,6 @@ -(void)drawRect:(NSRect)rect CGContextRef cr = [[NSGraphicsContext currentContext] CGContext]; - double new_device_scale = _get_device_scale(cr); - - if (device_scale != new_device_scale) { - device_scale = new_device_scale; - if (!PyObject_CallMethod(canvas, "_set_device_scale", "d", device_scale, NULL)) { - PyErr_Print(); - goto exit; - } - } if (!(renderer = PyObject_CallMethod(canvas, "_draw", "", NULL)) || !(renderer_buffer = PyObject_GetAttrString(renderer, "_renderer"))) { PyErr_Print(); @@ -1683,6 +1680,33 @@ -(void)drawRect:(NSRect)rect PyGILState_Release(gstate); } +- (void)updateDevicePixelRatio:(double)scale +{ + PyObject* change = NULL; + PyGILState_STATE gstate = PyGILState_Ensure(); + + device_scale = scale; + if (!(change = PyObject_CallMethod(canvas, "_set_device_pixel_ratio", "d", device_scale, NULL))) { + PyErr_Print(); + goto exit; + } + if (PyObject_IsTrue(change)) { + [self setNeedsDisplay: YES]; + } + + exit: + Py_XDECREF(change); + + PyGILState_Release(gstate); +} + +- (void)windowDidChangeBackingProperties:(NSNotification *)notification +{ + Window* window = [notification object]; + + [self updateDevicePixelRatio: [window backingScaleFactor]]; +} + - (void)windowDidResize: (NSNotification*)notification { int width, height; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy