fix(ibus): raise exception on setup failure to enable fallback (#240)

* fix(ibus): raise exception on setup failure to enable fallback

- Add IBusSetupError exception class for detailed error context
- Modify _setup_engine() to raise exception instead of silent return
- Ensures text_injector.py fallback mechanism works when IBus fails
- Add unit tests for IBusSetupError and setup failure scenarios

Fixes silent IBus text injection failures on Wayland/Fedora reported in #34

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* test(text-injector): add tests for IBus setup failure fallback

- Test that TextInjector falls back to xdotool when IBus fails
- Test fallback on both X11 and Wayland environments
- Test that text injection still works after IBus failure

Related to #34

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Jatin K Malik
2026-02-21 00:39:19 -08:00
committed by GitHub
co-authored by Sisyphus
parent be66bdad18
commit 59455098d3
4 changed files with 205 additions and 8 deletions
+1
View File
@@ -4,6 +4,7 @@ Text injection module for Vocalinux
from . import text_injector # noqa: F401
from .ibus_engine import ( # noqa: F401
IBusSetupError,
IBusTextInjector,
install_ibus_component,
is_engine_active,
+22 -5
View File
@@ -27,6 +27,19 @@ from typing import Optional
logger = logging.getLogger(__name__)
class IBusSetupError(RuntimeError):
"""
Exception raised when IBus engine setup fails.
This exception is raised when the IBus text injector cannot be properly
initialized, allowing the caller to fall back to alternative text
injection methods.
"""
pass
# Check if IBus is available
try:
import gi
@@ -576,13 +589,14 @@ class IBusTextInjector:
# Check again after installation
if not is_engine_registered():
logger.error("Failed to register IBus engine")
return
raise IBusSetupError(
"Failed to register IBus engine. "
"Try running 'ibus list-engine' to verify installation."
)
# Start the engine process (Vocalinux starts it, not IBus)
if not start_engine_process():
logger.error("Failed to start IBus engine process")
return
raise IBusSetupError("Failed to start IBus engine process. Check logs for details.")
# Save current engine and switch to Vocalinux
if not is_engine_active():
@@ -594,7 +608,10 @@ class IBusTextInjector:
if switch_engine(ENGINE_NAME):
logger.info("Vocalinux IBus engine activated")
else:
logger.error("Failed to activate Vocalinux IBus engine")
raise IBusSetupError(
"Failed to activate Vocalinux IBus engine. "
"Try manually: ibus engine vocalinux"
)
def stop(self) -> None:
"""