47
47
except TypeError as exc :
48
48
cursord = {} # deprecated in Matplotlib 3.5.
49
49
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
+
50
74
51
75
@functools .lru_cache ()
52
76
def _mpl_to_gtk_cursor (mpl_cursor ):
@@ -293,11 +317,9 @@ def idle_draw(*args):
293
317
294
318
def flush_events (self ):
295
319
# 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 )
301
323
302
324
303
325
class FigureManagerGTK3 (FigureManagerBase ):
@@ -317,7 +339,9 @@ class FigureManagerGTK3(FigureManagerBase):
317
339
318
340
"""
319
341
def __init__ (self , canvas , num ):
342
+ _create_application ()
320
343
self .window = Gtk .Window ()
344
+ _application .add_window (self .window )
321
345
super ().__init__ (canvas , num )
322
346
323
347
self .window .set_wmclass ("matplotlib" , "Matplotlib" )
@@ -379,10 +403,6 @@ def destroy(self, *args):
379
403
if self .toolbar :
380
404
self .toolbar .destroy ()
381
405
382
- if (Gcf .get_num_fig_managers () == 0 and not mpl .is_interactive () and
383
- Gtk .main_level () >= 1 ):
384
- Gtk .main_quit ()
385
-
386
406
def show (self ):
387
407
# show the figure window
388
408
self .window .show ()
@@ -499,7 +519,8 @@ def set_cursor(self, cursor):
499
519
window = self .canvas .get_property ("window" )
500
520
if window is not None :
501
521
window .set_cursor (_mpl_to_gtk_cursor (cursor ))
502
- Gtk .main_iteration ()
522
+ context = GLib .MainContext .default ()
523
+ context .iteration (True )
503
524
504
525
def draw_rubberband (self , event , x0 , y0 , x1 , y1 ):
505
526
height = self .canvas .figure .bbox .height
@@ -826,6 +847,10 @@ class _BackendGTK3(_Backend):
826
847
827
848
@staticmethod
828
849
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