summaryrefslogtreecommitdiff
path: root/src/gui.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-06 21:18:35 -0300
committerGabriel Schneider <[email protected]>2026-08-01 15:02:07 -0300
commita373fdda0102a99cde988f87f822fc451e0f4391 (patch)
treeda16427e6353138dfaf5ed27152adc17f53efb12 /src/gui.zig
parentf442004dcd8e91114765a918201ecabe99f69eeb (diff)
downloadpardes-a373fdda0102a99cde988f87f822fc451e0f4391.tar.gz
pardes-a373fdda0102a99cde988f87f822fc451e0f4391.zip
insert vs normal cursor shape (all pane types) + the tag is always insert mode. Surface.cursor grew a bar flag: the core sets it from the active pane mode (insert -> bar; normal/tty -> block) for both the modal/file cursor and the vt-tracking terminal cursor, and unconditionally for the tag cursor. tty shell: DECSCUSR via vaxis setCursorShape (beam for insert, the terminal default otherwise). gui shell: the insert cursor draws the left-eighth-block glyph in cell colors instead of the reverse-video block (ponytail: it hides the char under it; a dedicated quad if that ever matters). Tag editing: enterTagEdit goes straight to insert, Esc (or anything that exits the tag) restores the body normal mode; Enter looks / Tab executes the word at the cursor from inside the tag (tagChordText kept); the whole normal-mode tag machinery — handleTagKey motions, v/x selection, d/c/y/p, tagEnterInsert/tagDelete/tagYank/tagPaste — deleted as unreachable (~120 lines; multi-word tag execution stays the mouse middle-drag). tag.snap rewritten: INS on click, type/backspace straight in, Esc exit with the text persisting, Enter-look opens the file. Tutor documents it. Cursor SHAPE is not capturable by the harness (position only) — verify by eye: bar in insert/tags, block elsewhere, both shells. 30/30.
Diffstat (limited to 'src/gui.zig')
-rw-r--r--src/gui.zig17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/gui.zig b/src/gui.zig
index 60d9501f..cc949cd1 100644
--- a/src/gui.zig
+++ b/src/gui.zig
@@ -1650,12 +1650,13 @@ fn renderFrame(g: *Gui, gpa: std.mem.Allocator, surface: *pardes.Surface) !void
const instances: [*]CellInstance = @ptrCast(@alignCast(vptr));
const layout = fixedCellLayout(g);
const cursor_idx: u32 = if (surface.cursor) |cu| @as(u32, cu.y) * surface.cols + cu.x else cells;
+ const cursor_bar = if (surface.cursor) |cu| cu.bar else false;
var row: u16 = 0;
while (row < surface.rows) : (row += 1) {
var col: u16 = 0;
while (col < surface.cols) : (col += 1) {
const idx: u32 = @as(u32, row) * surface.cols + col;
- emitInstance(g, instances, idx, col, row, layout, win_w, win_h, surface.at(col, row), idx == cursor_idx);
+ emitInstance(g, instances, idx, col, row, layout, win_w, win_h, surface.at(col, row), idx == cursor_idx, cursor_bar);
}
}
c.SDL_UnmapGPUTransferBuffer(g.device, g.vxfer.?);
@@ -1701,13 +1702,15 @@ fn emitInstance(
win_h: f32,
cell: *const pardes.Cell,
is_cursor: bool,
+ cursor_bar: bool,
) void {
// resolve the cell style to concrete fg/bg, matching the prototype's
// cellKey: reverse swaps, invisible hides, dim darkens. The cursor cell
- // renders as reverse (cancelling an already-reversed cell).
+ // renders as reverse (cancelling an already-reversed cell); an insert
+ // cursor keeps the cell colors and draws a bar glyph instead.
var fg = fg_default;
var bg = bg_default;
- var reverse = is_cursor;
+ var reverse = is_cursor and !cursor_bar;
if (!cell.default) {
const st = cell.style;
fg = switch (st.fg) {
@@ -1737,7 +1740,10 @@ fn emitInstance(
const y1 = 1.0 - ((py0 + layout.h) / win_h) * 2.0;
const grapheme = cell.grapheme();
- const cp: u32 = if (cell.default or grapheme.len == 0) ' ' else firstCp(grapheme);
+ var cp: u32 = if (cell.default or grapheme.len == 0) ' ' else firstCp(grapheme);
+ // ponytail: the insert bar is the left-eighth block glyph over the cell
+ // (hides the char under it); a dedicated quad if that ever matters
+ if (is_cursor and cursor_bar) cp = 0x258F;
const slot = if (cp == ' ') g.space_slot else ensureGlyph(g, cp);
const aw_f: f32 = @floatFromInt(atlas_w);
const ah_f: f32 = @floatFromInt(atlas_h);
@@ -1944,12 +1950,13 @@ fn renderFrameGl(g: *Gui, gpa: std.mem.Allocator, surface: *pardes.Surface) !voi
const win_h: f32 = @floatFromInt(sh);
const layout = cellLayout(g, surface.cols, surface.rows, sw, sh);
const cursor_idx: u32 = if (surface.cursor) |cu| @as(u32, cu.y) * surface.cols + cu.x else cells;
+ const cursor_bar = if (surface.cursor) |cu| cu.bar else false;
var row: u16 = 0;
while (row < surface.rows) : (row += 1) {
var col: u16 = 0;
while (col < surface.cols) : (col += 1) {
const idx: u32 = @as(u32, row) * surface.cols + col;
- emitInstance(g, g.gl_instances.ptr, idx, col, row, layout, win_w, win_h, surface.at(col, row), idx == cursor_idx);
+ emitInstance(g, g.gl_instances.ptr, idx, col, row, layout, win_w, win_h, surface.at(col, row), idx == cursor_idx, cursor_bar);
}
}
if (g.atlas_dirty) uploadAtlasGl(g);