mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-24 20:56:08 +03:00
terminal/kitty-gfx: placement now works properly
This commit is contained in:
@ -2,6 +2,7 @@ const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const point = @import("../point.zig");
|
||||
const Terminal = @import("../Terminal.zig");
|
||||
const command = @import("graphics_command.zig");
|
||||
const image = @import("graphics_image.zig");
|
||||
@ -9,6 +10,11 @@ const Command = command.Command;
|
||||
const Response = command.Response;
|
||||
const Image = image.Image;
|
||||
|
||||
// TODO:
|
||||
// - image ids need to be assigned, can't just be zero
|
||||
// - delete
|
||||
// (not exhaustive, almost every op is ignoring additional config)
|
||||
|
||||
/// Execute a Kitty graphics command against the given terminal. This
|
||||
/// will never fail, but the response may indicate an error and the
|
||||
/// terminal state may not be updated to reflect the command. This will
|
||||
@ -112,16 +118,47 @@ fn display(
|
||||
cmd: *Command,
|
||||
) Response {
|
||||
const d = cmd.display().?;
|
||||
|
||||
// Display requires image ID or number.
|
||||
if (d.image_id == 0 and d.image_number == 0) {
|
||||
return .{ .message = "EINVAL: image ID or number required" };
|
||||
}
|
||||
|
||||
// Build up our response
|
||||
var result: Response = .{
|
||||
.id = d.image_id,
|
||||
.image_number = d.image_number,
|
||||
.placement_id = d.placement_id,
|
||||
};
|
||||
|
||||
// TODO
|
||||
// Verify the requested image exists if we have an ID
|
||||
const storage = &terminal.screen.kitty_images;
|
||||
const img_: ?Image = if (d.image_id != 0)
|
||||
storage.imageById(d.image_id)
|
||||
else
|
||||
storage.imageByNumber(d.image_number);
|
||||
const img = img_ orelse {
|
||||
result.message = "EINVAL: image not found";
|
||||
return result;
|
||||
};
|
||||
|
||||
// Make sure our response has the image id in case we looked up by number
|
||||
result.id = img.id;
|
||||
|
||||
// Determine the screen point for the placement.
|
||||
const placement_point = (point.Viewport{
|
||||
.x = terminal.screen.cursor.x,
|
||||
.y = terminal.screen.cursor.y,
|
||||
}).toScreen(&terminal.screen);
|
||||
|
||||
// Add the placement
|
||||
storage.addPlacement(alloc, img.id, d.placement_id, .{
|
||||
.point = placement_point,
|
||||
}) catch |err| {
|
||||
encodeError(&result, err);
|
||||
return result;
|
||||
};
|
||||
|
||||
_ = alloc;
|
||||
_ = terminal;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,22 @@ pub const ImageStorage = struct {
|
||||
/// 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 {
|
||||
// Do the gop op first so if it fails we don't get a partial state
|
||||
const gop = try self.images.getOrPut(alloc, img.id);
|
||||
|
||||
// If the image has an image number, we need to invalidate the last
|
||||
// image with that same number.
|
||||
if (img.number > 0) {
|
||||
var it = self.images.iterator();
|
||||
while (it.next()) |kv| {
|
||||
if (kv.value_ptr.number == img.number) {
|
||||
kv.value_ptr.number = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write our new image
|
||||
if (gop.found_existing) gop.value_ptr.deinit(alloc);
|
||||
gop.value_ptr.* = img;
|
||||
}
|
||||
@ -59,6 +74,16 @@ pub const ImageStorage = struct {
|
||||
return self.images.get(image_id);
|
||||
}
|
||||
|
||||
/// Get an image by its number. If the image doesn't exist, return null.
|
||||
pub fn imageByNumber(self: *ImageStorage, image_number: u32) ?Image {
|
||||
var it = self.images.iterator();
|
||||
while (it.next()) |kv| {
|
||||
if (kv.value_ptr.number == image_number) return kv.value_ptr.*;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Every placement is uniquely identified by the image ID and the
|
||||
/// placement ID. If an image ID isn't specified it is assumed to be 0.
|
||||
/// Likewise, if a placement ID isn't specified it is assumed to be 0.
|
||||
|
Reference in New Issue
Block a user