@@ -41,6 +41,9 @@ def __init__(self, args: Namespace) -> None:
4141 self .dbus_control : MiniEqDbusControl | None = None
4242 self .signal_source_ids : list [int ] = []
4343 self .window_present_source_id = 0
44+ self .window_starting = False
45+ self .window_start_hold = False
46+ self .pending_present_when_ready = False
4447 self .background_mode = load_background_mode () or bool (getattr (args , "background" , False ))
4548 self .start_at_login = load_start_at_login ()
4649 self .start_active_at_login = load_start_active_at_login () and self .start_at_login
@@ -94,13 +97,15 @@ def ensure_window(self, *, present: bool) -> None:
9497 self .window .schedule_startup_ready ()
9598 return
9699
100+ if self .window_starting :
101+ self .pending_present_when_ready = self .pending_present_when_ready or present
102+ return
103+
97104 controller : SystemWideEqController | None = None
98105 initial_curve_label : str | None = None
99106
100107 try :
101108 controller = SystemWideEqController (self .args .output_sink )
102- controller .start ()
103-
104109 if self .args .import_apo :
105110 controller .import_apo_preset (self .args .import_apo )
106111 initial_curve_label = imported_apo_curve_label (self .args .import_apo )
@@ -110,14 +115,52 @@ def ensure_window(self, *, present: bool) -> None:
110115 raise SystemExit (str (exc )) from exc
111116
112117 self .controller = controller
113- self .window = MiniEqWindow (self , self .controller , self .args .auto_route , initial_curve_label = initial_curve_label )
114- self .window .set_icon_name (APP_ICON_NAME )
115- self .window .present_when_ready = present
116- self .window .set_visible (False )
117- self .window .schedule_startup_ready ()
118- if not present :
119- self .update_background_status ()
120- self .emit_control_state_changed ()
118+ self .window_starting = True
119+ self .window_start_hold = True
120+ self .pending_present_when_ready = present
121+ self .hold ()
122+
123+ def release_start_hold () -> None :
124+ if not self .window_start_hold :
125+ return
126+
127+ self .window_start_hold = False
128+ self .release ()
129+
130+ def on_ready () -> None :
131+ if self .controller is not controller :
132+ return
133+
134+ try :
135+ self .window_starting = False
136+ present_when_ready = self .pending_present_when_ready
137+ self .pending_present_when_ready = False
138+ self .window = MiniEqWindow (
139+ self , self .controller , self .args .auto_route , initial_curve_label = initial_curve_label
140+ )
141+ self .window .set_icon_name (APP_ICON_NAME )
142+ self .window .present_when_ready = present_when_ready
143+ self .window .set_visible (False )
144+ self .window .schedule_startup_ready ()
145+ if not present_when_ready :
146+ self .update_background_status ()
147+ self .emit_control_state_changed ()
148+ finally :
149+ release_start_hold ()
150+
151+ def on_error (exc : Exception ) -> None :
152+ self .window_starting = False
153+ self .pending_present_when_ready = False
154+ try :
155+ controller .shutdown ()
156+ finally :
157+ if self .controller is controller :
158+ self .controller = None
159+ print (str (exc ), file = sys .stderr )
160+ release_start_hold ()
161+ self .quit ()
162+
163+ controller .start (on_ready = on_ready , on_error = on_error )
121164
122165 def present_main_window (self ) -> None :
123166 self .ensure_window (present = True )
@@ -220,34 +263,50 @@ def run_headless(args: Namespace) -> int:
220263 duration_ms = 0
221264
222265 controller : SystemWideEqController | None = None
266+ exit_code = 0
267+ loop = GLib .MainLoop ()
268+ signal_source_ids = install_unix_signal_handlers (loop .quit )
223269
224270 try :
225271 controller = SystemWideEqController (args .output_sink )
226- controller .start ()
227272
228273 if args .import_apo :
229274 controller .import_apo_preset (args .import_apo )
230275
231- if args .auto_route :
232- controller .route_system_audio (True )
233-
234- loop = GLib .MainLoop ()
235- signal_source_ids = install_unix_signal_handlers (loop .quit )
236-
237276 if duration_ms > 0 :
238277 GLib .timeout_add (duration_ms , lambda : (loop .quit (), False )[1 ])
239278
279+ def on_ready () -> None :
280+ nonlocal exit_code
281+
282+ try :
283+ if args .auto_route :
284+ controller .route_system_audio (True )
285+ except Exception as exc :
286+ exit_code = 1
287+ print (str (exc ), file = sys .stderr )
288+ loop .quit ()
289+
290+ def on_error (exc : Exception ) -> None :
291+ nonlocal exit_code
292+
293+ exit_code = 1
294+ print (str (exc ), file = sys .stderr )
295+ loop .quit ()
296+
297+ controller .start (on_ready = on_ready , on_error = on_error )
298+
240299 try :
241- loop .run ()
300+ if exit_code == 0 :
301+ loop .run ()
242302 except KeyboardInterrupt :
243303 pass
244- finally :
245- signal_source_ids .clear ()
246304 finally :
305+ signal_source_ids .clear ()
247306 if controller is not None :
248307 controller .shutdown ()
249308
250- return 0
309+ return exit_code
251310
252311
253312def install_unix_signal_handlers (callback ) -> list [int ]:
0 commit comments