docs(packaging): prefer Ayatana AppIndicator in Fedora/Arch hints (#638)

* docs(packaging): prefer Ayatana AppIndicator in Fedora/Arch hints

Follow-up to #621: align docs, AUR depends, package map, dependency
check messages, and troubleshooting copy with the Ayatana-first install
path so manual installs and AUR users get a working KDE tray icon.

Co-authored-by: Jatin K Malik <jatinkrmalik@users.noreply.github.com>

* style(main): black-format Ayatana install hint lines

CI black --check failed on the multi-line logger.error calls for the
Fedora/Arch package hints.

Co-authored-by: Jatin K Malik <jatinkrmalik@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Jatin K Malik <jatinkrmalik@users.noreply.github.com>
This commit is contained in:
Jatin K Malik
2026-08-04 04:53:34 +05:30
committed by GitHub
co-authored by Jatin K Malik Cursor Agent
parent afc4b37c80
commit 9c340029e1
8 changed files with 57 additions and 28 deletions
+3 -3
View File
@@ -173,7 +173,7 @@ native dependencies; it does **not** mean beta or unstable packages. If
### Gentoo
```bash
sudo emerge dev-python/pygobject:3 x11-libs/gtk+:3 dev-libs/libappindicator:3 \
sudo emerge dev-python/pygobject:3 x11-libs/gtk+:3 dev-libs/libayatana-appindicator \
media-libs/portaudio dev-lang/python:3.9
```
@@ -239,14 +239,14 @@ On Ubuntu 24.04+ or Pop!_OS, install `libgirepository-2.0-dev` if
#### Fedora
```bash
sudo dnf install python3-gobject gtk3 gtk3-devel libappindicator-gtk3 \
sudo dnf install python3-gobject gtk3 gtk3-devel libayatana-appindicator-gtk3 \
gobject-introspection-devel portaudio-devel python3-devel \
python3-virtualenv pkg-config xdotool wtype wl-clipboard xclip xsel
```
#### Arch Linux
```bash
sudo pacman -S python-gobject gtk3 libappindicator gobject-introspection \
sudo pacman -S python-gobject gtk3 libayatana-appindicator gobject-introspection \
python-cairo portaudio python-virtualenv pkg-config xdotool wtype wl-clipboard xclip xsel
```
+4 -4
View File
@@ -69,7 +69,7 @@ vocalinux
```bash
sudo dnf install -y \
python3-virtualenv python3-devel python3-gobject gtk3 gtk3-devel \
libappindicator-gtk3 gobject-introspection-devel portaudio-devel \
libayatana-appindicator-gtk3 gobject-introspection-devel portaudio-devel \
pkg-config xdotool wtype wl-clipboard xclip xsel
python3 -m venv ~/.local/share/vocalinux-pypi/venv --system-site-packages
@@ -89,7 +89,7 @@ See [AUR.md](AUR.md). Or via PyPI:
```bash
sudo pacman -S --needed \
python python-virtualenv python-gobject gtk3 libappindicator-gtk3 \
python python-virtualenv python-gobject gtk3 libayatana-appindicator \
gobject-introspection python-cairo portaudio pkg-config xdotool wtype wl-clipboard xclip xsel
python -m venv ~/.local/share/vocalinux-pypi/venv --system-site-packages
@@ -369,7 +369,7 @@ sudo apt install -y wtype wl-clipboard xclip xsel
```bash
sudo dnf install -y \
python3-pip python3-devel python3-virtualenv \
python3-gobject gtk3 libappindicator-gtk3 \
python3-gobject gtk3 libayatana-appindicator-gtk3 \
gobject-introspection-devel portaudio-devel \
wget curl unzip xdotool wtype wl-clipboard xclip xsel
```
@@ -378,7 +378,7 @@ sudo dnf install -y \
```bash
sudo pacman -S --noconfirm \
python-pip python-gobject gtk3 \
libappindicator-gtk3 gobject-introspection \
libayatana-appindicator gobject-introspection \
python-cairo portaudio python-virtualenv \
wget curl unzip xdotool wtype wl-clipboard xclip xsel
```
+1 -1
View File
@@ -14,7 +14,7 @@ depends=(
'python>=3.9'
'python-gobject'
'gtk3'
'libappindicator-gtk3'
'libayatana-appindicator'
'ibus'
'gobject-introspection'
'python-cairo'
+5 -5
View File
@@ -161,10 +161,10 @@ PY
echo " sudo apt install -y python3-gi gir1.2-gtk-3.0 gir1.2-gdkpixbuf-2.0 portaudio19-dev python3-dev python3-venv pkg-config xdotool wtype wl-clipboard xclip xsel"
elif [[ "$DETECTED_DISTRO" == "fedora" || "$DETECTED_DISTRO_LIKE" == *"fedora"* || "$DETECTED_DISTRO" == "rhel" || "$DETECTED_DISTRO" == "centos" || "$DETECTED_DISTRO" == "rocky" || "$DETECTED_DISTRO" == "almalinux" ]]; then
echo "Fedora/RHEL-based:"
echo " sudo dnf install -y python3-gobject gtk3-devel gobject-introspection-devel portaudio-devel python3-devel python3-virtualenv pkg-config xdotool wtype wl-clipboard xclip xsel"
echo " sudo dnf install -y python3-gobject gtk3-devel libayatana-appindicator-gtk3 gobject-introspection-devel portaudio-devel python3-devel python3-virtualenv pkg-config xdotool wtype wl-clipboard xclip xsel"
elif [[ "$DETECTED_DISTRO" == "arch" || "$DETECTED_DISTRO_LIKE" == *"arch"* || "$DETECTED_DISTRO" == "manjaro" || "$DETECTED_DISTRO" == "endeavouros" ]]; then
echo "Arch Linux-based:"
echo " sudo pacman -S --needed python-gobject gtk3 gobject-introspection portaudio python pkg-config xdotool wtype wl-clipboard xclip xsel"
echo " sudo pacman -S --needed python-gobject gtk3 libayatana-appindicator gobject-introspection portaudio python pkg-config xdotool wtype wl-clipboard xclip xsel"
elif [[ "$DETECTED_DISTRO" == "opensuse" || "$DETECTED_DISTRO_LIKE" == *"suse"* ]]; then
echo "openSUSE:"
echo " PYVER=\$(python3 -c 'import sys; print(f\"python{sys.version_info.major}{sys.version_info.minor}\")')"
@@ -172,7 +172,7 @@ PY
echo " If \"\${PYVER}-virtualenv\" is unavailable, try \"\${PYVER}-venv\"."
elif [[ "$DETECTED_DISTRO" == "gentoo" ]]; then
echo "Gentoo:"
echo " sudo emerge dev-python/pygobject:3 x11-libs/gtk+:3 dev-libs/libappindicator:3 media-libs/portaudio dev-lang/python:3.9 xdotool wtype"
echo " sudo emerge dev-python/pygobject:3 x11-libs/gtk+:3 dev-libs/libayatana-appindicator media-libs/portaudio dev-lang/python:3.9 xdotool wtype"
elif [[ "$DETECTED_DISTRO" == "alpine" ]]; then
echo "Alpine Linux:"
echo " sudo apk add py3-gobject3 py3-pip gtk+3.0 py3-cairo portaudio-dev py3-virtualenv pkgconf xdotool wtype"
@@ -194,10 +194,10 @@ PY
echo " sudo apt install -y python3-gi gir1.2-gtk-3.0 portaudio19-dev python3-dev pkg-config xdotool wtype wl-clipboard xclip xsel"
echo ""
echo "Fedora/RHEL-based:"
echo " sudo dnf install -y python3-gobject gtk3-devel portaudio-devel python3-devel pkg-config xdotool wtype wl-clipboard xclip xsel"
echo " sudo dnf install -y python3-gobject gtk3-devel libayatana-appindicator-gtk3 portaudio-devel python3-devel pkg-config xdotool wtype wl-clipboard xclip xsel"
echo ""
echo "Arch Linux:"
echo " sudo pacman -S python-gobject gtk3 portaudio python pkg-config xdotool wtype wl-clipboard xclip xsel"
echo " sudo pacman -S python-gobject gtk3 libayatana-appindicator portaudio python pkg-config xdotool wtype wl-clipboard xclip xsel"
fi
echo ""
+5 -3
View File
@@ -22,14 +22,16 @@ system_packages:
solus: ["python3-gobject", "gtk3"]
# AppIndicator / Ayatana AppIndicator
# Prefer Ayatana: legacy Canonical AppIndicator can load without error but
# fail to register a StatusNotifierItem on modern KDE Plasma.
appindicator:
ubuntu: ["gir1.2-appindicator3-0.1"]
debian_11: ["gir1.2-ayatanaappindicator3-0.1"]
debian_12_plus: ["gir1.2-ayatanaappindicator3-0.1"]
fedora: ["libappindicator-gtk3"]
arch: ["libappindicator-gtk3"]
fedora: ["libayatana-appindicator-gtk3"]
arch: ["libayatana-appindicator"]
opensuse: ["typelib-1_0-AyatanaAppIndicator3-0_1", "libayatana-appindicator3-1", "typelib-1_0-AppIndicator3-0_1"]
gentoo: ["dev-libs/libappindicator:3"]
gentoo: ["dev-libs/libayatana-appindicator"]
alpine: ["libayatana-appindicator"]
void: ["libappindicator"]
solus: ["libappindicator"]
+8 -7
View File
@@ -109,18 +109,19 @@ def check_dependencies():
"GTK3 (install with: sudo apt install python3-gi gir1.2-gtk-3.0)"
)
# Check for AppIndicator3 / Ayatana AppIndicator
# Prefer Ayatana AppIndicator (maintained; registers on KDE Plasma).
# Legacy Canonical AppIndicator3 is only accepted as a fallback.
try:
import gi
gi.require_version("AppIndicator3", "0.1")
from gi.repository import AppIndicator3 # noqa: F401
gi.require_version("AyatanaAppIndicator3", "0.1")
from gi.repository import AyatanaAppIndicator3 # noqa: F401
except (ImportError, ValueError):
try:
import gi
gi.require_version("AyatanaAppIndicator3", "0.1")
from gi.repository import AyatanaAppIndicator3 # noqa: F401
gi.require_version("AppIndicator3", "0.1")
from gi.repository import AppIndicator3 # noqa: F401
except (ImportError, ValueError):
missing_system_deps.append(
"AppIndicator3/AyatanaAppIndicator3 - Required for system tray icon"
@@ -152,10 +153,10 @@ def check_dependencies():
logger.error(" Then log out and back in. Ubuntu includes this by default.")
logger.error("")
logger.error(" Fedora:")
logger.error(" sudo dnf install python3-gobject gtk3 libappindicator-gtk3")
logger.error(" sudo dnf install python3-gobject gtk3 libayatana-appindicator-gtk3")
logger.error("")
logger.error(" Arch Linux:")
logger.error(" sudo pacman -S python-gobject gtk3 libappindicator")
logger.error(" sudo pacman -S python-gobject gtk3 libayatana-appindicator")
logger.error("")
logger.error(" openSUSE Tumbleweed:")
logger.error(
+30 -4
View File
@@ -699,10 +699,9 @@ class TestCheckDependencies(unittest.TestCase):
self.assertFalse(result)
def test_check_dependencies_missing_appindicator_with_ayatana_fallback(self):
"""Test when AppIndicator3 is missing but AyatanaAppIndicator3 is available."""
"""Test when legacy AppIndicator3 is missing but Ayatana is available."""
# Make gi.require_version raise ValueError for AppIndicator3 only
# AyatanaAppIndicator3 should work as fallback
# Prefer Ayatana; legacy AppIndicator3 is only a fallback.
def require_version_side_effect(name, version):
if name == "AppIndicator3":
raise ValueError("AppIndicator3 not found")
@@ -726,7 +725,34 @@ class TestCheckDependencies(unittest.TestCase):
):
with patch("vocalinux.main.logger"):
result = check_dependencies()
# Should return True because AyatanaAppIndicator3 fallback works
# Should return True because AyatanaAppIndicator3 works
self.assertTrue(result)
def test_check_dependencies_falls_back_to_legacy_appindicator(self):
"""Test when Ayatana is missing but legacy AppIndicator3 is available."""
def require_version_side_effect(name, version):
if name == "AyatanaAppIndicator3":
raise ValueError("AyatanaAppIndicator3 not found")
mock_gi = MagicMock()
mock_gi.require_version = MagicMock(side_effect=require_version_side_effect)
mock_gtk = MagicMock()
mock_appindicator = MagicMock()
mock_pynput = MagicMock()
mock_requests = MagicMock()
with patch.dict(
"sys.modules",
{
"gi": mock_gi,
"gi.repository": MagicMock(Gtk=mock_gtk, AppIndicator3=mock_appindicator),
"pynput": mock_pynput,
"requests": mock_requests,
},
):
with patch("vocalinux.main.logger"):
result = check_dependencies()
self.assertTrue(result)
def test_check_dependencies_missing_both_appindicators(self):
+1 -1
View File
@@ -153,7 +153,7 @@ const troubleshootingItems = [
"Ensure your desktop environment supports system trays (GNOME requires an AppIndicator extension)",
"Install the GNOME AppIndicator extension (pick your distro): Debian/Ubuntu: sudo apt install gnome-shell-extension-appindicator — Fedora: sudo dnf install gnome-shell-extension-appindicator — Arch: sudo pacman -S gnome-shell-extension-appindicator",
"Then enable the extension (Extensions app, or: gnome-extensions enable appindicatorsupport@rgcjonas.gmail.com) and log out/in if needed",
"Debian/Ubuntu only — also check ayatana: sudo apt install libayatana-appindicator3-1 (Fedora already pulls libappindicator-gtk3 via the installer)",
"Debian/Ubuntu: sudo apt install libayatana-appindicator3-1 — Fedora: sudo dnf install libayatana-appindicator-gtk3 — Arch: sudo pacman -S libayatana-appindicator (legacy libappindicator-gtk3 can leave the icon missing on KDE)",
"Try launching from terminal to see any errors: vocalinux --debug",
],
},