Repository navigation
Add "Run at startup" toggle in Settings - #16
Merged
Merged
Conversation
Add an in-app autostart toggle that works across all distribution
channels (Inno installer, portable ZIP, MSIX/Store).
New module src/autostart.rs defines an AutostartBackend trait with two
mutually-exclusive Windows backends:
- Unpackaged builds use the HKCU ...\CurrentVersion\Run registry value
"OpenWritr" (quoted current_exe, argless = silent tray start). Includes
stale-path repair on read, StartupApproved disabled-blob parsing for
OS-disabled detection, and one-time migration of the legacy
{userstartup}\OpenWritr.lnk shortcut.
- MSIX/Store builds use the WinRT StartupTask "OpenWritrStartup"
(RequestEnableAsync/Disable), mapping DisabledByUser/DisabledByPolicy
to a DisabledByOs state.
The toggle is OS state, not a Settings serde field: it writes through
immediately, is verified by read-back, never participates in persist()
or the dirty flag, and re-reads real OS state each time the window opens.
Failures surface through inline_error instead of silently no-oping.
Installer .iss files switched from the startup-folder shortcut to the
same HKCU Run value (gated on the autostart task), remove the legacy
shortcut, and always clean the value on uninstall. Diagnostics bundle
and --self-check now report the resolved backend and current state.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1bdc56e7-31d0-49bb-ab08-fc1011f46419
The [InstallDelete] entry that removes the legacy {userstartup}\OpenWritr.lnk
ran unconditionally on install, while the replacement HKCU Run value is only
written with Tasks: autostart. An existing user who deselected the autostart
task on upgrade (or any silent/default run where the task is unset) would lose
their previously active autostart silently, and the app-side migration in
autostart.rs could no longer recover it because the shortcut was already gone.
Gate the shortcut deletion on Tasks: autostart in both .iss files, so the
legacy shortcut is only removed when the Run value is actually written in its
place; otherwise it is left intact for the app-side migration to handle. Also
add an [Code] InitializeWizard that preselects the autostart task when a legacy
shortcut or Run value already exists, so upgrades default to preserving state.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1bdc56e7-31d0-49bb-ab08-fc1011f46419
The autostart task has no Flags: unchecked, so it is checked by default; the old comment's "otherwise unchecked-by-default" aside was wrong. Explain the real reason for the InitializeWizard preselect: Inno remembers the previous task selection across upgrades, so a user who once deselected the task would get it deselected again by default — the preselect restores it to checked when prior autostart state (legacy shortcut or Run value) is detected. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1bdc56e7-31d0-49bb-ab08-fc1011f46419
The [Code] block used a Pascal brace comment { ... } whose text contained the
Inno constant {userstartup}. Pascal brace comments do not nest, so the } of
{userstartup} closed the comment early (column 65) and the remainder was parsed
as code, failing both scripts with "'BEGIN' expected" (regression from 54611d1;
the earlier wording also contained {userstartup}). Switch to // line comments,
which have no such interaction with brace constants.
Verified: ISCC.exe compiles both openwritr.iss and openwritr-x64.iss with
exit 0 (they failed with exit 2 before this fix).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1bdc56e7-31d0-49bb-ab08-fc1011f46419
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #15.
Summary
Adds an in-app Run at startup toggle (Settings → Startup) that works across every distribution channel — Inno installer, portable ZIP, and MSIX/Store — replacing the old install-time-only autostart that could never be changed from inside the app.
What changed
New module
src/autostart.rs— anAutostartBackendtrait (mirroring the existingCredentialStorepattern) with two mutually-exclusive Windows backends, plusenable_verified/disable_verifiedwrite-then-read-back helpers and abackend()factory that picks packaged vs unpackaged at runtime.HKCU\…\CurrentVersion\RunvalueOpenWritr(quotedcurrent_exe, no args — an argless start is already silent tray mode). Includes:StartupApproved\Runblob (first byte ≠ 2 ⇒ disabled) → surfaced asDisabledByOs; never re-enabled on launch;{userstartup}\OpenWritr.lnkshortcut into the registry value.StartupTaskOpenWritrStartup(RequestEnableAsync/Disable), mappingDisabledByUser/DisabledByPolicytoDisabledByOswith a reason string.UI (
src/settings_ui.rs) — new "Startup" section with checkbox “Start OpenWritr automatically when I sign in to Windows” and an info button noting it starts silently in the tray. The toggle is deliberately not aSettingsserde field: it's OS state, writes through immediately, is verified by read-back, never touchespersist()/dirty/SettingsRevision, and re-reads real OS state each time the window opens (so external Task Manager / Settings → Apps → Startup changes show truthfully). WhenDisabledByOsthe checkbox is disabled with an explanation; write failures render throughinline_error(no silent no-op).Installer — both
installer/openwritr.issandinstaller/openwritr-x64.issdrop the{userstartup}shortcut and instead write the same HKCURunvalue (gated on theautostarttask), and always remove the value on uninstall even if enabled later from the app.AppxManifest.template.xmlstaysEnabled="false"(the in-app toggle callsRequestEnableAsync).Deletion of the legacy
{userstartup}\OpenWritr.lnkshortcut is coupled to theautostarttask ([InstallDelete] … Tasks: autostart): the shortcut is only removed when the replacement Run value is actually written in its place. If an existing user deselects the autostart task on upgrade (or in any silent/default run where the task is unset), the legacy shortcut is left intact so the app-side migration inautostart.rscan still pick it up — a previously active autostart is never silently dropped. AnInitializeWizard[Code]hook additionally preselects the autostart task when a legacy shortcut or an existing Run value is detected (Inno otherwise remembers a prior deselection across upgrades).Diagnostics — the diagnostics bundle (
autostart-status.json) and--self-checknow report the resolved backend and current state.Docs — README installer + portable sections updated.
Validation
cargo fmt --check— clean (exit 0).cargo clippy --all-targets— no new warnings from the changed files (pre-existing warnings only).cargo test --bins—test result: ok. 283 passed; 0 failed; 8 ignored(main bin suite), plus the other bin suites green. Includes new unit tests: enable/disable/read round-trip, stale-path repair,StartupApproveddisabled-blob parsing, legacy shortcut migration, and asettings_uitest asserting a write failure surfaces an error instead of silently flipping state.openwritr.issandopenwritr-x64.isscompile withISCC.exeat exit 0 (verified against a staged scratch tree).Note: the
.issscripts are not covered bycargo test; an ISCC compile check in CI would close that gap, but that's left as a separate follow-up (out of scope for this PR).Could NOT be verified automatically — please check manually
DisabledByOs.Runvalue and no leftover shortcut, including the enabled-later-in-app case..lnk→ registry migration and the new task-preselect / gated-deletion behaviour on a machine upgrading from a prior install.