Skip to content

Commit

Permalink
Small BRLTTY driver improvements
Browse files Browse the repository at this point in the history
* Mark the BRLTTY braille display driver as thread safe
* Improve availability check for BRLTTY braille display driver: only report as available if a named pipe for BrlAPI is present
* Add more BRLTTY key bindings (nvaccess#6483):
  * learn: toggle NVDA input help
  * prefmenu: open the NVDA menu
  * prefload/prefsave: Load/save NVDA configuration
  * time: Show time
  * say_line: Speak the current line where the review cursor is located
  * say_below: Say all using review cursor
  • Loading branch information
bramd committed Aug 27, 2023
1 parent 64b6074 commit cef4690
Showing 1 changed file with 36 additions and 9 deletions.
45 changes: 36 additions & 9 deletions source/brailleDisplayDrivers/brltty.py
@@ -1,9 +1,9 @@
#brailleDisplayDrivers/brltty.py
#A part of NonVisual Desktop Access (NVDA)
#This file is covered by the GNU General Public License.
#See the file COPYING for more details.
#Copyright (C) 2008-2019 NV Access Limited, Babbage B.V>
# A part of NonVisual Desktop Access (NVDA)
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.
# Copyright (C) 2008-2023 NV Access Limited, Babbage B.V, Bram Duvigneau

import os
import time
import wx
import braille
Expand All @@ -21,18 +21,38 @@

KEY_CHECK_INTERVAL = 50

# BRLAPI named pipes for local connections are numbered and all start with a common name.
# This name is set on compile time and should be the same for all BRLTTY releases,
# however, if a user compiles their own version this may differ
BRLAPI_NAMED_PIPE_PREFIX = "BrlAPI"

class BrailleDisplayDriver(braille.BrailleDisplayDriver):
"""brltty braille display driver.
"""
name = "brltty"
description = "brltty"
isThreadSafe = True

@classmethod
def _get_brlapi_pipes(cls) -> List[str]:
"""Get the BrlAPI named pipes
Every BRLTTY instance with the BrlAPI enabled will have it's own named pipe to accept API connections.
The brlapi.Connection constructor takes either a `host:port` argument or just `:port`.
If only a port is given, this corresponds to the number at the end of the named pipe.
"""
return [pipe.name for pipe in os.scandir("//./pipe/") if pipe.name.startswith(BRLAPI_NAMED_PIPE_PREFIX)]

@classmethod
def check(cls):
return bool(brlapi)
if not bool(brlapi):
return False
# Since this driver only supports local connections for now,
# we can mark it as unavailable if there are no BrlAPI named pipes present
return bool(cls.brlapi_pipes)

def __init__(self):
super(BrailleDisplayDriver, self).__init__()
super().__init__()
self._con = brlapi.Connection()
self._con.enterTtyModeWithPath()
self._keyCheckTimer = wx.PyTimer(self._handleKeyPresses)
Expand All @@ -42,7 +62,7 @@ def __init__(self):
self._con.ignoreKeys(brlapi.rangeType_type, (brlapi.KEY_TYPE_SYM,))

def terminate(self):
super(BrailleDisplayDriver, self).terminate()
super().terminate()
# Exceptions might be raised if initialisation failed. Just ignore them.
try:
self._keyCheckTimer.Stop()
Expand Down Expand Up @@ -100,6 +120,13 @@ def _onKeyPress(self, key):
"braille_previousLine": ("br(brltty):lnup",),
"braille_nextLine": ("br(brltty):lndn",),
"braille_routeTo": ("br(brltty):route",),
"toggleInputHelp": ("brl(brltty):learn"),
"showGui": ("brl(brltty):prefmenu",),
"revertConfiguration": ("brl(brltty):prefload",),
"saveConfiguration": ("brl(brltty):prefsave",),
"dateTime": ("brl(brltty):time",),
"review_currentLine": ("brl(brltty):say_line",),
"review_sayAll": ("brl(brltty):say_below",),
}
})

Expand All @@ -108,7 +135,7 @@ class InputGesture(braille.BrailleDisplayGesture):
source = BrailleDisplayDriver.name

def __init__(self, model, command, argument):
super(InputGesture, self).__init__()
super().__init__()
self.model = model
self.id = BRLAPI_CMD_KEYS[command]
if command == brlapi.KEY_CMD_ROUTE:
Expand Down

0 comments on commit cef4690

Please sign in to comment.