diff --git a/CHANGELOG.md b/CHANGELOG.md index 10b5637..d430318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ The release workflow publishes the section that matches the tag as the GitHub release notes, so each version gets a heading of the form `## X.Y.Z (date)`. +## 4.1.1 (2026-10-02) + +- Setting up a Windows PC that an earlier version had set up (when the + app was called BroLink) now registers the `LatchStream` service. Setup + moved the engine's folder and removed the old service, but treated the + running engine as needing nothing more, so the new service was never + registered and the engine ran only once someone had signed in. + ## 4.1.0 (2026-10-02) - **BroLink is now Latch, by Bardbro.** The app, the repository diff --git a/Cargo.lock b/Cargo.lock index 195261e..a5c05c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2114,7 +2114,7 @@ dependencies = [ [[package]] name = "latch-client" -version = "4.1.0" +version = "4.1.1" dependencies = [ "anyhow", "eframe", @@ -2137,7 +2137,7 @@ dependencies = [ [[package]] name = "latch-core" -version = "4.1.0" +version = "4.1.1" dependencies = [ "anyhow", "directories", @@ -2155,7 +2155,7 @@ dependencies = [ [[package]] name = "latch-host" -version = "4.1.0" +version = "4.1.1" dependencies = [ "anyhow", "arboard", @@ -2180,7 +2180,7 @@ dependencies = [ [[package]] name = "latch-stream" -version = "4.1.0" +version = "4.1.1" dependencies = [ "aes", "aes-gcm", @@ -2203,7 +2203,7 @@ dependencies = [ [[package]] name = "latch-ui" -version = "4.1.0" +version = "4.1.1" dependencies = [ "egui", "latch-core", diff --git a/Cargo.toml b/Cargo.toml index d37bdff..ddee38c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = [ ] [workspace.package] -version = "4.1.0" +version = "4.1.1" edition = "2021" license = "GPL-3.0-or-later" authors = ["Latch Contributors"] diff --git a/crates/client/src/stream.rs b/crates/client/src/stream.rs index 047c7cd..6d5d416 100644 --- a/crates/client/src/stream.rs +++ b/crates/client/src/stream.rs @@ -2105,7 +2105,7 @@ pub(crate) mod tests { v }, Extra { - handover: Some("Installing Latch Host 4.1.0 on Gaming-PC: waiting for it to fetch the file…".into()), + handover: Some("Installing Latch Host 4.1.1 on Gaming-PC: waiting for it to fetch the file…".into()), ..windows() }, None, diff --git a/crates/host/src/app.rs b/crates/host/src/app.rs index 7b1d24c..fbabb86 100644 --- a/crates/host/src/app.rs +++ b/crates/host/src/app.rs @@ -213,7 +213,10 @@ impl HostApp { } let cfg = self.cfg.clone(); let ctx = ctx.clone(); - let install_engine = !status.streamer.installed || migrate || !status.streamer.running; + let install_engine = !status.streamer.installed + || migrate + || !status.streamer.running + || crate::streamer::find().is_some_and(|i| crate::streamer::in_old_folder(&i)); let adapter = status.wake_adapter.clone(); let desc = status.wake_adapter_description.clone(); std::thread::spawn(move || { @@ -1249,7 +1252,7 @@ mod snapshots { }), setup: vec![], log: vec![ - "Latch 4.1.0 listening on TCP 47850".into(), + "Latch 4.1.1 listening on TCP 47850".into(), "listening for wake packets on UDP 9".into(), "Tailscale up as user@example.com (100.64.0.10)".into(), "the streaming engine is running and Latch is signed in".into(), diff --git a/crates/host/src/setup.rs b/crates/host/src/setup.rs index d75adb4..59863cd 100644 --- a/crates/host/src/setup.rs +++ b/crates/host/src/setup.rs @@ -692,9 +692,10 @@ pub fn run_as_admin() -> Result<()> { let kind = install.as_ref().map(|i| i.kind).unwrap_or(""); let migrate = crate::migrate::uses_old_engine(kind); let running = install.is_some() && crate::streamer::running(); + let old_folder = install.as_ref().is_some_and(crate::streamer::in_old_folder); let plan = Plan { exe: &exe, - install_engine: install.is_none() || migrate || !running, + install_engine: install.is_none() || migrate || !running || old_folder, migrate, dry_run: false, sunshine_user: &cfg.sunshine_user, diff --git a/crates/host/src/streamer.rs b/crates/host/src/streamer.rs index 690c506..d90ef5c 100644 --- a/crates/host/src/streamer.rs +++ b/crates/host/src/streamer.rs @@ -6,7 +6,7 @@ use anyhow::{bail, Context, Result}; use latch_core::{SUNSHINE_PORT, SUNSHINE_WEB_PORT}; use std::net::{SocketAddr, TcpStream}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; use std::time::Duration; @@ -25,6 +25,13 @@ pub const INSTALL_DIRS: [(&str, &str); 4] = [ ("Apollo", r"C:\Program Files\Apollo"), ]; +/// Whether `install` is the engine in the folder an earlier version used. +/// Setup moves it to [`ENGINE_DIR`] and registers the service under its new +/// name, so it has to run the engine step even though an engine is up. +pub fn in_old_folder(install: &Install) -> bool { + install.dir.as_path() == Path::new(crate::legacy::WINDOWS_ENGINE_DIR) +} + /// GitHub repository the setup script fetches the engine archive from. pub const REPO: &str = "LizardByte/Sunshine"; @@ -580,6 +587,20 @@ mod tests { let _ = SUNSHINE_PORT; } + #[test] + fn an_engine_in_the_old_folder_is_recognised_so_setup_moves_it() { + let old = Install { + kind: "Latch", + dir: PathBuf::from(crate::legacy::WINDOWS_ENGINE_DIR), + }; + let new = Install { + kind: "Latch", + dir: PathBuf::from(ENGINE_DIR), + }; + assert!(in_old_folder(&old)); + assert!(!in_old_folder(&new)); + } + #[test] fn session_listed_reads_current_app_and_running_flags() { assert!(!session_listed(&serde_json::json!({"apps": []})));