diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/config.zig | 7 | ||||
| -rw-r--r-- | src/pardes.zig | 34 |
2 files changed, 35 insertions, 6 deletions
diff --git a/src/config.zig b/src/config.zig index 0db1d344..0dc12f98 100644 --- a/src/config.zig +++ b/src/config.zig @@ -392,7 +392,12 @@ pub const PREFIX_W: u16 = 5; /// above/below the cursor (clamped at file boundaries and short panes), and /// the same count of COLUMNS horizontally pub const scroll_off = 3; -/// the pane's left chrome: scrollbar + the layout box in the tag row +/// the pane's left chrome: scrollbar + the layout box in the tag row. The +/// scrollbar PAINTS only the first of these columns; the second is the pane's +/// own background, so the bar reads as one column with a column of page +/// between it and the text. Layout is untouched by that — the gutter is still +/// GUTTER columns and a click anywhere in them still scrolls; only the ink +/// narrowed. A half-block glyph in the second column was tried and rejected. pub const GUTTER: u16 = 2; /// a pane never shrinks past this (the h-handle can still take it to its tag /// row alone, which is BOX_H and a structural fact, not this) diff --git a/src/pardes.zig b/src/pardes.zig index 760a452f..4dd35758 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -7005,6 +7005,11 @@ pub const Pardes = struct { const th = p.theme(); const tx = r.x + config.GUTTER; // text area (tag + body), right of the gutter const tw = r.w - config.GUTTER; + // the pane's own background, for everything that has to read as "no + // chrome here": the body text, and the blank right half of the + // scrollbar's second column. `.default` means the host terminal's own + // background, which is what a themeless dark pane wants. + const pane_bg: Color = if (th.bg) |c| .{ .rgb = c } else .default; // text area resets to terminal-default cells (vaxis clear semantics); // light themes paint the page over it. @@ -7059,7 +7064,10 @@ pub const Pardes = struct { p.drawImage(pane, r, tx, tw); const box_bg2 = if (active) th.box else th.box_dim; s.fill(r.x, r.y, config.GUTTER, BOX_H, .{ .bg = .{ .rgb = box_bg2 } }); - if (r.h > BOX_H) s.fill(r.x, r.y + BOX_H, config.GUTTER, r.h - BOX_H, .{ .bg = .{ .rgb = th.scroll_track } }); + // thumbless, but the same one column as the real scrollbar below — + // that is the whole point of drawing it + s.fill(r.x, r.y + BOX_H, 1, r.h -| BOX_H, .{ .bg = .{ .rgb = th.scroll_track } }); + s.fill(r.x + 1, r.y + BOX_H, 1, r.h -| BOX_H, .{ .bg = pane_bg }); return; } @@ -7067,7 +7075,7 @@ pub const Pardes = struct { const body_h = if (r.h > BOX_H) r.h - BOX_H else 0; const body_style: CellStyle = .{ .fg = if (th.fg) |c| .{ .rgb = c } else .default, - .bg = if (th.bg) |c| .{ .rgb = c } else .default, + .bg = pane_bg, }; const tz_body = tracy.zone(@src(), "bodyText"); const body = try p.bodyText(arena, pane); @@ -7207,11 +7215,27 @@ pub const Pardes = struct { } } - // gutter: move box on top, scrollbar track + thumb below + // gutter: move box on top, scrollbar track + thumb below. + // + // The bar is ONE column: column 1 is the track/thumb, column 2 is the + // pane's own background. That second fill is not optional — render() + // pre-fills the whole surface with scroll_track so the gaps between + // panes read as chrome, so a column left unpainted here keeps the + // track colour and the bar looks two wide again. + // + // The move box above stays the full GUTTER. It is a target you drag, + // not a gauge you read, and its whole width is the affordance — the + // step where the box ends and the narrower bar begins is the one place + // on screen that says those are two different pieces of chrome. + // + // Nothing here touches layout or hit-testing: the gutter is still + // config.GUTTER columns and the click handlers still scroll on any of + // them, so the blank column is still live. Only the ink narrowed. const box_bg = if (active) th.box else th.box_dim; s.fill(r.x, r.y, config.GUTTER, BOX_H, .{ .bg = .{ .rgb = box_bg } }); if (r.h > BOX_H) { - s.fill(r.x, r.y + BOX_H, config.GUTTER, r.h - BOX_H, .{ .bg = .{ .rgb = th.scroll_track } }); + s.fill(r.x, r.y + BOX_H, 1, r.h - BOX_H, .{ .bg = .{ .rgb = th.scroll_track } }); + s.fill(r.x + 1, r.y + BOX_H, 1, r.h - BOX_H, .{ .bg = pane_bg }); const sb: struct { total: usize, offset: usize, len: usize } = if (pane.file) |*f| .{ .total = file_pane.nlines(p.gpa, f), .offset = f.scroll, @@ -7226,7 +7250,7 @@ pub const Pardes = struct { const pos = (track_h * sb.offset) / total; var sy: usize = pos; while (sy < track_h and sy < pos + len) : (sy += 1) { - s.fill(r.x, r.y + BOX_H + @as(u16, @intCast(sy)), config.GUTTER, 1, .{ .bg = .{ .rgb = th.scroll_thumb } }); + s.fill(r.x, r.y + BOX_H + @as(u16, @intCast(sy)), 1, 1, .{ .bg = .{ .rgb = th.scroll_thumb } }); } } } |
