Merge pull request #5599 from Tyriar/flush

Flush writes on resize
This commit is contained in:
Daniel Imms
2026-01-09 05:37:21 -08:00
committed by GitHub
3 changed files with 55 additions and 0 deletions
+4
View File
@@ -176,6 +176,10 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
x = Math.max(x, MINIMUM_COLS);
y = Math.max(y, MINIMUM_ROWS);
// Flush pending writes before resize to avoid race conditions where async
// writes are processed with incorrect dimensions
this._writeBuffer.flushSync();
this._bufferService.resize(x, y);
}
+19
View File
@@ -106,5 +106,24 @@ describe('WriteBuffer', () => {
wb.writeSync('1', 10);
assert.equal(last, '11'); // 1 + 10 sub calls = 11
});
it('flushSync processes all pending writes', done => {
wb.write('a', () => { cbStack.push('a'); });
wb.write('b', () => { cbStack.push('b'); });
wb.write('c', () => { cbStack.push('c'); });
wb.flushSync();
assert.deepEqual(stack, ['a', 'b', 'c']);
assert.deepEqual(cbStack, ['a', 'b', 'c']);
wb.write('x', () => { cbStack.push('x'); });
wb.write('', () => {
assert.deepEqual(stack, ['a', 'b', 'c', 'x', '']);
assert.deepEqual(cbStack, ['a', 'b', 'c', 'x']);
done();
});
});
it('flushSync with no pending writes is a no-op', () => {
wb.flushSync();
assert.deepEqual(stack, []);
assert.deepEqual(cbStack, []);
});
});
});
+32
View File
@@ -54,6 +54,38 @@ export class WriteBuffer extends Disposable {
this._didUserInput = true;
}
/**
* Flushes all pending writes synchronously. This is useful when you need to
* ensure all queued data is processed before performing an operation that
* depends upon everything being parsed like resize.
*
* Note: This is unreliable with async parser handlers as it does not wait for
* promises to resolve.
*/
public flushSync(): void {
// exit early if another sync write loop is active
if (this._isSyncWriting) {
return;
}
this._isSyncWriting = true;
// Process all pending chunks synchronously
let chunk: string | Uint8Array | undefined;
while (chunk = this._writeBuffer.shift()) {
this._action(chunk);
const cb = this._callbacks.shift();
if (cb) cb();
}
// Reset buffer state
this._pendingData = 0;
this._bufferOffset = 0x7FFFFFFF;
this._writeBuffer.length = 0;
this._callbacks.length = 0;
this._isSyncWriting = false;
}
/**
* @deprecated Unreliable, to be removed soon.
*/