Skip to content

Commit 814c2fb

Browse files
committed
Fixup some issues in the auto-updater.
1 parent 8c65824 commit 814c2fb

7 files changed

Lines changed: 59 additions & 15 deletions

File tree

docs/specs/auto-update.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ app launch
3030
└─ install fails → overwrite with failure marker → exit normally
3131
```
3232

33-
The `Update` object from `download()` is held in memory for the session. The close handler intercepts the window close event, writes a success marker to `localStorage` *before* calling `install()` (because on Windows, NSIS force-kills the process), then calls `install()`.
33+
The `Update` object from `download()` is held in memory for the session. The close handler intercepts the window close event, writes a success marker to `localStorage` *before* calling `install()` (because on Windows, NSIS force-kills the process), then calls `install()`. In Vite dev mode (`pnpm dev:standalone`), the close handler skips `install()` without preventing the close. Dev mode is useful for testing check/download/banner behavior, but install must be tested from a packaged app because the updater resolves its replacement target from the current executable path.
3434

3535
## Update notice in the Baseboard
3636

@@ -57,6 +57,7 @@ The Baseboard is in `lib/` but the updater is standalone-only. The notice is thr
5757
| Windows | Launches NSIS installer in passive mode (progress bar, no user interaction). Force-kills the app. | Automatic (NSIS) |
5858
| macOS | Replaces the `.app` bundle in place | `getCurrentWindow().close()` after `install()` returns |
5959
| Linux | Replaces the AppImage in place | `getCurrentWindow().close()` after `install()` returns |
60+
| Vite dev mode | Skips `install()` to avoid replacing the dev executable directory | Native close proceeds normally |
6061

6162
Windows uses `"installMode": "passive"` (configured in `tauri.conf.json` under `plugins.updater.windows`).
6263

@@ -95,7 +96,7 @@ In `standalone/src-tauri/tauri.conf.json`:
9596
}
9697
```
9798

98-
The Rust side registers the plugin with `tauri_plugin_updater::Builder::new().build()` in `lib.rs`. No custom Rust commands or `on_before_exit` hooks — the JS close handler handles everything.
99+
The Rust side registers the plugin with `tauri_plugin_updater::Builder::new().build()` in `lib.rs`. No custom Rust commands or `on_before_exit` hooks — the JS close handler handles everything. Capabilities must include `core:window:allow-destroy` as well as `core:window:allow-close`: Tauri's `onCloseRequested` API calls `destroy()` after the handler returns when the close was not prevented.
99100

100101
## Dependencies
101102

standalone/src-tauri/build.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{
22
env,
33
error::Error,
44
fs,
5-
path::PathBuf,
5+
path::{Path, PathBuf},
66
process::Command,
77
};
88

@@ -22,6 +22,7 @@ fn bundle_node_runtime() -> Result<(), Box<dyn Error>> {
2222
let node_source = resolve_node_binary(&host, &target)?;
2323

2424
println!("cargo:rerun-if-changed={}", node_source.display());
25+
validate_node_binary(&node_source, &target)?;
2526

2627
let binaries_dir = manifest_dir.join("binaries");
2728
fs::create_dir_all(&binaries_dir)?;
@@ -41,6 +42,43 @@ fn bundle_node_runtime() -> Result<(), Box<dyn Error>> {
4142
Ok(())
4243
}
4344

45+
#[cfg(target_os = "macos")]
46+
fn validate_node_binary(node_source: &Path, target: &str) -> Result<(), Box<dyn Error>> {
47+
if target.contains("apple-darwin") {
48+
reject_macos_dynamic_node(node_source)?;
49+
}
50+
51+
Ok(())
52+
}
53+
54+
#[cfg(not(target_os = "macos"))]
55+
fn validate_node_binary(_node_source: &Path, _target: &str) -> Result<(), Box<dyn Error>> {
56+
Ok(())
57+
}
58+
59+
#[cfg(target_os = "macos")]
60+
fn reject_macos_dynamic_node(node_source: &Path) -> Result<(), Box<dyn Error>> {
61+
let output = Command::new("otool").arg("-L").arg(node_source).output()?;
62+
if !output.status.success() {
63+
return Err(format!(
64+
"failed to inspect Node.js runtime at {}",
65+
node_source.display()
66+
)
67+
.into());
68+
}
69+
70+
let deps = String::from_utf8_lossy(&output.stdout);
71+
if deps.contains("@rpath/libnode.") {
72+
return Err(format!(
73+
"{} depends on @rpath/libnode*.dylib and cannot be copied as a self-contained Tauri sidecar. Use a standalone Node.js binary, or set MOUSETERM_NODE_BINARY to one.",
74+
node_source.display()
75+
)
76+
.into());
77+
}
78+
79+
Ok(())
80+
}
81+
4482
fn resolve_node_binary(host: &str, target: &str) -> Result<PathBuf, Box<dyn Error>> {
4583
if let Some(path) = env::var_os("MOUSETERM_NODE_BINARY").or_else(|| env::var_os("NODE_BINARY"))
4684
{

standalone/src-tauri/capabilities/default.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
"description": "Default capability set for MouseTerm",
44
"windows": ["main"],
55
"permissions": [
6-
"core:default",
6+
"core:app:allow-version",
7+
"core:event:allow-listen",
8+
"core:event:allow-unlisten",
79
"core:window:allow-minimize",
810
"core:window:allow-toggle-maximize",
911
"core:window:allow-close",
12+
"core:window:allow-destroy",
1013
"core:window:allow-is-maximized",
1114
"core:window:allow-start-dragging",
12-
"shell:allow-spawn",
13-
"shell:allow-stdin-write",
14-
"shell:allow-kill",
15-
"shell:allow-open",
15+
"shell:default",
1616
"updater:default"
1717
]
1818
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"default":{"identifier":"default","description":"Default capability set for MouseTerm","local":true,"windows":["main"],"permissions":["core:app:allow-version","core:event:allow-listen","core:event:allow-unlisten","core:window:allow-minimize","core:window:allow-toggle-maximize","core:window:allow-close","core:window:allow-is-maximized","core:window:allow-start-dragging","shell:default","updater:default"]}}
1+
{"default":{"identifier":"default","description":"Default capability set for MouseTerm","local":true,"windows":["main"],"permissions":["core:app:allow-version","core:event:allow-listen","core:event:allow-unlisten","core:window:allow-minimize","core:window:allow-toggle-maximize","core:window:allow-close","core:window:allow-destroy","core:window:allow-is-maximized","core:window:allow-start-dragging","shell:default","updater:default"]}}

standalone/src-tauri/src/lib.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,11 +307,6 @@ pub fn run() {
307307

308308
Ok(())
309309
})
310-
.on_window_event(|_window, event| {
311-
if let tauri::WindowEvent::CloseRequested { .. } = event {
312-
std::process::exit(0);
313-
}
314-
})
315310
.invoke_handler(tauri::generate_handler![
316311
pty_spawn,
317312
pty_write,

standalone/src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "MouseTerm",
4-
"version": "0.6.0",
4+
"version": "0.6.1",
55
"identifier": "com.mouseterm.app",
66
"build": {
77
"beforeDevCommand": "pnpm dev",

standalone/src/updater.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ let currentVersion = '';
1515

1616
const listeners = new Set<() => void>();
1717

18+
function shouldSkipInstallInDev(): boolean {
19+
return import.meta.env.DEV && import.meta.env.MODE !== 'test';
20+
}
21+
1822
function setState(next: UpdateBannerState) {
1923
state = next;
2024
for (const listener of listeners) {
@@ -123,6 +127,12 @@ function registerCloseHandler(): void {
123127
getCurrentWindow().onCloseRequested(async (event) => {
124128
if (!pendingUpdate) return;
125129

130+
if (shouldSkipInstallInDev()) {
131+
console.warn('[updater] Skipping update install in dev mode. Use a packaged app to test install.');
132+
pendingUpdate = null;
133+
return;
134+
}
135+
126136
event.preventDefault();
127137

128138
try {

0 commit comments

Comments
 (0)