summaryrefslogtreecommitdiff
path: root/src/pardes.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-08 04:44:56 -0300
committerGabriel Schneider <[email protected]>2026-08-01 15:02:07 -0300
commit4314f442048c6654b9179633539495836f7fae82 (patch)
tree4007db76673d19f4e18bc83838e02f630b867f98 /src/pardes.zig
parentb6b899b40a339441694ab7443b00967da8f0b100 (diff)
downloadpardes-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.zig34
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 };