Skip to content

Backport PR #21212 on branch v3.5.x (Fix set_size_inches on HiDPI and also GTK4) #21406

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -1760,7 +1760,12 @@ def blit(self, bbox=None):
"""Blit the canvas in bbox (default entire canvas)."""

def resize(self, w, h):
"""Set the canvas size in pixels."""
"""
UNUSED: Set the canvas size in pixels.

Certain backends may implement a similar method internally, but this is
not a requirement of, nor is it used by, Matplotlib itself.
"""

def draw_event(self, renderer):
"""Pass a `DrawEvent` to all functions connected to ``draw_event``."""
Expand Down Expand Up @@ -2813,7 +2818,7 @@ def full_screen_toggle(self):
pass

def resize(self, w, h):
"""For GUI backends, resize the window (in pixels)."""
"""For GUI backends, resize the window (in physical pixels)."""

@_api.deprecated(
"3.4", alternative="self.canvas.callbacks.process(event.name, event)")
Expand Down
2 changes: 2 additions & 0 deletions lib/matplotlib/backends/backend_gtk3.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,8 @@ def set_window_title(self, title):

def resize(self, width, height):
"""Set the canvas size in pixels."""
width = int(width / self.canvas.device_pixel_ratio)
height = int(height / self.canvas.device_pixel_ratio)
if self.toolbar:
toolbar_size = self.toolbar.size_request()
height += toolbar_size.height
Expand Down
15 changes: 5 additions & 10 deletions lib/matplotlib/backends/backend_gtk4.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,18 +374,13 @@ def set_window_title(self, title):

def resize(self, width, height):
"""Set the canvas size in pixels."""
width = int(width / self.canvas.device_pixel_ratio)
height = int(height / self.canvas.device_pixel_ratio)
if self.toolbar:
toolbar_size = self.toolbar.size_request()
height += toolbar_size.height
min_size, nat_size = self.toolbar.get_preferred_size()
height += nat_size.height
canvas_size = self.canvas.get_allocation()
if canvas_size.width == canvas_size.height == 1:
# A canvas size of (1, 1) cannot exist in most cases, because
# window decorations would prevent such a small window. This call
# must be before the window has been mapped and widgets have been
# sized, so just change the window's starting size.
self.window.set_default_size(width, height)
else:
self.window.resize(width, height)
self.window.set_default_size(width, height)


class NavigationToolbar2GTK4(_NavigationToolbar2GTK, Gtk.Box):
Expand Down
6 changes: 4 additions & 2 deletions lib/matplotlib/backends/backend_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,8 +589,10 @@ def _get_toolbar(self, canvas, parent):
return toolbar

def resize(self, width, height):
# these are Qt methods so they return sizes in 'virtual' pixels
# so we do not need to worry about dpi scaling here.
# The Qt methods return sizes in 'virtual' pixels so we do need to
# rescale from physical to logical pixels.
width = int(width / self.canvas.device_pixel_ratio)
height = int(height / self.canvas.device_pixel_ratio)
extra_width = self.window.width() - self.canvas.width()
extra_height = self.window.height() - self.canvas.height()
self.canvas.resize(width, height)
Expand Down
3 changes: 1 addition & 2 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -2657,10 +2657,9 @@ def set_size_inches(self, w, h=None, forward=True):
if forward:
canvas = getattr(self, 'canvas')
if canvas is not None:
dpi_ratio = getattr(canvas, '_dpi_ratio', 1)
manager = getattr(canvas, 'manager', None)
if manager is not None:
manager.resize(*(size * self.dpi / dpi_ratio).astype(int))
manager.resize(*(size * self.dpi).astype(int))
self.stale = True

def get_size_inches(self):
Expand Down