Fix terminal size on connect — send dimensions after handshake

Root cause: The PTY is allocated at 80x24 during the SSH handshake.
The frontend xterm.js fits correctly to the container (e.g. 120x35),
but term.onResize fires before the backend connection is ready, so the
ResizeSession call is silently rejected. When the connection completes,
fitAddon.fit() sees the terminal already has the right cols/rows and
does NOT fire another onResize event. The PTY stays at 80x24.

Fix: On 'session:state → connected', explicitly read the current
terminal cols/rows and send them to the backend via ResizeSession,
bypassing the onResize event dependency.

Also fix empty-state ordering in addTab() — hide the empty-state
BEFORE activating the panel so the panel-container gets the full
workspace height immediately (empty-state has flex:1 and was stealing
half the height during initial layout).

Simplify createTerminal() fit logic — force a synchronous reflow
via offsetHeight access, then fit immediately.
This commit is contained in:
2026-04-16 00:00:00 +01:00
parent 48680d0eaf
commit 8915500eac
3 changed files with 27 additions and 22 deletions
+16 -5
View File
@@ -134,13 +134,24 @@ class App {
window.runtime.EventsOn('session:state', (payload) => {
this.tabs.updateSessionState(payload.sessionID, payload.state, payload.error);
this.updateStatusBar();
// Re-fit the terminal once connected so it picks up the final container size.
// Use multiple delays because the panel layout may still be settling.
// Once connected, ensure the backend PTY has the correct dimensions.
// The initial fit happens before the SSH handshake completes, so the
// onResize callback fires when the backend isn't ready. By the time
// the connection is established, xterm already has the right cols/rows
// and fitAddon.fit() won't trigger a new resize event. We must
// explicitly send the current terminal size to the backend.
if (payload.state === 'connected') {
const entry = this.terminals.terminals.get(payload.sessionID);
if (entry) {
const { cols, rows } = entry.term;
try {
window.go.api.Service.ResizeSession(payload.sessionID, cols, rows);
} catch (_) { /* noop */ }
}
// Also re-fit to catch any layout changes that occurred while connecting.
const fit = () => this.terminals.fitSession(payload.sessionID);
setTimeout(fit, 30);
setTimeout(fit, 150);
setTimeout(fit, 500);
setTimeout(fit, 50);
setTimeout(fit, 300);
}
});