The fork takes its own name everywhere a user can see it: binaries (voculinux, voculinux-gui), desktop entry, autostart, tray, D-Bus namespace (com.voculinux.Voculinux, no alias for the old name), config/data/cache dirs, single-instance lock, IBus engine identity, tray icons, resource prefixes, VOCULINUX_* environment names, and the update-checker user agent. The internal Python module stays vocalinux and the distribution metadata keeps the upstream URLs as provenance. On first run a previous Vocalinux install's config.json, custom dictionary, and portal restore token are copied once into the new locations (new config always wins, no merge, no write-back); models re-resolve through the pinned-checksum download path. An offline naming-sweep test proves no old-name strings remain on user-visible surfaces outside the allowlist. Refs #18
164 lines
8.0 KiB
YAML
164 lines
8.0 KiB
YAML
# Voculinux Snap packaging
|
|
#
|
|
# First ship: strict confinement, default whisper.cpp engine path, GTK tray UI,
|
|
# mic capture, model download, and text injection (RemoteDesktop portal, wtype, xdotool).
|
|
# Informed by issue #48 and packaging/flatpak lessons on feat/flatpak-packaging.
|
|
#
|
|
# Build (from repo root, with snapcraft + LXD or Multipass):
|
|
# snapcraft pack
|
|
# See docs/SNAP.md for controlled inputs, the build gate and verification limits.
|
|
|
|
name: voculinux
|
|
base: core24 # Ubuntu 24.04 / Python 3.12 (project requires-python >=3.11)
|
|
# Fallback version; live version is set from src/vocalinux/version.py via
|
|
# adopt-info + craftctl set in the voculinux part (required for craftctl).
|
|
version: "0.17.0"
|
|
adopt-info: voculinux
|
|
summary: Free offline voice dictation for Linux
|
|
description: |
|
|
Voculinux is free voice typing for Linux. Hold a shortcut or toggle dictation, and text lands in almost any app on X11 or Wayland.
|
|
|
|
Speech recognition runs on your machine after you download a model. No Voca account. No cloud transcription on the default path.
|
|
|
|
This snap ships the whisper.cpp engine. Optional local speech engines are not bundled.
|
|
|
|
Features:
|
|
- System tray control and GTK settings
|
|
- Offline dictation (models download on first use)
|
|
- Microphone capture and short feedback tones
|
|
- Text injection via the Wayland RemoteDesktop portal, wtype, or xdotool
|
|
|
|
Sandbox notes:
|
|
- Global hotkeys need: sudo snap connect voculinux:raw-input
|
|
and sudo snap connect voculinux:hardware-observe
|
|
- Native Wayland typing uses the RemoteDesktop portal: the compositor
|
|
asks once on first dictation. The snap ships no uinput plug and no
|
|
ydotool; the Store denied the super-privileged grant.
|
|
- KDE Plasma: KWin's portal can mistype letter case (KDE bug 489021);
|
|
set "Virtual Keyboard = IBus Wayland" so the IBus path delivers text.
|
|
- Microphone may need: sudo snap connect voculinux:audio-record
|
|
The microphone list comes from the sound server, so pick a device
|
|
in Settings rather than relying on the system default.
|
|
- whisper.cpp runs on the CPU in this snap; it has no GPU backend.
|
|
For Vulkan acceleration install the AppImage or use install.sh.
|
|
- Config and models live under ~/snap/voculinux/
|
|
|
|
grade: stable
|
|
confinement: strict
|
|
license: AGPL-3.0-only
|
|
icon: snap/gui/voculinux.png
|
|
contact: https://github.com/VocaHQ/vocalinux/issues
|
|
issues: https://github.com/VocaHQ/vocalinux/issues
|
|
website: https://voculinux.com
|
|
source-code: https://github.com/VocaHQ/vocalinux
|
|
donation: https://github.com/sponsors/jatinkrmalik
|
|
|
|
apps:
|
|
voculinux:
|
|
command: bin/voculinux
|
|
extensions: [gnome]
|
|
plugs:
|
|
# gnome extension already grants desktop, desktop-legacy, gsettings,
|
|
# opengl, wayland, x11, unity7 (tray / indicators).
|
|
- audio-record # microphone (may require manual connect)
|
|
- audio-playback # start/stop feedback tones (PipeWire-pulse / PulseAudio)
|
|
- home # optional access outside snap HOME (shared files)
|
|
- network # download speech models on first run
|
|
- network-bind # optional remote_api engine
|
|
# Global hotkeys via python-evdev (/dev/input/event*).
|
|
# Super-privileged: not auto-connected; user must:
|
|
# sudo snap connect voculinux:raw-input
|
|
- raw-input
|
|
# Needed for /proc/bus/input/devices; not auto-connected:
|
|
# sudo snap connect voculinux:hardware-observe
|
|
- hardware-observe
|
|
# No uinput plug; the RemoteDesktop portal types on Wayland instead.
|
|
# The Store denied the super-privileged grant
|
|
# (https://forum.snapcraft.io/t/53528), and ydotool is not staged
|
|
# because it cannot reach /dev/uinput under confinement.
|
|
common-id: com.voculinux.Voculinux
|
|
desktop: usr/share/applications/voculinux.desktop
|
|
environment:
|
|
# Prefer bundled CLI helpers (xdotool, xsel, xclip, wl-copy).
|
|
# Do NOT prepend $SNAP/usr/lib over the gnome extension platform path:
|
|
# that loads a second GLib/GTK and segfaults on `from gi.repository import Gtk`.
|
|
PATH: $SNAP/usr/bin:$SNAP/bin:$PATH
|
|
# PortAudio opens ALSA first. Point at snap-local config that routes to Pulse.
|
|
ALSA_CONFIG_PATH: $SNAP/etc/asound.conf
|
|
# core24 gnome-46-2404: desktop-launch rebuilds gdk-pixbuf-loaders.cache
|
|
# by running query-loaders, which picks the SVG loader from the first
|
|
# LD_LIBRARY_PATH entry ending in /$CRAFT_ARCH_TRIPLET. Stage-packages
|
|
# (via libavcodec and friends) put a gdk-pixbuf tree without
|
|
# libpixbufloader_svg.so at $SNAP/usr/lib/$CRAFT_ARCH_TRIPLET, ahead of
|
|
# gnome-platform. About page and other GdkPixbuf SVG loads then fail
|
|
# with "Image type svg is not supported".
|
|
# https://forum.snapcraft.io/t/missing-svg-support-for-gtk3-in-core24/48851
|
|
LD_LIBRARY_PATH: $SNAP/gnome-platform/usr/lib/$CRAFT_ARCH_TRIPLET:$LD_LIBRARY_PATH
|
|
|
|
# Make ALSA data/plugins visible at the paths libasound expects.
|
|
layout:
|
|
/usr/share/alsa:
|
|
bind: $SNAP/usr/share/alsa
|
|
/usr/lib/$CRAFT_ARCH_TRIPLET/alsa-lib:
|
|
bind: $SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/alsa-lib
|
|
|
|
parts:
|
|
voculinux:
|
|
# The Python plugin would resolve dependencies and build tools again.
|
|
plugin: nil
|
|
source: .
|
|
source-type: local
|
|
build-environment:
|
|
# pywhispercpp's PyPI wheel ships a libggml-cpu compiled for AVX2+FMA,
|
|
# which dies with SIGILL at model load on pre-Haswell CPUs (#957), so
|
|
# the pinned sdist is built instead of installing that wheel.
|
|
# GGML_NATIVE=OFF alone is not the portable baseline either: while
|
|
# ggml's native default is on it turns every GGML_* SIMD option on, so
|
|
# each one is pinned off for the plain x86-64 baseline.
|
|
- CMAKE_ARGS: "-DGGML_NATIVE=OFF -DGGML_SSE42=OFF -DGGML_AVX=OFF -DGGML_AVX2=OFF -DGGML_BMI2=OFF -DGGML_FMA=OFF -DGGML_F16C=OFF"
|
|
build-packages:
|
|
- build-essential
|
|
- git
|
|
- pkg-config
|
|
- portaudio19-dev
|
|
- libgirepository1.0-dev
|
|
- libcairo2-dev
|
|
- python3-dev
|
|
- python3-venv
|
|
- libdbus-1-dev
|
|
stage-packages:
|
|
# Only extras not provided by the gnome-46-2404 platform content snap.
|
|
# Staging GTK/GLib/AppIndicator here duplicates the platform and can crash GI.
|
|
- libportaudio2
|
|
- libasound2t64 # Ubuntu 24.04 / core24 name for libasound2
|
|
- libasound2-data
|
|
- libasound2-plugins # pcm/ctl pulse → host PulseAudio/PipeWire
|
|
- pulseaudio-utils # paplay for start/stop UI sounds; pactl lists microphones
|
|
- xdotool
|
|
- wtype # virtual-keyboard protocol (GNOME often rejects this)
|
|
- x11-utils # xprop for XWayland WM_CLASS
|
|
- xsel
|
|
- xclip
|
|
- wl-clipboard
|
|
override-pull: |
|
|
craftctl default
|
|
version="$(python3 -c "import pathlib, re; t = pathlib.Path('${CRAFT_PART_SRC}/src/vocalinux/version.py').read_text(); m = re.search(r'__version__\\s*=\\s*[\\'\"]([^\\'\"]+)', t); assert m, 'version not found'; print(m.group(1))")"
|
|
craftctl set version="$version"
|
|
override-build: |
|
|
# The runtime export already excludes PyGObject; GI comes from the gnome
|
|
# extension. Keep pyproject.toml and installed metadata unchanged.
|
|
/usr/bin/python3 "${CRAFT_PART_SRC}/snap/local/build.py" \
|
|
--source "${CRAFT_PART_BUILD}" --install "${CRAFT_PART_INSTALL}" \
|
|
--work "${CRAFT_PART_BUILD}/.snap-python-build"
|
|
install -Dm644 "${CRAFT_PART_SRC}/snap/local/check_runtime.py" \
|
|
"${CRAFT_PART_INSTALL}/usr/lib/voculinux/check_runtime.py"
|
|
install -Dm644 "${CRAFT_PROJECT_DIR}/snap/gui/voculinux.desktop" \
|
|
"${CRAFT_PART_INSTALL}/usr/share/applications/voculinux.desktop"
|
|
install -Dm644 "${CRAFT_PROJECT_DIR}/resources/icons/scalable/voculinux.svg" \
|
|
"${CRAFT_PART_INSTALL}/usr/share/icons/hicolor/scalable/apps/voculinux.svg"
|
|
# meta/gui is what snapd uses for the store/desktop icon when present.
|
|
install -Dm644 "${CRAFT_PROJECT_DIR}/resources/icons/scalable/voculinux.svg" \
|
|
"${CRAFT_PART_INSTALL}/meta/gui/icon.svg"
|
|
install -Dm644 "${CRAFT_PROJECT_DIR}/snap/local/alsa/asound.conf" \
|
|
"${CRAFT_PART_INSTALL}/etc/asound.conf"
|