fix(web): repeindre les terminaux au retour-visible + flush ACK ciblé
Un terminal caché dans une grille de groupe (ou hors-écran) n'était pas repeint au retour — `visibilitychange` ne couvre que l'onglet — d'où l'écran noir avec curseur ; et son ACK ne progressait plus (callback xterm.write throttlé) → le serveur mettait le PTY en pause → sortie « par à-coups ». Ajoute un IntersectionObserver (repaint + flushAck ciblé au retour-visible) et expose Attachment.flushAck (factorisé avec flushAcks).
This commit is contained in:
@@ -100,6 +100,12 @@ export class Attachment {
|
||||
this.pending = null;
|
||||
this.client.releaseAttachment(this);
|
||||
}
|
||||
|
||||
/** Flush ACK ciblé : relance immédiatement le flux si le serveur avait mis ce PTY en pause
|
||||
* (ex. retour-visible de la cellule, dont le rendu était gelé hors-écran). N'ACK que du traité. */
|
||||
flushAck(): void {
|
||||
this.client.flushAck(this);
|
||||
}
|
||||
}
|
||||
|
||||
export class WsClient {
|
||||
@@ -357,15 +363,25 @@ export class WsClient {
|
||||
/** ACK immédiat du reliquat traité pour tous les terminaux ouverts — au retour en avant-plan,
|
||||
* pour rattraper sans attendre le débounce un serveur éventuellement en pause. */
|
||||
private flushAcks(): void {
|
||||
for (const att of this.attachments) {
|
||||
if (att.closed || att.channel < 0) continue;
|
||||
if (att.processedBytes > att.lastAckBytes) {
|
||||
att.lastAckBytes = att.processedBytes;
|
||||
this.sendControl({ type: 'ack', channel: att.channel, bytes: att.processedBytes });
|
||||
}
|
||||
for (const att of this.attachments) this.flushAttachmentAck(att);
|
||||
}
|
||||
|
||||
/** ACK immédiat du reliquat traité d'UN attachment — n'ACK que du réellement traité (invariant
|
||||
* préservé). Factorisé : utilisé par flushAcks() et par le flush ciblé flushAck(). */
|
||||
private flushAttachmentAck(att: Attachment): void {
|
||||
if (att.closed || att.channel < 0) return;
|
||||
if (att.processedBytes > att.lastAckBytes) {
|
||||
att.lastAckBytes = att.processedBytes;
|
||||
this.sendControl({ type: 'ack', channel: att.channel, bytes: att.processedBytes });
|
||||
}
|
||||
}
|
||||
|
||||
/** Flush ACK ciblé d'un seul attachment : relance un PTY mis en pause par le serveur quand la
|
||||
* cellule était cachée (cf. Attachment.flushAck, appelé au retour-visible). */
|
||||
flushAck(att: Attachment): void {
|
||||
this.flushAttachmentAck(att);
|
||||
}
|
||||
|
||||
private handleServerMessage(msg: ServerMessage): void {
|
||||
switch (msg.type) {
|
||||
case 'hello_ok': {
|
||||
|
||||
Reference in New Issue
Block a user