Skip to main content

Mountain/IPC/WindServiceHandlers/Terminal/
LocalPTYResize.rs

1#![allow(unused_variables, dead_code, unused_imports)]
2
3//! Wire method: `localPty:resize`.
4//! Forwards a resize event to the PTY master (SIGWINCH) via
5//! `TerminalProvider::ResizeTerminal`. Accepts either positional
6//! `[id, cols, rows]` or object `{ id, cols, rows }` from the workbench.
7//!
8//! Clamps cols/rows to ≥ 1 - portable-pty crashes the IO thread with
9//! "size out of range" on 0×0, which the workbench can emit during
10//! pane drag-storms before the requestAnimationFrame settle.
11
12use std::sync::Arc;
13
14use CommonLibrary::{Environment::Requires::Requires, Terminal::TerminalProvider::TerminalProvider};
15use serde_json::Value;
16
17use crate::RunTime::ApplicationRunTime::ApplicationRunTime;
18
19pub async fn Fn(RunTime:Arc<ApplicationRunTime>, Arguments:Vec<Value>) -> Result<Value, String> {
20	let (TerminalId, Columns, Rows) = {
21		let First = Arguments.first().cloned().unwrap_or(Value::Null);
22
23		if First.is_object() {
24			let Id = First.get("id").and_then(|V| V.as_u64()).unwrap_or(0);
25
26			let C = First.get("cols").and_then(|V| V.as_u64()).unwrap_or(80) as u16;
27
28			let R = First.get("rows").and_then(|V| V.as_u64()).unwrap_or(24) as u16;
29
30			(Id, C, R)
31		} else {
32			let Id = Arguments.first().and_then(|V| V.as_u64()).unwrap_or(0);
33
34			let C = Arguments.get(1).and_then(|V| V.as_u64()).unwrap_or(80) as u16;
35
36			let R = Arguments.get(2).and_then(|V| V.as_u64()).unwrap_or(24) as u16;
37
38			(Id, C, R)
39		}
40	};
41
42	if TerminalId == 0 {
43		return Ok(Value::Null);
44	}
45
46	let Columns = if Columns == 0 { 1 } else { Columns };
47
48	let Rows = if Rows == 0 { 1 } else { Rows };
49
50	let Provider:Arc<dyn TerminalProvider> = RunTime.Environment.Require();
51
52	match Provider.ResizeTerminal(TerminalId, Columns, Rows).await {
53		Ok(_) => Ok(Value::Null),
54
55		Err(Error) => {
56			// Resize on a disposed terminal is a common race during shutdown -
57			// the workbench layout pass fires after `exit`, the PTY closes, and
58			// the resize call lands on a dropped master. Log at warn, return
59			// Null so the workbench's resize loop continues instead of stalling.
60			crate::dev_log!(
61				"terminal",
62				"warn: localPty:resize id={} cols={} rows={} failed: {}",
63				TerminalId,
64				Columns,
65				Rows,
66				Error
67			);
68
69			Ok(Value::Null)
70		},
71	}
72}