Add synchronized output support (DEC mode 2026)
Implement synchronized output mode (CSI ? 2026 h/l) which allows applications to batch terminal updates and render them atomically, preventing screen tearing during rapid output. Features: - BSU (CSI ? 2026 h) pauses rendering, buffering row updates - ESU (CSI ? 2026 l) flushes buffer and renders atomically - Configurable timeout via synchronizedOutputTimeout option (default 5s) - Exposed via terminal.modes.synchronizedOutputMode Closes #3375 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1969,6 +1969,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)
|
||||
this._coreService.decPrivateModes.bracketedPasteMode = true;
|
||||
break;
|
||||
case 2026: // synchronized output (https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036)
|
||||
this._coreService.decPrivateModes.synchronizedOutput = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -2197,6 +2200,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)
|
||||
this._coreService.decPrivateModes.bracketedPasteMode = false;
|
||||
break;
|
||||
case 2026: // synchronized output (https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036)
|
||||
this._coreService.decPrivateModes.synchronizedOutput = false;
|
||||
// Trigger a full refresh now that the synchronized output block has ended
|
||||
this._onRequestRefreshRows.fire(undefined);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -102,6 +102,7 @@ export class MockCoreService implements ICoreService {
|
||||
origin: false,
|
||||
reverseWraparound: false,
|
||||
sendFocus: false,
|
||||
synchronizedOutput: false,
|
||||
wraparound: true
|
||||
};
|
||||
public onData: Event<string> = new Emitter<string>().event;
|
||||
|
||||
@@ -273,6 +273,7 @@ export interface IDecPrivateModes {
|
||||
origin: boolean;
|
||||
reverseWraparound: boolean;
|
||||
sendFocus: boolean;
|
||||
synchronizedOutput: boolean;
|
||||
wraparound: boolean; // defaults: xterm - true, vt100 - false
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ const DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({
|
||||
origin: false,
|
||||
reverseWraparound: false,
|
||||
sendFocus: false,
|
||||
synchronizedOutput: false,
|
||||
wraparound: true // defaults: xterm - true, vt100 - false
|
||||
});
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ export const DEFAULT_OPTIONS: Readonly<Required<ITerminalOptions>> = {
|
||||
scrollSensitivity: 1,
|
||||
screenReaderMode: false,
|
||||
smoothScrollDuration: 0,
|
||||
synchronizedOutputTimeout: 5000,
|
||||
macOptionIsMeta: false,
|
||||
macOptionClickForcesSelection: false,
|
||||
minimumContrastRatio: 1,
|
||||
|
||||
@@ -259,6 +259,7 @@ export interface ITerminalOptions {
|
||||
scrollOnUserInput?: boolean;
|
||||
scrollSensitivity?: number;
|
||||
smoothScrollDuration?: number;
|
||||
synchronizedOutputTimeout?: number;
|
||||
tabStopWidth?: number;
|
||||
theme?: ITheme;
|
||||
windowsMode?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user