fix(terminal): a pane on a hidden tab never shrinks its tmux window
A terminal mounted on a hidden tab sits in a 0x0 box; its first fit shrank xterm to 12x6 and the attach carried that size to tmux, so every background pane was squeezed (Claude's TUI redrawn at 12 columns). It now neither fits nor reports a size until shown, attaches with no size, and the server spawns such an attach at the window's own size (tmux.windowSize). A shown tab reports its size even when the fit did not change xterm's. Settings > Agents shows the host's login profiles to staff only: a developer got two 403s from reads that were never theirs.
This commit is contained in:
@@ -162,12 +162,16 @@ function attach(ws, runId, { cols, rows, platform = process.platform }) {
|
||||
const [file, args] = require("./drop-caps").ptyArgv(
|
||||
...(tmux.memberAttach(runId) || [attachBinary(), ["attach-session", "-t", tmux.session(runId)]])
|
||||
);
|
||||
// An attach with no size of its own (a terminal on a hidden tab, 0×0) takes
|
||||
// the window's current size, so attaching it never shrinks the pane.
|
||||
const own =
|
||||
cols && rows ? { cols, rows } : (!lead && tmux.windowSize(runId)) || { cols: 80, rows: 24 };
|
||||
// A follower attaches at the driver's size: tmux sizes the window to the
|
||||
// newest client, so its own size would resize the driver's pane first.
|
||||
const pty = spawnImpl(file, args, {
|
||||
name: "xterm-256color",
|
||||
cols: lead ? lead.cols : cols || 80,
|
||||
rows: lead ? lead.rows : rows || 24,
|
||||
cols: lead ? lead.cols : own.cols,
|
||||
rows: lead ? lead.rows : own.rows,
|
||||
// Windows' inbox ConPTY re-renders psmux's output instead of passing it
|
||||
// through, and wherever its glyph widths disagree with xterm.js's (⏺, ✻,
|
||||
// Vietnamese) it leaves stray cells: a torn left edge, bars mid-screen.
|
||||
@@ -176,7 +180,7 @@ function attach(ws, runId, { cols, rows, platform = process.platform }) {
|
||||
...(platform === "win32" && { useConptyDll: true }),
|
||||
});
|
||||
swallowPipeErrors(pty);
|
||||
const me = { ws, pty, cols: cols || 80, rows: rows || 24, exited: false };
|
||||
const me = { ws, pty, cols: own.cols, rows: own.rows, exited: false };
|
||||
group.viewers.add(me);
|
||||
if (lead) tell(me, { type: "size", cols: lead.cols, rows: lead.rows });
|
||||
else group.driver = me;
|
||||
|
||||
@@ -723,6 +723,25 @@ function leaveCopyMode(name) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The session's window size as tmux has it now, `{cols, rows}`, or null when
|
||||
* tmux can't answer. An attach that brings no size of its own (a terminal on
|
||||
* a hidden tab) is spawned at this, so attaching it resizes nothing.
|
||||
*/
|
||||
function windowSize(name) {
|
||||
try {
|
||||
const [cols, rows] = String(
|
||||
onServerOf(name, ["display-message", "-p", "-t", pane(name), "#{window_width} #{window_height}"])
|
||||
)
|
||||
.trim()
|
||||
.split(" ")
|
||||
.map(Number);
|
||||
return cols >= 2 && rows >= 2 ? { cols, rows } : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The command currently running in the session's active pane (`bash`, `zsh`,
|
||||
* `claude`, …). Null when tmux can't answer — callers treat that as "unknown,
|
||||
@@ -1013,6 +1032,7 @@ module.exports = {
|
||||
enableMouse,
|
||||
leaveCopyMode,
|
||||
paneCommand,
|
||||
windowSize,
|
||||
sendCommand,
|
||||
sendText,
|
||||
pasteText,
|
||||
|
||||
Reference in New Issue
Block a user