4747except 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 ()
5276def _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
303325class 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