diff --git a/app/electron/menubar.test.ts b/app/electron/menubar.test.ts index 1a85fbe1..d676873f 100644 --- a/app/electron/menubar.test.ts +++ b/app/electron/menubar.test.ts @@ -398,6 +398,25 @@ describe('MenubarCompanion', () => { expect(JSON.parse(readFileSync(dockPrefsPath(home), 'utf8'))).toEqual({ enabled: true, scale: 1.2 }) }) + it('seeds launch at login again after this app reinstalls the tray', async () => { + stageMsi() + await new MenubarCompanion(deps()).bootstrap() + expect(regCalls).toEqual([runKeyArgs(true, TRAY_EXE)]) + + // The tray app went away with an uninstall that took its Run value along; the exe is + // back only once the CLI has installed it again. Seeded once is no reason to leave a + // freshly placed tray app without launch at login. + regCalls = [] + present.delete(TRAY_EXE) + installResult = result({ action: 'installed' }) + await new MenubarCompanion(deps({ + exists: (path: string) => (path === TRAY_EXE ? cliCalls.length > 1 : present.has(path)), + })).bootstrap() + + expect(cliCalls).toHaveLength(2) + expect(regCalls).toEqual([runKeyArgs(true, TRAY_EXE)]) + }) + it('leaves an existing launch-at-login value alone', async () => { stageMsi() existingRunKey = `"${TRAY_EXE}"` diff --git a/app/electron/menubar.ts b/app/electron/menubar.ts index 14d1b28e..aee81259 100644 --- a/app/electron/menubar.ts +++ b/app/electron/menubar.ts @@ -581,20 +581,27 @@ export class MenubarCompanion { this.save({ trayExePath: exePath }) if (firstRun && existingDock === undefined && this.settings.sidebar) this.applyDockSetting(true) - await this.reconcileRunKey(firstRun) + // A tray app this launch just put on the machine has no Run value yet: the previous + // one's uninstall took it, and that was the installer's doing, not the person's choice. + await this.reconcileRunKey(firstRun || this.placedTray) + this.placedTray = false this.launch(exePath, ['--reload-settings'], this.launchEnv()) } + /** True between an install that placed a tray app and the seeding that follows it. */ + private placedTray = false + /** * Launch at login, without overriding a choice. An existing Run value was written by the * tray app's own toggle or by an earlier launch of this one, so it is left alone; only a - * first run seeds one. The exception is a value pointing at a file that is not there, which - * is not a preference but the old wrong path, and would fail silently at every login. + * first run, or a tray app freshly installed by this launch, seeds one. The exception is a + * value pointing at a file that is not there, which is not a preference but the old wrong + * path, and would fail silently at every login. */ - private async reconcileRunKey(firstRun: boolean): Promise { + private async reconcileRunKey(seed: boolean): Promise { const existing = await this.existingRunKey() if (existing === null) { - if (firstRun) await this.setRunKey(true) + if (seed) await this.setRunKey(true) return } if (!this.exists(runKeyTarget(existing))) await this.setRunKey(true) @@ -674,6 +681,7 @@ export class MenubarCompanion { return null } const exePath = parsed.exePath || this.settings.trayExePath + this.placedTray = parsed.action === 'installed' this.save({ installDeclinedVersion: null, // What is actually on disk now, which is the staged version except under