Skip to content

snap: bundle gstreamer plugins so audio bell works#12676

Open
aaron-ang wants to merge 2 commits into
ghostty-org:mainfrom
aaron-ang:fix/snap-bell-audio
Open

snap: bundle gstreamer plugins so audio bell works#12676
aaron-ang wants to merge 2 commits into
ghostty-org:mainfrom
aaron-ang:fix/snap-bell-audio

Conversation

@aaron-ang
Copy link
Copy Markdown
Contributor

@aaron-ang aaron-ang commented May 14, 2026

Summary

With bell-features = audio and a valid bell-audio-path configured, no sound plays in the snap build of Ghostty.

The snap stages libgtk-4-media-gstreamer and the core GStreamer libraries but ships only libgstcoreelements.so and libgstcoretracers.so — none of the playback, decode, or audio-sink plugins that the GTK media backend needs to build a pipeline. The bell therefore silently fails.

bell-features = system (compositor sound, routed via gdk_surface_beep()) already works and is unchanged.

Fix

  • Stage gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, and gstreamer1.0-pulseaudio so the snap ships typefind, decodebin, vorbis, audioconvert, autoaudiosink, pulsesink, etc.
  • Export GST_PLUGIN_SYSTEM_PATH, GST_PLUGIN_SCANNER, and GST_REGISTRY in snap/local/launcher so GStreamer finds the bundled plugins and writes a per-user registry cache under SNAP_USER_COMMON.

Local build (how this PR was verified)

Official snap CI builds from a release tarball, so the committed snapcraft.yaml assumes pre-generated .ui resources are present. Building from a git checkout requires two extra things that are not part of this PR (they would belong in a separate change to make snap/snapcraft.yaml git-source-buildable):

  1. A VERSION file at the repo root (release tarballs include one):

    echo 1.3.2-dev > VERSION
  2. A blueprint-compiler part plus PyGObject build deps so the GTK UI resources can be generated at build time. Apply this diff on top of the PR before running snapcraft pack:

     parts:
       ...
    +  blueprint-compiler:
    +    source: https://gitlab.gnome.org/jwestman/blueprint-compiler.git
    +    source-tag: v0.18.0
    +    plugin: meson
    +    meson-parameters: [--prefix=/usr]
    +    build-packages:
    +      - meson
    +      - python3
    +      - python3-jinja2
    +    prime:
    +      - -*
    +
       ghostty:
         source: .
    -    after: [zig]
    +    after: [zig, blueprint-compiler]
         plugin: nil
         build-attributes: [enable-patchelf]
         build-packages:
           - libgtk-4-dev
           - libadwaita-1-dev
           - libxml2-utils
           - git
           - patchelf
           - gettext
    +      - python3-gi
    +      - gir1.2-gtk-4.0
    +      - gir1.2-adw-1
         override-build: |
           craftctl set version=$(cat VERSION)
    +      export PATH="$CRAFT_PART_SRC/../../zig/src:$CRAFT_STAGE/usr/bin:$PATH"
    +      cp -r "$CRAFT_STAGE/usr/lib/python3/dist-packages/blueprintcompiler" \
    +        /usr/lib/python3/dist-packages/
           $CRAFT_PART_SRC/../../zig/src/zig build \

    The cp is needed because blueprint-compiler.py hard-codes the meson-configured module path (/usr/lib/python3/dist-packages) into the installed script; making the staged copy importable means putting it on that exact path inside the build container.

With those in place:

snapcraft pack
sudo snap install --dangerous --classic ./ghostty_1.3.2-dev_*.snap

Test plan

Verified locally on Ubuntu 24.04 / arm64 using the build above.

  • With config
    bell-features = system,audio
    bell-audio-path = /usr/share/sounds/freedesktop/stereo/bell.oga
    
    printf '\a' rings both the compositor system bell and plays the audio file.
  • No new warnings in Ghostty startup logs related to GStreamer plugin discovery.

AI Disclosure

Claude Code was used throughout: diagnosing why bell-features = audio produced silence in the snap (no playback/decode/sink plugins bundled despite libgtk-4-media-gstreamer being staged), drafting the snapcraft.yaml and snap/local/launcher changes, and driving the snapcraft pack build iteration that uncovered the temporary git-source build requirements documented above (which are not part of this PR).

I reviewed every line of the diff and understand the role of each change: the three GStreamer plugin packages provide the pipeline elements GTK media needs (typefind, decodebin, vorbis, audioconvert, autoaudiosink, pulsesink), and the three new env vars in the launcher point GStreamer at the bundled plugin directory and a user-writable registry cache. I rebuilt the snap, installed it, and confirmed both system and audio bell fire when configured.

@jcollie
Copy link
Copy Markdown
Member

jcollie commented May 14, 2026

You need to disclose your use of AI. See https://github.com/ghostty-org/ghostty/blob/main/AI_POLICY.md

@aaron-ang
Copy link
Copy Markdown
Contributor Author

You need to disclose your use of AI. See main/AI_POLICY.md

added

When `bell-features = audio` is enabled the GTK media stack uses
libgtk-4-media-gstreamer, which in turn needs GStreamer playback and
sink plugins to decode and route the audio. The current snap stages
libgtk-4-media-gstreamer but ships none of the actual plugins, so the
bell silently fails to play even when configured.

Stage gstreamer1.0-plugins-base/-good/-pulseaudio for the decode +
audio sink pipeline (typefind, decodebin, vorbis, audioconvert,
autoaudiosink, pulsesink), and export GST_PLUGIN_SYSTEM_PATH,
GST_PLUGIN_SCANNER and GST_REGISTRY in the launcher so child
processes find the bundled plugins and write a per-user registry
cache under SNAP_USER_COMMON.
@aaron-ang aaron-ang force-pushed the fix/snap-bell-audio branch from 26b7256 to dd6d401 Compare May 14, 2026 04:26
@kenvandine kenvandine self-requested a review May 14, 2026 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants