apprt/embedded: API to read text can get top left/bottom right coords

This commit is contained in:
Mitchell Hashimoto
2025-06-15 13:06:18 -07:00
parent c5f921bb06
commit e1ee180172
2 changed files with 47 additions and 19 deletions

View File

@ -366,8 +366,15 @@ typedef enum {
GHOSTTY_POINT_SURFACE, GHOSTTY_POINT_SURFACE,
} ghostty_point_tag_e; } ghostty_point_tag_e;
typedef enum {
GHOSTTY_POINT_COORD_EXACT,
GHOSTTY_POINT_COORD_TOP_LEFT,
GHOSTTY_POINT_COORD_BOTTOM_RIGHT,
} ghostty_point_coord_e;
typedef struct { typedef struct {
ghostty_point_tag_e tag; ghostty_point_tag_e tag;
ghostty_point_coord_e coord;
uint32_t x; uint32_t x;
uint32_t y; uint32_t y;
} ghostty_point_s; } ghostty_point_s;

View File

@ -1166,6 +1166,7 @@ pub const CAPI = struct {
// ghostty_point_s // ghostty_point_s
const Point = extern struct { const Point = extern struct {
tag: Tag, tag: Tag,
coord_tag: CoordTag,
x: u32, x: u32,
y: u32, y: u32,
@ -1176,27 +1177,51 @@ pub const CAPI = struct {
history = 3, history = 3,
}; };
fn core(self: Point) terminal.Point { const CoordTag = enum(c_int) {
// This comes from the C API so we can't trust the input. exact = 0,
const pt_x = std.math.cast( top_left = 1,
terminal.size.CellCountInt, bottom_right = 2,
self.x, };
) orelse std.math.maxInt(terminal.size.CellCountInt);
return switch (self.tag) { fn pin(
inline else => |tag| @unionInit( self: Point,
terminal.Point, screen: *const terminal.Screen,
) ?terminal.Pin {
// The core point tag.
const tag: terminal.point.Tag = switch (self.tag) {
inline else => |tag| @field(
terminal.point.Tag,
@tagName(tag), @tagName(tag),
.{ .x = pt_x, .y = self.y },
), ),
}; };
}
fn clamp(self: Point, screen: *const terminal.Screen) Point {
// Clamp our point to the screen bounds. // Clamp our point to the screen bounds.
const clamped_x = @min(self.x, screen.pages.cols -| 1); const clamped_x = @min(self.x, screen.pages.cols -| 1);
const clamped_y = @min(self.y, screen.pages.rows -| 1); const clamped_y = @min(self.y, screen.pages.rows -| 1);
return .{ .tag = self.tag, .x = clamped_x, .y = clamped_y };
return switch (self.coord_tag) {
// Exact coordinates require a specific pin.
.exact => exact: {
const pt_x = std.math.cast(
terminal.size.CellCountInt,
clamped_x,
) orelse std.math.maxInt(terminal.size.CellCountInt);
const pt: terminal.Point = switch (tag) {
inline else => |v| @unionInit(
terminal.Point,
@tagName(v),
.{ .x = pt_x, .y = clamped_y },
),
};
break :exact screen.pages.pin(pt) orelse null;
},
.top_left => screen.pages.getTopLeft(tag),
.bottom_right => screen.pages.getBottomRight(tag),
};
} }
}; };
@ -1212,12 +1237,8 @@ pub const CAPI = struct {
) ?terminal.Selection { ) ?terminal.Selection {
return .{ return .{
.bounds = .{ .untracked = .{ .bounds = .{ .untracked = .{
.start = screen.pages.pin( .start = self.tl.pin(screen) orelse return null,
self.tl.clamp(screen).core(), .end = self.br.pin(screen) orelse return null,
) orelse return null,
.end = screen.pages.pin(
self.br.clamp(screen).core(),
) orelse return null,
} }, } },
.rectangle = self.rectangle, .rectangle = self.rectangle,
}; };