@@ -22,6 +22,8 @@ export interface ImageRenderOptions {
|
||||
preserveAspectRatio?: boolean;
|
||||
/** Kitty image ID. If provided, reuses/replaces existing image with this ID. */
|
||||
imageId?: number;
|
||||
/** Whether Kitty should apply its default cursor movement after placement. */
|
||||
moveCursor?: boolean;
|
||||
}
|
||||
|
||||
let cachedCapabilities: TerminalCapabilities | null = null;
|
||||
@@ -46,10 +48,7 @@ export function detectCapabilities(): TerminalCapabilities {
|
||||
// sequences differently). Force hyperlinks off whenever we detect them, even
|
||||
// when the outer terminal would otherwise support OSC 8. Image protocols are
|
||||
// also unreliable under tmux/screen, so leave `images: null` for safety.
|
||||
// cmux currently also gets this conservative fallback due to image corruption:
|
||||
// https://github.com/badlogic/pi-mono/issues/4208
|
||||
const inTmuxOrScreen =
|
||||
!!process.env.TMUX || !!process.env.CMUX_WORKSPACE_ID || term.startsWith("tmux") || term.startsWith("screen");
|
||||
const inTmuxOrScreen = !!process.env.TMUX || term.startsWith("tmux") || term.startsWith("screen");
|
||||
if (inTmuxOrScreen) {
|
||||
const trueColor = colorTerm === "truecolor" || colorTerm === "24bit";
|
||||
return { images: null, trueColor, hyperlinks: false };
|
||||
@@ -131,12 +130,15 @@ export function encodeKitty(
|
||||
columns?: number;
|
||||
rows?: number;
|
||||
imageId?: number;
|
||||
/** Whether Kitty should apply its default cursor movement after placement. Default: true. */
|
||||
moveCursor?: boolean;
|
||||
} = {},
|
||||
): string {
|
||||
const CHUNK_SIZE = 4096;
|
||||
|
||||
const params: string[] = ["a=T", "f=100", "q=2"];
|
||||
|
||||
if (options.moveCursor === false) params.push("C=1");
|
||||
if (options.columns) params.push(`c=${options.columns}`);
|
||||
if (options.rows) params.push(`r=${options.rows}`);
|
||||
if (options.imageId) params.push(`i=${options.imageId}`);
|
||||
@@ -173,7 +175,7 @@ export function encodeKitty(
|
||||
* Uses uppercase 'I' to also free the image data.
|
||||
*/
|
||||
export function deleteKittyImage(imageId: number): string {
|
||||
return `\x1b_Ga=d,d=I,i=${imageId}\x1b\\`;
|
||||
return `\x1b_Ga=d,d=I,i=${imageId},q=2\x1b\\`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +183,7 @@ export function deleteKittyImage(imageId: number): string {
|
||||
* Uses uppercase 'A' to also free the image data.
|
||||
*/
|
||||
export function deleteAllKittyImages(): string {
|
||||
return `\x1b_Ga=d,d=A\x1b\\`;
|
||||
return "\x1b_Ga=d,d=A,q=2\x1b\\";
|
||||
}
|
||||
|
||||
export function encodeITerm2(
|
||||
@@ -377,8 +379,12 @@ export function renderImage(
|
||||
const rows = calculateImageRows(imageDimensions, maxWidth, getCellDimensions());
|
||||
|
||||
if (caps.images === "kitty") {
|
||||
// Only use imageId if explicitly provided - static images don't need IDs
|
||||
const sequence = encodeKitty(base64Data, { columns: maxWidth, rows, imageId: options.imageId });
|
||||
const sequence = encodeKitty(base64Data, {
|
||||
columns: maxWidth,
|
||||
rows,
|
||||
imageId: options.imageId,
|
||||
moveCursor: options.moveCursor,
|
||||
});
|
||||
return { sequence, rows, imageId: options.imageId };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user