diff options
Diffstat (limited to 'src/layout.zig')
| -rw-r--r-- | src/layout.zig | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/layout.zig b/src/layout.zig index c58f3bcf..b9b24e79 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; }; @@ -280,7 +291,7 @@ pub fn applyRowSplit(p: *Pardes, cc: usize, k: usize, cur_y: u16) void { b.vweight = pair - a.vweight; } -pub fn findPane(p: *Pardes, id: usize) ?struct { col: usize, idx: usize } { +pub fn findPane(p: *const Pardes, id: usize) ?struct { col: usize, idx: usize } { for (0..p.ncol) |c| { for (0..p.col_n[c]) |k| { if (p.col_panes[c][k] == id) return .{ .col = c, .idx = k }; @@ -311,6 +322,7 @@ pub fn removePane(p: *Pardes, id: usize) void { /// it (the first column's to its right), as acme's rowclose gives it. pub fn dropColumn(p: *Pardes, c: usize) void { std.debug.assert(p.col_n[c] == 0); + const serial = columnSerial(p, c); tagline.exitHeader(p); if (p.ncol > 1) p.col_weight[if (c > 0) c - 1 else c + 1] +|= p.col_weight[c]; p.col_tags[c].deinit(p.gpa); @@ -325,6 +337,14 @@ pub fn dropColumn(p: *Pardes, c: usize) void { p.ncol -= 1; p.col_tags[p.ncol] = .{ .what = .column, .gpa = p.gpa }; p.col_serial[p.ncol] = 0; + noteColumn(p, "delcol", serial); +} + +/// `newcol <serial>` or `delcol <serial>` in the log: the column's serial, +/// as /layout and /col name it. +fn noteColumn(p: *Pardes, what: []const u8, serial: u32) void { + var buf: [16]u8 = undefined; + pardes.ctlfs.events.notePath(p, what, std.fmt.bufPrint(&buf, "{d}", .{serial}) catch return); } /// Fold column `c` into the one on its right, its panes below theirs. @@ -480,6 +500,7 @@ pub fn insertColumn(p: *Pardes, col: usize, before: bool) ?usize { p.col_serial[c] = 0; p.col_n[c] = 0; p.ncol += 1; + noteColumn(p, "newcol", columnSerial(p, c)); return c; } |
