From 5c7881422060055680b30544e91c0176cfc3ed94 Mon Sep 17 00:00:00 2001 From: Lucas Nogueira Date: Tue, 22 Sep 2026 21:56:01 -0300 Subject: [PATCH] fix(autostart): handle disabling when the autostart is already disabled --- .changes/fix-autostart-windows-disable.md | 5 ++++ packages/api-e2e/test/specs/autostart.spec.ts | 29 ++++++++++++------- plugins/autostart/src/lib.rs | 11 ++++--- 3 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 .changes/fix-autostart-windows-disable.md diff --git a/.changes/fix-autostart-windows-disable.md b/.changes/fix-autostart-windows-disable.md new file mode 100644 index 000000000..1bae66871 --- /dev/null +++ b/.changes/fix-autostart-windows-disable.md @@ -0,0 +1,5 @@ +--- +autostart: patch +--- + +Fixed `disable()` failing on Windows when autostart is already disabled. It now succeeds, as it does on macOS and Linux. diff --git a/packages/api-e2e/test/specs/autostart.spec.ts b/packages/api-e2e/test/specs/autostart.spec.ts index 20a09a00c..b45a0af68 100644 --- a/packages/api-e2e/test/specs/autostart.spec.ts +++ b/packages/api-e2e/test/specs/autostart.spec.ts @@ -8,9 +8,6 @@ import { tauri, describePlugin } from '../helpers/index.js' // Enabling autostart registers the app with the host for real (a Launch Agent // on macOS, an XDG autostart entry on Linux, a `Run` registry value on // Windows), so the spec puts back whatever state it found. -// -// `disable` is only called while autostart is enabled: on Windows it fails -// when there is no `Run` value to delete. describePlugin('autostart', { desktopOnly: true }, () => { let initiallyEnabled = false @@ -20,10 +17,11 @@ describePlugin('autostart', { desktopOnly: true }, () => { }) after(async () => { - await tauri(async (api, enabled) => { - if ((await api.autostart.isEnabled()) === enabled) return - await (enabled ? api.autostart.enable() : api.autostart.disable()) - }, initiallyEnabled) + await tauri( + (api, enabled) => + enabled ? api.autostart.enable() : api.autostart.disable(), + initiallyEnabled + ) }) it('enable and disable toggle isEnabled', async () => { @@ -37,13 +35,24 @@ describePlugin('autostart', { desktopOnly: true }, () => { }) it('enabling twice keeps it enabled', async () => { - const states = await tauri(async (api) => { + const enabled = await tauri(async (api) => { await api.autostart.enable() await api.autostart.enable() const enabled = await api.autostart.isEnabled() await api.autostart.disable() - return { enabled, disabled: await api.autostart.isEnabled() } + return enabled }) - expect(states).toEqual({ enabled: true, disabled: false }) + expect(enabled).toBe(true) + }) + + it('disable resolves when autostart is already disabled', async () => { + // Windows used to fail here, having no `Run` registry value to delete + const disabled = await tauri(async (api) => { + await api.autostart.enable() + await api.autostart.disable() + await api.autostart.disable() + return !(await api.autostart.isEnabled()) + }) + expect(disabled).toBe(true) }) }) diff --git a/plugins/autostart/src/lib.rs b/plugins/autostart/src/lib.rs index 4ff9503d1..af9ef7564 100644 --- a/plugins/autostart/src/lib.rs +++ b/plugins/autostart/src/lib.rs @@ -83,10 +83,13 @@ impl AutoLaunchManager { /// /// Returns [`Error::Anyhow`] if the platform-specific removal fails. pub fn disable(&self) -> Result<()> { - self.0 - .disable() - .map_err(|e| e.to_string()) - .map_err(Error::Anyhow) + match self.0.disable() { + // On Windows, disabling deletes the app's `Run` registry value, which fails with + // "not found" when autostart is already disabled. macOS and Linux treat that as a + // no-op, so do the same here. + Err(auto_launch::Error::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), + result => result.map_err(|e| e.to_string()).map_err(Error::Anyhow), + } } /// Returns whether auto start is currently enabled for the application.