diff options
| author | Gabriel Schneider <[email protected]> | 2026-07-08 04:44:56 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-01 15:02:07 -0300 |
| commit | 4314f442048c6654b9179633539495836f7fae82 (patch) | |
| tree | 4007db76673d19f4e18bc83838e02f630b867f98 /src/pardes.zig | |
| parent | b6b899b40a339441694ab7443b00967da8f0b100 (diff) | |
| download | pardes-4314f442048c6654b9179633539495836f7fae82.tar.gz pardes-4314f442048c6654b9179633539495836f7fae82.zip | |
panes can shrink to just their tagline: border-drag clamps drop from MINH to BOX_H (the tag row doubles as the re-enlarge handle; the gutter move box wins over the handle so a tag-only pane stays movable), a hidden body's pty/vt is never resized so re-enlarging restores it intact, and cursor/modal-selection paints never land on the tag row. New shrinktag.snap; tutor updated.
Diffstat (limited to 'src/pardes.zig')
| -rw-r--r-- | src/pardes.zig | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index c6513392..c14154e5 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -3577,7 +3577,17 @@ pub const Pardes = struct { return; } if (mrow < TOPBAR_H) return; // topbar: left click deliberately inert - // resize handles first: a pane's own trailing edge (v: the + // the layout box (gutter cells of the tag row) wins over + // the resize handles: a tag-only pane's single row IS its + // pair's h-handle, and the box must stay grabbable to move + if (hovered) |mid| { + const mr = p.rects[mid]; + if (mcol < mr.x + GUTTER and mrow < mr.y + BOX_H) { + p.drag = .{ .move = .{ .id = mid, .cur_x = mcol, .cur_y = mrow } }; + return; + } + } + // resize handles next: a pane's own trailing edge (v: the // left column's last col; h: the upper pane's last row) for (0..p.ncol -| 1) |c| { if (mcol == p.col_x[c] + p.col_w[c] -| 1) { @@ -3598,9 +3608,7 @@ pub const Pardes = struct { const id = hovered orelse return; const r = p.rects[id]; const pane = p.panes[id] orelse return; - if (mcol < r.x + GUTTER and mrow < r.y + BOX_H) { - p.drag = .{ .move = .{ .id = id, .cur_x = mcol, .cur_y = mrow } }; - } else if (mcol < r.x + GUTTER) { + if (mcol < r.x + GUTTER) { // gutter scrollbar: a left click scrolls UP to that row p.active = id; pane.scrollBy(-(@as(i32, mrow) - @as(i32, r.y + BOX_H))); @@ -3687,8 +3695,9 @@ pub const Pardes = struct { if (k + 1 < p.col_n[cc]) { const a = p.rects[p.col_terms[cc][k]]; const b = p.rects[p.col_terms[cc][k + 1]]; - const lo = a.y + MINH; - const hi = a.y +| a.h +| b.h -| MINH; + // either pane may shrink to just its tag row (BOX_H) + const lo = a.y + BOX_H - 1; + const hi = a.y +| a.h +| b.h -| (BOX_H + 1); d.cur_y = if (lo <= hi) std.math.clamp(mrow, lo, hi) else mrow; } else d.cur_y = mrow; }, @@ -3737,7 +3746,7 @@ pub const Pardes = struct { const rb = p.rects[p.col_terms[cc][k + 1]]; const combined: f32 = @floatFromInt(ra.h + rb.h); var nt: f32 = @floatFromInt((d.cur_y + 1) -| ra.y); - nt = std.math.clamp(nt, @as(f32, MINH), @max(@as(f32, MINH), combined - MINH)); + nt = std.math.clamp(nt, @as(f32, BOX_H), @max(@as(f32, BOX_H), combined - BOX_H)); const pair = a.vweight + b.vweight; a.vweight = pair * (nt / combined); b.vweight = pair - a.vweight; @@ -4602,7 +4611,10 @@ pub const Pardes = struct { const r = p.rects[id]; const cols = @max(1, r.w -| GUTTER); const rows = @max(1, r.h -| BOX_H); // the tag steals the top row - if (cols != pane.cols or rows != pane.rows) { + // a pane shrunk to just its tag keeps its last real grid: no + // pty/vt reflow while the body is hidden, so re-enlarging brings + // it back exactly as it was + if ((cols != pane.cols or rows != pane.rows) and r.h > BOX_H) { // doc panes have no pty/emulator grid to reflow; just record // the size so bodyText renders the right number of rows if (pane.isTerminal()) { @@ -4999,7 +5011,7 @@ pub const Pardes = struct { if (pane.mode == .normal and pane.msel.active) { const lo = @min(pane.msel.r0, pane.msel.r1) - off + @as(i32, BOX_H); const hi = @max(pane.msel.r0, pane.msel.r1) - off + @as(i32, BOX_H); - var row: u16 = 0; + var row: u16 = BOX_H; // never paint the tag row while (row < r.h) : (row += 1) { if (@as(i32, row) < lo or @as(i32, row) > hi) continue; var col: u16 = if (pane.file != null) PREFIX_W else 0; @@ -5019,7 +5031,7 @@ pub const Pardes = struct { var ar: i32 = bnd.lo_row; while (ar <= bnd.hi_row) : (ar += 1) { const prow = ar - off + @as(i32, BOX_H); - if (prow < 0 or prow >= @as(i32, r.h)) continue; + if (prow < BOX_H or prow >= @as(i32, r.h)) continue; const cstart: i32 = if (ar == bnd.lo_row) bnd.lo_col - vhs + vpfx else vpfx; const cend: i32 = if (ar == bnd.hi_row) bnd.hi_col - vhs + vpfx else @as(i32, tw) - 1; var col: i32 = @max(cstart, vpfx); @@ -5050,7 +5062,7 @@ pub const Pardes = struct { pane.renderedCol(crow, ccol, coff) else ccol; - if (prow >= 0 and cx >= 0 and prow < r.h and cx < tw) + if (prow >= BOX_H and cx >= 0 and prow < r.h and cx < tw) s.cursor = .{ .x = tx + @as(u16, @intCast(cx)), .y = r.y + @as(u16, @intCast(prow)), .bar = pane.mode == .insert }; } else if (cur.y + BOX_H < r.h and cur.x < tw) { s.cursor = .{ .x = tx + cur.x, .y = r.y + cur.y + BOX_H, .bar = pane.mode == .insert }; |
