fix(native): Wave-2 audit fixes (D1, D3, D5)
- D1 (HIGH): Linux no-sleep was completely non-functional — the zbus
ScreenSaver inhibit was bound to a function-local D-Bus connection dropped on
return, so the screensaver service auto-released it instantly. Keep a
long-lived Connection in managed state (InhibitState { conn, cookie }) so the
same connection holds Inhibit and issues UnInhibit; created once, reused.
- D3: tray "Do Not Disturb" desynced from the web manualDndAtom after any reload
(custom-chrome toggle / logout) — the atom is in-memory and reset while the
tray stayed checked. Added TrayDndState + a get_tray_dnd command so the web
hook re-hydrates the atom on mount.
- D5: install_update now calls app.restart() after a successful install so the
new version actually runs (Linux AppImage kept running the old binary; the UI
hung on "installing").
CI-compile-verified (windows + linux). Web-side wiring (get_tray_dnd query,
updater terminal state) landed on cinny:lotus.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -138,6 +138,13 @@ async fn install_update(app: tauri::AppHandle) -> Result<(), String> {
|
||||
.download_and_install(|_chunk, _total| {}, || {})
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
// Only reached on a successful download+install (the `?` above bails
|
||||
// otherwise). Relaunch so the freshly installed version actually
|
||||
// runs — without this the UI hangs on "installing", and on a Linux
|
||||
// AppImage the running process is still the old binary. `restart()`
|
||||
// exits the current process and never returns, so nothing after it
|
||||
// runs for the update case.
|
||||
app.restart();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -368,6 +375,23 @@ struct TrayUnreadState {
|
||||
height: u32,
|
||||
}
|
||||
|
||||
/// Holds a clone of the tray "Do Not Disturb" `CheckMenuItem` so `get_tray_dnd`
|
||||
/// can read its live checkstate. The tray only emits `lotus-dnd-changed` on
|
||||
/// click, but the web `manualDndAtom` is in-memory and resets on every reload,
|
||||
/// so the web hook re-hydrates from this on mount. `CheckMenuItem` is a cheap
|
||||
/// clonable handle to the same underlying menu item.
|
||||
struct TrayDndState(CheckMenuItem<tauri::Wry>);
|
||||
|
||||
/// Return the tray DND toggle's current checkstate so the web side can
|
||||
/// re-hydrate `manualDndAtom` after a reload. Returns `false` when the tray
|
||||
/// wasn't created (e.g. missing bundled icon) rather than erroring the call.
|
||||
#[tauri::command]
|
||||
fn get_tray_dnd(app: tauri::AppHandle) -> bool {
|
||||
app.try_state::<TrayDndState>()
|
||||
.map(|s| s.0.is_checked().unwrap_or(false))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Paint a small white-ringed red "unread" dot into the bottom-right corner of
|
||||
/// an RGBA buffer, in place. Cross-platform (operates on raw pixels).
|
||||
fn draw_unread_dot(rgba: &mut [u8], width: u32, height: u32) {
|
||||
@@ -448,6 +472,7 @@ pub fn run() {
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
set_badge_count,
|
||||
set_tray_unread,
|
||||
get_tray_dnd,
|
||||
flash_window,
|
||||
send_notification,
|
||||
check_for_update,
|
||||
@@ -563,6 +588,10 @@ pub fn run() {
|
||||
width,
|
||||
height,
|
||||
});
|
||||
|
||||
// Keep a handle to the DND CheckMenuItem so `get_tray_dnd` can
|
||||
// report its live checkstate for web re-hydration after reload.
|
||||
app.manage(TrayDndState(dnd_item));
|
||||
} else {
|
||||
eprintln!("tray: no bundled window icon; skipping system tray setup");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user