From 15ddd805905f785f4dde463d4d6b91e1d2c41e26 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Tue, 29 Sep 2026 00:17:45 -0300 Subject: A pane's last row of text is no resize handle; the grip is, and the GUI's rule A press on a pane's last row began a seam drag, so the row could not be clicked or swept like the rest of the text (rsearch dragged the handle out of the way first). Now no row of text is a handle: in the GUI a press on the 2 px rule between two panes drags their seam, and anywhere the grip does, as acme's button moves a window -- dragged up or down its own column it moves the pane's top, either pane down to its tag alone (acme's coldragwin), dragged down inside itself too. The hover hint over a last row is gone; column edges resize as they did. Scripts that dragged a seam drag a grip instead and match their goldens; six goldens lost the hint or moved a cursor to the clicked text, re-recorded by name. Co-Authored-By: Claude Opus 5.5 --- src/layout.zig | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src/layout.zig') diff --git a/src/layout.zig b/src/layout.zig index 6de7a912..25c95d30 100644 --- a/src/layout.zig +++ b/src/layout.zig @@ -162,8 +162,15 @@ pub fn targetColumn(p: *Pardes, cur_x: u16) usize { } pub fn splitRowForExtent(y: u16, h: u16, cur_y: u16) ?u16 { + return splitRowFor(y, h, cur_y, null); +} + +/// As `splitRowForExtent`, each pane keeping at least `least` rows when +/// given: a pane dragged by its grip within its own column is how a +/// terminal resizes, and acme lets either window keep only its tag. +fn splitRowFor(y: u16, h: u16, cur_y: u16, least: ?u16) ?u16 { if (h < 2) return null; - const min_each: u16 = if (h >= config.MINH * 2) config.MINH else 1; + const min_each: u16 = least orelse if (h >= config.MINH * 2) config.MINH else 1; const lo = y +| min_each; const hi = y + h - min_each; if (lo > hi) return y + h / 2; @@ -176,7 +183,11 @@ pub fn movePlacement(p: *Pardes, id: usize, cur_x: u16, cur_y: u16) ?MovePlaceme if (tc == src.col and p.col_n[src.col] == 1) return null; if (tc == src.col) { const sr = p.rects[id]; - if (cur_y >= sr.y and cur_y < sr.y + sr.h) return null; + // Dropped on itself it stays, unless dragged down from its top with + // a pane above: its top moves down there, the pane above taking the + // rows, as acme's window dragged by its button does. With no rule + // between panes, that is how a terminal resizes them. + if (cur_y >= sr.y and cur_y < sr.y + sr.h and (src.idx == 0 or cur_y <= sr.y)) return null; } var heights: [MAX_PANES]u16 = @splat(0); for (0..p.ncol) |c| { @@ -196,7 +207,7 @@ pub fn movePlacement(p: *Pardes, id: usize, cur_x: u16, cur_y: u16) ?MovePlaceme const pid = p.col_panes[tc][k]; if (pid == id) continue; const h = heights[pid]; - const row = splitRowForExtent(y, h, cur_y) orelse { + const row = splitRowFor(y, h, cur_y, if (tc == src.col) BOX_H else null) orelse { y +|= h; continue; }; -- cgit v1.3