Stabilize initial terminal sizing
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "textual-webterm"
|
name = "textual-webterm"
|
||||||
version = "0.3.21"
|
version = "0.3.22"
|
||||||
description = "Serve terminal sessions over the web"
|
description = "Serve terminal sessions over the web"
|
||||||
authors = ["Will McGugan <will@textualize.io>"]
|
authors = ["Will McGugan <will@textualize.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -59,6 +59,7 @@ class WebTerminal {
|
|||||||
private reconnectAttempts = 0;
|
private reconnectAttempts = 0;
|
||||||
private maxReconnectAttempts = 5;
|
private maxReconnectAttempts = 5;
|
||||||
private reconnectDelay = 1000;
|
private reconnectDelay = 1000;
|
||||||
|
private resizeEventsEnabled = false;
|
||||||
|
|
||||||
constructor(container: HTMLElement, wsUrl: string, config: TerminalConfig = {}) {
|
constructor(container: HTMLElement, wsUrl: string, config: TerminalConfig = {}) {
|
||||||
this.element = container;
|
this.element = container;
|
||||||
@@ -114,6 +115,9 @@ class WebTerminal {
|
|||||||
|
|
||||||
// Handle resize
|
// Handle resize
|
||||||
this.terminal.onResize(({ cols, rows }) => {
|
this.terminal.onResize(({ cols, rows }) => {
|
||||||
|
if (!this.resizeEventsEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.send(["resize", { width: cols, height: rows }]);
|
this.send(["resize", { width: cols, height: rows }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -135,11 +139,7 @@ class WebTerminal {
|
|||||||
if (!("fonts" in document)) {
|
if (!("fonts" in document)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const fontSet = document.fonts;
|
document.fonts.ready
|
||||||
if (fontSet.status === "loaded") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fontSet.ready
|
|
||||||
.then(() => this.scheduleFit())
|
.then(() => this.scheduleFit())
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
// Ignore font readiness errors; resize observer will handle future resizes.
|
// Ignore font readiness errors; resize observer will handle future resizes.
|
||||||
@@ -180,25 +180,40 @@ class WebTerminal {
|
|||||||
this.element.classList.remove("-disconnected");
|
this.element.classList.remove("-disconnected");
|
||||||
|
|
||||||
// Send initial size.
|
// Send initial size.
|
||||||
// Important: avoid sending a bogus early resize before fonts/layout settle,
|
// Important: the PTY hard-wraps output based on its initial cols/rows.
|
||||||
// otherwise the PTY will hard-wrap output at the wrong column count.
|
// If we send a resize before fonts/layout settle, the initial cols can be
|
||||||
this.fit();
|
// too small and the shell will wrap permanently.
|
||||||
const sendResize = () => {
|
this.resizeEventsEnabled = false;
|
||||||
const dims = this.fitAddon.proposeDimensions();
|
|
||||||
if (dims) {
|
const init = () => {
|
||||||
|
const fallback = { cols: 132, rows: 45 };
|
||||||
|
const maxAttempts = 120;
|
||||||
|
|
||||||
|
const attemptFitAndResize = (attempt: number) => {
|
||||||
|
const dims = this.fitAddon.proposeDimensions();
|
||||||
|
if (!dims) {
|
||||||
|
if (attempt < maxAttempts) {
|
||||||
|
window.requestAnimationFrame(() => attemptFitAndResize(attempt + 1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.terminal.resize(fallback.cols, fallback.rows);
|
||||||
|
this.resizeEventsEnabled = true;
|
||||||
|
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.terminal.resize(dims.cols, dims.rows);
|
||||||
|
this.resizeEventsEnabled = true;
|
||||||
this.send(["resize", { width: dims.cols, height: dims.rows }]);
|
this.send(["resize", { width: dims.cols, height: dims.rows }]);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
window.requestAnimationFrame(() => attemptFitAndResize(0));
|
||||||
};
|
};
|
||||||
|
|
||||||
if ("fonts" in document) {
|
if ("fonts" in document) {
|
||||||
document.fonts.ready
|
document.fonts.ready.then(init).catch(init);
|
||||||
.then(() => {
|
|
||||||
this.scheduleFit();
|
|
||||||
sendResize();
|
|
||||||
})
|
|
||||||
.catch(() => sendResize());
|
|
||||||
} else {
|
} else {
|
||||||
sendResize();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Focus terminal
|
// Focus terminal
|
||||||
|
|||||||
Reference in New Issue
Block a user