Repository: nvaccess/nvda

Issue:
Input Gestures window shows the name of the last braille display, not the originally defined one
In the "gestures.ini" the braille hotkeys are of course labelled correctly, but the Input Gestures window shows the name of the last set/connected braille display with NVDA. I have set many BAUM hotkeys but after connecting the ALVA BC680 to NVDA all BAUM hotkeys are now labelled as hotkeys for this new ALVA braille display in the GUI.

Example from the German GUI:
"Pfeiltaste nach links
- d2+d3+routing (Optelec ALVA 6-Serien/Protokoll-Konverter)
- d2+d4+d6 (Optelec ALVA 6-Serien/Protokoll-Konverter)
- spleft (Optelec ALVA 6-Serien/Protokoll-Konverter)"

Expected solution:
"Pfeiltaste nach links
- d2+d3+routing (Baum / HumanWare / APH  / Orbit Braillezeilen)
- d2+d4+d6 (Baum / HumanWare / APH  / Orbit Braillezeilen)
- spleft (Optelec ALVA 6-Serien/Protokoll-Konverter)"

The source for the variable (braille display) should be read from the "gestures.ini" file, not from the braille display which was connected/set to NVDA at last..


Discussion:

Resolving patch:
diff --git a/source/braille.py b/source/braille.py
--- a/source/braille.py
+++ b/source/braille.py
@@ -309,8 +309,18 @@ def NVDAObjectHasUsefulText(obj):
 		# Let the NVDAObject choose if the text should be presented
 		return obj._hasNavigableText
 
-def _getDisplayDriver(name):
-	return __import__("brailleDisplayDrivers.%s" % name, globals(), locals(), ("brailleDisplayDrivers",)).BrailleDisplayDriver
+def _getDisplayDriver(moduleName, caseSensitive=True):
+	try:
+		return __import__("brailleDisplayDrivers.%s" % moduleName, globals(), locals(), ("brailleDisplayDrivers",)).BrailleDisplayDriver
+	except ImportError as initialException:
+		if caseSensitive:
+			raise initialException
+		for loader, name, isPkg in pkgutil.iter_modules(brailleDisplayDrivers.__path__):
+			if name.startswith('_') or name.lower() != moduleName.lower():
+				continue
+			return __import__("brailleDisplayDrivers.%s" % name, globals(), locals(), ("brailleDisplayDrivers",)).BrailleDisplayDriver
+		else:
+			raise initialException
 
 def getDisplayList(excludeNegativeChecks=True):
 	"""Gets a list of available display driver names with their descriptions.
@@ -2487,18 +2497,27 @@ def _get_keyNames(self):
 
 	@classmethod
 	def getDisplayTextForIdentifier(cls, identifier):
+		# Translators: Displayed when the source driver of a braille display gesture is unknown.
+		unknownDisplayDescription = _("Unknown braille display")
 		idParts = cls.ID_PARTS_REGEX.match(identifier)
 		if not idParts:
 			log.error("Invalid braille gesture identifier: %s"%identifier)
-			return handler.display.description, "malformed:%s"%identifier
-		modelName = idParts.group(2)
-		key = idParts.group(3)
+			return unknownDisplayDescription, "malformed:%s"%identifier
+		source, modelName, key = idParts.groups()
+		# Optimisation: Do not try to get the braille display class if this identifier belongs to the current driver.
+		if handler.display.name.lower() == source.lower():
+			description = handler.display.description
+		else:
+			try:
+				description = _getDisplayDriver(source, caseSensitive=False).description
+			except ImportError:
+				description = unknownDisplayDescription
 		if modelName: # The identifier contains a model name
-			return handler.display.description, "{modelName}: {key}".format(
+			return description, "{modelName}: {key}".format(
 				modelName=modelName, key=key
 			)
 		else:
-			return handler.display.description, key
+			return description, key
 
 inputCore.registerGestureSource("br", BrailleDisplayGesture)
 


Test patch: