fix: the plot's two side margins are balanced, and the dump outlives its widgets
With the axis titles gone the left gutter was 200 px of an 870 px viewport and the right side had no margin at all, so the newest tick's label was drawn half outside the plot and the newest sample's ink landed on the frame. Two causes on the left. The reservation covered `format_si()`'s `%.3g` fallback (`-1.23e-45`), which no signal on an `Si` axis produces -- the widest real label for a unitless axis is `-1.23m` -- and `note_y_gutter()` added 6 px of slack to a figure that is already the maximum of the labels and last frame's floor, making the gutter a ratchet that climbed to its 200 px cap in ~19 frames. It settles at 104 px now, with `axes.w changes: 1` where it read 17. The right side did not exist: a plot's `axes` rect reached the viewport's right edge by construction. `deps/plotter` gains `Plot::set_right_gutter()` and `Figure::set_right_gutter()` -- a want rather than a measurement, since nothing is drawn there, imposed figure-wide so the rows end on one column as they already start on one. udpscope asks for half the widest time label plus the label padding (59 px), x labels being centred on their tick. Separately: the exit dump asked two destroyed widgets for their size, which is where the "exactly two Gtk-CRITICALs" baseline came from. The pointer is freed memory by then, so a run that had destroyed other windows first (UDPSCOPE_PROBE_HELP_MS opens three) segfaulted in the middle of the dump instead. Both sizes are captured on the tick; a clean run now carries no critical. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
811c6d80f0
commit
62df049f53
7 files changed
+153
-39
No files matched your search
+16
-9
@@ -373,18 +373,22 @@ class RowSet {
|
||||
/// left and right by a few pixels every frame. Since `set_min_y_gutter()` is a
|
||||
/// floor and the library still takes the larger of the two, a floor smaller than
|
||||
/// the labels cannot stop that; the reservation therefore covers the widest label
|
||||
/// `format_si()` can produce (three significant digits, a sign and a prefix, or the
|
||||
/// `%.3g` fallback) plus the label padding, measured once with the plot's own font.
|
||||
/// Both reservations only ever grow, so the gutter is constant in practice.
|
||||
/// `format_si()` writes for an axis with no unit -- a sign, three significant figures
|
||||
/// and a one-glyph prefix -- plus the label padding, measured once with the plot's own
|
||||
/// font. Both reservations only ever grow, so the gutter is constant in practice.
|
||||
///
|
||||
/// The same metrics fix the **right** gutter, which is a want and not a measurement:
|
||||
/// see `apply_gutters()`.
|
||||
void note_y_gutter(double need_px);
|
||||
|
||||
/// Applies the stable gutter as the figure's floor. Call once per frame, before the
|
||||
/// frame is drawn.
|
||||
/// Applies the stable left gutter as the figure's floor, and the right gutter beside
|
||||
/// it. Call once per frame, before the frame is drawn.
|
||||
///
|
||||
/// It has to be the *figure's* floor and not each row's: `Figure::layout()` clears
|
||||
/// every row's `set_min_y_gutter()` to measure what its own labels need, so a floor
|
||||
/// written onto the rows survives exactly until the next layout.
|
||||
void apply_y_gutter();
|
||||
/// Both have to be the *figure's* and not each row's: `Figure::layout()` clears every
|
||||
/// row's `set_min_y_gutter()` to measure what its own labels need, so a floor written
|
||||
/// onto the rows survives exactly until the next layout, and the rows have to end on
|
||||
/// one column as well as start on one.
|
||||
void apply_gutters();
|
||||
|
||||
/// The palette entry `index`, wrapped. Keyed by the *signal*, so that the colour a
|
||||
/// trace is drawn in is the colour the signal list's chip shows, on every row the
|
||||
@@ -431,6 +435,9 @@ class RowSet {
|
||||
/// gesture to be honoured; one that matches it is just the clamp's own answer arriving back.
|
||||
plot::Range pinned_stated_{0.0, 0.0};
|
||||
double y_gutter_px_ = 0.0;
|
||||
/// The empty band kept to the right of the data, device pixels. Nothing is drawn in it,
|
||||
/// so it is reserved once from the font's metrics and never measured or grown.
|
||||
double right_gutter_px_ = 0.0;
|
||||
bool y_gutter_reserved_ = false;
|
||||
std::array<Row, static_cast<std::size_t>(kMaxRows)> storage_{};
|
||||
CursorMode cursor_mode_ = CursorMode::Vertical;
|
||||
|
||||
Reference in new issue
Block a user