mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-20 02:03:16 +00:00
fix(tui): prevent image ID collisions between modules
- allocateImageId() now returns random IDs instead of sequential - Static images no longer auto-allocate IDs (transient display) - Only explicit imageId usage (like DOSBox) gets tracked IDs - Suppress emulators exit logging in DOSBox dispose Fixes image replacement bug when extension and main app both allocated sequential IDs starting at 1.
This commit is contained in:
parent
df1d5c40ea
commit
fbd6b7f9ba
3 changed files with 26 additions and 22 deletions
|
|
@ -206,8 +206,23 @@ export class DosboxComponent implements Component {
|
||||||
this.kittyPushed = false;
|
this.kittyPushed = false;
|
||||||
}
|
}
|
||||||
if (this.ci) {
|
if (this.ci) {
|
||||||
void this.ci.exit().catch(() => undefined);
|
// Suppress emulators exit logging
|
||||||
|
const origLog = console.log;
|
||||||
|
const origError = console.error;
|
||||||
|
console.log = () => {};
|
||||||
|
console.error = () => {};
|
||||||
|
const ci = this.ci;
|
||||||
this.ci = null;
|
this.ci = null;
|
||||||
|
void ci
|
||||||
|
.exit()
|
||||||
|
.catch(() => undefined)
|
||||||
|
.finally(() => {
|
||||||
|
// Restore after a delay to catch async logging
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log = origLog;
|
||||||
|
console.error = origError;
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import {
|
import {
|
||||||
deleteKittyImage,
|
|
||||||
getCapabilities,
|
getCapabilities,
|
||||||
getImageDimensions,
|
getImageDimensions,
|
||||||
type ImageDimensions,
|
type ImageDimensions,
|
||||||
|
|
@ -102,15 +101,4 @@ export class Image implements Component {
|
||||||
|
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the terminal image. Call this when done with the image
|
|
||||||
* to free terminal resources.
|
|
||||||
*/
|
|
||||||
dispose(): void {
|
|
||||||
if (this.imageId !== undefined) {
|
|
||||||
process.stdout.write(deleteKittyImage(this.imageId));
|
|
||||||
this.imageId = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,13 +81,14 @@ export function resetCapabilitiesCache(): void {
|
||||||
cachedCapabilities = null;
|
cachedCapabilities = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Counter for generating unique image IDs
|
/**
|
||||||
let nextImageId = 1;
|
* Generate a random image ID for Kitty graphics protocol.
|
||||||
|
* Uses random IDs to avoid collisions between different module instances
|
||||||
|
* (e.g., main app vs extensions).
|
||||||
|
*/
|
||||||
export function allocateImageId(): number {
|
export function allocateImageId(): number {
|
||||||
const id = nextImageId;
|
// Use random ID in range [1, 0xffffffff] to avoid collisions
|
||||||
nextImageId = (nextImageId % 0xffffffff) + 1; // Wrap around at max uint32
|
return Math.floor(Math.random() * 0xfffffffe) + 1;
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function encodeKitty(
|
export function encodeKitty(
|
||||||
|
|
@ -342,9 +343,9 @@ export function renderImage(
|
||||||
const rows = calculateImageRows(imageDimensions, maxWidth, getCellDimensions());
|
const rows = calculateImageRows(imageDimensions, maxWidth, getCellDimensions());
|
||||||
|
|
||||||
if (caps.images === "kitty") {
|
if (caps.images === "kitty") {
|
||||||
const imageId = options.imageId ?? allocateImageId();
|
// Only use imageId if explicitly provided - static images don't need IDs
|
||||||
const sequence = encodeKitty(base64Data, { columns: maxWidth, rows, imageId });
|
const sequence = encodeKitty(base64Data, { columns: maxWidth, rows, imageId: options.imageId });
|
||||||
return { sequence, rows, imageId };
|
return { sequence, rows, imageId: options.imageId };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (caps.images === "iterm2") {
|
if (caps.images === "iterm2") {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue