improved perfs and event management

This commit is contained in:
Martino Ferrari committed 2026-10-13 23:00:42 +02:00
1 parent 667ed0c100
commit bb99be5889
17 files changed
+626 -59

No files matched your search

+17
View File
@@ -207,6 +207,23 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
thread and `gtk_picture_set_paintable()` hands over the result -- and a NULL texture at least says
so. A picture that must be on screen is also a picture with a **height request**: `can_shrink`
alone asks for no height at all in a box.
- **A cache that is the *only* source of a widget's content must be created by the thing that reads
it.** The event pane's thumbnails come from an `EventThumbCache` hung off the list box with
`g_object_set_data_full`, and `event_preview_texture()` answers out of that cache or not at all.
Nothing ever created it — so for as long as the pane existed, **every** row came up without a
picture, which is what "event screenshot are unusable and sometime missing" was. A missing cache
there is not a slow path, it is a blank one; `event_thumb_cache()` therefore creates one on first
use. Owned by the **list**, because nothing else has the pane's lifetime: textures of a list that
no longer exists are so much held memory, and the destroy notify is where they are unref'd.
- **Hover magnification is a tooltip, not a popover of ours.** A row's thumbnail is 138 px wide and
the stored preview is 480: the small one says *which* event this is, and the zoom says what is in
it. GTK's own tooltip (`gtk_widget_set_has_tooltip` + `query-tooltip` + `gtk_tooltip_set_custom`)
is shown, placed, dismissed **and destroyed** by GTK, and takes no pointer grab. A popover per row
would be a parented widget to unparent on every rebuild of the pane — one defect below — and a
grab to lose, for a thing with no interaction in it. Two details: `can_shrink` must be FALSE on the
tooltip's picture or the tooltip is given the smallest size its content allows (the opposite of the
point), and the path handed to the handler has to be **owned by the closure**
(`g_signal_connect_data` with a destroy func), since the record it came from is a loop variable.
- **Unparenting a popover inside its own `closed` emission is a use-after-free.** Dismissals go
through `gtk_popover_popdown()`, which emits `closed`; a handler that unparents the popover there
drops the reference the parent held, the widget dies, and GTK's own popdown path then runs on freed