fix: place the guided tour's card from its allocation, and count GTK warnings

The tour measured its card with a height-for-width request whose for_size
came from the natural width minus the margins the tour sets for positioning.
A measure reports margins *included*, so that for_size landed a margin short
of the minimum the box answers with and GTK warned once per frame:

  Trying to measure GtkBox 0x... for width of N, but it needs at least M

(about 9/s for as long as the tour was up). The card now takes its size from
gtk_widget_compute_bounds() once a frame has run -- its allocation rectangle,
not gtk_widget_get_width(), which is only the content box -- and falls back
to a measure with no for_size at all only on a frame with nothing allocated.

GTK is built with structured logging, so its messages reach the log writer
and never the handler API; no existing probe can read one. The exit dump now
counts them (`gtk warnings:`, must read 0) through a writer function chained
to g_log_writer_default(), which leaves stderr unchanged.
This commit is contained in:
Martino Ferrari committed 2026-10-14 17:38:25 +02:00
1 parent d8a79b96ba
commit bb62b8178c
5 files changed
+94 -12

No files matched your search

+17
View File
@@ -511,6 +511,23 @@ The `Help` submenu, the contextual help's "?" and the guided tour, and the traps
request did not help -- the margin alone was the loop). Take the margins off a measure that feeds a
position back. `hdl`/`bd`-style CSS padding is *not* part of it, and neither is the other axis's
margin, so it is `margin-start + margin-end` on the horizontal and top/bottom on the vertical.
- **A widget's allocation is not `gtk_widget_get_width()`, and a measure is never a position.** GTK's
`gtk_widget_get_width()`/`get_height()` return the widget's **content** box: `size_allocate`
subtracts the CSS border and padding before storing them (measured on the tour card, which carries
`border 1px` + `padding 12px`: `get_width()` reads 254 where the rectangle on screen is 280), so a
card *placed* from it overhangs its own size and covers the target it is meant to sit beside.
`gtk_widget_compute_bounds()` is that rectangle -- border and padding in, margins out -- and is what
the probe's geometry and the help's figures already read. And `gtk_widget_measure()` cannot stand in
for it: its size includes the widget's margins (the bullet above), and asking for a **height with a
width** (`for_size`) on a widget whose margins were then subtracted from that width makes GTK warn
`Trying to measure GtkBox ... for width of N, but it needs at least M` **once per frame**, because
the for_size lands one margin short of the minimum the widget answers with. The guided tour's card
therefore takes its size from `compute_bounds()` once a frame has run and falls back to a measure
**with no for_size at all** (`-1`, the form GTK measures without that check) only on a frame with
nothing allocated yet. The warning reaches no probe -- GTK is built with **structured logging**, so
it goes through the log *writer* and never `g_log_set_handler()`/`g_log_set_default_handler()` --
which is why the exit dump counts GTK's own warnings through a writer function (`gtk warnings:`,
which must read 0) as the one reading that can assert the class away.
- **The overflow menu's `Help` submenu is a two-page `GtkStack`, and neither of the obvious
alternatives works.** Rebuilding the rows -- the plot menu's own shape -- destroys
`app.layout_toggle`, which points into the main view and which `sync_layout_editor()` and the `L`
+11
View File
@@ -410,6 +410,17 @@ Two lines of the self-check output are assertions in disguise:
against the same config directory reads `auto=0` — and `requested=1` is the **chooser's** "Guided tour"
(`Config::tour_pending`) having been carried into this run instead, which is `auto=0` because it is not
the auto-start.
- `gtk warnings: N` (in the exit dump, beside `help layer:`) — **GTK's own log at warning or above,
counted for the whole run, and it must read `0`.** It is counted through a log *writer* function
because GTK is built with structured logging: its messages go through the writer and never through
`g_log_set_handler()`/`g_log_set_default_handler()`, which is exactly why no probe can read one —
the message is written by the toolkit from inside a call of ours and is stored in no widget. The
first class to need it was `Trying to measure GtkBox … for width of N, but it needs at least M`
(once per frame, from a card measured for a height with a width a margin short of its own minimum;
see the allocation bullet in
[invariants-gtk-and-chrome.md](invariants-gtk-and-chrome.md)). The writer chains to
`g_log_writer_default()`, so every message still reaches stderr exactly as before and the documented
baselines are read the same way.
- `help figures: trigger_head=X,Y,W,H trigger_summary=… trigger_panel=… signal_list=… side_switcher=… side_stack=… window_button=… status_label=… header_bar=… plot=…` (in the exit
dump, beside `help layer:`) — the **window-coordinate** rectangle of each surface the help's annotated
figures label, `x,y,width,height`, or `-1,-1,0,0` for a surface that is **not on screen**. It is
+4 -1
View File
@@ -24,7 +24,10 @@ touching each `*.gresource.xml` under `src/` and rebuilding; a third `-Wmissing-
or any other warning is a finding. (The fifth warning that used to appear here was an unused
`output_built` in `math_probe()`; it was **deleted** as dead code — redundant with the
`output_after_add` already printed on the same line — which dropped the baseline from five to
four.) And an exit-dump run emits **no** `Gtk-CRITICAL` at all.
four.) And an exit-dump run emits **no** `Gtk-CRITICAL` at all, nor any `Gtk-WARNING`: the dump's
`gtk warnings:` line counts GTK's own log (through a writer function — GTK is built with structured
logging, so the handler API never sees its messages) and must read `0`; see
[probe-readings.md](probe-readings.md).
An *incremental* build reads **one** of those three: the generated GResource `.c` is not recompiled
when only `src/` changed, so its `-Woverlength-strings` does not reappear.