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
class TimerGTK3 (TimerBase ):
52
76
"""Subclass of `.TimerBase` using GTK3 timer events."""
@@ -282,11 +306,9 @@ def idle_draw(*args):
282
306
283
307
def flush_events (self ):
284
308
# 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 )
290
312
291
313
292
314
class FigureManagerGTK3 (FigureManagerBase ):
@@ -306,7 +328,9 @@ class FigureManagerGTK3(FigureManagerBase):
306
328
307
329
"""
308
330
def __init__ (self , canvas , num ):
331
+ _create_application ()
309
332
self .window = Gtk .Window ()
333
+ _application .add_window (self .window )
310
334
super ().__init__ (canvas , num )
311
335
312
336
self .window .set_wmclass ("matplotlib" , "Matplotlib" )
@@ -368,10 +392,6 @@ def destroy(self, *args):
368
392
if self .toolbar :
369
393
self .toolbar .destroy ()
370
394
371
- if (Gcf .get_num_fig_managers () == 0 and not mpl .is_interactive () and
372
- Gtk .main_level () >= 1 ):
373
- Gtk .main_quit ()
374
-
375
395
def show (self ):
376
396
# show the figure window
377
397
self .window .show ()
@@ -500,7 +520,8 @@ def set_cursor(self, cursor):
500
520
window = self .canvas .get_property ("window" )
501
521
if window is not None :
502
522
window .set_cursor (self ._mpl_to_gtk_cursor (cursor ))
503
- Gtk .main_iteration ()
523
+ context = GLib .MainContext .default ()
524
+ context .iteration (True )
504
525
505
526
def draw_rubberband (self , event , x0 , y0 , x1 , y1 ):
506
527
height = self .canvas .figure .bbox .height
@@ -827,6 +848,8 @@ class _BackendGTK3(_Backend):
827
848
828
849
@staticmethod
829
850
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