fix: improve Debian/pipx installation experience (#289)

* fix: improve Debian/pipx installation experience

- Enhanced error messages in check_dependencies() to provide distro-specific
  installation commands (Ubuntu/Debian, Fedora, Arch Linux)
- Added explicit pipx guidance: install system packages BEFORE pipx install
- Updated error message to use gir1.2-ayatanaappindicator3-0.1 for Debian
- Added comprehensive pipx installation section to DISTRO_COMPATIBILITY.md
  with step-by-step instructions for all major distributions

* fix: add display availability check to prevent GTK crash on Debian

The original PR only added documentation and improved error messages.
This commit adds the actual fix for issue #288.

Root cause: On some systems (especially Debian), GTK widgets can be
created before the display connection is properly established, causing
the crash: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed

Fix: Add check_display_available() function that verifies Gdk.Display
is available before any GTK widgets are created. This provides a clear
error message instead of a cryptic GTK crash.

Fixes #288
This commit is contained in:
Jatin K Malik
2026-03-14 13:02:45 -07:00
committed by GitHub
parent 73082fa393
commit 8a4dbad4ee
2 changed files with 129 additions and 5 deletions
+84
View File
@@ -146,6 +146,90 @@ sudo urpmi -y python3-gobject gtk3-devel gobject-introspection-devel \
portaudio-devel python3-devel python3-virtualenv pkg-config
```
## pipx Installation
pipx is a popular tool for installing Python CLI applications in isolated environments. However, **Vocalinux requires system GTK packages** that cannot be installed via pip/pipx.
### Important: Install System Packages First
Before running `pipx install vocalinux`, you **must** install the required system packages:
#### Ubuntu/Debian
```bash
sudo apt install python3-gi gir1.2-gtk-3.0 gir1.2-ayatanaappindicator3-0.1 \
portaudio19-dev python3-dev pkg-config
```
#### Fedora
```bash
sudo dnf install python3-gobject gtk3 libappindicator-gtk3 \
portaudio-devel python3-devel pkg-config
```
#### Arch Linux
```bash
sudo pacman -S python-gobject gtk3 libappindicator portaudio pkg-config
```
#### openSUSE
```bash
sudo zypper install python3-gobject gtk3 libappindicator \
portaudio-devel python3-devel pkg-config
```
### pipx Installation Steps
1. **Install system packages** (see above for your distribution)
2. **Install pipx** (if not already installed):
```bash
# Ubuntu/Debian
sudo apt install pipx
pipx ensurepath
# Fedora
sudo dnf install pipx
pipx ensurepath
# Arch Linux
sudo pacman -S pipx
pipx ensurepath
```
3. **Install Vocalinux**:
```bash
pipx install vocalinux
```
4. **Run Vocalinux**:
```bash
vocalinux-gui
```
### Why System Packages Are Required
Vocalinux uses GTK3 for its GUI and AppIndicator for the system tray icon. These are system libraries that use GObject Introspection (GI) bindings, which must be installed via your distribution's package manager. The Python packages in pip only provide the Python interface to these libraries - they don't include the actual GTK libraries.
### Troubleshooting pipx Installation
If `vocalinux-gui` fails to start:
1. **Check for missing system packages** - The error message will indicate which packages are missing
2. **Verify GI_TYPELIB_PATH** - In rare cases, you may need to set this environment variable:
```bash
export GI_TYPELIB_PATH=/usr/lib/x86_64-linux-gnu/girepository-1.0
vocalinux-gui
```
### Recommended Alternative
For the best experience with automatic dependency handling, use the official installer:
```bash
curl -fsSL https://raw.githubusercontent.com/jatinkrmalik/vocalinux/v0.8.0-beta/install.sh | bash
```
This installer automatically detects your distribution and installs all required system packages.
## Text Injection Tools
Vocalinux requires text injection tools to work with X11 or Wayland:
+45 -5
View File
@@ -100,8 +100,7 @@ def check_dependencies():
from gi.repository import AyatanaAppIndicator3 # noqa: F401
except (ImportError, ValueError):
missing_system_deps.append(
"AppIndicator3 (install with: sudo apt install gir1.2-appindicator3-0.1) "
"Note: On Debian 11+ use gir1.2-ayatanaappindicator3-0.1 instead"
"AppIndicator3/AyatanaAppIndicator3 - Required for system tray icon"
)
# pynput is used for keyboard detection but we check at module startup
@@ -123,10 +122,24 @@ def check_dependencies():
logger.error(f" - {dep}")
if missing_system_deps:
logger.error("")
logger.error("If you installed via pip/pipx, you also need system GTK packages:")
logger.error(" sudo apt install python3-gi gir1.2-gtk-3.0 gir1.2-appindicator3-0.1")
logger.error("System GTK packages are required. Install them first:")
logger.error("")
logger.error("For the best experience, install using the recommended method:")
logger.error(" Ubuntu/Debian:")
logger.error(
" sudo apt install python3-gi gir1.2-gtk-3.0 gir1.2-ayatanaappindicator3-0.1"
)
logger.error("")
logger.error(" Fedora:")
logger.error(" sudo dnf install python3-gobject gtk3 libappindicator-gtk3")
logger.error("")
logger.error(" Arch Linux:")
logger.error(" sudo pacman -S python-gobject gtk3 libappindicator")
logger.error("")
logger.error(
"For pipx users: Install system packages BEFORE running 'pipx install vocalinux'"
)
logger.error("")
logger.error("For the best experience, use the recommended installer:")
logger.error(
" curl -fsSL https://raw.githubusercontent.com/jatinkrmalik/vocalinux/v0.8.0-beta/install.sh | bash"
)
@@ -135,6 +148,29 @@ def check_dependencies():
return True
def check_display_available():
"""Check if a display is available for GTK."""
try:
import gi
gi.require_version("Gdk", "3.0")
from gi.repository import Gdk
display = Gdk.Display.get_default()
if display is None:
logger.error("No display available. Vocalinux requires a graphical environment.")
logger.error("")
logger.error("If running remotely, ensure DISPLAY is set:")
logger.error(" export DISPLAY=:0")
logger.error("")
logger.error("If running in a headless environment, Vocalinux cannot run.")
return False
return True
except Exception as e:
logger.error(f"Failed to initialize display: {e}")
return False
def main():
"""Main entry point for the application."""
# Check for single instance BEFORE any initialization
@@ -176,6 +212,10 @@ def main():
logger.error("Cannot start Vocalinux due to missing dependencies")
sys.exit(1)
# Check if display is available before creating any GTK widgets
if not check_display_available():
sys.exit(1)
# Now it's safe to import GTK-dependent modules
from .common_types import RecognitionState
from .speech_recognition import recognition_manager