From 2227d9f8fbe5a409586e1388cd8a44908b5ff75c Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 28 Mar 2024 19:12:22 -0400 Subject: [PATCH] gtk: Ensure pending draws are done before GTK draw Originally, the resize event happens first, adds an idle draw callback, and then the widget draws itself. Since the draw callback only happens when _idle_, it happens after the draw, so the figure appears blank. After the mouse is released, the idle draw callback fires, and the figure appears again. This is already done in the Qt backend [1], and doing so ensures the figure remains visible during resizes with the mouse. [1] https://github.com/matplotlib/matplotlib/blob/0afc5d6ca49cf6e8aa1da76b5bab0faca2f340f2/lib/matplotlib/backends/backend_qtagg.py#L25 --- lib/matplotlib/backends/backend_gtk3agg.py | 7 ++++++- lib/matplotlib/backends/backend_gtk3cairo.py | 7 ++++++- lib/matplotlib/backends/backend_gtk4agg.py | 7 ++++++- lib/matplotlib/backends/backend_gtk4cairo.py | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/backends/backend_gtk3agg.py b/lib/matplotlib/backends/backend_gtk3agg.py index a006a4c6f127..90b38ffa4ec3 100644 --- a/lib/matplotlib/backends/backend_gtk3agg.py +++ b/lib/matplotlib/backends/backend_gtk3agg.py @@ -2,7 +2,7 @@ from .. import cbook, transforms from . import backend_agg, backend_gtk3 -from .backend_gtk3 import Gtk, _BackendGTK3 +from .backend_gtk3 import GLib, Gtk, _BackendGTK3 import cairo # Presence of cairo is already checked by _backend_gtk. @@ -14,6 +14,11 @@ def __init__(self, figure): self._bbox_queue = [] def on_draw_event(self, widget, ctx): + if self._idle_draw_id: + GLib.source_remove(self._idle_draw_id) + self._idle_draw_id = 0 + self.draw() + scale = self.device_pixel_ratio allocation = self.get_allocation() w = allocation.width * scale diff --git a/lib/matplotlib/backends/backend_gtk3cairo.py b/lib/matplotlib/backends/backend_gtk3cairo.py index 1da8419e5381..24a26111f062 100644 --- a/lib/matplotlib/backends/backend_gtk3cairo.py +++ b/lib/matplotlib/backends/backend_gtk3cairo.py @@ -1,11 +1,16 @@ from contextlib import nullcontext from .backend_cairo import FigureCanvasCairo -from .backend_gtk3 import Gtk, FigureCanvasGTK3, _BackendGTK3 +from .backend_gtk3 import GLib, Gtk, FigureCanvasGTK3, _BackendGTK3 class FigureCanvasGTK3Cairo(FigureCanvasCairo, FigureCanvasGTK3): def on_draw_event(self, widget, ctx): + if self._idle_draw_id: + GLib.source_remove(self._idle_draw_id) + self._idle_draw_id = 0 + self.draw() + with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar else nullcontext()): self._renderer.set_context(ctx) diff --git a/lib/matplotlib/backends/backend_gtk4agg.py b/lib/matplotlib/backends/backend_gtk4agg.py index efddfec56075..0af07850a30a 100644 --- a/lib/matplotlib/backends/backend_gtk4agg.py +++ b/lib/matplotlib/backends/backend_gtk4agg.py @@ -2,7 +2,7 @@ from .. import cbook from . import backend_agg, backend_gtk4 -from .backend_gtk4 import Gtk, _BackendGTK4 +from .backend_gtk4 import GLib, Gtk, _BackendGTK4 import cairo # Presence of cairo is already checked by _backend_gtk. @@ -11,6 +11,11 @@ class FigureCanvasGTK4Agg(backend_agg.FigureCanvasAgg, backend_gtk4.FigureCanvasGTK4): def on_draw_event(self, widget, ctx): + if self._idle_draw_id: + GLib.source_remove(self._idle_draw_id) + self._idle_draw_id = 0 + self.draw() + scale = self.device_pixel_ratio allocation = self.get_allocation() diff --git a/lib/matplotlib/backends/backend_gtk4cairo.py b/lib/matplotlib/backends/backend_gtk4cairo.py index d57f53fb28d6..b1d543704351 100644 --- a/lib/matplotlib/backends/backend_gtk4cairo.py +++ b/lib/matplotlib/backends/backend_gtk4cairo.py @@ -1,13 +1,18 @@ from contextlib import nullcontext from .backend_cairo import FigureCanvasCairo -from .backend_gtk4 import Gtk, FigureCanvasGTK4, _BackendGTK4 +from .backend_gtk4 import GLib, Gtk, FigureCanvasGTK4, _BackendGTK4 class FigureCanvasGTK4Cairo(FigureCanvasCairo, FigureCanvasGTK4): _context_is_scaled = True def on_draw_event(self, widget, ctx): + if self._idle_draw_id: + GLib.source_remove(self._idle_draw_id) + self._idle_draw_id = 0 + self.draw() + with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar else nullcontext()): self._renderer.set_context(ctx)