diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 756d263..3c9c7ef 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -546,18 +546,20 @@ fn terminal_open( }; let url = terminal::url(&app_url, &target, cols, rows)?; let h = handle.clone(); - Ok(app.terminals.open(url, token, move |down| { - if down.kind == "end" { - h.state::().terminals.forget(down.id); - let refused = down.data.get("code").and_then(Value::as_u64) - == Some(u64::from(terminal::CLOSE_UNAUTHORIZED)) - || down.data.get("status").and_then(Value::as_u64) == Some(401); - if refused { - token_refused(&h); + let on_end = handle.clone(); + Ok(app.terminals.open( + url, + token, + move |down| { + let _ = h.emit("terminal", down); + }, + move |id, end| { + on_end.state::().terminals.forget(id); + if end.unauthorized() { + token_refused(&on_end); } - } - let _ = h.emit("terminal", down); - })) + }, + )) } /// Keys typed (or pasted) into a terminal, as text: sent to the shell as its bytes. diff --git a/src-tauri/src/terminal.rs b/src-tauri/src/terminal.rs index 2c247e9..c767b87 100644 --- a/src-tauri/src/terminal.rs +++ b/src-tauri/src/terminal.rs @@ -167,14 +167,21 @@ pub struct Sessions { impl Sessions { /// Open a terminal's socket on its own thread. `emit` gets every frame, the `end` last; - /// the id is the page's handle on it. - pub fn open(&self, url: String, token: String, emit: impl Fn(Down) + Send + 'static) -> u64 { + /// `ended` is told how it ended just before. The id is the page's handle on it. + pub fn open( + &self, + url: String, + token: String, + emit: impl Fn(Down) + Send + 'static, + ended: impl FnOnce(u64, &End) + Send + 'static, + ) -> u64 { let id = self.next.fetch_add(1, Ordering::SeqCst) + 1; let (tx, rx) = mpsc::channel(); self.open.lock().unwrap().insert(id, tx); std::thread::spawn(move || { let send = |kind: &'static str, data: Value| emit(Down { id, kind, data }); let end = run(&url, &token, &rx, &send); + ended(id, &end); send("end", serde_json::to_value(&end).unwrap_or(Value::Null)); }); id