Repository navigation
feat(tray): persist module start/stop to autostart_modules - #138
Conversation
The xdg_tmp fixture only sets XDG_*_HOME, which platformdirs ignores on macOS and Windows. There, test_profile_config.py wrote its fixture files into the real ActivityWatch config dirs (aw-qt.toml, aw-server.toml, aw-server-rust/config.toml, ...), overwriting the user's config. An autouse fixture now points platformdirs' user dirs into tmp_path on every platform, laid out like the XDG dirs so existing tests are unchanged.
A module started or stopped from the tray now stays that way after a restart: the click adds the module to, or removes it from, autostart_modules in aw-qt.toml. Mirrors ActivityWatch/aw-tauri#285. - Only explicit menu clicks persist. Crash auto-restarts, the restart dialog and shutdown call Module.start/stop directly and never write. - aw-server and aw-server-rust are never written, so stopping the server from the tray can't leave the next start without one. - With --autostart-modules the run isn't using the configured list, so toggles only change what is running. - The file is re-read right before each write and edited in place with tomlkit (comments and layout kept), in the same file and section AwQtSettings reads for the profile. A file that fails to parse is left untouched and the failure logged. Writes are atomic and follow symlinks. - Enable appends, disable removes; order is kept and no duplicates are added. A section without the key (the commented-out first-run file) gets the effective default list with the change applied.
|
@greptileai review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 46e073b964
ℹ️ 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".
|
…fety - Read and write aw-qt.toml as UTF-8 with newline="" (keeps line endings); an undecodable file is logged and left untouched. - Don't persist a click on a system module that a bundled copy of the same name shadows: autostart_modules holds names, and autostart runs the bundled copy. Manager.resolve() is the shared lookup. - Catch any error from persisting so it can't escape the Qt slot. - Skip the symlink test where symlinks can't be created (Windows).
|
@greptileai review |
🤖 AI code reviewThis PR makes tray start/stop of modules persist to autostart_modules in aw-qt.toml. It adds set_module_autostart and persist_module_autostart functions in config.py, with atomic write and profile-aware location resolution. It changes Module.toggle to return the new state, adds Manager.resolve, and wires TrayIcon._on_module_clicked to persist toggles unless --autostart-modules overrides. It adds tests for config editing, persistence, profile locations, tray click behavior, and main wiring. Not safe to merge — 1 P1 openConfidence 3/5 2 findings · ❌ 1 P1 ·
|
| return get | ||
|
|
||
| for kind in ("data", "config", "cache", "log"): | ||
| monkeypatch.setattr(platformdirs, f"user_{kind}_dir", _dir(kind)) |
There was a problem hiding this comment.
❌ P1 — In tests/conftest.py, the fixture _isolated_platform_dirs monkeypatches platformdirs.user_config_dir etc. However, aw_core.dirs may have already imported and cached the original functions. The fixture patches platformdirs attributes, but aw_core.dirs might have done from platformdirs import user_config_dir at import time, so the patch won't affect the already-bound reference. This means the tests may not actually isolate the config dir, and could write to the real user config. The test suite would then be non-hermetic and could overwrite the developer's real aw-qt.toml. This is a test defect. The fix is to patch aw_core.dirs functions directly, or ensure aw_core.dirs uses the platformdirs functions at call time (which it likely does, but need to verify). (3/3 passes)
| f.write(content) | ||
| f.flush() | ||
| os.fsync(f.fileno()) | ||
| if os.path.exists(target): |
There was a problem hiding this comment.
A module started or stopped from the tray now stays that way after a restart. The click adds the module to, or removes it from,
autostart_modulesinaw-qt.toml. Until nowModule.toggle()only changed the running state, and the only way to make it stick was to hand-edit the TOML.This mirrors ActivityWatch/aw-tauri#285, so both apps behave the same in v0.14.1. A tray toggle means "on or off from now on". To stop everything for now, quit ActivityWatch. There is no pause state.
Behaviour
TrayIcon._on_module_clicked, which toggles the module and then saves the new state. Crash auto-restarts, the "Restart" button in the crash dialog, and shutdown callModule.start/stopdirectly and never write the config. A start that raises (e.g. exec failure) is not saved.aw-server/aw-server-rust. Toggling the server stays useful (restarting a crashed server, switching to an external one), so I kept those menu items and skip writing them instead of hiding them. Stopping the server from the tray therefore lasts only for this run, and the next start always has a server.autostart_modulesholds only names and autostart runs the bundled copy. A click on the bundled copy, or on a system module with no bundled twin, is saved. A click on a system copy that a bundled one shadows only changes what is running, since saving it would start the other copy next time.--autostart-modulesdisables persisting. That run isn't using the configured list, so toggles only change what is running.AwQtSettingsreads for the profile:[aw-qt]in the profile'saw-qt.toml,[aw-qt-testing]in the legacy shared-root testing layout, and[aw-qt-<profile>]in the shared root for a named profile that still uses the pre-isolation section.tomlkit, so comments and layout are kept. It is read and written as UTF-8, and line endings are kept. A file that fails to decode or parse, or whose list isn't a list of strings, is left untouched, and the failure is logged. Writes go through a temp file + rename and follow a symlinked config. Errors from saving are caught in the tray slot, because an exception escaping a PyQt6 slot aborts the app.Module.toggle()now returns whether the module is meant to be running.Manager.resolve()is the bundled-first lookup thatManager.start()already used.Test isolation fix (separate commit)
The
xdg_tmpfixture intests/test_profile_config.pyonly setsXDG_*_HOME, which platformdirs ignores on macOS and Windows. Running the suite there wrote fixture files into the real ActivityWatch config dirs, overwritingaw-qt.toml,aw-server.tomlandaw-server-rust/config*.toml. A new autouse fixture intests/conftest.pypoints platformdirs intotmp_pathon every platform. Its layout matches the XDG dirs, so existing tests are unchanged.Tests
tests/test_persist_toggles.pycovers:AwQtSettingsmain()passingpersist_toggles=Falsewith--autostart-modulesLocally (macOS, Python 3.9):
pytest tests(166 passed),make typecheckandmake testpass.Note that CI runs
make test(an import check) andmake typecheck, but notpytest, so the unit tests intests/aren't run in CI today.