fix: Mute and Min Interesting key codes not properly assigned#45
Conversation
AndyCappDev
left a comment
There was a problem hiding this comment.
Thanks for tracking this down — you nailed the root cause. KEY_MIN_INTERESTING was getting written instead of KEY_MUTE, then dropped by config_loader.parse_action because only KEY_MUTE is in the whitelist. The prebuilt reverse-lookup is also a nice cleanup over the per-call e.__dict__ scan.
One change before merging: the "pick the shortest alias" tiebreak works for KEY_MUTE today, but it's a heuristic. For example, code 152 (KEY_COFFEE / KEY_SCREENLOCK) would pick KEY_COFFEE even though KEY_SCREENLOCK is what users would expect, and any future entry added to SPECIAL_KEYS is one alphabetical reshuffle away from re-breaking the same bug.
We already use an explicit preferred-name dict for a similar case in tuxbox/gui/controls_list.py (PREFERRED_NAMES, mapping codes → display labels). Mirroring that pattern here makes the intent explicit and matches config_loader.KEY_NAMES (the parse whitelist) by construction. Suggestion inline.
| # Build reverse lookup: evdev keycode int -> KEY_* name string | ||
| _EVDEV_CODE_TO_NAME = {} | ||
| for _code, _name in e.bytype[e.EV_KEY].items(): | ||
| if isinstance(_name, tuple): | ||
| _name = _name[0] | ||
| if isinstance(_name, (tuple, list)): | ||
| _name = sorted(list(_name), key=len)[0] | ||
| if _name.startswith('KEY_'): | ||
| _EVDEV_CODE_TO_NAME[_code] = _name |
There was a problem hiding this comment.
| # Build reverse lookup: evdev keycode int -> KEY_* name string | |
| _EVDEV_CODE_TO_NAME = {} | |
| for _code, _name in e.bytype[e.EV_KEY].items(): | |
| if isinstance(_name, tuple): | |
| _name = _name[0] | |
| if isinstance(_name, (tuple, list)): | |
| _name = sorted(list(_name), key=len)[0] | |
| if _name.startswith('KEY_'): | |
| _EVDEV_CODE_TO_NAME[_code] = _name | |
| # Preferred KEY_* name for codes that evdev exposes under multiple aliases. | |
| # config_loader.KEY_NAMES is the parse whitelist, so the alias chosen here | |
| # must match the name listed there (e.g. KEY_MUTE, not KEY_MIN_INTERESTING). | |
| _PREFERRED_CODE_NAMES = { | |
| e.KEY_MUTE: 'KEY_MUTE', | |
| } | |
| # Build reverse lookup: evdev keycode int -> KEY_* name string | |
| _EVDEV_CODE_TO_NAME = {} | |
| for _code, _name in e.bytype[e.EV_KEY].items(): | |
| if _code in _PREFERRED_CODE_NAMES: | |
| _name = _PREFERRED_CODE_NAMES[_code] | |
| elif isinstance(_name, tuple): | |
| _name = _name[0] | |
| if _name.startswith('KEY_'): | |
| _EVDEV_CODE_TO_NAME[_code] = _name |
Hey,
TourBox Neo user here. Thanks for maintaining this project. I have been happily using these drivers in a variety of applications and recently I wanted to use the TourBox for common tasks so I set up the knob to control the volume of the session but, when I tried to assign the "Mute" function is was not working.
I gave it a try it's now working as intended (and everything else).
But I lack context about the internal workings of the project so feel free to reject the PR or ask me for some change.
Cheers