Merge branch 'testing' moving closer to tagged release.
This commit is contained in:
173
README.md
173
README.md
@ -12,6 +12,8 @@ This software is licensed under the LGPL v3.
|
||||
- **Multiple Interface Support**: Works in Linux TTY, and terminal emulators
|
||||
- **Flexible Driver System**: Modular architecture with multiple drivers for speech, sound, input, and screen
|
||||
- **Review Mode**: Navigate and review screen content without moving the edit cursor
|
||||
- **Table Navigation**: Advanced table mode with column headers, cell-by-cell navigation, and boundary feedback
|
||||
- **Progress Bar Monitoring**: Automatic detection and audio feedback for progress indicators with ascending tones
|
||||
- **Multiple Clipboard Support**: Manage multiple clipboard entries
|
||||
- **Configurable Key Bindings**: Desktop and laptop keyboard layouts
|
||||
- **Sound Icons**: Audio feedback for various events
|
||||
@ -156,6 +158,7 @@ By default Fenrir uses:
|
||||
- `Keypad 2` - Read current character
|
||||
- `Fenrir + T` - Announce time
|
||||
- `Fenrir + S` - Spell check current word
|
||||
- `Fenrir + Keypad *` - Toggle table mode / highlight tracking
|
||||
|
||||
### Keyboard Layouts
|
||||
|
||||
@ -402,6 +405,176 @@ setting <action> [parameters]
|
||||
- `time#delaySec=seconds` - Announcement interval
|
||||
- `time#onMinutes=00,30` - Specific minutes to announce
|
||||
|
||||
## Table Navigation
|
||||
|
||||
Fenrir includes advanced table navigation capabilities for working with tabular data in terminal applications, CSV files, and formatted text output.
|
||||
|
||||
### Entering Table Mode
|
||||
|
||||
Table mode is activated through the **toggle_highlight_tracking** command, which cycles through three focus modes:
|
||||
|
||||
1. **Highlight tracking mode** (default) - Follows text highlighting
|
||||
2. **Cursor tracking mode** - Follows text cursor movement
|
||||
3. **Table mode** - Enables table navigation
|
||||
|
||||
**Key bindings:**
|
||||
- **Desktop layout**: `Fenrir + Keypad *` (asterisk)
|
||||
- **Laptop layout**: `Fenrir + Y`
|
||||
|
||||
Press the key combination repeatedly to cycle through modes until you hear "table mode enabled".
|
||||
|
||||
### Table Navigation Commands
|
||||
|
||||
#### Column Navigation (Desktop Layout)
|
||||
- **Next column**: `Keypad 6` - Move to next table column
|
||||
- **Previous column**: `Keypad 4` - Move to previous table column
|
||||
- **First column**: `Fenrir + Keypad 4` - Jump to first column of current row
|
||||
- **Last column**: `Fenrir + Keypad 6` - Jump to last column of current row
|
||||
|
||||
#### Column Navigation (Laptop Layout)
|
||||
- **Next column**: `Fenrir + L` - Move to next table column
|
||||
- **Previous column**: `Fenrir + J` - Move to previous table column
|
||||
- **First column**: `Fenrir + Shift + J` - Jump to first column of current row
|
||||
- **Last column**: `Fenrir + Shift + L` - Jump to last column of current row
|
||||
|
||||
#### Cell Character Navigation
|
||||
- **First character in cell**: `Fenrir + Keypad 1` (desktop) or `Fenrir + Ctrl + J` (laptop)
|
||||
- **Last character in cell**: `Fenrir + Keypad 3` (desktop) or `Fenrir + Ctrl + L` (laptop)
|
||||
|
||||
### Setting Column Headers
|
||||
|
||||
For better navigation experience, you can set column headers:
|
||||
|
||||
1. **Navigate to header row**: Use normal navigation to reach the row containing column headers
|
||||
2. **Set headers**: Press `Fenrir + X` to mark the current line as the header row
|
||||
3. **Navigation feedback**: Column headers will be announced along with cell content
|
||||
|
||||
### Table Detection
|
||||
|
||||
Fenrir automatically detects table structures using multiple strategies:
|
||||
- **Delimited text**: CSV, pipe-separated (`|`), semicolon-separated (`;`), tab-separated
|
||||
- **Aligned columns**: Space-aligned columns (2+ spaces between columns)
|
||||
- **Flexible parsing**: Handles various table formats commonly found in terminal applications
|
||||
|
||||
### Table Mode Features
|
||||
|
||||
- **Cell-by-cell navigation**: Navigate through table cells with precise positioning
|
||||
- **Column header support**: Set and announce column headers for better context
|
||||
- **Boundary feedback**: Audio cues when reaching start/end of rows
|
||||
- **Empty cell handling**: Blank cells are announced as "blank"
|
||||
- **Independent tracking**: Table position is maintained independently of cursor movement
|
||||
|
||||
### Speech Output in Table Mode
|
||||
|
||||
When navigating in table mode, Fenrir announces:
|
||||
- **Cell content** followed by **column header/name**
|
||||
- **Boundary notifications**: "end of line", "start of line"
|
||||
- **Position indicators**: "first character in cell [column name]"
|
||||
|
||||
### Example Usage
|
||||
|
||||
```bash
|
||||
# Working with CSV data
|
||||
cat data.csv
|
||||
Name,Age,City
|
||||
Alice,30,New York
|
||||
Bob,25,Los Angeles
|
||||
|
||||
# 1. Press Fenrir + Keypad * until "table mode enabled"
|
||||
# 2. Navigate to "Name,Age,City" line
|
||||
# 3. Press Fenrir + X to set headers
|
||||
# 4. Use Keypad 4/6 to navigate between columns
|
||||
# 5. Each cell will be announced with its column header
|
||||
```
|
||||
|
||||
## Progress Bar Monitoring
|
||||
|
||||
Fenrir provides intelligent progress bar detection and audio feedback for various progress indicators commonly found in terminal applications.
|
||||
|
||||
### Enabling Progress Monitoring
|
||||
|
||||
**Command**: `progress_bar_monitor` (no default key binding - assign manually)
|
||||
|
||||
To enable progress monitoring:
|
||||
1. Add a key binding in your keyboard layout file
|
||||
2. Or use the remote control system: `echo "command progress_bar_monitor" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock`
|
||||
|
||||
### Progress Detection Patterns
|
||||
|
||||
Fenrir automatically detects various progress indicator formats:
|
||||
|
||||
#### 1. Percentage Progress
|
||||
```
|
||||
Download: 45%
|
||||
Processing: 67.5%
|
||||
Installing: 100%
|
||||
```
|
||||
|
||||
#### 2. Fraction Progress
|
||||
```
|
||||
Files: 15/100
|
||||
Progress: 3 of 10
|
||||
Step 7/15
|
||||
```
|
||||
|
||||
#### 3. Progress Bars
|
||||
```
|
||||
[#### ] 40%
|
||||
[====> ] 50%
|
||||
[**********] 100%
|
||||
```
|
||||
|
||||
#### 4. Activity Indicators
|
||||
```
|
||||
Loading...
|
||||
Processing...
|
||||
Working...
|
||||
Installing...
|
||||
Downloading...
|
||||
Compiling...
|
||||
Building...
|
||||
```
|
||||
|
||||
### Audio Feedback
|
||||
|
||||
#### Progress Tones
|
||||
- **Ascending tones**: 400Hz to 1200Hz frequency range
|
||||
- **Percentage mapping**: 0% = 400Hz, 100% = 1200Hz
|
||||
- **Smooth progression**: Frequency increases proportionally with progress
|
||||
|
||||
#### Activity Indicators
|
||||
- **Steady beep**: 800Hz tone every 2 seconds for ongoing activity
|
||||
- **Non-intrusive**: Beeps don't interrupt speech or other audio
|
||||
|
||||
### Progress Monitoring Features
|
||||
|
||||
- **Automatic detection**: No manual configuration required
|
||||
- **Multiple format support**: Handles various progress indicator styles
|
||||
- **Prompt awareness**: Automatically pauses when command prompts are detected
|
||||
- **Non-blocking**: Progress tones don't interrupt speech or other functionality
|
||||
- **Configurable**: Can be enabled/disabled as needed
|
||||
|
||||
### Usage Examples
|
||||
|
||||
```bash
|
||||
# Enable progress monitoring
|
||||
echo "command progress_bar_monitor" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
||||
|
||||
# Common scenarios where progress monitoring is useful:
|
||||
wget https://example.com/large-file.zip # Download progress
|
||||
tar -xvf archive.tar.gz # Extraction progress
|
||||
make -j4 # Compilation progress
|
||||
pacman -S package # Package installation
|
||||
rsync -av source/ destination/ # File synchronization
|
||||
```
|
||||
|
||||
### Customization
|
||||
|
||||
Progress monitoring can be configured through settings:
|
||||
- **Default enabled**: Set `progressMonitoring=True` in sound section
|
||||
- **Sound integration**: Works with all sound drivers (sox, gstreamer)
|
||||
- **Remote control**: Enable/disable through remote commands
|
||||
|
||||
### Scripting Examples
|
||||
|
||||
#### Bash Script for Speech Notifications
|
||||
|
@ -50,7 +50,7 @@ def check_dependency(dep: Dependency) -> bool:
|
||||
dependencyList = [
|
||||
# Core dependencies
|
||||
Dependency('FenrirCore', 'core', 'core',
|
||||
pythonImports=['daemonize', 'enchant']),
|
||||
pythonImports=['daemonize', 'enchant', 'pyperclip', 'setproctitle']),
|
||||
|
||||
# Screen drivers
|
||||
Dependency('DummyScreen', 'screen', 'dummyDriver'),
|
||||
@ -58,7 +58,7 @@ dependencyList = [
|
||||
pythonImports=['dbus'],
|
||||
devicePaths=['/dev/vcsa']),
|
||||
Dependency('PTY', 'screen', 'ptyDriver',
|
||||
pythonImports=['pyte']),
|
||||
pythonImports=['pyte', 'xdg']),
|
||||
|
||||
# Input drivers
|
||||
Dependency('DummyInput', 'input', 'dummyDriver'),
|
||||
@ -82,7 +82,11 @@ dependencyList = [
|
||||
Dependency('Speechd', 'speech', 'speechdDriver',
|
||||
pythonImports=['speechd']),
|
||||
Dependency('GenericSpeech', 'speech', 'genericDriver',
|
||||
checkCommands=['espeak-ng'])
|
||||
checkCommands=['espeak-ng']),
|
||||
|
||||
# Additional dependencies
|
||||
Dependency('Pexpect', 'core', 'pexpectDriver',
|
||||
pythonImports=['pexpect'])
|
||||
]
|
||||
|
||||
defaultModules = {
|
||||
@ -90,7 +94,8 @@ defaultModules = {
|
||||
'VCSA',
|
||||
'Evdev',
|
||||
'GenericSpeech',
|
||||
'GenericSound'
|
||||
'GenericSound',
|
||||
'Pexpect'
|
||||
}
|
||||
|
||||
def check_all_dependencies():
|
||||
|
@ -1,4 +1,46 @@
|
||||
|
||||
# Fenrir Keyboard Configuration
|
||||
|
||||
This directory contains keyboard layout files for Fenrir screen reader.
|
||||
|
||||
## Available Layouts
|
||||
|
||||
- **desktop.conf** - Desktop layout using numeric keypad (recommended)
|
||||
- **laptop.conf** - Laptop layout for keyboards without numeric keypad
|
||||
- **nvda-desktop.conf** - NVDA-compatible desktop layout
|
||||
- **nvda-laptop.conf** - NVDA-compatible laptop layout
|
||||
- **pty.conf** - PTY emulation layout for terminal use
|
||||
- **pty2.conf** - Alternative PTY emulation layout
|
||||
|
||||
## Key Features
|
||||
|
||||
### Table Navigation
|
||||
- **Toggle table mode**: `Fenrir + Keypad *` (desktop) or `Fenrir + Y` (laptop)
|
||||
- **Column navigation**: `Keypad 4/6` (desktop) or `Fenrir + J/L` (laptop)
|
||||
- **Row boundaries**: `Fenrir + Keypad 4/6` (desktop) or `Fenrir + Shift + J/L` (laptop)
|
||||
- **Set headers**: `Fenrir + X` in table mode
|
||||
|
||||
### Progress Bar Monitoring
|
||||
- **Monitor progress**: `progress_bar_monitor` command (assign key binding manually)
|
||||
- **Auto-detection**: Percentage, fractions, progress bars, activity indicators
|
||||
- **Audio feedback**: Ascending tones (400Hz-1200Hz) for progress
|
||||
|
||||
### Review Mode
|
||||
- **Basic navigation**: `Keypad 7/8/9` (lines), `Keypad 4/5/6` (words), `Keypad 1/2/3` (characters)
|
||||
- **Exit review**: `Fenrir + Keypad .`
|
||||
- **Screen reading**: `Fenrir + Keypad 5` (current screen)
|
||||
|
||||
## Configuration
|
||||
|
||||
To change keyboard layout, edit `/etc/fenrir/settings/settings.conf`:
|
||||
|
||||
```ini
|
||||
[keyboard]
|
||||
keyboardLayout=desktop # or laptop, nvda-desktop, nvda-laptop, pty, pty2
|
||||
```
|
||||
|
||||
## Available Key Constants
|
||||
|
||||
Keymap for Fenrir
|
||||
KEY_RESERVED
|
||||
KEY_ESC
|
||||
|
47
docs/user.md
47
docs/user.md
@ -50,6 +50,12 @@ Navigate the screen without moving the text cursor. Essential for examining cont
|
||||
- `Keypad 1/3` - Previous/next character
|
||||
- `Fenrir + Keypad dot` - Exit review mode
|
||||
|
||||
### Table Navigation
|
||||
- `Fenrir + Keypad *` - Toggle table mode / highlight tracking
|
||||
- `Keypad 4/6` - Previous/next column (in table mode)
|
||||
- `Fenrir + Keypad 4/6` - First/last column (in table mode)
|
||||
- `Fenrir + X` - Set column headers (in table mode)
|
||||
|
||||
### Information
|
||||
- `Fenrir + T` - Announce time
|
||||
- `Fenrir + T T` - Announce date
|
||||
@ -240,6 +246,47 @@ send_fenrir_command("command say Process complete")
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Table Navigation Mode
|
||||
|
||||
Fenrir includes advanced table navigation capabilities for working with tabular data in terminal applications, CSV files, and formatted text output.
|
||||
|
||||
#### Entering Table Mode
|
||||
1. Press `Fenrir + Keypad *` (desktop) or `Fenrir + Y` (laptop)
|
||||
2. Cycle through: Highlight tracking → Cursor tracking → Table mode
|
||||
3. Listen for "table mode enabled" announcement
|
||||
|
||||
#### Table Navigation Commands
|
||||
- **Column navigation**: `Keypad 4/6` - Move between columns
|
||||
- **Row boundaries**: `Fenrir + Keypad 4/6` - Jump to first/last column
|
||||
- **Cell characters**: `Fenrir + Keypad 1/3` - First/last character in cell
|
||||
- **Set headers**: `Fenrir + X` - Mark current line as column headers
|
||||
|
||||
#### Table Features
|
||||
- **Automatic detection**: Supports CSV, pipe-separated, space-aligned columns
|
||||
- **Column headers**: Set and announce headers for better context
|
||||
- **Boundary feedback**: Audio cues when reaching row boundaries
|
||||
- **Cell-by-cell navigation**: Precise positioning within tables
|
||||
|
||||
### Progress Bar Monitoring
|
||||
|
||||
Fenrir automatically detects and provides audio feedback for progress indicators.
|
||||
|
||||
#### Progress Detection
|
||||
- **Percentage**: 45%, 67.5%, 100%
|
||||
- **Fractions**: 15/100, 3 of 10, Step 7/15
|
||||
- **Progress bars**: [#### ], [====> ]
|
||||
- **Activity indicators**: Loading..., Processing...
|
||||
|
||||
#### Audio Feedback
|
||||
- **Progress tones**: Ascending 400Hz-1200Hz frequency range
|
||||
- **Activity beeps**: 800Hz tone every 2 seconds
|
||||
- **Non-intrusive**: Doesn't interrupt speech or other audio
|
||||
|
||||
#### Usage
|
||||
- **Enable**: Use `progress_bar_monitor` command (assign key binding)
|
||||
- **Automatic**: Works with downloads, compilations, installations
|
||||
- **Remote control**: Enable via socket commands
|
||||
|
||||
### Spell Checking
|
||||
- `Fenrir + S` - Spell check current word
|
||||
- `Fenrir + S S` - Add word to dictionary
|
||||
|
@ -20,22 +20,15 @@ class command:
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("presents the date")
|
||||
return _("Test mc search functionality")
|
||||
|
||||
def run(self):
|
||||
date_format = self.env["runtime"]["SettingsManager"].get_setting(
|
||||
"general", "date_format"
|
||||
)
|
||||
|
||||
# get the time formatted
|
||||
date_string = datetime.datetime.strftime(
|
||||
datetime.datetime.now(), date_format
|
||||
)
|
||||
|
||||
# present the time via speak and braile, there is no soundicon,
|
||||
# interrupt the current speech
|
||||
# Test command for mc search operations
|
||||
test_message = _("MC search test: This demonstrates search functionality")
|
||||
|
||||
# present the test message
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
date_string, sound_icon="", interrupt=True
|
||||
test_message, sound_icon="", interrupt=True
|
||||
)
|
||||
|
||||
def set_callback(self, callback):
|
||||
|
@ -20,22 +20,15 @@ class command:
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("presents the date")
|
||||
return _("Test mutt search functionality")
|
||||
|
||||
def run(self):
|
||||
date_format = self.env["runtime"]["SettingsManager"].get_setting(
|
||||
"general", "date_format"
|
||||
)
|
||||
|
||||
# get the time formatted
|
||||
date_string = datetime.datetime.strftime(
|
||||
datetime.datetime.now(), date_format
|
||||
)
|
||||
|
||||
# present the time via speak and braile, there is no soundicon,
|
||||
# interrupt the current speech
|
||||
# Test command for mutt search operations
|
||||
test_message = _("Mutt search test: This demonstrates search functionality")
|
||||
|
||||
# present the test message
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
date_string, sound_icon="", interrupt=True
|
||||
test_message, sound_icon="", interrupt=True
|
||||
)
|
||||
|
||||
def set_callback(self, callback):
|
||||
|
@ -20,22 +20,15 @@ class command:
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("presents the date")
|
||||
return _("Test nano search functionality")
|
||||
|
||||
def run(self):
|
||||
date_format = self.env["runtime"]["SettingsManager"].get_setting(
|
||||
"general", "date_format"
|
||||
)
|
||||
|
||||
# get the time formatted
|
||||
date_string = datetime.datetime.strftime(
|
||||
datetime.datetime.now(), date_format
|
||||
)
|
||||
|
||||
# present the time via speak and braile, there is no soundicon,
|
||||
# interrupt the current speech
|
||||
# Test command for nano search operations
|
||||
test_message = _("Nano search test: This demonstrates search functionality")
|
||||
|
||||
# present the test message
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
date_string, sound_icon="", interrupt=True
|
||||
test_message, sound_icon="", interrupt=True
|
||||
)
|
||||
|
||||
def set_callback(self, callback):
|
||||
|
@ -20,22 +20,15 @@ class command:
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("presents the date")
|
||||
return _("Test vim search functionality")
|
||||
|
||||
def run(self):
|
||||
date_format = self.env["runtime"]["SettingsManager"].get_setting(
|
||||
"general", "date_format"
|
||||
)
|
||||
|
||||
# get the time formatted
|
||||
date_string = datetime.datetime.strftime(
|
||||
datetime.datetime.now(), date_format
|
||||
)
|
||||
|
||||
# present the time via speak and braile, there is no soundicon,
|
||||
# interrupt the current speech
|
||||
# Test command for vim search operations
|
||||
test_message = _("Vim search test: This demonstrates search functionality")
|
||||
|
||||
# present the test message
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
date_string, sound_icon="", interrupt=True
|
||||
test_message, sound_icon="", interrupt=True
|
||||
)
|
||||
|
||||
def set_callback(self, callback):
|
||||
|
@ -64,7 +64,7 @@ class ProcessManager:
|
||||
args=(event_queue, function, pargs, run_once),
|
||||
)
|
||||
self._Processes.append(t)
|
||||
else: # thread not implemented yet
|
||||
else: # use thread instead of process
|
||||
t = Thread(
|
||||
target=self.custom_event_worker_thread,
|
||||
args=(event_queue, function, pargs, run_once),
|
||||
|
@ -494,11 +494,14 @@ class SettingsManager:
|
||||
self.set_setting("general", "debug_level", 3)
|
||||
self.set_setting("general", "debug_mode", "PRINT")
|
||||
if cliArgs.emulated_pty:
|
||||
self.set_setting("screen", "driver", "ptyDriver")
|
||||
self.set_setting("keyboard", "driver", "ptyDriver")
|
||||
# TODO needs cleanup use dict
|
||||
# self.set_option_arg_dict('keyboard', 'keyboardLayout', 'pty')
|
||||
self.set_setting("keyboard", "keyboardLayout", "pty")
|
||||
# Set PTY driver settings
|
||||
pty_settings = {
|
||||
"screen": {"driver": "ptyDriver"},
|
||||
"keyboard": {"driver": "ptyDriver", "keyboardLayout": "pty"}
|
||||
}
|
||||
for section, settings in pty_settings.items():
|
||||
for key, value in settings.items():
|
||||
self.set_setting(section, key, value)
|
||||
if cliArgs.emulated_evdev:
|
||||
self.set_setting("screen", "driver", "ptyDriver")
|
||||
self.set_setting("keyboard", "driver", "evdevDriver")
|
||||
|
Reference in New Issue
Block a user