fix: terminal size sync — resize message handler + xterm-256color default-terminal
This commit is contained in:
parent
b64aaab40a
commit
fcfe729d23
|
|
@ -22,6 +22,7 @@ import { readChunks } from "../../buffer/reader.js";
|
||||||
import type { StateEvent } from "../../pi/events.js";
|
import type { StateEvent } from "../../pi/events.js";
|
||||||
import { SequenceCounter } from "../../sequence.js";
|
import { SequenceCounter } from "../../sequence.js";
|
||||||
import { ControlClient } from "../../tmux/control.js";
|
import { ControlClient } from "../../tmux/control.js";
|
||||||
|
import { resizeSession } from "../../tmux/manager.js";
|
||||||
import { capturePane } from "../../tmux/snapshot.js";
|
import { capturePane } from "../../tmux/snapshot.js";
|
||||||
import type { WsClient, WsServer } from "../types.js";
|
import type { WsClient, WsServer } from "../types.js";
|
||||||
|
|
||||||
|
|
@ -155,6 +156,12 @@ function handleStreamConnection(
|
||||||
if (ws.readyState !== 1) break;
|
if (ws.readyState !== 1) break;
|
||||||
sendBinary(ws, buildBinaryFrame(chunk.seq, chunk.data));
|
sendBinary(ws, buildBinaryFrame(chunk.seq, chunk.data));
|
||||||
}
|
}
|
||||||
|
} else if (m.type === "resize") {
|
||||||
|
// IC-1 extension: client reports its actual terminal dimensions.
|
||||||
|
// Resize the tmux window so line-wrapping matches what the client sees.
|
||||||
|
const cols = typeof m.cols === "number" ? m.cols : 80;
|
||||||
|
const rows = typeof m.rows === "number" ? m.rows : 24;
|
||||||
|
resizeSession(sessionId, cols, rows).catch(() => {});
|
||||||
} else if (m.type === "snapshot-request") {
|
} else if (m.type === "snapshot-request") {
|
||||||
capturePane({ session: sessionId })
|
capturePane({ session: sessionId })
|
||||||
.then((text) => {
|
.then((text) => {
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,15 @@ export async function spawnSession(opts: {
|
||||||
await checkTmuxVersion();
|
await checkTmuxVersion();
|
||||||
const { name, width = 120, height = 40, command = "" } = opts;
|
const { name, width = 120, height = 40, command = "" } = opts;
|
||||||
|
|
||||||
|
// Set default-terminal globally so programs inside tmux get xterm-256color
|
||||||
|
// and emit the escape sequences that SwiftTerm / xterm-compatible clients expect.
|
||||||
|
await execFileAsync("tmux", [
|
||||||
|
"set-option",
|
||||||
|
"-g",
|
||||||
|
"default-terminal",
|
||||||
|
"xterm-256color",
|
||||||
|
]).catch(() => {}); // best-effort; older tmux may not support all options
|
||||||
|
|
||||||
const args = [
|
const args = [
|
||||||
"new-session",
|
"new-session",
|
||||||
"-d",
|
"-d",
|
||||||
|
|
@ -76,6 +85,28 @@ export async function spawnSession(opts: {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize an existing session's window.
|
||||||
|
* Safe to call at any time; silently ignores unknown sessions.
|
||||||
|
*/
|
||||||
|
export async function resizeSession(
|
||||||
|
name: string,
|
||||||
|
cols: number,
|
||||||
|
rows: number,
|
||||||
|
): Promise<void> {
|
||||||
|
const c = Math.max(1, Math.min(Math.round(cols), 500));
|
||||||
|
const r = Math.max(1, Math.min(Math.round(rows), 200));
|
||||||
|
await execFileAsync("tmux", [
|
||||||
|
"resize-window",
|
||||||
|
"-t",
|
||||||
|
name,
|
||||||
|
"-x",
|
||||||
|
String(c),
|
||||||
|
"-y",
|
||||||
|
String(r),
|
||||||
|
]).catch(() => {}); // session may not exist yet; ignore
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all tmux sessions with metadata.
|
* List all tmux sessions with metadata.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue