mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
config: image-storage-limit to set maximum image memory per terminal
This commit is contained in:
@ -186,6 +186,15 @@ pub const Config = struct {
|
||||
/// This does not affect data sent to the clipboard via "clipboard-write".
|
||||
@"clipboard-trim-trailing-spaces": bool = true,
|
||||
|
||||
/// The total amount of bytes that can be used for image data (i.e.
|
||||
/// the Kitty image protocol) per terminal scren. The maximum value
|
||||
/// is 4,294,967,295 (4GB). The default is 320MB. If this is set to zero,
|
||||
/// then all image protocols will be disabled.
|
||||
///
|
||||
/// This value is separate for primary and alternate screens so the
|
||||
/// effective limit per surface is double.
|
||||
@"image-storage-limit": u32 = 320 * 1000 * 1000,
|
||||
|
||||
/// Whether to automatically copy selected text to the clipboard. "true"
|
||||
/// will only copy on systems that support a selection clipboard.
|
||||
///
|
||||
|
@ -26,6 +26,11 @@ pub fn execute(
|
||||
terminal: *Terminal,
|
||||
cmd: *Command,
|
||||
) ?Response {
|
||||
// If storage is disabled then we disable the full protocol. This means
|
||||
// we don't even respond to queries so the terminal completely acts as
|
||||
// if this feature is not supported.
|
||||
if (!terminal.screen.kitty_images.enabled()) return null;
|
||||
|
||||
log.debug("executing kitty graphics command: {}", .{cmd.control});
|
||||
|
||||
const resp_: ?Response = switch (cmd.control) {
|
||||
|
@ -57,6 +57,34 @@ pub const ImageStorage = struct {
|
||||
self.placements.deinit(alloc);
|
||||
}
|
||||
|
||||
/// Kitty image protocol is enabled if we have a non-zero limit.
|
||||
pub fn enabled(self: *const ImageStorage) bool {
|
||||
return self.total_limit != 0;
|
||||
}
|
||||
|
||||
/// Sets the limit in bytes for the total amount of image data that
|
||||
/// can be loaded. If this limit is lower, this will do an eviction
|
||||
/// if necessary. If the value is zero, then Kitty image protocol will
|
||||
/// be disabled.
|
||||
pub fn setLimit(self: *ImageStorage, alloc: Allocator, limit: usize) !void {
|
||||
// Special case disabling by quickly deleting all
|
||||
if (limit == 0) {
|
||||
self.deinit(alloc);
|
||||
self.* = .{};
|
||||
}
|
||||
|
||||
// If we re lowering our limit, check if we need to evict.
|
||||
if (limit < self.total_bytes) {
|
||||
const req_bytes = self.total_bytes - limit;
|
||||
log.info("evicting images to lower limit, evicting={}", .{req_bytes});
|
||||
if (!try self.evictImage(alloc, req_bytes)) {
|
||||
log.warn("failed to evict enough images for required bytes", .{});
|
||||
}
|
||||
}
|
||||
|
||||
self.total_limit = limit;
|
||||
}
|
||||
|
||||
/// Add an already-loaded image to the storage. This will automatically
|
||||
/// free any existing image with the same ID.
|
||||
pub fn addImage(self: *ImageStorage, alloc: Allocator, img: Image) Allocator.Error!void {
|
||||
|
@ -71,6 +71,7 @@ data: ?*EventData,
|
||||
/// pass around Config pointers which makes memory management a pain.
|
||||
pub const DerivedConfig = struct {
|
||||
palette: terminal.color.Palette,
|
||||
image_storage_limit: usize,
|
||||
|
||||
pub fn init(
|
||||
alloc_gpa: Allocator,
|
||||
@ -80,6 +81,7 @@ pub const DerivedConfig = struct {
|
||||
|
||||
return .{
|
||||
.palette = config.palette.value,
|
||||
.image_storage_limit = config.@"image-storage-limit",
|
||||
};
|
||||
}
|
||||
|
||||
@ -106,6 +108,10 @@ pub fn init(alloc: Allocator, opts: termio.Options) !Exec {
|
||||
term.width_px = opts.screen_size.width;
|
||||
term.height_px = opts.screen_size.height;
|
||||
|
||||
// Set the image size limits
|
||||
try term.screen.kitty_images.setLimit(alloc, opts.config.image_storage_limit);
|
||||
try term.secondary_screen.kitty_images.setLimit(alloc, opts.config.image_storage_limit);
|
||||
|
||||
var subprocess = try Subprocess.init(alloc, opts);
|
||||
errdefer subprocess.deinit();
|
||||
|
||||
@ -244,6 +250,16 @@ pub fn changeConfig(self: *Exec, config: *DerivedConfig) !void {
|
||||
// Update the palette. Note this will only apply to new colors drawn
|
||||
// since we decode all palette colors to RGB on usage.
|
||||
self.terminal.color_palette = config.palette;
|
||||
|
||||
// Set the image size limits
|
||||
try self.terminal.screen.kitty_images.setLimit(
|
||||
self.alloc,
|
||||
config.image_storage_limit,
|
||||
);
|
||||
try self.terminal.secondary_screen.kitty_images.setLimit(
|
||||
self.alloc,
|
||||
config.image_storage_limit,
|
||||
);
|
||||
}
|
||||
|
||||
/// Resize the terminal.
|
||||
|
Reference in New Issue
Block a user