From 1639459293d538b70aa81221956c9080cd68e8f3 Mon Sep 17 00:00:00 2001 From: jahruz67 Date: Thu, 14 May 2026 19:49:01 -0700 Subject: [PATCH] Fix debounce race and recorder callback write handling --- app.go | 12 ++++++++---- internal/audio/recorder/recorder.go | 9 ++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app.go b/app.go index 344b9fc..9dd5b95 100644 --- a/app.go +++ b/app.go @@ -149,11 +149,15 @@ var lastToggleUnixNano int64 func (a *App) ToggleRecording() { // Debounce toggle calls to prevent rapid firing from double-binds or Wayland glitches now := time.Now().UnixNano() - last := atomic.LoadInt64(&lastToggleUnixNano) - if last != 0 && time.Duration(now-last) < 500*time.Millisecond { - return + for { + last := atomic.LoadInt64(&lastToggleUnixNano) + if last != 0 && time.Duration(now-last) < 500*time.Millisecond { + return + } + if atomic.CompareAndSwapInt64(&lastToggleUnixNano, last, now) { + break + } } - atomic.StoreInt64(&lastToggleUnixNano, now) if atomic.LoadInt32(&a.recording) == 1 { a.StopRecording() diff --git a/internal/audio/recorder/recorder.go b/internal/audio/recorder/recorder.go index 9348070..35d0c67 100644 --- a/internal/audio/recorder/recorder.go +++ b/internal/audio/recorder/recorder.go @@ -254,8 +254,15 @@ func (r *AudioRecorder) Cleanup() { // onAudioData is called by miniaudio when audio data is available. func (r *AudioRecorder) onAudioData(_, inputSamples []byte, _ uint32) { + r.mu.Lock() + defer r.mu.Unlock() + if r.outputFile != nil && len(inputSamples) > 0 { - n, _ := r.outputFile.Write(inputSamples) + n, err := r.outputFile.Write(inputSamples) + if err != nil { + logger.Error("Failed to write audio data: %v", err) + return + } r.dataSize += uint32(n) // Calculate volume if callback is set