summaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/pardes.zig34
-rw-r--r--src/tutor.txt4
2 files changed, 26 insertions, 12 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 };
diff --git a/src/tutor.txt b/src/tutor.txt
index 0b78da72..50b92558 100644
--- a/src/tutor.txt
+++ b/src/tutor.txt
@@ -106,7 +106,9 @@
last row above the next tag) IS the resize handle: hover it and a dashed
line overlays that edge (keeping the underlying colors) to mark the drag.
- drag a column's right edge to resize it against its neighbour
- - drag a window's bottom edge to resize it against the one below
+ - drag a window's bottom edge to resize it against the one below;
+ either window may shrink to just its tagline (the tag row then IS
+ the handle) — re-enlarging brings the body back intact
- drag the accent box (top-left of a pane; indigo-purple, brighter
when the pane is focused) to MOVE a window between columns / reorder
- the scrollbar is the gutter below the box: left-click scrolls UP