diff --git a/lib/matplotlib/backends/_backend_tk.py b/lib/matplotlib/backends/_backend_tk.py
index 7c1ff265aea3..260a5664e465 100644
--- a/lib/matplotlib/backends/_backend_tk.py
+++ b/lib/matplotlib/backends/_backend_tk.py
@@ -512,6 +512,14 @@ def __init__(self, canvas, window, *, pack_toolbar=True):
if tooltip_text is not None:
ToolTip.createToolTip(button, tooltip_text)
+ # This filler item ensures the toolbar is always at least two text
+ # lines high. Otherwise the canvas gets redrawn as the mouse hovers
+ # over images because those use two-line messages which resize the
+ # toolbar.
+ label = tk.Label(master=self,
+ text='\N{NO-BREAK SPACE}\n\N{NO-BREAK SPACE}')
+ label.pack(side=tk.RIGHT)
+
self.message = tk.StringVar(master=self)
self._message_label = tk.Label(master=self, textvariable=self.message)
self._message_label.pack(side=tk.RIGHT)
diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py
index c9094eb1df33..a8b6e801205c 100644
--- a/lib/matplotlib/backends/backend_gtk3.py
+++ b/lib/matplotlib/backends/backend_gtk3.py
@@ -521,6 +521,17 @@ def __init__(self, canvas, window):
toolitem.set_draw(False)
toolitem.set_expand(True)
+ # This filler item ensures the toolbar is always at least two text
+ # lines high. Otherwise the canvas gets redrawn as the mouse hovers
+ # over images because those use two-line messages which resize the
+ # toolbar.
+ toolitem = Gtk.ToolItem()
+ self.insert(toolitem, -1)
+ label = Gtk.Label()
+ label.set_markup(
+ '\N{NO-BREAK SPACE}\n\N{NO-BREAK SPACE}')
+ toolitem.add(label)
+
toolitem = Gtk.ToolItem()
self.insert(toolitem, -1)
self.message = Gtk.Label()
@@ -536,7 +547,8 @@ def ctx(self):
return self.canvas.get_property("window").cairo_create()
def set_message(self, s):
- self.message.set_label(s)
+ escaped = GLib.markup_escape_text(s)
+ self.message.set_markup(f'{escaped}')
def set_cursor(self, cursor):
self.canvas.get_property("window").set_cursor(cursord[cursor])