From 965b558567e889f581eb76bc96442fe8057fd8e4 Mon Sep 17 00:00:00 2001 From: TuringLambdaAI Date: Tue, 20 Oct 2026 20:23:53 +0800 Subject: [PATCH 1/2] fix(windows): do not revert newer UI preferences on stale save replies --- windows/MainWindow.xaml.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/windows/MainWindow.xaml.cpp b/windows/MainWindow.xaml.cpp index 1c6d708..6aebbd1 100644 --- a/windows/MainWindow.xaml.cpp +++ b/windows/MainWindow.xaml.cpp @@ -1936,12 +1936,13 @@ winrt::fire_and_forget MainWindow::SaveSettingAsync(std::string const& key, key, value, [dispatcher, weak](rivet_app::Result result) { try { - auto const settings = result.get(); - dispatcher.TryEnqueue([weak, settings] { - if (auto window = weak.get()) { - window->settings_ = settings; - } - }); + // SaveSettingAsync is a persistence acknowledgement, not a fresh + // snapshot of the UI's current intent. Each caller already + // updates its own language/theme/selected-list state before the + // RPC, and another setting may change while this call is running. + // Applying the whole returned struct here can roll those newer + // values back when callbacks arrive out of order. + (void)result.get(); } catch (std::exception const& e) { auto message = std::string(e.what()); dispatcher.TryEnqueue([weak, message = std::move(message)] { From 8f501d31926abe93d06151df559eebc9fdcc8f49 Mon Sep 17 00:00:00 2001 From: TuringLambdaAI Date: Tue, 20 Oct 2026 20:24:16 +0800 Subject: [PATCH 2/2] docs: prohibit stale settings-save callbacks from reverting current UI state --- shared/spec/PRODUCT-SPEC.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/shared/spec/PRODUCT-SPEC.md b/shared/spec/PRODUCT-SPEC.md index 1cec5fa..5fe8bc6 100644 --- a/shared/spec/PRODUCT-SPEC.md +++ b/shared/spec/PRODUCT-SPEC.md @@ -149,8 +149,14 @@ pickers. Save (blank text silently ignored), Delete (confirm first), Cancel (light) / 深色 (dark), persisted in config `theme`; follow-system tracks OS personalization live. Windows reads the persisted language and theme before first window activation (no temporary English/light frame); the - backend settings RPC remains authoritative once connected. macOS follows the system appearance at launch - and live; its Settings toggle is a per-session override. Plus 检查更新… / + backend settings RPC remains authoritative once connected. macOS follows + the system appearance at launch and live; its Settings toggle is a + per-session override. Async persistence + acknowledgements must **not** overwrite local settings changed since the + request began (including `last-selected-list-id`, theme and language). + The locally selected list remains authoritative through overlapping + preferences saves; the backend result confirms persistence or an error. + Plus 检查更新… / Check for Updates… (manual online-update check; auto-check runs at launch and every 4 h — contract: `UPDATE.md`). - Help: About — `Taskly v` + `© 2026 Taskly Team` +