Skip to content

fix(lightweight): persist lightweight-mode preference across sessions#2547

Open
skyswordw wants to merge 1 commit intofarion1231:mainfrom
skyswordw:fix/lightweight-mode-persistence
Open

fix(lightweight): persist lightweight-mode preference across sessions#2547
skyswordw wants to merge 1 commit intofarion1231:mainfrom
skyswordw:fix/lightweight-mode-persistence

Conversation

@skyswordw
Copy link
Copy Markdown

Summary

修复轻量模式(Lightweight Mode)的两个相关问题:

  1. 偏好不持久化 — 托盘"轻量模式"开关在每次重启后被重置为 false。从用户视角看是一个看似带 ✓ 标记的"持久开关",实际却只在当前会话生效。
  2. 临时打开窗口会清除偏好 — 托盘"打开主界面"、macOS Reopen(点 dock)、单实例唤起、deep link 等任何"重新看一眼窗口"的动作都会把偏好一起清掉,导致下次关窗口/重启不再是轻量模式。

根因:LIGHTWEIGHT_MODE 一个 AtomicBool 同时承担"运行期是否处于轻量"和"用户是否偏好轻量"两个不同的概念,且没有持久化。

What Changed

把这两个概念彻底拆开:

概念 存储 谁能改
偏好 lightweight_mode ~/.cc-switch/settings.json(设备级) 仅托盘 ✓ 轻量模式开关
运行期 LIGHTWEIGHT_RUNTIME AtomicBool(内存) 启动 / 关窗口 / 打开主界面 / Reopen / deep link

lightweight.rs 拆分为:

  • enter_lightweight_runtime / exit_lightweight_runtime:仅操作窗口与 dock
  • is_lightweight_runtime:当前运行期状态
  • set_lightweight_preference:写偏好 + 同步运行期 + 刷新菜单
  • is_lightweight_preferred:读偏好

并修正各调用点的语义:

  • 启动时若偏好=true → 进入轻量运行期(优先级高于 silent_startup
  • WindowEvent::CloseRequested:偏好=true 时关窗口直接进入轻量运行期,否则沿用 minimize_to_tray_on_close
  • 托盘"打开主界面"、macOS Reopen、单实例、deep link → 仅 exit_lightweight_runtime不动偏好
  • 托盘 ✓ checkmark 改为反映偏好(即使临时调出窗口看,✓ 仍亮着)

防御前端污染:get_settings_for_frontendlightweightMode 抹零,update_settings 保留磁盘上的真值,避免 save_settings 携带过期值时回写 false。

Tauri 命令名(enter_lightweight_mode / exit_lightweight_mode / is_lightweight_mode)保留不变以维护 IPC 稳定性,但语义改为读写偏好。

Test plan

  • cargo fmt
  • cargo check
  • cargo clippy --lib --bins
  • cargo test --lib settings::(4/4 passed)
  • 手动验证(macOS Apple Silicon):
    • 托盘 ✓ 轻量模式 → ~/.cc-switch/settings.jsonlightweightMode: true
    • 托盘"打开主界面" → 主窗口出现,但 ✓ 仍亮,lightweightMode 仍为 true
    • 关闭主窗口(X / Cmd+W)→ 销毁窗口、隐藏 dock,回到轻量运行期(不是 hide)
    • 退出应用 → 重启 → 直接进入轻量模式(无窗口、无 dock)
    • 托盘 ✓ 取消勾选 → 主窗口立即出现 + dock 图标恢复 + 文件写为 false
    • open -a cc-switch(已运行时)→ 窗口出现但偏好仍为 true,下次关窗口仍回轻量
  • 不影响:偏好=false 时所有路径行为完全不变(silent_startup / minimize_to_tray_on_close 等)

Notes

  • 无前端改动;TypeScript 类型也无需新增字段
  • 无需 migration:缺失 lightweightMode 字段的旧 settings.json 会按 #[serde(default)] 落到 false
  • 主要测试平台为 macOS Apple Silicon;Windows/Linux 路径沿用既有 set_skip_taskbar / Linux fix 逻辑

🤖 Generated with Claude Code

…om runtime state

The tray's "Lightweight Mode" checkbox previously toggled a single in-memory
AtomicBool that doubled as both runtime state (window destroyed, dock hidden)
and user preference. This caused two related bugs:

1. The preference was lost on every app restart — the menu looked persistent
   but behaved as session-only.
2. Tray "Open main window" reused exit_lightweight_mode, which cleared the
   preference along with the runtime state. macOS Reopen / single-instance /
   deep-link wake-ups did the same. Result: any wake-up implicitly opted the
   user out of lightweight mode.

Split the concept:
- AppSettings.lightweight_mode (persisted in ~/.cc-switch/settings.json) is the
  user preference; only the tray ✓ toggle writes it. get_settings_for_frontend
  masks it and update_settings preserves it so the frontend save_settings
  round-trip cannot clobber the persisted value.
- LIGHTWEIGHT_RUNTIME (AtomicBool) tracks whether the window is currently
  destroyed; only mutated by enter/exit_lightweight_runtime.
- set_lightweight_preference writes the preference and syncs runtime to match.

Behavior changes (preference=true paths):
- Startup enters lightweight runtime instead of normal window.
- Closing the main window enters lightweight runtime, taking precedence over
  minimize_to_tray_on_close.
- Tray "Open main window", macOS Reopen, single-instance wake-up, and deep
  links exit only the runtime — the preference is preserved.
- Tray ✓ checkmark now reflects the preference, not the transient runtime
  state, so the checkmark stays lit when the user temporarily opens the window.

No frontend changes; existing Tauri command names (enter_lightweight_mode /
exit_lightweight_mode / is_lightweight_mode) are kept as preference-level
wrappers for IPC stability.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Owner

@codex review
@claude review

@claude
Copy link
Copy Markdown

claude Bot commented May 3, 2026

Claude finished @farion1231's task in 3m 3s —— View job


Claude PR Review

LGTM — no blocking issues.

The split between persisted preference (AppSettings.lightweight_mode) and runtime state (LIGHTWEIGHT_RUNTIME AtomicBool) is clean and the call-site mapping in lib.rs / tray.rs correctly distinguishes "user changed the preference" (only the tray ✓) from "user temporarily wants to look at the window" (Reopen / single-instance / deep link / "Open Main Window"). A few things I checked and found OK:

  • No stale references to the renamed enter_lightweight_mode / exit_lightweight_mode / is_lightweight_mode outside commands/lightweight.rs — IPC names are intentionally preserved (PR description).
  • Tray checkmark is bound to is_lightweight_preferred() (tray.rs:572), so it correctly stays on while a temporary window is shown. Skipping refresh_tray_menu inside enter_/exit_lightweight_runtime is now semantically correct — the menu only reflects the preference.
  • Migration: #[serde(default)] covers older settings.json without the field. No SCHEMA_VERSION bump needed.
  • Frontend defense: get_settings_for_frontend zeroing lightweightMode and update_settings overriding it from the persisted value (settings.rs:521,528) keeps stale/missing frontend payloads from clobbering the tray-owned preference. Consistent with the webdav_backup pattern already in place.
  • Cross-platform: lightweight enter/exit code is unchanged structurally — same #[cfg] guards as before; PR only added the new startup-time preference branch in lib.rs. PR description correctly flags that hands-on testing was macOS only.
  • Startup ordering in lib.rs:1016 puts lightweight_mode ahead of silent_startup, matching the documented intent ("更激进").
    · branch: fix/lightweight-mode-persistence

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants