This repository has no description

apprt/gtk: fix audio-bell GStreamer thread leak (reuse one MediaFile per surface) (#12815) master

## Problem Every audio bell calls `gtk.MediaFile.newForFilename`, which spins up a full GStreamer pipeline. The GTK4 GStreamer backend's GL sink starts `gstglcontext`/`gldisplay-event` threads that are **never joined on teardown**, so allocating a fresh `MediaFile` per ring leaks a pipeline and ~4 threads on every bell. The old `notify::ended -> unref` handler discarded the pipeline but did not (and could not) join those threads. A long-running instance accumulated **705 threads over ~4h** of normal use. ## Fix Cache one `MediaFile` per surface (`priv.bell_media`), rebuilt only when `bell-audio-path` changes and unref'd on `dispose`. Each bell now replays the same pipeline via `seek(0)` + `play()` instead of creating a new one. `seek(0)` is required so an ended stream plays again (cf. #8957). ## Verification Confirmed on a real running instance with the fix: GStreamer's global element counter only ever reached `oggdemux4` over an hour of use (one pipeline per bell-ringing surface, reused for every subsequent bell) and the process thread count stayed flat — versus the per-bell growth before. ## Commits 1. **The fix** — reuse one MediaFile per surface. 2. **Unit regression test** — guards the `bellMediaFile` reuse contract (same path → same object, changed path → rebuild). Runs in the existing `test-gtk` CI job; needs no display. 3. **End-to-end CI job** *(kept separate so it can be dropped independently)* — `test/bell-leak.sh` + a `test-gtk-bell-leak` workflow job that runs ghostty headless (Xvfb + software GL), rings 120 bells, and fails if the thread count grows per-bell. It's heavier and more environment-sensitive (needs Xvfb/Mesa/GStreamer on the runner), so it's isolated for easy review/removal. 🤖 Generated with [Claude Code](https://claude.com/claude-code)


+202 -20
3 changed files