4.6 KiB
Development Philosophy
Clean code over backward compatibility. Breaking changes are acceptable in major versions.
- PEP8 compliance (snake_case for all variables/functions/settings)
- Remove deprecated code completely - no compatibility hacks
- Trust users to update configs when upgrading
Exception: Never break core accessibility (speech output, basic navigation).
Core Architecture
Drivers
- Screen:
vcsaDriver(TTY),ptyDriver(terminal emulation) - Input:
evdevDriver(evdev),x11Driver(X11 terminal mode) - Speech:
speechdDriver(speech-dispatcher),genericDriver(subprocess) - Sound:
gstreamerDriver(GStreamer),genericDriver(Sox subprocess) - Remote:
unixDriver(Unix sockets),tcpDriver
Command System
Commands in trigger folders execute automatically:
onKeyInput/,onCursorChange/,onScreenUpdate/,onScreenChanged/,onHeartBeat/- Numeric prefixes control priority (lower = higher priority):
15000-char_echo.py - Manual commands in
commands/commands/
Core Managers (in src/fenrirscreenreader/core/)
fenrirManager.py, commandManager.py, eventManager.py, screenManager.py, inputManager.py, outputManager.py
Configuration
- Main:
config/settings/settings.conf - Keyboards:
config/keyboard/(desktop.conf, laptop.conf) - Sounds:
config/sound/ - Punctuation:
config/punctuation/
🚨 CRITICAL: Files to NEVER Modify
These are timing-critical - only fix critical bugs, never refactor:
evdevDriver.py- Input event processingvcsaDriver.py- Screen monitoring
Symptoms of breakage: echo changes, input lag, missing screen updates, sync issues.
Development Commands
# Run from source (requires root)
cd src/ && sudo ./fenrir -f -d # foreground with debug
# Validation before commit
python3 tools/validate_syntax.py --fix
python3 tools/validate_release.py --quick
# Tests
pytest tests/
pytest tests/ --cov=src/fenrirscreenreader --cov-report=html
Note: Standard TTY Fenrir blocks - only one instance at a time. fenrir -x
can run multiple foreground X terminal instances. Ask user to run tests that
need real Fenrir instances or root access.
Creating Commands
Use commands/command_template.py as base. Required methods:
initialize(self, environment),shutdown(),run(),get_description()
Import Pattern (Required)
Fenrir's command loader doesn't support relative imports:
import os, importlib.util
_base_path = os.path.join(os.path.dirname(__file__), 'base_file.py')
_spec = importlib.util.spec_from_file_location("base_module", _base_path)
_module = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(_module)
BaseClass = _module.BaseClass
Consolidated Base Classes
- Bookmarks:
bookmark_base.py-BookmarkCommand(id, 'read'|'set'|'clear') - Adjustments:
adjustment_base.py-AdjustmentCommand('speech'|'sound', 'rate'|'pitch'|'volume', 'inc'|'dec') - VMenu Search:
vmenu_search_base.py-VMenuSearchCommand('a'-'z')
VMenu System
Application-specific menus in vmenu-profiles/KEY/{app}/:
- Directories = submenus,
.pyfiles = actions - Activate:
Fenrir+F10, navigate with arrows, Enter to execute
Remote Control
Unix socket: /tmp/fenrirscreenreader-deamon.sock
TCP: localhost:22447
echo "command say Hello" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
echo "setting set speech#rate=0.8" | nc localhost 22447
In fenrir -x, each instance has a private socket:
/tmp/fenrirscreenreader-<pid>.sock. One instance may also own the standard
socket. Use ls/list on the standard socket to discover registered instances
and their socket paths. Untargeted remote commands use a short cross-process
claim lock so only one instance handles the same broadcast command; direct
commands to a private instance socket still run on that instance.
Disable in untrusted environments: [remote] enable=False
Key Implementation Details
- Commands via
command_mod.command()instantiation - Bookmark structure:
env['commandBuffer']['bookMarks'][ID][app]['1'/'2'] - VMenu search:
env['runtime']['vmenuManager'].searchEntry(char)
Recent Fixes (Reference)
- Enhanced application detection for screen/tmux sessions
- Table navigation consistency (sound feedback)
- Blank line detection in 22 command files
- Character/space review during navigation
Safe vs Risky Changes
Safe: Commands, VMenu profiles, config handling, sound/speech drivers, docs
Risky (extra testing): Core managers, event processing
Avoid: evdevDriver, vcsaDriver, timing-critical code