Latest changes.
This commit is contained in:
@@ -45,6 +45,12 @@ rate=0.5
|
|||||||
pitch=0.5
|
pitch=0.5
|
||||||
# Pitch for capital letters
|
# Pitch for capital letters
|
||||||
capital_pitch=0.9
|
capital_pitch=0.9
|
||||||
|
# How to indicate capital letters:
|
||||||
|
# pitch = change speech pitch (uses capital_pitch value)
|
||||||
|
# beep = play Caps.wav sound icon
|
||||||
|
# both = play beep AND change pitch
|
||||||
|
# none = no special indication
|
||||||
|
capital_indicator=pitch
|
||||||
|
|
||||||
# Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
|
# Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
|
||||||
volume=1.0
|
volume=1.0
|
||||||
@@ -243,20 +249,6 @@ leave_review_on_cursor_change=True
|
|||||||
# Exit review mode when switching to a different TTY/screen
|
# Exit review mode when switching to a different TTY/screen
|
||||||
leave_review_on_screen_change=True
|
leave_review_on_screen_change=True
|
||||||
|
|
||||||
[promote]
|
|
||||||
# Enable promoting (announcing) important text updates automatically
|
|
||||||
enabled=True
|
|
||||||
# Seconds of inactivity before promoting text updates (prevents spam during active typing)
|
|
||||||
inactive_timeout_sec=120
|
|
||||||
# Comma-separated list of text patterns to promote when detected
|
|
||||||
# Leave empty to disable pattern-based promotion
|
|
||||||
# Examples:
|
|
||||||
# error,warning,failed - Announce build/command errors
|
|
||||||
# complete,finished,done - Announce task completions
|
|
||||||
# new message,@username - Announce chat notifications
|
|
||||||
# download complete - Announce download completions
|
|
||||||
list=
|
|
||||||
|
|
||||||
[menu]
|
[menu]
|
||||||
# Custom path for VMenu (virtual menu) profiles
|
# Custom path for VMenu (virtual menu) profiles
|
||||||
# Leave empty to use default location (/etc/fenrirscreenreader/vmenu-profiles/)
|
# Leave empty to use default location (/etc/fenrirscreenreader/vmenu-profiles/)
|
||||||
|
|||||||
Binary file not shown.
@@ -46,8 +46,6 @@ ErrorSpeech='ErrorSpeech.wav'
|
|||||||
ErrorScreen='ErrorScreen.wav'
|
ErrorScreen='ErrorScreen.wav'
|
||||||
# If you cursor over an text that has attributs (like color)
|
# If you cursor over an text that has attributs (like color)
|
||||||
HasAttributes='has_attribute.wav'
|
HasAttributes='has_attribute.wav'
|
||||||
# fenrir can promote strings if they appear on the screen.
|
|
||||||
PromotedText='PromotedText.wav'
|
|
||||||
# missspelled indicator
|
# missspelled indicator
|
||||||
mispell='mispell.wav'
|
mispell='mispell.wav'
|
||||||
# the for capital letter
|
# the for capital letter
|
||||||
|
|||||||
@@ -50,8 +50,6 @@ ErrorBraille=''
|
|||||||
ErrorScreen=''
|
ErrorScreen=''
|
||||||
# If you cursor over an text that has attributs (like color)
|
# If you cursor over an text that has attributs (like color)
|
||||||
HasAttributes=''
|
HasAttributes=''
|
||||||
# fenrir can promote strings if they appear on the screen.
|
|
||||||
PromotedText=''
|
|
||||||
# misspelled indicator
|
# misspelled indicator
|
||||||
mispell=''
|
mispell=''
|
||||||
# the for capital letter:
|
# the for capital letter:
|
||||||
|
|||||||
@@ -1095,23 +1095,6 @@ announce=True
|
|||||||
interrupt=False
|
interrupt=False
|
||||||
....
|
....
|
||||||
|
|
||||||
==== Promoted List
|
|
||||||
|
|
||||||
Promoted Lists are a nice feature if you are away from your computer or
|
|
||||||
performing more longer tasks. you can define a list of words which you
|
|
||||||
want to hear a sound icon for after a period of inactivity. Example if
|
|
||||||
the word "Chrys" appears after 120 Seconds of inactivity:
|
|
||||||
|
|
||||||
....
|
|
||||||
[promote]
|
|
||||||
enabled=True
|
|
||||||
inactive_timeout_sec=120
|
|
||||||
list=Chrys
|
|
||||||
....
|
|
||||||
|
|
||||||
See section link:#Promote[Promote] in `+settings.conf+` for more
|
|
||||||
information.
|
|
||||||
|
|
||||||
=== Dictionary
|
=== Dictionary
|
||||||
|
|
||||||
You can make use of different kinds of built-in dictionary's. A
|
You can make use of different kinds of built-in dictionary's. A
|
||||||
@@ -2049,39 +2032,6 @@ leave_review_on_screen_change=True
|
|||||||
|
|
||||||
Values: on=`+True+`, off=`+False+`
|
Values: on=`+True+`, off=`+False+`
|
||||||
|
|
||||||
==== Promote
|
|
||||||
|
|
||||||
"Promoted Lists" are configured in the section `+[promote]+`. Turn
|
|
||||||
Promoted Lists" on or off:
|
|
||||||
|
|
||||||
....
|
|
||||||
enabled=True
|
|
||||||
....
|
|
||||||
|
|
||||||
Values: on=`+True+`, off=`+False+`
|
|
||||||
|
|
||||||
The minimum time interval of inactivity to activate promoting. By
|
|
||||||
default it promotes after 120 Seconds inactivity:
|
|
||||||
|
|
||||||
....
|
|
||||||
inactive_timeout_sec=120
|
|
||||||
....
|
|
||||||
|
|
||||||
Values: in Seconds
|
|
||||||
|
|
||||||
Define a list of promoted words comma seperated:
|
|
||||||
|
|
||||||
....
|
|
||||||
list=
|
|
||||||
....
|
|
||||||
|
|
||||||
Values: text (comma seperated) Example to promote the word "nickname" or
|
|
||||||
a bash prompt:
|
|
||||||
|
|
||||||
....
|
|
||||||
list=nickname,$:,#:
|
|
||||||
....
|
|
||||||
|
|
||||||
==== Time
|
==== Time
|
||||||
|
|
||||||
The automated time announcement is configured in the section `+[time]+`.
|
The automated time announcement is configured in the section `+[time]+`.
|
||||||
|
|||||||
@@ -729,15 +729,6 @@ Example on fix minutes in an hour. example every quarter "delaySec=0" and "onMin
|
|||||||
onMinutes=00,15,30,45
|
onMinutes=00,15,30,45
|
||||||
announce=True
|
announce=True
|
||||||
interrupt=False
|
interrupt=False
|
||||||
==== Promoted List ====
|
|
||||||
Promoted Lists are a nice feature if you are away from your computer or performing more longer tasks.
|
|
||||||
you can define a list of words which you want to hear a sound icon for after a period of inactivity.
|
|
||||||
Example if the word "Chrys" appears after 120 Seconds of inactivity:
|
|
||||||
[promote]
|
|
||||||
enabled=True
|
|
||||||
inactive_timeout_sec=120
|
|
||||||
list=Chrys
|
|
||||||
See section [[#Promote|Promote]] in ''settings.conf'' for more information.
|
|
||||||
==== Punctuation ====
|
==== Punctuation ====
|
||||||
Fenrir handles punctuation levels and names for you with several provided dictionaries.
|
Fenrir handles punctuation levels and names for you with several provided dictionaries.
|
||||||
|
|
||||||
@@ -1199,23 +1190,6 @@ Values: on=''True'', off=''False''
|
|||||||
Leave the review mode when changing the screen (From TTY3 to TTY4):
|
Leave the review mode when changing the screen (From TTY3 to TTY4):
|
||||||
leave_review_on_screen_change=True
|
leave_review_on_screen_change=True
|
||||||
Values: on=''True'', off=''False''
|
Values: on=''True'', off=''False''
|
||||||
==== Promote ====
|
|
||||||
"Promoted Lists" are configured in the section ''[promote]''.
|
|
||||||
Turn Promoted Lists" on or off:
|
|
||||||
enabled=True
|
|
||||||
Values: on=''True'', off=''False''
|
|
||||||
|
|
||||||
The minimum time interval of inactivity to activate promoting.
|
|
||||||
By default it promotes after 120 Seconds inactivity:
|
|
||||||
inactive_timeout_sec=120
|
|
||||||
Values: in Seconds
|
|
||||||
|
|
||||||
Define a list of promoted words comma seperated:
|
|
||||||
list=
|
|
||||||
Values: text (comma seperated)
|
|
||||||
Example to promote the word "nickname" or a bash prompt:
|
|
||||||
list=nickname,$:,#:
|
|
||||||
|
|
||||||
==== Time ====
|
==== Time ====
|
||||||
The automated time announcement is configured in the section ''[time]''.
|
The automated time announcement is configured in the section ''[time]''.
|
||||||
Time announcement is disabled by default.
|
Time announcement is disabled by default.
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
from fenrirscreenreader.core.i18n import _
|
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributors.
|
|
||||||
|
|
||||||
|
|
||||||
class command:
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_description(self):
|
|
||||||
return "No Description found"
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
if not self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
|
||||||
"promote", "enabled"
|
|
||||||
):
|
|
||||||
return
|
|
||||||
if (
|
|
||||||
self.env["runtime"]["SettingsManager"]
|
|
||||||
.get_setting("promote", "list")
|
|
||||||
.strip(" \t\n")
|
|
||||||
== ""
|
|
||||||
):
|
|
||||||
return
|
|
||||||
if int(time.time() - self.env["input"]["last_input_time"]) < self.env[
|
|
||||||
"runtime"
|
|
||||||
]["SettingsManager"].get_setting_as_int(
|
|
||||||
"promote", "inactive_timeout_sec"
|
|
||||||
):
|
|
||||||
return
|
|
||||||
if (
|
|
||||||
len(
|
|
||||||
self.env["runtime"]["SettingsManager"].get_setting(
|
|
||||||
"promote", "list"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
== 0
|
|
||||||
):
|
|
||||||
return
|
|
||||||
for promote in (
|
|
||||||
self.env["runtime"]["SettingsManager"]
|
|
||||||
.get_setting("promote", "list")
|
|
||||||
.split(",")
|
|
||||||
):
|
|
||||||
if promote in self.env["screen"]["new_delta"]:
|
|
||||||
self.env["runtime"]["OutputManager"].play_sound_icon(
|
|
||||||
"PromotedText"
|
|
||||||
)
|
|
||||||
self.env["input"]["last_input_time"] = time.time()
|
|
||||||
return
|
|
||||||
|
|
||||||
def set_callback(self, callback):
|
|
||||||
pass
|
|
||||||
@@ -17,8 +17,7 @@ from fenrirscreenreader.core.eventData import FenrirEventType
|
|||||||
class EventManager:
|
class EventManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.running = Value(c_bool, True)
|
self.running = Value(c_bool, True)
|
||||||
# Bounded queue to prevent memory exhaustion
|
self._eventQueue = Queue()
|
||||||
self._eventQueue = Queue(maxsize=100)
|
|
||||||
self.clean_event_queue()
|
self.clean_event_queue()
|
||||||
|
|
||||||
def initialize(self, environment):
|
def initialize(self, environment):
|
||||||
@@ -107,23 +106,5 @@ class EventManager:
|
|||||||
return False
|
return False
|
||||||
if event == FenrirEventType.ignore:
|
if event == FenrirEventType.ignore:
|
||||||
return False
|
return False
|
||||||
# Use bounded queue - if full, this will block briefly or drop older
|
self._eventQueue.put({"Type": event, "data": data})
|
||||||
# events
|
|
||||||
try:
|
|
||||||
self._eventQueue.put({"Type": event, "data": data}, timeout=0.1)
|
|
||||||
except Exception as e:
|
|
||||||
# Queue full - drop oldest event and add new one for critical
|
|
||||||
# events
|
|
||||||
if event in [
|
|
||||||
FenrirEventType.screen_update,
|
|
||||||
FenrirEventType.keyboard_input,
|
|
||||||
]:
|
|
||||||
try:
|
|
||||||
self._eventQueue.get_nowait() # Remove oldest
|
|
||||||
self._eventQueue.put(
|
|
||||||
{"Type": event, "data": data}, timeout=0.1
|
|
||||||
)
|
|
||||||
except BaseException:
|
|
||||||
pass # If still can't add, drop the event
|
|
||||||
# For non-critical events, just drop them if queue is full
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -65,13 +65,31 @@ class OutputManager:
|
|||||||
return
|
return
|
||||||
if (len(text) > 1) and (text.strip(string.whitespace) == ""):
|
if (len(text) > 1) and (text.strip(string.whitespace) == ""):
|
||||||
return
|
return
|
||||||
to_announce_capital = announce_capital and text[0].isupper()
|
is_capital = announce_capital and text[0].isupper()
|
||||||
if to_announce_capital:
|
use_pitch_for_capital = False
|
||||||
if self.play_sound_icon("capital", False):
|
|
||||||
to_announce_capital = False
|
if is_capital:
|
||||||
|
indicator = self.env["runtime"]["SettingsManager"].get_setting(
|
||||||
|
"speech", "capital_indicator"
|
||||||
|
).lower()
|
||||||
|
|
||||||
|
if indicator == "none":
|
||||||
|
pass # No indication
|
||||||
|
elif indicator == "beep":
|
||||||
|
# Play beep with interrupt=True to fix stacking
|
||||||
|
self.play_sound_icon("capital", True)
|
||||||
|
elif indicator == "pitch":
|
||||||
|
use_pitch_for_capital = True
|
||||||
|
elif indicator == "both":
|
||||||
|
self.play_sound_icon("capital", True)
|
||||||
|
use_pitch_for_capital = True
|
||||||
|
else:
|
||||||
|
# Default to pitch for unknown values
|
||||||
|
use_pitch_for_capital = True
|
||||||
|
|
||||||
self.last_echo = text
|
self.last_echo = text
|
||||||
self.speak_text(
|
self.speak_text(
|
||||||
text, interrupt, ignore_punctuation, to_announce_capital, flush
|
text, interrupt, ignore_punctuation, use_pitch_for_capital, flush
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_last_echo(self):
|
def get_last_echo(self):
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ settings_data = {
|
|||||||
"rate": 0.75,
|
"rate": 0.75,
|
||||||
"pitch": 0.5,
|
"pitch": 0.5,
|
||||||
"capital_pitch": 0.8,
|
"capital_pitch": 0.8,
|
||||||
|
"capital_indicator": "pitch",
|
||||||
"volume": 1.0,
|
"volume": 1.0,
|
||||||
"module": "",
|
"module": "",
|
||||||
"voice": "en-us",
|
"voice": "en-us",
|
||||||
@@ -97,11 +98,6 @@ settings_data = {
|
|||||||
"vmenu_path": "",
|
"vmenu_path": "",
|
||||||
"quick_menu": "speech#rate;speech#pitch;speech#volume",
|
"quick_menu": "speech#rate;speech#pitch;speech#volume",
|
||||||
},
|
},
|
||||||
"promote": {
|
|
||||||
"enabled": True,
|
|
||||||
"inactive_timeout_sec": 120,
|
|
||||||
"list": "",
|
|
||||||
},
|
|
||||||
"time": {
|
"time": {
|
||||||
"enabled": False,
|
"enabled": False,
|
||||||
"present_time": True,
|
"present_time": True,
|
||||||
|
|||||||
@@ -4,5 +4,5 @@
|
|||||||
# Fenrir TTY screen reader
|
# Fenrir TTY screen reader
|
||||||
# By Chrys, Storm Dragon, and contributors.
|
# By Chrys, Storm Dragon, and contributors.
|
||||||
|
|
||||||
version = "2025.12.20"
|
version = "2025.12.30"
|
||||||
code_name = "master"
|
code_name = "master"
|
||||||
|
|||||||
Reference in New Issue
Block a user