diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index 5777d147..44a9bc77 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -107,6 +107,9 @@ export class MockTerminal implements ITerminal { public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable { throw new Error('Method not implemented.'); } + public registerApcHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable { + throw new Error('Method not implemented.'); + } public registerLinkProvider(linkProvider: ILinkProvider): IDisposable { throw new Error('Method not implemented.'); } diff --git a/src/common/CoreTerminal.ts b/src/common/CoreTerminal.ts index dd312af1..01dded5e 100644 --- a/src/common/CoreTerminal.ts +++ b/src/common/CoreTerminal.ts @@ -242,6 +242,11 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal { return this._inputHandler.registerOscHandler(ident, callback); } + /** Add handler for APC escape sequence. See xterm.d.ts for details. */ + public registerApcHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable { + return this._inputHandler.registerApcHandler(ident, callback); + } + protected _setup(): void { this._handleWindowsPtyOptionChange(); } diff --git a/src/common/Types.ts b/src/common/Types.ts index 269b30c8..25d39d5f 100644 --- a/src/common/Types.ts +++ b/src/common/Types.ts @@ -22,6 +22,7 @@ export interface ICoreTerminal { registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable; registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable; registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable; + registerApcHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable; } export interface IDisposable { @@ -475,6 +476,7 @@ export interface IInputHandler { registerDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean | Promise): IDisposable; registerEscHandler(id: IFunctionIdentifier, callback: () => boolean | Promise): IDisposable; registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable; + registerApcHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable; /** C0 BEL */ bell(): boolean; /** C0 LF */ lineFeed(): boolean; diff --git a/src/common/public/ParserApi.ts b/src/common/public/ParserApi.ts index afcc01be..a9b97188 100644 --- a/src/common/public/ParserApi.ts +++ b/src/common/public/ParserApi.ts @@ -34,4 +34,7 @@ export class ParserApi implements IParser { public addOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable { return this.registerOscHandler(ident, callback); } + public registerApcHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable { + return this._core.registerApcHandler(ident, callback); + } } diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index ee3364dd..604e9504 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -1932,6 +1932,24 @@ declare module '@xterm/xterm' { * @returns An IDisposable you can call to remove this handler. */ registerOscHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable; + + /** + * Adds a handler for APC escape sequences. + * @param ident The identifier (first character) of the sequence as a + * character code, e.g. 71 for 'G' (Kitty graphics protocol). + * @param callback The function to handle the sequence. Note that the + * function will only be called once if the sequence finished successfully. + * There is currently no way to intercept smaller data chunks, data chunks + * will be stored up until the sequence is finished. Since APC sequences are + * not limited by the amount of data this might impose a problem for big + * payloads. Currently xterm.js limits APC payload to 10 MB which should + * give enough room for most use cases. The callback is called with APC data + * string (excluding the identifier character). Return `true` if the + * sequence was handled, `false` if the parser should try a previous + * handler. The most recently added handler is tried first. + * @returns An IDisposable you can call to remove this handler. + */ + registerApcHandler(ident: number, callback: (data: string) => boolean | Promise): IDisposable; } /**