perf(settings): save opacity, chat and contacts sliders on release

Six sliders (noise opacity, UI opacity, window opacity, chat font size,
chat poll rate, contacts list scale) rewrote settings.json, with its two
fsyncs, on every frame the value changed: 60-300 durable writes per
drag, at 1-4 ms each on NVMe, 3-20 ms on a Windows SSD, 20-60 ms on a
HDD and seconds while dragonxd is busy on the disk.

The value still applies live and is kept in Settings for the per-frame
readers; settings.json is written once, when the slider is released, as
the blur and font-scale sliders already did. A drag cut off before its
release (a dialog closed mid-drag) is persisted by the next save or at
exit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-09 21:09:48 -05:00
co-authored by Claude Opus 5.5
parent 8f8dc4c922
commit 72054fe17f
3 changed files with 12 additions and 6 deletions
+6 -3
View File
@@ -1115,9 +1115,10 @@ void RenderSettingsPage(App* app) {
if (ImGui::SliderFloat("##NoiseOpacity", &s_settingsState.noise_opacity, 0.0f, 1.0f, noise_fmt,
ImGuiSliderFlags_AlwaysClamp)) {
effects::ImGuiAcrylic::SetNoiseOpacity(s_settingsState.noise_opacity);
saveSettingsPageState(app->settings());
if (app->settings()) app->settings()->setNoiseOpacity(s_settingsState.noise_opacity); // live; persisted on release
}
}
if (ImGui::IsItemDeactivatedAfterEdit()) saveSettingsPageState(app->settings());
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_noise"));
ImGui::SetCursorScreenPos(ImVec2(baseX, afterRow1Y));
@@ -1131,9 +1132,10 @@ void RenderSettingsPage(App* app) {
if (ImGui::SliderFloat("##UIOpacity", &s_settingsState.ui_opacity, 0.3f, 1.0f, uiop_fmt,
ImGuiSliderFlags_AlwaysClamp)) {
effects::ImGuiAcrylic::SetUIOpacity(s_settingsState.ui_opacity);
saveSettingsPageState(app->settings());
if (app->settings()) app->settings()->setUIOpacity(s_settingsState.ui_opacity); // live; persisted on release
}
}
if (ImGui::IsItemDeactivatedAfterEdit()) saveSettingsPageState(app->settings());
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_ui_opacity"));
float afterRow2Y = ImGui::GetCursorScreenPos().y;
@@ -1146,9 +1148,10 @@ void RenderSettingsPage(App* app) {
snprintf(winop_fmt, sizeof(winop_fmt), "%.0f%%%%", s_settingsState.window_opacity * 100.0f);
if (ImGui::SliderFloat("##WindowOpacity", &s_settingsState.window_opacity, 0.3f, 1.0f, winop_fmt,
ImGuiSliderFlags_AlwaysClamp)) {
saveSettingsPageState(app->settings());
if (app->settings()) app->settings()->setWindowOpacity(s_settingsState.window_opacity); // live; persisted on release
}
}
if (ImGui::IsItemDeactivatedAfterEdit()) saveSettingsPageState(app->settings());
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_window_opacity"));
ImGui::SetCursorScreenPos(ImVec2(baseX, afterRow2Y));
+4 -2
View File
@@ -2220,8 +2220,9 @@ void RenderChatSettingsControls(App* app, float contentWidth, bool drawCards)
beginRow(TR("chat_opt_font_size"));
float v = st->getChatFontScale();
if (ImGui::SliderFloat("##chat_font", &v, 0.8f, 1.5f, "%.2fx", ImGuiSliderFlags_AlwaysClamp)) {
st->setChatFontScale(v); st->save();
st->setChatFontScale(v); // live (readers poll Settings); persisted on release
}
if (ImGui::IsItemDeactivatedAfterEdit()) st->save();
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_chat_font_size"));
}
@@ -2242,8 +2243,9 @@ void RenderChatSettingsControls(App* app, float contentWidth, bool drawCards)
beginRow(TR("chat_opt_poll"));
float v = st->getChatPollRateSec();
if (ImGui::SliderFloat("##chat_poll", &v, 0.5f, 15.0f, "%.1f s", ImGuiSliderFlags_AlwaysClamp)) {
st->setChatPollRateSec(v); st->save();
st->setChatPollRateSec(v); // live (App::update polls it); persisted on release
}
if (ImGui::IsItemDeactivatedAfterEdit()) st->save();
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_chat_poll_rate"));
}
// Chat timestamps (segmented) — overrides the app-wide clock (Settings → General) for this tab only.
+2 -1
View File
@@ -1446,8 +1446,9 @@ void RenderContactsTab(App* app)
rowStart(TR("contacts_list_scale"));
float v = st->getContactsListScale();
if (ImGui::SliderFloat("##contactsScale", &v, 0.8f, 1.5f, "%.2fx", ImGuiSliderFlags_AlwaysClamp)) {
st->setContactsListScale(v); st->save();
st->setContactsListScale(v); // live; persisted on release
}
if (ImGui::IsItemDeactivatedAfterEdit()) st->save();
}
ImGui::Dummy(ImVec2(0.0f, 8.0f * dp));
{