Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Comment thread
cybercop23 marked this conversation as resolved.
-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.
Expand Down
41 changes: 30 additions & 11 deletions src-ui-wx/app-shell/TabSequence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())) {
Comment thread
cybercop23 marked this conversation as resolved.
wxDateTime jsonTime = presetsFile.GetModificationTime();
wxDateTime bkpTime = presetsBkp.GetModificationTime();
if (bkpTime > jsonTime) {
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -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);
}
}
}
}
Expand Down