v0.20.6: one press, sixteen hundred songs

A single Right-arrow press skipped 1,676 tracks in 81 s and hard-froze the
desktop. On Wayland key repeat is generated by the client until the
compositor delivers the release, and the key filter treated every repeat as
a new press. Each skip sent gnome-shell an MPRIS Metadata whose xesam:artist
was a plain Python list, which marshals as "av" instead of "as". gnome-shell
logged an error for every one (50k/min) and reloaded the cover, and that load
is what kept it from ever delivering the release.

Space/Left/Right now act once per press and swallow the repeats.
xesam:artist goes out through mpris.string_array, which build_properties_changed
now shares for invalidated_properties. The new test round-trips the signal
into GDBus, which is what gnome-shell validates with, and fails 'av' == 'as'
against the old code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-17 21:52:45 -07:00
co-authored by Claude Opus 5
parent f091a545f5
commit 0e726af0da
6 changed files with 186 additions and 8 deletions
+7 -1
View File
@@ -283,7 +283,13 @@ persistence) → GUI (Qt widgets that read the manager and connect to its signal
- **`lintunes/mpris.py`** — registers `org.mpris.MediaPlayer2.lintunes` over D-Bus
so the desktop's media keys / now-playing popup control playback. Spacebar and
arrow keys are handled locally via `MainWindow.eventFilter`.
arrow keys are handled locally via `MainWindow.eventFilter`, which **ignores
auto-repeat**: on Wayland repeats are generated client-side until the
compositor delivers the release, and a busy gnome-shell turned one held
arrow into 1,676 track skips (Round 56). Every list sent over D-Bus must be
a typed `QDBusArgument` (`mpris.string_array`) — a plain Python list goes
out as `av`, which GDBus rejects. That was `xesam:artist`, and the error
flood it caused is what kept gnome-shell busy.
- **`lintunes/trash.py`** — freedesktop.org Trash spec 1.0, hand-rolled (no new
dep). The trash is **per-filesystem**: music usually lives on a mounted volume,