Attempt to fix forward keypress and numpad state.
This commit is contained in:
@@ -0,0 +1,742 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Fenrir TTY screen reader
|
||||||
|
# By Chrys, Storm Dragon, and contributors.
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
import os
|
||||||
|
from configparser import ConfigParser
|
||||||
|
|
||||||
|
from fenrirscreenreader.core import applicationManager
|
||||||
|
from fenrirscreenreader.core import attributeManager
|
||||||
|
from fenrirscreenreader.core import barrierManager
|
||||||
|
from fenrirscreenreader.core import commandManager
|
||||||
|
from fenrirscreenreader.core import cursorManager
|
||||||
|
from fenrirscreenreader.core import debug
|
||||||
|
from fenrirscreenreader.core import debugManager
|
||||||
|
from fenrirscreenreader.core import diffReviewManager
|
||||||
|
from fenrirscreenreader.core import environment
|
||||||
|
from fenrirscreenreader.core import eventManager
|
||||||
|
from fenrirscreenreader.core import helpManager
|
||||||
|
from fenrirscreenreader.core import inputManager
|
||||||
|
from fenrirscreenreader.core import memoryManager
|
||||||
|
from fenrirscreenreader.core import outputManager
|
||||||
|
from fenrirscreenreader.core import processManager
|
||||||
|
from fenrirscreenreader.core import punctuationManager
|
||||||
|
from fenrirscreenreader.core import quickMenuManager
|
||||||
|
from fenrirscreenreader.core import readAllManager
|
||||||
|
from fenrirscreenreader.core import remoteManager
|
||||||
|
from fenrirscreenreader.core import sayAllManager
|
||||||
|
from fenrirscreenreader.core import screenManager
|
||||||
|
from fenrirscreenreader.core import tableManager
|
||||||
|
from fenrirscreenreader.core import textManager
|
||||||
|
from fenrirscreenreader.core import vmenuManager
|
||||||
|
from fenrirscreenreader.core.settingsData import settings_data
|
||||||
|
from fenrirscreenreader.utils import module_utils
|
||||||
|
|
||||||
|
currentdir = os.path.dirname(
|
||||||
|
os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||||
|
)
|
||||||
|
fenrir_path = os.path.dirname(currentdir)
|
||||||
|
|
||||||
|
|
||||||
|
class SettingsManager:
|
||||||
|
def __init__(self):
|
||||||
|
self.settings = settings_data
|
||||||
|
self.settingArgDict = {}
|
||||||
|
self.bindingsBackup = None
|
||||||
|
self.settings_file = ""
|
||||||
|
|
||||||
|
def initialize(self, environment):
|
||||||
|
self.env = environment
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_binding_backup(self):
|
||||||
|
return self.bindingsBackup.copy()
|
||||||
|
|
||||||
|
def load_sound_icons(self, soundIconPath, environment=None):
|
||||||
|
# Use passed environment or fall back to self.env
|
||||||
|
env = environment if environment is not None else self.env
|
||||||
|
try:
|
||||||
|
with open(soundIconPath + "/soundicons.conf", "r") as siConfig:
|
||||||
|
while True:
|
||||||
|
line = siConfig.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
line = line.replace("\n", "")
|
||||||
|
if line.replace(" ", "") == "":
|
||||||
|
continue
|
||||||
|
if line.replace(" ", "").startswith("#"):
|
||||||
|
continue
|
||||||
|
if line.count("=") != 1:
|
||||||
|
continue
|
||||||
|
values = line.split("=")
|
||||||
|
sound_icon = values[0].upper()
|
||||||
|
values[1] = values[1].replace("'", "")
|
||||||
|
values[1] = values[1].replace('"', "")
|
||||||
|
sound_icon_file = ""
|
||||||
|
if os.path.exists(values[1]):
|
||||||
|
sound_icon_file = values[1]
|
||||||
|
else:
|
||||||
|
if not soundIconPath.endswith("/"):
|
||||||
|
soundIconPath += "/"
|
||||||
|
if os.path.exists(soundIconPath + values[1]):
|
||||||
|
sound_icon_file = soundIconPath + values[1]
|
||||||
|
env["soundIcons"][sound_icon] = sound_icon_file
|
||||||
|
env["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
"SoundIcon: " + sound_icon + "." + sound_icon_file,
|
||||||
|
debug.DebugLevel.INFO,
|
||||||
|
on_any_level=True,
|
||||||
|
)
|
||||||
|
except (IOError, OSError) as e:
|
||||||
|
env["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
"load_sound_icons: failed to load sound icons from "
|
||||||
|
+ soundIconPath
|
||||||
|
+ ". Error: "
|
||||||
|
+ str(e),
|
||||||
|
debug.DebugLevel.ERROR,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_settings_file(self):
|
||||||
|
return self.settings_file
|
||||||
|
|
||||||
|
def set_settings_file(self, settings_file):
|
||||||
|
if not os.path.exists(settings_file):
|
||||||
|
return
|
||||||
|
if not os.access(settings_file, os.R_OK):
|
||||||
|
return
|
||||||
|
self.settings_file = settings_file
|
||||||
|
|
||||||
|
def load_settings(self, setting_config_path):
|
||||||
|
if not os.path.exists(setting_config_path):
|
||||||
|
return False
|
||||||
|
if not os.access(setting_config_path, os.R_OK):
|
||||||
|
return False
|
||||||
|
self.env["settings"] = ConfigParser()
|
||||||
|
try:
|
||||||
|
self.env["settings"].read(setting_config_path)
|
||||||
|
except Exception as e:
|
||||||
|
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
"settings_manager load_settings: Error reading config file: "
|
||||||
|
+ str(e),
|
||||||
|
debug.DebugLevel.ERROR,
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
self.set_settings_file(setting_config_path)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def save_settings(self, setting_config_path):
|
||||||
|
# set opt dict here
|
||||||
|
# save file
|
||||||
|
try:
|
||||||
|
# print('file: ',setting_config_path)
|
||||||
|
for section, settings in self.settingArgDict.items():
|
||||||
|
for setting, value in settings.items():
|
||||||
|
# print(section, setting, value)
|
||||||
|
self.env["settings"].set(section, setting, value)
|
||||||
|
# print('full',self.env['settings'])
|
||||||
|
|
||||||
|
config_file = open(setting_config_path, "w")
|
||||||
|
self.env["settings"].write(config_file)
|
||||||
|
config_file.close()
|
||||||
|
os.chmod(setting_config_path, 0o644)
|
||||||
|
except Exception as e:
|
||||||
|
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
"save_settings: save settingsfile:"
|
||||||
|
+ setting_config_path
|
||||||
|
+ "failed. Error:"
|
||||||
|
+ str(e),
|
||||||
|
debug.DebugLevel.ERROR,
|
||||||
|
)
|
||||||
|
|
||||||
|
def set_setting(self, section, setting, value):
|
||||||
|
self.set_option_arg_dict(section, setting, value)
|
||||||
|
# self.env['settings'].set(section, setting, value)
|
||||||
|
|
||||||
|
def get_setting(self, section, setting):
|
||||||
|
value = ""
|
||||||
|
try:
|
||||||
|
value = self.settingArgDict[section][setting]
|
||||||
|
return value
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
value = self.env["settings"].get(section, setting)
|
||||||
|
except Exception as e:
|
||||||
|
value = str(self.settings[section][setting])
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_setting_as_int(self, section, setting):
|
||||||
|
value = 0
|
||||||
|
try:
|
||||||
|
value = int(self.settingArgDict[section][setting])
|
||||||
|
return value
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
value = self.env["settings"].getint(section, setting)
|
||||||
|
except Exception as e:
|
||||||
|
value = self.settings[section][setting]
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_setting_as_float(self, section, setting):
|
||||||
|
value = 0.0
|
||||||
|
try:
|
||||||
|
value = float(self.settingArgDict[section][setting])
|
||||||
|
return value
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
value = self.env["settings"].getfloat(section, setting)
|
||||||
|
except Exception as e:
|
||||||
|
value = self.settings[section][setting]
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_setting_as_bool(self, section, setting):
|
||||||
|
value = False
|
||||||
|
try:
|
||||||
|
value = self.settingArgDict[section][setting].upper() in [
|
||||||
|
"1",
|
||||||
|
"YES",
|
||||||
|
"JA",
|
||||||
|
"TRUE",
|
||||||
|
]
|
||||||
|
return value
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
value = self.env["settings"].getboolean(section, setting)
|
||||||
|
except Exception as e:
|
||||||
|
value = self.settings[section][setting]
|
||||||
|
return value
|
||||||
|
|
||||||
|
def load_driver(self, driverName, driverType):
|
||||||
|
# Map runtime keys to actual directory names
|
||||||
|
driver_dir_map = {
|
||||||
|
"InputDriver": "inputDriver",
|
||||||
|
"ScreenDriver": "screenDriver",
|
||||||
|
"SpeechDriver": "speechDriver",
|
||||||
|
"SoundDriver": "soundDriver",
|
||||||
|
"RemoteDriver": "remoteDriver",
|
||||||
|
}
|
||||||
|
driver_dir = driver_dir_map.get(driverType, driverType)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if self.env["runtime"][driverType] is not None:
|
||||||
|
self.env["runtime"][driverType].shutdown(self.env)
|
||||||
|
except Exception as e:
|
||||||
|
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
"settings_manager load_driver: Error shutting down driver: "
|
||||||
|
+ str(e),
|
||||||
|
debug.DebugLevel.ERROR,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
driver_mod = module_utils.import_module(
|
||||||
|
driverName,
|
||||||
|
fenrir_path + "/" + driver_dir + "/" + driverName + ".py",
|
||||||
|
)
|
||||||
|
self.env["runtime"][driverType] = driver_mod.driver()
|
||||||
|
self.env["runtime"][driverType].initialize(self.env)
|
||||||
|
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
"Loading Driver " + driverType + " (" + driverName + ") OK",
|
||||||
|
debug.DebugLevel.INFO,
|
||||||
|
on_any_level=True,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
"Loading Driver "
|
||||||
|
+ driverType
|
||||||
|
+ " ("
|
||||||
|
+ driverName
|
||||||
|
+ ") FAILED:"
|
||||||
|
+ str(e),
|
||||||
|
debug.DebugLevel.ERROR,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
driver_mod = module_utils.import_module(
|
||||||
|
driverName,
|
||||||
|
fenrir_path + "/" + driver_dir + "/dummyDriver.py",
|
||||||
|
)
|
||||||
|
self.env["runtime"][driverType] = driver_mod.driver()
|
||||||
|
self.env["runtime"][driverType].initialize(self.env)
|
||||||
|
except Exception as e:
|
||||||
|
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
"(fallback) Loading Driver "
|
||||||
|
+ driverType
|
||||||
|
+ " (dummyDriver) FAILED:"
|
||||||
|
+ str(e),
|
||||||
|
debug.DebugLevel.ERROR,
|
||||||
|
)
|
||||||
|
|
||||||
|
def shutdown_driver(self, driverType):
|
||||||
|
try:
|
||||||
|
self.env["runtime"][driverType].shutdown()
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
del self.env["runtime"][driverType]
|
||||||
|
|
||||||
|
def set_fenrir_keys(self, keys):
|
||||||
|
keys = keys.upper()
|
||||||
|
key_list = keys.split(",")
|
||||||
|
for key in key_list:
|
||||||
|
if key not in self.env["input"]["fenrir_key"]:
|
||||||
|
self.env["input"]["fenrir_key"].append(key)
|
||||||
|
|
||||||
|
def set_script_keys(self, keys):
|
||||||
|
keys = keys.upper()
|
||||||
|
key_list = keys.split(",")
|
||||||
|
for key in key_list:
|
||||||
|
if key not in self.env["input"]["script_key"]:
|
||||||
|
self.env["input"]["script_key"].append(key)
|
||||||
|
|
||||||
|
def reset_setting_arg_dict(self):
|
||||||
|
self.settingArgDict = {}
|
||||||
|
self.env["runtime"]["OutputManager"].reset_SpeechDriver()
|
||||||
|
|
||||||
|
def set_option_arg_dict(self, section, setting, value):
|
||||||
|
# section = section.lower()
|
||||||
|
# setting = setting.lower()
|
||||||
|
try:
|
||||||
|
e = self.settingArgDict[section]
|
||||||
|
except KeyError:
|
||||||
|
self.settingArgDict[section] = {}
|
||||||
|
try:
|
||||||
|
t = self.settings[section][setting]
|
||||||
|
except Exception as e:
|
||||||
|
print(section, setting, "not found")
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
v = value # Initialize v with the original value
|
||||||
|
if isinstance(self.settings[section][setting], str):
|
||||||
|
v = str(value)
|
||||||
|
elif isinstance(self.settings[section][setting], bool):
|
||||||
|
if value not in ["True", "False"]:
|
||||||
|
raise ValueError(
|
||||||
|
"could not convert string to bool: " + value
|
||||||
|
)
|
||||||
|
v = value == "True"
|
||||||
|
elif isinstance(self.settings[section][setting], int):
|
||||||
|
v = int(value)
|
||||||
|
elif isinstance(self.settings[section][setting], float):
|
||||||
|
v = float(value)
|
||||||
|
|
||||||
|
# Content validation for critical settings
|
||||||
|
self._validate_setting_value(section, setting, v)
|
||||||
|
|
||||||
|
self.settingArgDict[section][setting] = str(value)
|
||||||
|
except Exception as e:
|
||||||
|
print(
|
||||||
|
"settings_manager:set_option_arg_dict:Datatype missmatch: "
|
||||||
|
+ section
|
||||||
|
+ "#"
|
||||||
|
+ setting
|
||||||
|
+ "="
|
||||||
|
+ str(value)
|
||||||
|
+ " Error:"
|
||||||
|
+ str(e)
|
||||||
|
)
|
||||||
|
# self.env['runtime']['DebugManager'].write_debug_out('settings_manager:set_option_arg_dict:Datatype
|
||||||
|
# missmatch: '+ section + '#' + setting + '=' + value + ' Error:'
|
||||||
|
# + str(e), debug.DebugLevel.ERROR)
|
||||||
|
return
|
||||||
|
|
||||||
|
def _validate_setting_value(self, section, setting, value):
|
||||||
|
"""Validate setting values for critical screen reader functionality.
|
||||||
|
Only validates settings that could cause crashes or accessibility issues.
|
||||||
|
Invalid values raise ValueError which is caught by the calling method.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Speech settings validation - critical for accessibility
|
||||||
|
if section == "speech":
|
||||||
|
if setting == "rate":
|
||||||
|
if not (0.0 <= value <= 3.0):
|
||||||
|
raise ValueError(
|
||||||
|
f"Speech rate must be between 0.0 and 3.0, got {value}"
|
||||||
|
)
|
||||||
|
elif setting == "pitch":
|
||||||
|
if not (0.0 <= value <= 2.0):
|
||||||
|
raise ValueError(
|
||||||
|
f"Speech pitch must be between 0.0 and 2.0, got {value}"
|
||||||
|
)
|
||||||
|
elif setting == "volume":
|
||||||
|
if not (0.0 <= value <= 1.5):
|
||||||
|
raise ValueError(
|
||||||
|
f"Speech volume must be between 0.0 and 1.5, got {value}"
|
||||||
|
)
|
||||||
|
elif setting == "driver":
|
||||||
|
valid_drivers = [
|
||||||
|
"speechdDriver",
|
||||||
|
"genericDriver",
|
||||||
|
"dummyDriver",
|
||||||
|
]
|
||||||
|
if value not in valid_drivers:
|
||||||
|
raise ValueError(
|
||||||
|
f"Invalid speech driver: {value}. Valid options: {valid_drivers}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sound settings validation
|
||||||
|
elif section == "sound":
|
||||||
|
if setting == "volume":
|
||||||
|
if not (0.0 <= value <= 1.5):
|
||||||
|
raise ValueError(
|
||||||
|
f"Sound volume must be between 0.0 and 1.5, got {value}"
|
||||||
|
)
|
||||||
|
elif setting == "driver":
|
||||||
|
valid_drivers = [
|
||||||
|
"genericDriver",
|
||||||
|
"gstreamerDriver",
|
||||||
|
"dummyDriver",
|
||||||
|
]
|
||||||
|
if value not in valid_drivers:
|
||||||
|
raise ValueError(
|
||||||
|
f"Invalid sound driver: {value}. Valid options: {valid_drivers}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Screen settings validation
|
||||||
|
elif section == "screen":
|
||||||
|
if setting == "driver":
|
||||||
|
valid_drivers = ["vcsaDriver", "ptyDriver", "dummyDriver"]
|
||||||
|
if value not in valid_drivers:
|
||||||
|
raise ValueError(
|
||||||
|
f"Invalid screen driver: {value}. Valid options: {valid_drivers}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Input settings validation
|
||||||
|
elif section == "keyboard":
|
||||||
|
if setting == "driver":
|
||||||
|
valid_drivers = [
|
||||||
|
"evdevDriver",
|
||||||
|
"x11Driver",
|
||||||
|
"dummyDriver",
|
||||||
|
]
|
||||||
|
if value not in valid_drivers:
|
||||||
|
raise ValueError(
|
||||||
|
f"Invalid input driver: {value}. Valid options: {valid_drivers}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# General settings validation
|
||||||
|
elif section == "general":
|
||||||
|
if setting == "debug_level":
|
||||||
|
if not (0 <= value <= 3):
|
||||||
|
raise ValueError(
|
||||||
|
f"Debug level must be between 0 and 3, got {value}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def parse_setting_args(self, settingArgs):
|
||||||
|
if settingArgs is None:
|
||||||
|
return
|
||||||
|
for optionElem in settingArgs.split(";"):
|
||||||
|
setting_val_list = []
|
||||||
|
section_option_list = []
|
||||||
|
section = ""
|
||||||
|
option = ""
|
||||||
|
value = ""
|
||||||
|
setting_val_list = optionElem.split("=", 1)
|
||||||
|
if len(setting_val_list) != 2:
|
||||||
|
continue
|
||||||
|
if "#" in setting_val_list[0]:
|
||||||
|
section_option_list = setting_val_list[0].split("#", 1)
|
||||||
|
elif "." in setting_val_list[0]:
|
||||||
|
section_option_list = setting_val_list[0].split(".", 1)
|
||||||
|
elif "," in setting_val_list[0]:
|
||||||
|
section_option_list = setting_val_list[0].split(",", 1)
|
||||||
|
elif "!" in setting_val_list[0]:
|
||||||
|
section_option_list = setting_val_list[0].split("!", 1)
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
if len(section_option_list) != 2:
|
||||||
|
continue
|
||||||
|
|
||||||
|
section = str(section_option_list[0])
|
||||||
|
option = str(section_option_list[1])
|
||||||
|
value = str(setting_val_list[1])
|
||||||
|
self.set_option_arg_dict(section, option, value)
|
||||||
|
|
||||||
|
def init_fenrir_config(
|
||||||
|
self, cliArgs, fenrir_manager=None, environment=environment.environment
|
||||||
|
):
|
||||||
|
settings_root = "/etc/fenrirscreenreader/"
|
||||||
|
settings_file = cliArgs.setting
|
||||||
|
sound_root = "/usr/share/sounds/fenrirscreenreader/"
|
||||||
|
# get fenrir settings root
|
||||||
|
if not os.path.exists(settings_root):
|
||||||
|
if os.path.exists(fenrir_path + "/../../config/"):
|
||||||
|
settings_root = fenrir_path + "/../../config/"
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
# get settings file
|
||||||
|
if settings_file is None or not os.path.exists(settings_file):
|
||||||
|
if os.path.exists(settings_root + "/settings/settings.conf"):
|
||||||
|
settings_file = settings_root + "/settings/settings.conf"
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
# get sound themes root
|
||||||
|
if not os.path.exists(sound_root):
|
||||||
|
if os.path.exists(fenrir_path + "/../../config/sound/"):
|
||||||
|
sound_root = fenrir_path + "/../../config/sound/"
|
||||||
|
|
||||||
|
environment["runtime"]["SettingsManager"] = self
|
||||||
|
environment["runtime"]["SettingsManager"].initialize(environment)
|
||||||
|
|
||||||
|
valid_config = environment["runtime"]["SettingsManager"].load_settings(
|
||||||
|
settings_file
|
||||||
|
)
|
||||||
|
if not valid_config:
|
||||||
|
return None
|
||||||
|
if cliArgs.options != "":
|
||||||
|
self.parse_setting_args(cliArgs.options)
|
||||||
|
if cliArgs.debug:
|
||||||
|
self.set_setting("general", "debug_level", 3)
|
||||||
|
if cliArgs.print:
|
||||||
|
self.set_setting("general", "debug_level", 3)
|
||||||
|
self.set_setting("general", "debug_mode", "PRINT")
|
||||||
|
if cliArgs.x11:
|
||||||
|
self.set_setting("screen", "driver", "ptyDriver")
|
||||||
|
self.set_setting("keyboard", "driver", "x11Driver")
|
||||||
|
if cliArgs.x11_window_id:
|
||||||
|
self.set_setting(
|
||||||
|
"keyboard", "x11_window_id", cliArgs.x11_window_id
|
||||||
|
)
|
||||||
|
|
||||||
|
self.set_fenrir_keys(self.get_setting("general", "fenrir_keys"))
|
||||||
|
self.set_script_keys(self.get_setting("general", "script_keys"))
|
||||||
|
|
||||||
|
environment["runtime"]["DebugManager"] = debugManager.DebugManager(
|
||||||
|
self.env["runtime"]["SettingsManager"].get_setting(
|
||||||
|
"general", "debug_file"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
environment["runtime"]["DebugManager"].initialize(environment)
|
||||||
|
|
||||||
|
if cliArgs.force_all_screens:
|
||||||
|
environment["runtime"]["force_all_screens"] = True
|
||||||
|
|
||||||
|
if cliArgs.ignore_screen:
|
||||||
|
current_ignore_screen = self.get_setting("screen", "ignore_screen")
|
||||||
|
if current_ignore_screen:
|
||||||
|
ignore_screens = (
|
||||||
|
current_ignore_screen.split(",") + cliArgs.ignore_screen
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
ignore_screens = cliArgs.ignore_screen
|
||||||
|
self.set_setting(
|
||||||
|
"screen", "ignore_screen", ",".join(ignore_screens)
|
||||||
|
)
|
||||||
|
|
||||||
|
if not os.path.exists(
|
||||||
|
self.get_setting("sound", "theme") + "/soundicons.conf"
|
||||||
|
):
|
||||||
|
if os.path.exists(sound_root + self.get_setting("sound", "theme")):
|
||||||
|
self.set_setting(
|
||||||
|
"sound",
|
||||||
|
"theme",
|
||||||
|
sound_root + self.get_setting("sound", "theme"),
|
||||||
|
)
|
||||||
|
if os.path.exists(
|
||||||
|
self.get_setting("sound", "theme") + "/soundicons.conf"
|
||||||
|
):
|
||||||
|
environment["runtime"]["SettingsManager"].load_sound_icons(
|
||||||
|
self.get_setting("sound", "theme"), environment
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
environment["runtime"]["SettingsManager"].load_sound_icons(
|
||||||
|
self.get_setting("sound", "theme"), environment
|
||||||
|
)
|
||||||
|
|
||||||
|
environment["runtime"][
|
||||||
|
"PunctuationManager"
|
||||||
|
] = punctuationManager.PunctuationManager()
|
||||||
|
environment["runtime"]["PunctuationManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"]["TextManager"] = textManager.TextManager()
|
||||||
|
environment["runtime"]["TextManager"].initialize(environment)
|
||||||
|
|
||||||
|
if not os.path.exists(
|
||||||
|
self.get_setting("general", "punctuation_profile")
|
||||||
|
):
|
||||||
|
if os.path.exists(
|
||||||
|
settings_root
|
||||||
|
+ "punctuation/"
|
||||||
|
+ self.get_setting("general", "punctuation_profile")
|
||||||
|
):
|
||||||
|
self.set_setting(
|
||||||
|
"general",
|
||||||
|
"punctuation_profile",
|
||||||
|
settings_root
|
||||||
|
+ "punctuation/"
|
||||||
|
+ self.get_setting("general", "punctuation_profile"),
|
||||||
|
)
|
||||||
|
environment["runtime"]["PunctuationManager"].load_dicts(
|
||||||
|
self.get_setting("general", "punctuation_profile")
|
||||||
|
)
|
||||||
|
if os.path.exists(
|
||||||
|
settings_root
|
||||||
|
+ "punctuation/"
|
||||||
|
+ self.get_setting("general", "punctuation_profile")
|
||||||
|
+ ".conf"
|
||||||
|
):
|
||||||
|
self.set_setting(
|
||||||
|
"general",
|
||||||
|
"punctuation_profile",
|
||||||
|
settings_root
|
||||||
|
+ "punctuation/"
|
||||||
|
+ self.get_setting("general", "punctuation_profile")
|
||||||
|
+ ".conf",
|
||||||
|
)
|
||||||
|
environment["runtime"]["PunctuationManager"].load_dicts(
|
||||||
|
self.get_setting("general", "punctuation_profile")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
environment["runtime"]["PunctuationManager"].load_dicts(
|
||||||
|
self.get_setting("general", "punctuation_profile")
|
||||||
|
)
|
||||||
|
|
||||||
|
if fenrir_manager:
|
||||||
|
environment["runtime"]["FenrirManager"] = fenrir_manager
|
||||||
|
|
||||||
|
environment["runtime"]["MemoryManager"] = memoryManager.MemoryManager()
|
||||||
|
environment["runtime"]["MemoryManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"][
|
||||||
|
"AttributeManager"
|
||||||
|
] = attributeManager.AttributeManager()
|
||||||
|
environment["runtime"]["AttributeManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"]["EventManager"] = eventManager.EventManager()
|
||||||
|
environment["runtime"]["EventManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"][
|
||||||
|
"ProcessManager"
|
||||||
|
] = processManager.ProcessManager()
|
||||||
|
environment["runtime"]["ProcessManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"]["OutputManager"] = outputManager.OutputManager()
|
||||||
|
environment["runtime"]["OutputManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"]["InputManager"] = inputManager.InputManager()
|
||||||
|
environment["runtime"]["InputManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"]["ScreenManager"] = screenManager.ScreenManager()
|
||||||
|
environment["runtime"]["ScreenManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"][
|
||||||
|
"CommandManager"
|
||||||
|
] = commandManager.CommandManager()
|
||||||
|
environment["runtime"]["CommandManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"]["HelpManager"] = helpManager.HelpManager()
|
||||||
|
environment["runtime"]["HelpManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"]["RemoteManager"] = remoteManager.RemoteManager()
|
||||||
|
environment["runtime"]["RemoteManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"][
|
||||||
|
"DiffReviewManager"
|
||||||
|
] = diffReviewManager.DiffReviewManager()
|
||||||
|
environment["runtime"]["DiffReviewManager"].initialize(environment)
|
||||||
|
|
||||||
|
if not os.path.exists(
|
||||||
|
self.get_setting("keyboard", "keyboard_layout")
|
||||||
|
):
|
||||||
|
if os.path.exists(
|
||||||
|
settings_root
|
||||||
|
+ "keyboard/"
|
||||||
|
+ self.get_setting("keyboard", "keyboard_layout")
|
||||||
|
):
|
||||||
|
self.set_setting(
|
||||||
|
"keyboard",
|
||||||
|
"keyboard_layout",
|
||||||
|
settings_root
|
||||||
|
+ "keyboard/"
|
||||||
|
+ self.get_setting("keyboard", "keyboard_layout"),
|
||||||
|
)
|
||||||
|
environment["runtime"]["InputManager"].load_shortcuts(
|
||||||
|
self.get_setting("keyboard", "keyboard_layout")
|
||||||
|
)
|
||||||
|
if os.path.exists(
|
||||||
|
settings_root
|
||||||
|
+ "keyboard/"
|
||||||
|
+ self.get_setting("keyboard", "keyboard_layout")
|
||||||
|
+ ".conf"
|
||||||
|
):
|
||||||
|
self.set_setting(
|
||||||
|
"keyboard",
|
||||||
|
"keyboard_layout",
|
||||||
|
settings_root
|
||||||
|
+ "keyboard/"
|
||||||
|
+ self.get_setting("keyboard", "keyboard_layout")
|
||||||
|
+ ".conf",
|
||||||
|
)
|
||||||
|
environment["runtime"]["InputManager"].load_shortcuts(
|
||||||
|
self.get_setting("keyboard", "keyboard_layout")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
environment["runtime"]["InputManager"].load_shortcuts(
|
||||||
|
self.get_setting("keyboard", "keyboard_layout")
|
||||||
|
)
|
||||||
|
|
||||||
|
environment["runtime"]["CursorManager"] = cursorManager.CursorManager()
|
||||||
|
environment["runtime"]["CursorManager"].initialize(environment)
|
||||||
|
environment["runtime"][
|
||||||
|
"ApplicationManager"
|
||||||
|
] = applicationManager.ApplicationManager()
|
||||||
|
environment["runtime"]["ApplicationManager"].initialize(environment)
|
||||||
|
environment["runtime"]["TextManager"] = textManager.TextManager()
|
||||||
|
environment["runtime"]["TextManager"].initialize(environment)
|
||||||
|
environment["runtime"]["TableManager"] = tableManager.TableManager()
|
||||||
|
environment["runtime"]["TableManager"].initialize(environment)
|
||||||
|
environment["runtime"][
|
||||||
|
"BarrierManager"
|
||||||
|
] = barrierManager.BarrierManager()
|
||||||
|
environment["runtime"]["BarrierManager"].initialize(environment)
|
||||||
|
environment["runtime"]["SayAllManager"] = sayAllManager.SayAllManager()
|
||||||
|
environment["runtime"]["SayAllManager"].initialize(environment)
|
||||||
|
environment["runtime"]["VmenuManager"] = vmenuManager.VmenuManager()
|
||||||
|
environment["runtime"]["VmenuManager"].initialize(environment)
|
||||||
|
environment["runtime"][
|
||||||
|
"QuickMenuManager"
|
||||||
|
] = quickMenuManager.QuickMenuManager()
|
||||||
|
environment["runtime"]["QuickMenuManager"].initialize(environment)
|
||||||
|
|
||||||
|
environment["runtime"][
|
||||||
|
"ReadAllManager"
|
||||||
|
] = readAllManager.ReadAllManager()
|
||||||
|
environment["runtime"]["ReadAllManager"].initialize(environment)
|
||||||
|
|
||||||
|
# only possible after having input and screen managers with clean
|
||||||
|
# buffer
|
||||||
|
environment["runtime"]["InputManager"].write_event_buffer()
|
||||||
|
environment["runtime"]["InputManager"].handle_device_grab(force=True)
|
||||||
|
|
||||||
|
environment["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
r"/-------environment-------/",
|
||||||
|
debug.DebugLevel.INFO,
|
||||||
|
on_any_level=True,
|
||||||
|
)
|
||||||
|
environment["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
str(environment), debug.DebugLevel.INFO, on_any_level=True
|
||||||
|
)
|
||||||
|
environment["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
r"/-------settings.conf-------/",
|
||||||
|
debug.DebugLevel.INFO,
|
||||||
|
on_any_level=True,
|
||||||
|
)
|
||||||
|
environment["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
str(environment["settings"]._sections),
|
||||||
|
debug.DebugLevel.INFO,
|
||||||
|
on_any_level=True,
|
||||||
|
)
|
||||||
|
environment["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
r"/-------self.settingArgDict-------/",
|
||||||
|
debug.DebugLevel.INFO,
|
||||||
|
on_any_level=True,
|
||||||
|
)
|
||||||
|
environment["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
str(self.settingArgDict), debug.DebugLevel.INFO, on_any_level=True
|
||||||
|
)
|
||||||
|
self.bindingsBackup = environment["bindings"].copy()
|
||||||
|
|
||||||
|
return environment
|
||||||
@@ -437,8 +437,8 @@ class driver(inputDriver):
|
|||||||
self.refresh_interesting_keys()
|
self.refresh_interesting_keys()
|
||||||
passive_grabs = self.build_passive_grabs()
|
passive_grabs = self.build_passive_grabs()
|
||||||
failed_before = self.failed_grabs
|
failed_before = self.failed_grabs
|
||||||
for key_name, modifier_mask in passive_grabs:
|
for key_name, modifier_mask, include_num_lock in passive_grabs:
|
||||||
self.grab_key_name(key_name, modifier_mask)
|
self.grab_key_name(key_name, modifier_mask, include_num_lock)
|
||||||
self.display.flush()
|
self.display.flush()
|
||||||
self.grab_signature = signature
|
self.grab_signature = signature
|
||||||
self.write_debug(
|
self.write_debug(
|
||||||
@@ -454,9 +454,10 @@ class driver(inputDriver):
|
|||||||
def build_passive_grabs(self):
|
def build_passive_grabs(self):
|
||||||
grabs = set()
|
grabs = set()
|
||||||
for fenrir_key in self.env["input"]["fenrir_key"]:
|
for fenrir_key in self.env["input"]["fenrir_key"]:
|
||||||
grabs.add((fenrir_key, 0))
|
grabs.add((fenrir_key, 0, True))
|
||||||
for script_key in self.env["input"]["script_key"]:
|
for script_key in self.env["input"]["script_key"]:
|
||||||
grabs.add((script_key, 0))
|
grabs.add((script_key, 0, True))
|
||||||
|
grabs.add(("KEY_NUMLOCK", 0, True))
|
||||||
for shortcut in self.env.get("rawBindings", {}).values():
|
for shortcut in self.env.get("rawBindings", {}).values():
|
||||||
keys = shortcut[1]
|
keys = shortcut[1]
|
||||||
expanded_keys = self.expand_special_keys(keys)
|
expanded_keys = self.expand_special_keys(keys)
|
||||||
@@ -470,12 +471,40 @@ class driver(inputDriver):
|
|||||||
final_key = non_modifier_keys[-1]
|
final_key = non_modifier_keys[-1]
|
||||||
if "KEY_FENRIR" in keys:
|
if "KEY_FENRIR" in keys:
|
||||||
for fenrir_key in self.env["input"]["fenrir_key"]:
|
for fenrir_key in self.env["input"]["fenrir_key"]:
|
||||||
grabs.add((fenrir_key, modifier_mask))
|
grabs.add((fenrir_key, modifier_mask, True))
|
||||||
|
fenrir_modifier_mask = self.modifier_masks.get(
|
||||||
|
fenrir_key, 0
|
||||||
|
)
|
||||||
|
if fenrir_modifier_mask:
|
||||||
|
grabs.add(
|
||||||
|
(
|
||||||
|
final_key,
|
||||||
|
modifier_mask | fenrir_modifier_mask,
|
||||||
|
not final_key.startswith("KEY_KP"),
|
||||||
|
)
|
||||||
|
)
|
||||||
elif "KEY_SCRIPT" in keys:
|
elif "KEY_SCRIPT" in keys:
|
||||||
for script_key in self.env["input"]["script_key"]:
|
for script_key in self.env["input"]["script_key"]:
|
||||||
grabs.add((script_key, modifier_mask))
|
grabs.add((script_key, modifier_mask, True))
|
||||||
|
script_modifier_mask = self.modifier_masks.get(
|
||||||
|
script_key, 0
|
||||||
|
)
|
||||||
|
if script_modifier_mask:
|
||||||
|
grabs.add(
|
||||||
|
(
|
||||||
|
final_key,
|
||||||
|
modifier_mask | script_modifier_mask,
|
||||||
|
not final_key.startswith("KEY_KP"),
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
grabs.add((final_key, modifier_mask))
|
grabs.add(
|
||||||
|
(
|
||||||
|
final_key,
|
||||||
|
modifier_mask,
|
||||||
|
not final_key.startswith("KEY_KP"),
|
||||||
|
)
|
||||||
|
)
|
||||||
return grabs
|
return grabs
|
||||||
|
|
||||||
def expand_special_keys(self, keys):
|
def expand_special_keys(self, keys):
|
||||||
@@ -495,7 +524,9 @@ class driver(inputDriver):
|
|||||||
modifier_mask |= self.modifier_masks.get(key_name, 0)
|
modifier_mask |= self.modifier_masks.get(key_name, 0)
|
||||||
return modifier_mask
|
return modifier_mask
|
||||||
|
|
||||||
def grab_key_name(self, key_name, modifier_mask=0):
|
def grab_key_name(
|
||||||
|
self, key_name, modifier_mask=0, include_num_lock=True
|
||||||
|
):
|
||||||
keysym_names = self.key_name_to_keysym_names(key_name)
|
keysym_names = self.key_name_to_keysym_names(key_name)
|
||||||
for keysym_name in keysym_names:
|
for keysym_name in keysym_names:
|
||||||
keysym = XK.string_to_keysym(keysym_name)
|
keysym = XK.string_to_keysym(keysym_name)
|
||||||
@@ -504,7 +535,9 @@ class driver(inputDriver):
|
|||||||
keycode = self.display.keysym_to_keycode(keysym)
|
keycode = self.display.keysym_to_keycode(keysym)
|
||||||
if not keycode:
|
if not keycode:
|
||||||
continue
|
continue
|
||||||
for effective_mask in self.optional_modifier_masks(modifier_mask):
|
for effective_mask in self.optional_modifier_masks(
|
||||||
|
modifier_mask, include_num_lock
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
self.window.grab_key(
|
self.window.grab_key(
|
||||||
keycode,
|
keycode,
|
||||||
@@ -524,9 +557,9 @@ class driver(inputDriver):
|
|||||||
debug.DebugLevel.WARNING,
|
debug.DebugLevel.WARNING,
|
||||||
)
|
)
|
||||||
|
|
||||||
def optional_modifier_masks(self, modifier_mask):
|
def optional_modifier_masks(self, modifier_mask, include_num_lock=True):
|
||||||
optional_masks = [0, X.LockMask]
|
optional_masks = [0, X.LockMask]
|
||||||
if self.num_lock_mask:
|
if include_num_lock and self.num_lock_mask:
|
||||||
optional_masks += [self.num_lock_mask, self.num_lock_mask | X.LockMask]
|
optional_masks += [self.num_lock_mask, self.num_lock_mask | X.LockMask]
|
||||||
return {modifier_mask | optional for optional in optional_masks}
|
return {modifier_mask | optional for optional in optional_masks}
|
||||||
|
|
||||||
@@ -610,6 +643,15 @@ class driver(inputDriver):
|
|||||||
self.ungrab_all_devices()
|
self.ungrab_all_devices()
|
||||||
|
|
||||||
def get_led_state(self, led=0):
|
def get_led_state(self, led=0):
|
||||||
|
try:
|
||||||
|
pointer = self.root.query_pointer()
|
||||||
|
mask = getattr(pointer, "mask", 0)
|
||||||
|
if led == 0:
|
||||||
|
return bool(self.num_lock_mask and mask & self.num_lock_mask)
|
||||||
|
if led == 1:
|
||||||
|
return bool(mask & X.LockMask)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def set_led_state(self, led_dict):
|
def set_led_state(self, led_dict):
|
||||||
|
|||||||
Reference in New Issue
Block a user