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
+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