diff --git a/radio/src/gui/colorlcd/libui/dialog.cpp b/radio/src/gui/colorlcd/libui/dialog.cpp index 21bf778dc..8e594ad13 100644 --- a/radio/src/gui/colorlcd/libui/dialog.cpp +++ b/radio/src/gui/colorlcd/libui/dialog.cpp @@ -211,8 +211,8 @@ LabelDialog::LabelDialog(const char *label, int length, const char* title, }); new TextButton(box, rect_t{0, 0, 96, 0}, STR_SAVE, [=]() { - if (saveHandler != nullptr) saveHandler(this->label); deleteLater(); + if (saveHandler != nullptr) saveHandler(this->label); return 0; }); } diff --git a/radio/src/gui/colorlcd/radio/radio_mic_recorder.cpp b/radio/src/gui/colorlcd/radio/radio_mic_recorder.cpp index e212a88d7..6df5f23e0 100644 --- a/radio/src/gui/colorlcd/radio/radio_mic_recorder.cpp +++ b/radio/src/gui/colorlcd/radio/radio_mic_recorder.cpp @@ -396,21 +396,15 @@ RadioMicRecorder::RadioMicRecorder() : enterIdle(); } -RadioMicRecorder::~RadioMicRecorder() +void RadioMicRecorder::deleteLater() { - // An async call scheduled from the LabelDialog confirm path may still be - // pending when the page is closed (e.g. user long-presses EXIT while the - // dialog is being dismissed). Cancelling ensures the callback never fires - // on a destroyed instance. - lv_async_call_cancel(&RadioMicRecorder::asyncProcessPendingRename, this); - if (recorder.isRecording()) recorder.stop(); - if (isPlayingTake()) audioQueue.stopAll(); - pdmStop(); -} + if (!deleted()) { + if (recorder.isRecording()) recorder.stop(); + if (isPlayingTake()) audioQueue.stopAll(); + pdmStop(); -void RadioMicRecorder::asyncProcessPendingRename(void* ctx) -{ - static_cast(ctx)->processPendingRename(); + Page::deleteLater(); + } } void RadioMicRecorder::buildHeader(Window* window) @@ -643,16 +637,6 @@ void RadioMicRecorder::discardTake() if (!takeSaved && filename[0]) f_unlink(filename); } -void RadioMicRecorder::onEvent(event_t event) -{ - if (event == EVT_KEY_LONG(KEY_EXIT)) { - killEvents(event); - if (recorder.isRecording()) recorder.stop(); - if (isPlayingTake()) audioQueue.stopAll(); - onCancel(); - } -} - void RadioMicRecorder::onActionPressed() { switch (state) { @@ -758,13 +742,7 @@ void RadioMicRecorder::askSaveAs() strncpy(dir + SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); snprintf(pendingRename, sizeof(pendingRename), "%s%s.wav", dir, newName.c_str()); if (strcmp(pendingRename, filename) == 0) { takeSaved = true; refreshUI(); return; } - - // Defer the overwrite check until LabelDialog has finished closing — - // creating a modal now would leave us stacked on top of LabelDialog, - // which corrupts the lv_group chain when LabelDialog deletes itself. - // The page dtor cancels this async call if the user bails out before - // it fires (see ~RadioMicRecorder). - lv_async_call(&RadioMicRecorder::asyncProcessPendingRename, this); + processPendingRename(); }); } diff --git a/radio/src/gui/colorlcd/radio/radio_mic_recorder.h b/radio/src/gui/colorlcd/radio/radio_mic_recorder.h index d27c9ed69..bd67557ce 100644 --- a/radio/src/gui/colorlcd/radio/radio_mic_recorder.h +++ b/radio/src/gui/colorlcd/radio/radio_mic_recorder.h @@ -35,7 +35,6 @@ class RadioMicRecorder : public Page { public: RadioMicRecorder(); - ~RadioMicRecorder() override; protected: enum class State : uint8_t { IDLE, COUNTDOWN, RECORDING, REVIEW }; @@ -76,7 +75,7 @@ class RadioMicRecorder : public Page void buildHeader(Window* window); void buildBody(Window* window); void checkEvents() override; - void onEvent(event_t event) override; + void deleteLater() override; void onActionPressed(); void onPlayPressed(); @@ -100,10 +99,6 @@ class RadioMicRecorder : public Page void applyRename(); void refreshUI(); void pickNextFilename(); - - // Stable callback address so the dtor can cancel a pending lv_async call - // scheduled from the LabelDialog confirm path. - static void asyncProcessPendingRename(void* ctx); }; #endif // PDM_CLOCK