feat(autostart): start minimized to the tray on login (#3)
Build Lotus Chat Desktop / prepare (push) Successful in 7s
Build Lotus Chat Desktop / build-windows (push) Successful in 34m32s
Build Lotus Chat Desktop / build-linux (push) Successful in 36m5s
Build Lotus Chat Desktop / build-arch (push) Successful in 19s
Build Lotus Chat Desktop / update-manifest (push) Successful in 4s
Build Lotus Chat Desktop / prepare (push) Successful in 7s
Build Lotus Chat Desktop / build-windows (push) Successful in 34m32s
Build Lotus Chat Desktop / build-linux (push) Successful in 36m5s
Build Lotus Chat Desktop / build-arch (push) Successful in 19s
Build Lotus Chat Desktop / update-manifest (push) Successful in 4s
- Launch-on-login now starts the app with `--autostart`. With "Start minimized" on (the default), that launch begins "settled", so neither the page-load reveal nor the 8 s failsafe shows the window: it stays in the tray with sync and notifications running. The tray, a second launch or a deep link reveals it. - The choice is a file in the app config dir (`start-minimized`), read before the web client loads; `get_start_minimized` / `set_start_minimized` back the new Settings switch. - Existing registrations made without args are rewritten at startup (re-enable), so current launch-on-login users get `--autostart` too. - window-state no longer restores VISIBLE: it show()ed the window at creation whenever it was last closed visible (or on first run), before the page painted and even on a login start. Visibility is owned by the page-load reveal + failsafe. Verified on Linux under Xvfb with the debug build: normal launch → shown; --autostart → hidden (past the failsafe) and still running; --autostart with the setting off → shown; --autostart after quitting visible → hidden; normal launch after quitting visible → shown; a second launch reveals the hidden instance; an existing autostart entry gets `--autostart` added. Bump cinny (the Settings switch and the SW protocol guard). Closes #3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9e320fa326
commit
67253d02f8
+68
-4
@@ -582,6 +582,42 @@ fn get_tray_dnd(app: tauri::AppHandle) -> bool {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// cinny-desktop #3: launch-on-login starts the app with this arg, so a login
|
||||
/// start can stay in the tray instead of opening the window.
|
||||
const AUTOSTART_ARG: &str = "--autostart";
|
||||
|
||||
/// Where the "start minimized when launched at login" choice lives. A plain file
|
||||
/// in the app config dir, because it is needed natively before the web client
|
||||
/// (and its settings) has loaded.
|
||||
fn start_minimized_file(app: &tauri::AppHandle) -> Option<std::path::PathBuf> {
|
||||
app.path()
|
||||
.app_config_dir()
|
||||
.ok()
|
||||
.map(|dir| dir.join("start-minimized"))
|
||||
}
|
||||
|
||||
/// The saved choice; defaults to on (a login start lands in the tray).
|
||||
fn read_start_minimized(app: &tauri::AppHandle) -> bool {
|
||||
start_minimized_file(app)
|
||||
.and_then(|path| std::fs::read_to_string(path).ok())
|
||||
.map(|value| value.trim() != "0")
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn get_start_minimized(app: tauri::AppHandle) -> bool {
|
||||
read_start_minimized(&app)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn set_start_minimized(app: tauri::AppHandle, value: bool) -> Result<(), String> {
|
||||
let path = start_minimized_file(&app).ok_or("no app config dir")?;
|
||||
if let Some(dir) = path.parent() {
|
||||
std::fs::create_dir_all(dir).map_err(|e| e.to_string())?;
|
||||
}
|
||||
std::fs::write(path, if value { "1" } else { "0" }).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Paint a small white-ringed dot of `color` into the bottom-right (or, with
|
||||
/// `left`, bottom-left) corner of an RGBA buffer, in place. Cross-platform
|
||||
/// (operates on raw pixels).
|
||||
@@ -779,6 +815,8 @@ pub fn run() {
|
||||
set_tray_update_ready,
|
||||
set_tray_call_state,
|
||||
set_taskbar_progress,
|
||||
get_start_minimized,
|
||||
set_start_minimized,
|
||||
flash_window,
|
||||
focus_main_window,
|
||||
send_notification,
|
||||
@@ -805,10 +843,16 @@ pub fn run() {
|
||||
// decorated=false at startup would re-create the frameless window
|
||||
// BEFORE lib.rs applies Mica (a broken combination) and before the web
|
||||
// side has pushed the user's current setting.
|
||||
// VISIBLE is excluded too: the plugin `show()`s the window as soon as
|
||||
// it is created whenever the saved state was visible (or nothing was
|
||||
// saved yet) — before the page paints, and even on a launch-on-login
|
||||
// start that should stay in the tray (cinny-desktop #3). Visibility is
|
||||
// owned by the page-load reveal + failsafe in `setup`.
|
||||
tauri_plugin_window_state::Builder::default()
|
||||
.with_state_flags(
|
||||
tauri_plugin_window_state::StateFlags::all()
|
||||
& !tauri_plugin_window_state::StateFlags::DECORATIONS,
|
||||
& !tauri_plugin_window_state::StateFlags::DECORATIONS
|
||||
& !tauri_plugin_window_state::StateFlags::VISIBLE,
|
||||
)
|
||||
.build(),
|
||||
)
|
||||
@@ -822,10 +866,11 @@ pub fn run() {
|
||||
// P6-1 launch-on-login. The web side drives it via the plugin's own
|
||||
// `plugin:autostart|enable`/`disable`/`is-enabled` commands (no wrapper
|
||||
// command). The MacosLauncher arg is mandatory by the plugin API even
|
||||
// though macOS is out of scope; `None` = no extra launch args.
|
||||
// though macOS is out of scope. `--autostart` marks a login start
|
||||
// (cinny-desktop #3).
|
||||
builder = builder.plugin(tauri_plugin_autostart::init(
|
||||
tauri_plugin_autostart::MacosLauncher::LaunchAgent,
|
||||
None,
|
||||
Some(vec![AUTOSTART_ARG]),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -938,7 +983,15 @@ pub fn run() {
|
||||
// set true by the on_page_load reveal (window shown) and by the
|
||||
// close-to-tray handler (window intentionally hidden). The 8s failsafe
|
||||
// below only reveals the window if neither of those has happened.
|
||||
let window_settled = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
|
||||
//
|
||||
// cinny-desktop #3: a launch-on-login start with "start minimized" on
|
||||
// begins settled, so neither the reveal nor the failsafe shows the
|
||||
// window — it stays in the tray (sync + notifications running) until
|
||||
// the tray icon, a second launch or a deep link reveals it.
|
||||
let hide_on_launch = std::env::args().any(|arg| arg == AUTOSTART_ARG)
|
||||
&& read_start_minimized(app.handle());
|
||||
let window_settled =
|
||||
std::sync::Arc::new(std::sync::atomic::AtomicBool::new(hide_on_launch));
|
||||
let settled_page_load = window_settled.clone();
|
||||
let window = WebviewWindowBuilder::new(app, "main".to_string(), window_url)
|
||||
.title("Lotus Chat")
|
||||
@@ -1013,6 +1066,17 @@ pub fn run() {
|
||||
}
|
||||
});
|
||||
|
||||
// Registrations made before the `--autostart` arg existed have no
|
||||
// args; re-enabling rewrites the OS entry with the current ones.
|
||||
#[cfg(desktop)]
|
||||
{
|
||||
use tauri_plugin_autostart::ManagerExt;
|
||||
let autolaunch = app.autolaunch();
|
||||
if autolaunch.is_enabled().unwrap_or(false) {
|
||||
let _ = autolaunch.enable();
|
||||
}
|
||||
}
|
||||
|
||||
// Deep links (matrix:): route both the cold-start case and the
|
||||
// already-running case (forwarded via single-instance argv) into the
|
||||
// web client.
|
||||
|
||||
Reference in New Issue
Block a user