Improve handling of keyboard emulation gestures and testing of braille display gesture map integrity#8240
Improve handling of keyboard emulation gestures and testing of braille display gesture map integrity#8240LeonarddeR wants to merge 12 commits into
Conversation
…t gestures that have been disabled in the user gesture map
…y, thereby fixing several malformed gesture to script assignments
…w use fromIdentifier
…creating an emulated gesture
feerrenrut
left a comment
There was a problem hiding this comment.
I'm not sure that I fully understand this change. It bothers me somewhat that the code for processing gestures (including string manipulations etc) is spread around as it is. I wouldn't suggest it as part of this change, but I think it might be worthwhile considering the abstraction level for gestures. I would like to go over this again.
| for scriptCls, gesture, scriptName in globalMap.getScriptsForAllGestures() | ||
| if any(gesture.startswith(prefix.lower()) for prefix in prefixes) | ||
| and scriptCls is globalCommands.GlobalCommands | ||
| and (scriptName is None or scriptName.startswith("kb")) |
There was a problem hiding this comment.
The conditions in this block are fairly dense, and not very well explained. I would be all for trying to break this up a little bit. Something I am concerned about here (if I am reading this right), in the old version we took gesture / scriptName if only if scriptName started with "kb". Now we also take it if it is None?
There was a problem hiding this comment.
We also take scriptNames when they are None, because the following can happen:
- A display driver has br(alva):t3 assigned to control
- A user removes this binding from the input gestures dialog
- br(alva):t3 is now assigned to None
If we would ignore the None occurrences here, _getModifierGestures would still yield t3 as being assigned to control.
| and (scriptName is None or scriptName.startswith("kb")) | ||
| } | ||
| for gesture, scriptName in emuGestureToScriptMap.iteritems(): | ||
| if scriptName: |
There was a problem hiding this comment.
we accept scriptName when it's none, but then check to ensure it isn't? See my other comment.
There was a problem hiding this comment.
We accept the None to filter out the cases where a user has manually overridden an assignment as noted above. However, we only yield the assignments that are currently in effect. As in the example above, the function wouldn't yield anything for the br(alva):t3 key, as it has been re-assigned to None and therefore can be ignored within the scope of modifier gestures.
| # Find a script for L{gestureKeys}. | ||
| id = "+".join(gestureKeys) | ||
| fakeGestureIds = [u"br({source}):{id}".format(source=self.source, id=id),] | ||
| fakeGestureIds = [ |
There was a problem hiding this comment.
What is a "fake gesture"?
There was a problem hiding this comment.
I'm not very happy with this name either. I renamed fakeGestureId to gestureIdWithoutModifiers and added an explanation in comments, all in non committed code as of yet.
| for globalMap in globalMaps: | ||
| for fakeGestureId in fakeGestureIds: | ||
| scriptNames.extend(scriptName for cls, scriptName in globalMap.getScriptsForGesture(fakeGestureId.lower()) if scriptName.startswith("kb")) | ||
| scriptNames.extend(scriptName for cls, scriptName in globalMap.getScriptsForGesture(fakeGestureId) if scriptName is None or scriptName.startswith("kb")) |
There was a problem hiding this comment.
could you split this onto multiple lines?
| inputCore.normalizeGestureIdentifier(u"br({source}.{model}):{id}".format(source=self.source, model=self.model, id=id)) | ||
| ) | ||
| scriptNames = [] | ||
| # We can't bother about multiple scripts for a gesture, we will just use the first one |
There was a problem hiding this comment.
I think this comment could be clarified. I think this means
"Gestures may be duplicated across different maps (EG the same gesture is present in both the userGestureMap and the gestureMap. User gestures should override display gestures, so we intentionally order the maps with the most important first when finding matches. Later we just take the first"
| keys=scriptName.split(":")[1] | ||
| ) | ||
| else: | ||
| scriptName = scriptNames[0] |
There was a problem hiding this comment.
Given we are only interested in the first, could we just break out of the loop at line 2264 when we find the first match?
There was a problem hiding this comment.
Hmm, instead of extending the scriptNames list, I could imagine the creation of a nested loop, i.e.
for globalMap in globalMaps:
for gestureId in gestureIds:
for cls, scriptName in globalMap.getScriptsForGesture(gestureId):
if scriptName is something:
break
However as you know, this only breaks out of the inner most loop. I guess the only way to do this, would be by means of a function. I can declare a local function inside _get_script, but don't know whether that is very ideal.
| gestureKeys = set(self.keyNames) | ||
| # Input gestures are normalized in gesture maps. | ||
| # Therefore, if we look for possible modifiers in a gesture, we ought to convert the key names to lower case. | ||
| keyNames = [name.lower() for name in self.keyNames] |
There was a problem hiding this comment.
Why don't we run this through normalizedGesture?
| @@ -540,15 +547,41 @@ def fromName(cls, name): | |||
| keys.append((winUser.VK_MENU, False)) | |||
| # Not sure whether we need to support the Hankaku modifier (& 8). | |||
There was a problem hiding this comment.
What's this comment for
There was a problem hiding this comment.
I have no idea honestly.
|
It is likely that this needs a significant rewrite/refactor after the python 3 transition. Therefore I'm closing this for now. It is probably best to reopen smaller, more manageable pull requests in the future. |
|
@LeonarddeR some work has been done on this during last years, including a fix for #8149. cc: @burmancomp |
Link to issue number:
Fixes #8149
Fixes #8201
This pr also contains code from #7784. I consider this pr more important than #7784 and will revert duplicate code from #7784
Summary of the issue:
Description of how this pull request fixes the issue:
kb:nothingorkb:a+s+x+control.Other enhancements and improvements
Testing performed:
Unit tests.
Known issues with pull request:
Using fromIdentifier to create braille display gestures doesn't support the braille input framework. For example, when pressing dot1 on a hims display, this would map to the identifiers bk:dots, bk:dot1 and br(hims):dot1. However, when creating an input gesture from br(hims):dot1, the braille input identifiers won't be available on that instance. This would require manual implementations of fromModifier for every specific driver, which is way beyond the scope of this pr.
Change log entry:
Bug fixes
Changes for developers