summaryrefslogtreecommitdiff
path: root/src/macos.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-15 14:46:38 -0300
committerGabriel Schneider <[email protected]>2026-09-15 17:24:42 -0300
commit40c19fd4f52d20df94c2dfa2d68102b89bd9d3f1 (patch)
tree642150be8703f1d9a0766ff18516f06bfdc8801a /src/macos.zig
parent379f4fe55c7c9c7c8cc7b97dc921c83e2c24698b (diff)
downloadpardes-40c19fd4f52d20df94c2dfa2d68102b89bd9d3f1.tar.gz
pardes-40c19fd4f52d20df94c2dfa2d68102b89bd9d3f1.zip
Add optional compact tagline styling for source context
Diffstat (limited to 'src/macos.zig')
-rw-r--r--src/macos.zig82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/macos.zig b/src/macos.zig
index 7b71d9d5..bb5b6bf6 100644
--- a/src/macos.zig
+++ b/src/macos.zig
@@ -637,6 +637,7 @@ const State = struct {
core: *pardes.Pardes,
started: bool = false,
runtime: Runtime,
+ layer_cells: [pardes.MAX_PANES][]Cell = @splat(&.{}),
cells: []Cell = &.{},
previous_cells: []Cell = &.{},
changed_cells: []u8 = &.{},
@@ -778,6 +779,7 @@ export fn pardes_deinit() void {
st.inbox.close(st.gpa, st.io);
st.file_watches.deinit(st.gpa);
if (st.cells.len > 0) st.gpa.free(st.cells);
+ for (st.layer_cells) |cells| st.gpa.free(cells);
if (st.previous_cells.len > 0) st.gpa.free(st.previous_cells);
if (st.changed_cells.len > 0) st.gpa.free(st.changed_cells);
if (st.images.len > 0) st.gpa.free(st.images);
@@ -1480,6 +1482,22 @@ export fn pardes_paste(text_ptr: ?[*]const u8, len: usize) void {
}
export fn pardes_mouse(button_arg: c_int, kind_arg: c_int, col: u16, row: u16, mods: u32) void {
+ mouseWithHit(button_arg, kind_arg, col, row, mods, null);
+}
+
+export fn pardes_mouse_pixel(button_arg: c_int, kind_arg: c_int, col: u16, row: u16, mods: u32, x: f32, y: f32, bw: f32, bh: f32, tw: f32, th: f32) void {
+ const st = &(state orelse return);
+ const source = st.core.presentation.pointerFractional(st.core.screen_w, st.core.screen_h, x / @max(1, bw), y / @max(1, bh));
+ var hit: ?pardes.Mouse.BodyHit = null;
+ for (&st.core.surface.body_layers) |*layer| {
+ const point = source orelse break;
+ hit = layer.hitAt(point.x * bw, point.y * bh, bw, bh, tw, th);
+ if (hit != null) break;
+ }
+ mouseWithHit(button_arg, kind_arg, col, row, mods, hit);
+}
+
+fn mouseWithHit(button_arg: c_int, kind_arg: c_int, col: u16, row: u16, mods: u32, hit: ?pardes.Mouse.BodyHit) void {
const st = &(state orelse return);
const button: pardes.Mouse.Button = switch (button_arg) {
0 => .left,
@@ -1502,6 +1520,7 @@ export fn pardes_mouse(button_arg: c_int, kind_arg: c_int, col: u16, row: u16, m
else => return,
};
st.core.update(.{ .mouse = .{
+ .body_hit = hit,
.button = button,
.kind = kind,
.col = col,
@@ -1827,6 +1846,46 @@ export fn pardes_cursor_x() i32 {
return if (st.core.surface.cursor) |c| c.x else -1;
}
+export fn pardes_body_layer_value(index: u32, field: u32) u32 {
+ const st = &(state orelse return 0);
+ if (index >= pardes.MAX_PANES) return 0;
+ const layer = &st.core.surface.body_layers[index];
+ return switch (field) {
+ 0 => layer.rows,
+ 1 => layer.cols,
+ 2 => layer.context_rows,
+ 3 => layer.viewport.x,
+ 4 => layer.viewport.y,
+ 5 => layer.viewport.w,
+ 6 => layer.viewport.h,
+ 7 => layer.serial,
+ 8 => if (layer.cursor) |c| c.x else 65535,
+ 9 => if (layer.cursor) |c| c.y else 65535,
+ 10 => if (layer.cursor) |c| @intFromBool(c.bar) else 0,
+ else => 0,
+ };
+}
+
+export fn pardes_body_layer_cells(index: u32) ?[*]const Cell {
+ const st = &(state orelse return null);
+ if (index >= pardes.MAX_PANES) return null;
+ const layer = &st.core.surface.body_layers[index];
+ if (layer.rows == 0) return null;
+ const cells = &st.layer_cells[index];
+ if (cells.len != layer.cells.len) cells.* = st.gpa.realloc(cells.*, layer.cells.len) catch return null;
+ for (layer.cells, cells.*) |cell, *out| out.* = encodeCell(cell);
+ return cells.ptr;
+}
+
+export fn pardes_body_layer_limit() u32 {
+ return pardes.MAX_PANES;
+}
+
+export fn pardes_row_metrics(body_w: u16, body_h: u16, tagline_w: u16, tagline_h: u16) void {
+ const st = &(state orelse return);
+ st.core.update(.{ .resize = .{ .cols = st.core.screen_w, .rows = st.core.screen_h, .cell_pixels = st.core.cell_pixels, .row_metrics = .{ .body_w = @max(1, body_w), .body_h = @max(1, body_h), .tagline_w = @max(1, tagline_w), .tagline_h = @max(1, tagline_h) } } });
+}
+
export fn pardes_pointer_shape() u32 {
const st = &(state orelse return 0);
return @intFromEnum(st.core.surface.pointer_shape);
@@ -2287,6 +2346,10 @@ test "pardes.h declares every export the way it is defined" {
try expectSameAbi(@TypeOf(c.pardes_cursor_y), @TypeOf(pardes_cursor_y));
try expectSameAbi(@TypeOf(c.pardes_cursor_bar), @TypeOf(pardes_cursor_bar));
try expectSameAbi(@TypeOf(c.pardes_pointer_shape), @TypeOf(pardes_pointer_shape));
+ try expectSameAbi(@TypeOf(c.pardes_mouse_pixel), @TypeOf(pardes_mouse_pixel));
+ try expectSameAbi(@TypeOf(c.pardes_row_metrics), @TypeOf(pardes_row_metrics));
+ try expectSameAbi(@TypeOf(c.pardes_body_layer_value), @TypeOf(pardes_body_layer_value));
+ try expectSameAbi(@TypeOf(c.pardes_body_layer_cells), @TypeOf(pardes_body_layer_cells));
try expectSameAbi(@TypeOf(c.pardes_take_haptic), @TypeOf(pardes_take_haptic));
try expectSameAbi(@TypeOf(c.pardes_font_take), @TypeOf(pardes_font_take));
try expectSameAbi(@TypeOf(c.pardes_font_observe), @TypeOf(pardes_font_observe));
@@ -2565,3 +2628,22 @@ test "a live session renders on the draw and animates only on the display clock"
_ = pardes_frame();
try std.testing.expectEqual(step + 1, st.core.chrome_animation.step);
}
+
+test "mac row metrics ABI preserves PDF cell dimensions and the unrendered grid" {
+ const gpa = std.testing.allocator;
+ const core = try pardes.Pardes.init(gpa, .{ .tty_only = true, .cols = 80, .rows = 24 });
+ defer core.deinit();
+ state = .{ .gpa = gpa, .threaded = undefined, .io = std.testing.io, .core = core, .runtime = .{}, .config_arena = .init(gpa), .prompt_rcs = .{} };
+ defer {
+ state.?.config_arena.deinit();
+ state = null;
+ }
+ if (comptime pardes.pdf_enabled) core.cell_pixels = .{ .w = 22, .h = 39 };
+ const pixels = core.cell_pixels;
+ try std.testing.expectEqual(@as(u16, 0), core.surface.cols);
+ pardes_row_metrics(22, 39, 17, 30);
+ try std.testing.expectEqualDeep(pixels, core.cell_pixels);
+ try std.testing.expectEqual(@as(u16, 80), core.screen_w);
+ try std.testing.expectEqual(@as(u16, 24), core.screen_h);
+ try std.testing.expectEqualDeep(pardes.RowMetrics{ .body_w = 22, .body_h = 39, .tagline_w = 17, .tagline_h = 30 }, core.row_metrics);
+}