Repro
- Enable auto-update (settings → general →
autoUpdate: true).
- Be working in another app (browser, editor, etc.) when a new version is published.
- Screenpipe silently downloads the update, fires a macOS notification, then ~30s later the Screenpipe window jumps to the foreground, interrupting whatever you were doing.
Root cause
The auto-update flow ends with an unconditional app.restart(), and the freshly-spawned process re-activates the dock icon — which on macOS pulls the window in front of whatever app the user is currently focused on.
Sequence:
- Background check finds an update and downloads it.
- Notification fires: "v{x} downloaded — restarting now" —
apps/screenpipe-app-tauri/src-tauri/src/updates.rs:498-514.
update-restarting event emitted, sleep 30s, then self.app.restart() — apps/screenpipe-app-tauri/src-tauri/src/updates.rs:516-535.
- New process boots and runs
set_activation_policy(Regular) unconditionally — apps/screenpipe-app-tauri/src-tauri/src/main.rs:1964-1965 → apps/screenpipe-app-tauri/src-tauri/src/window/panel.rs:91.
- Switching
Accessory → Regular re-registers the dock icon and Tauri re-shows the main webview, stealing focus.
There is no "is the user focused elsewhere?" check before calling app.restart(), and no set_focus() / requestUserAttention() elsewhere in the update code — the focus-steal is purely a side effect of restarting the process while the user is in another app.
Secondary bug
After the restart, the "Restart to update v{x}" banner often still shows even though the new process is already on v{x}. The useUpdateBanner zustand store appears to persist across restarts and isn't cleared after the install completes (apps/screenpipe-app-tauri/components/update-banner.tsx).
Proposed fixes
- (a) Defer
app.restart() until Screenpipe is frontmost, or until the user explicitly quits — fall back to "restart on next launch" if they never come back to the app.
- (b) Drop the blind 30s timer in favor of Tauri's "install on next launch" updater flow.
- (c) Clear the persisted update-banner state once
app.restart() is about to fire (or on setup() if package_info().version already matches the pending version).
Repro
autoUpdate: true).Root cause
The auto-update flow ends with an unconditional
app.restart(), and the freshly-spawned process re-activates the dock icon — which on macOS pulls the window in front of whatever app the user is currently focused on.Sequence:
apps/screenpipe-app-tauri/src-tauri/src/updates.rs:498-514.update-restartingevent emitted, sleep 30s, thenself.app.restart()—apps/screenpipe-app-tauri/src-tauri/src/updates.rs:516-535.set_activation_policy(Regular)unconditionally —apps/screenpipe-app-tauri/src-tauri/src/main.rs:1964-1965→apps/screenpipe-app-tauri/src-tauri/src/window/panel.rs:91.Accessory→Regularre-registers the dock icon and Tauri re-shows the main webview, stealing focus.There is no "is the user focused elsewhere?" check before calling
app.restart(), and noset_focus()/requestUserAttention()elsewhere in the update code — the focus-steal is purely a side effect of restarting the process while the user is in another app.Secondary bug
After the restart, the "Restart to update v{x}" banner often still shows even though the new process is already on v{x}. The
useUpdateBannerzustand store appears to persist across restarts and isn't cleared after the install completes (apps/screenpipe-app-tauri/components/update-banner.tsx).Proposed fixes
app.restart()until Screenpipe is frontmost, or until the user explicitly quits — fall back to "restart on next launch" if they never come back to the app.app.restart()is about to fire (or onsetup()ifpackage_info().versionalready matches the pending version).