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

Skip to content

Commit 70059ae

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 0520d99 commit 70059ae

File tree

1 file changed

+38
-13
lines changed

1 file changed

+38
-13
lines changed

lib/matplotlib/backends/backend_gtk3.py

Lines changed: 38 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
@functools.lru_cache()
5276
def _mpl_to_gtk_cursor(mpl_cursor):
@@ -293,11 +317,9 @@ def idle_draw(*args):
293317

294318
def flush_events(self):
295319
# docstring inherited
296-
Gdk.threads_enter()
297-
while Gtk.events_pending():
298-
Gtk.main_iteration()
299-
Gdk.flush()
300-
Gdk.threads_leave()
320+
context = GLib.MainContext.default()
321+
while context.pending():
322+
context.iteration(True)
301323

302324

303325
class FigureManagerGTK3(FigureManagerBase):
@@ -317,7 +339,9 @@ class FigureManagerGTK3(FigureManagerBase):
317339
318340
"""
319341
def __init__(self, canvas, num):
342+
_create_application()
320343
self.window = Gtk.Window()
344+
_application.add_window(self.window)
321345
super().__init__(canvas, num)
322346

323347
self.window.set_wmclass("matplotlib", "Matplotlib")
@@ -379,10 +403,6 @@ def destroy(self, *args):
379403
if self.toolbar:
380404
self.toolbar.destroy()
381405

382-
if (Gcf.get_num_fig_managers() == 0 and not mpl.is_interactive() and
383-
Gtk.main_level() >= 1):
384-
Gtk.main_quit()
385-
386406
def show(self):
387407
# show the figure window
388408
self.window.show()
@@ -499,7 +519,8 @@ def set_cursor(self, cursor):
499519
window = self.canvas.get_property("window")
500520
if window is not None:
501521
window.set_cursor(_mpl_to_gtk_cursor(cursor))
502-
Gtk.main_iteration()
522+
context = GLib.MainContext.default()
523+
context.iteration(True)
503524

504525
def draw_rubberband(self, event, x0, y0, x1, y1):
505526
height = self.canvas.figure.bbox.height
@@ -826,6 +847,10 @@ class _BackendGTK3(_Backend):
826847

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

0 commit comments

Comments
 (0)