Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ba2b95d

Browse files
committed
Use a GtkApplication in GTK backend.
Also, stop using `gtk_main*` functions; these were deprecated in GTK3, and no longer exist in GTK4. The lower level GLib functions have always been there, and won't go away.
1 parent ecba512 commit ba2b95d

File tree

1 file changed

+36
-13
lines changed

1 file changed

+36
-13
lines changed

lib/matplotlib/backends/backend_gtk3.py

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,30 @@
4747
except TypeError as exc:
4848
cursord = {} # deprecated in Matplotlib 3.5.
4949

50+
# Placeholder
51+
_application = None
52+
53+
54+
def _create_application():
55+
global _application
56+
57+
if _application is None:
58+
app = Gio.Application.get_default()
59+
if app is None:
60+
# display_is_valid returns False only if on Linux and neither X11
61+
# nor Wayland display can be opened.
62+
if not mpl._c_internal_utils.display_is_valid():
63+
raise RuntimeError('Invalid DISPLAY variable')
64+
_application = Gtk.Application.new('org.matplotlib.Matplotlib3',
65+
Gio.ApplicationFlags.NON_UNIQUE)
66+
# The activate signal must be connected, but we don't care for
67+
# handling it, since we don't do any remote processing.
68+
_application.connect('activate', lambda *args, **kwargs: None)
69+
_application.register()
70+
cbook._setup_new_guiapp()
71+
else:
72+
_application = app
73+
5074

5175
class TimerGTK3(TimerBase):
5276
"""Subclass of `.TimerBase` using GTK3 timer events."""
@@ -282,11 +306,9 @@ def idle_draw(*args):
282306

283307
def flush_events(self):
284308
# docstring inherited
285-
Gdk.threads_enter()
286-
while Gtk.events_pending():
287-
Gtk.main_iteration()
288-
Gdk.flush()
289-
Gdk.threads_leave()
309+
context = GLib.MainContext.default()
310+
while context.pending():
311+
context.iteration(True)
290312

291313

292314
class FigureManagerGTK3(FigureManagerBase):
@@ -306,7 +328,9 @@ class FigureManagerGTK3(FigureManagerBase):
306328
307329
"""
308330
def __init__(self, canvas, num):
331+
_create_application()
309332
self.window = Gtk.Window()
333+
_application.add_window(self.window)
310334
super().__init__(canvas, num)
311335

312336
self.window.set_wmclass("matplotlib", "Matplotlib")
@@ -368,10 +392,6 @@ def destroy(self, *args):
368392
if self.toolbar:
369393
self.toolbar.destroy()
370394

371-
if (Gcf.get_num_fig_managers() == 0 and not mpl.is_interactive() and
372-
Gtk.main_level() >= 1):
373-
Gtk.main_quit()
374-
375395
def show(self):
376396
# show the figure window
377397
self.window.show()
@@ -500,7 +520,8 @@ def set_cursor(self, cursor):
500520
window = self.canvas.get_property("window")
501521
if window is not None:
502522
window.set_cursor(self._mpl_to_gtk_cursor(cursor))
503-
Gtk.main_iteration()
523+
context = GLib.MainContext.default()
524+
context.iteration(True)
504525

505526
def draw_rubberband(self, event, x0, y0, x1, y1):
506527
height = self.canvas.figure.bbox.height
@@ -827,6 +848,8 @@ class _BackendGTK3(_Backend):
827848

828849
@staticmethod
829850
def mainloop():
830-
if Gtk.main_level() == 0:
831-
cbook._setup_new_guiapp()
832-
Gtk.main()
851+
global _application
852+
853+
_application.run() # Quits when all added windows close.
854+
# Running after quit is undefined, so create a new one next time.
855+
_application = None

0 commit comments

Comments
 (0)