@@ -127,6 +127,7 @@ def __init__(self, root: tk.Tk):
127127 self .creator_segments : list [AudioSegment ] = [AudioSegment .empty ()] * 9
128128 self .version_str_var = tk .StringVar (value = "" )
129129 self .quality_var = tk .StringVar (value = next (iter (ENCODING_PRESETS )))
130+ self .thread_lock : threading .Lock = threading .Lock ()
130131
131132 self ._build_toolbar ()
132133 self ._build_tabs ()
@@ -370,6 +371,13 @@ def _populate_segments(self):
370371 row_widgets .extract_raw_btn ["command" ] = lambda s = seg , i = idx : (
371372 self ._extract_seg_raw (i , s )
372373 )
374+
375+ actions_state = tk .NORMAL if not self .thread_lock .locked () else tk .DISABLED
376+
377+ row_widgets .play_btn ["state" ] = actions_state
378+ row_widgets .extract_wav_btn ["state" ] = actions_state
379+ row_widgets .extract_raw_btn ["state" ] = actions_state
380+
373381 row_widgets .grid (row = idx + 1 )
374382
375383 def _populate_creator (self ):
@@ -410,22 +418,15 @@ def _populate_creator(self):
410418 row_widgets .inject_raw_btn ["command" ] = lambda i = idx : self ._inject_seg_raw (
411419 i
412420 )
413- if decoder_available :
414- row_widgets .stub_btn ["state" ] = tk .NORMAL
415- row_widgets .inject_wav_btn ["state" ] = tk .NORMAL
416- row_widgets .inject_raw_btn ["state" ] = tk .NORMAL
417- if len (seg .data ):
418- row_widgets .play_btn ["state" ] = tk .NORMAL
419- self .quality_combo ["state" ] = tk .NORMAL
420- self .fw_version_entry ["state" ] = tk .NORMAL
421- else :
422- row_widgets .stub_btn ["state" ] = tk .DISABLED
423- row_widgets .inject_wav_btn ["state" ] = tk .DISABLED
424- row_widgets .inject_raw_btn ["state" ] = tk .DISABLED
425- row_widgets .play_btn ["state" ] = tk .DISABLED
426- self .quality_combo ["state" ] = tk .DISABLED
427- self .version_str_var .set ("Loaded base firmware required to use creator-tab" )
428- self .fw_version_entry ["state" ] = tk .DISABLED
421+ actions_state = tk .NORMAL if decoder_available and not self .thread_lock .locked () else tk .DISABLED
422+
423+ row_widgets .stub_btn ["state" ] = actions_state
424+ row_widgets .inject_wav_btn ["state" ] = actions_state
425+ row_widgets .inject_raw_btn ["state" ] = actions_state
426+ row_widgets .play_btn ["state" ] = actions_state
427+ self .quality_combo ["state" ] = actions_state
428+ self .fw_version_entry ["state" ] = actions_state
429+ self .save_btn ["state" ] = actions_state
429430
430431 row_widgets .grid (row = idx + 1 )
431432 self ._update_space_indicator ()
@@ -605,7 +606,13 @@ def _run_in_thread(self, fn, *args):
605606 """Run fn(*args) on a background thread; keeps GUI responsive."""
606607
607608 def wrapper ():
608- fn (* args )
609+ with self .thread_lock :
610+ self ._populate_segments ()
611+ self ._populate_creator ()
612+ fn (* args )
613+ # Calling the update method outside of lock context
614+ self ._populate_segments ()
615+ self ._populate_creator ()
609616
610617 threading .Thread (target = wrapper , daemon = True ).start ()
611618
0 commit comments