diff --git a/README.txt b/README.txt index 3914782f84..b3163f45fc 100644 --- a/README.txt +++ b/README.txt @@ -11,6 +11,8 @@ Issue Tracker is found here: www.github.com/xLightsSequencer/xLights/issues XLIGHTS/NUTCRACKER RELEASE NOTES --------------------------------- 2026.12 June ??, 2026 + -bug (cybercop23) Don't create or save the effect presets JSON file when there are no presets and skip the "newer + backup" prompt if the backup file is empty. -enh (scott) Update dialog can download the new release installer from GitHub and run it (instead of opening a browser) -enh (scott) Show the active OpenGL backend (ANGLE vs native) in the About dialog and startup log -enh (cybercop23) Sequencer timeline fits the full sequence to the viewport width on load, keep same width for 20/40 fps. diff --git a/src-ui-wx/app-shell/TabSequence.cpp b/src-ui-wx/app-shell/TabSequence.cpp index e25148f350..b2c6843b00 100644 --- a/src-ui-wx/app-shell/TabSequence.cpp +++ b/src-ui-wx/app-shell/TabSequence.cpp @@ -318,7 +318,13 @@ void xLightsFrame::LoadEffectsFile() wxFileName presetsBkp(presetsFile); presetsBkp.SetFullName(_(XLIGHTS_PRESETS_FILE_BACKUP)); if (!_renderMode && !_checkSequenceMode && FileExists(presetsBkp.GetFullPath())) { - if (FileExists(presetsFile.GetFullPath())) { + // Discard empty backup files — nothing worth recovering + EffectPresetManager bkpCheck; + bool bkpEmpty = bkpCheck.LoadJsonFile(presetsBkp.GetFullPath().ToStdString()) && + bkpCheck.GetRoot().GetChildren().empty(); + if (bkpEmpty) { + wxRemoveFile(presetsBkp.GetFullPath()); + } else if (FileExists(presetsFile.GetFullPath())) { wxDateTime jsonTime = presetsFile.GetModificationTime(); wxDateTime bkpTime = presetsBkp.GetModificationTime(); if (bkpTime > jsonTime) { @@ -349,7 +355,9 @@ void xLightsFrame::LoadEffectsFile() // Migrate from XML effects node _effectPresetManager.Load(effectsNode); spdlog::info("Migrated effect presets from xlights_rgbeffects.xml to JSON"); - UnsavedRgbEffectsChanges = true; // trigger save to create the new JSON file + if (!_effectPresetManager.GetRoot().GetChildren().empty()) { + UnsavedRgbEffectsChanges = true; // trigger save to create the new JSON file + } } } if (_effectPresetManager.GetVersion().empty()) { @@ -872,19 +880,30 @@ bool xLightsFrame::SaveEffectsFile(bool backup) // Save effect presets to separate JSON file { - wxFileName presetsFile; - presetsFile.AssignDir(CurrentDir); + wxFileName presetsBkp; + presetsBkp.AssignDir(CurrentDir); + presetsBkp.SetFullName(_(XLIGHTS_PRESETS_FILE_BACKUP)); + if (backup) { - presetsFile.SetFullName(_(XLIGHTS_PRESETS_FILE_BACKUP)); + // Don't write an empty autosave backup — nothing to protect + if (!_effectPresetManager.GetRoot().GetChildren().empty()) { + if (!_effectPresetManager.SaveJsonFile(presetsBkp.GetFullPath().ToStdString())) { + spdlog::warn("Unable to save backup of effect presets file"); + } + } } else { + wxFileName presetsFile; + presetsFile.AssignDir(CurrentDir); presetsFile.SetFullName(_(XLIGHTS_PRESETS_FILE)); - } - - if (!_effectPresetManager.SaveJsonFile(presetsFile.GetFullPath().ToStdString())) { - if (backup) { - spdlog::warn("Unable to save backup of effect presets file"); + if (_effectPresetManager.GetRoot().GetChildren().empty()) { + // No presets — delete any existing file rather than writing an empty one + if (FileExists(presetsFile.GetFullPath())) { + wxRemoveFile(presetsFile.GetFullPath()); + } } else { - DisplayError("Unable to save effect presets file", this); + if (!_effectPresetManager.SaveJsonFile(presetsFile.GetFullPath().ToStdString())) { + DisplayError("Unable to save effect presets file", this); + } } } }