Make all key names work
This commit is contained in:
parent
601e56d2fa
commit
0b6d2c2b0a
@ -39,69 +39,63 @@ def _key_to_string(key):
|
||||
Return:
|
||||
A name of the key as a string.
|
||||
"""
|
||||
return QKeySequence(key).toString() # FIXME
|
||||
special_names_str = {
|
||||
# Some keys handled in a weird way by QKeySequence::toString.
|
||||
# See https://bugreports.qt.io/browse/QTBUG-40030
|
||||
# Most are unlikely to be ever needed, but you never know ;)
|
||||
# For dead/combining keys, we return the corresponding non-combining
|
||||
# key, as that's easier to add to the config.
|
||||
'Key_Blue': 'Blue',
|
||||
'Key_Calendar': 'Calendar',
|
||||
'Key_ChannelDown': 'Channel Down',
|
||||
'Key_ChannelUp': 'Channel Up',
|
||||
'Key_ContrastAdjust': 'Contrast Adjust',
|
||||
'Key_Dead_Abovedot': '˙',
|
||||
'Key_Dead_Abovering': '˚',
|
||||
'Key_Dead_Acute': '´',
|
||||
'Key_Dead_Belowdot': 'Belowdot',
|
||||
'Key_Dead_Breve': '˘',
|
||||
'Key_Dead_Caron': 'ˇ',
|
||||
'Key_Dead_Cedilla': '¸',
|
||||
'Key_Dead_Circumflex': '^',
|
||||
'Key_Dead_Diaeresis': '¨',
|
||||
'Key_Dead_Doubleacute': '˝',
|
||||
'Key_Dead_Grave': '`',
|
||||
'Key_Dead_Hook': 'Hook',
|
||||
'Key_Dead_Horn': 'Horn',
|
||||
'Key_Dead_Iota': 'Iota',
|
||||
'Key_Dead_Macron': '¯',
|
||||
'Key_Dead_Ogonek': '˛',
|
||||
'Key_Dead_Semivoiced_Sound': 'Semivoiced Sound',
|
||||
'Key_Dead_Tilde': '~',
|
||||
'Key_Dead_Voiced_Sound': 'Voiced Sound',
|
||||
'Key_Exit': 'Exit',
|
||||
'Key_Green': 'Green',
|
||||
'Key_Guide': 'Guide',
|
||||
'Key_Info': 'Info',
|
||||
'Key_LaunchG': 'LaunchG',
|
||||
'Key_LaunchH': 'LaunchH',
|
||||
'Key_MediaLast': 'MediaLast',
|
||||
'Key_Memo': 'Memo',
|
||||
'Key_MicMute': 'Mic Mute',
|
||||
'Key_Mode_switch': 'Mode switch',
|
||||
'Key_Multi_key': 'Multi key',
|
||||
'Key_PowerDown': 'Power Down',
|
||||
'Key_Red': 'Red',
|
||||
'Key_Settings': 'Settings',
|
||||
'Key_SingleCandidate': 'Single Candidate',
|
||||
'Key_ToDoList': 'Todo List',
|
||||
'Key_TouchpadOff': 'Touchpad Off',
|
||||
'Key_TouchpadOn': 'Touchpad On',
|
||||
'Key_TouchpadToggle': 'Touchpad toggle',
|
||||
'Key_Yellow': 'Yellow',
|
||||
'Key_Alt': 'Alt',
|
||||
'Key_AltGr': 'AltGr',
|
||||
'Key_Control': 'Control',
|
||||
'Key_Direction_L': 'Direction L',
|
||||
'Key_Direction_R': 'Direction R',
|
||||
'Key_Hyper_L': 'Hyper L',
|
||||
'Key_Hyper_R': 'Hyper R',
|
||||
'Key_Meta': 'Meta',
|
||||
'Key_Shift': 'Shift',
|
||||
'Key_Super_L': 'Super L',
|
||||
'Key_Super_R': 'Super R',
|
||||
'Key_unknown': 'Unknown',
|
||||
|
||||
'Super_L': 'Super L',
|
||||
'Super_R': 'Super R',
|
||||
'Hyper_L': 'Hyper L',
|
||||
'Hyper_R': 'Hyper R',
|
||||
'Direction_L': 'Direction L',
|
||||
'Direction_R': 'Direction R',
|
||||
|
||||
'Shift': 'Shift',
|
||||
'Control': 'Control',
|
||||
'Meta': 'Meta',
|
||||
'Alt': 'Alt',
|
||||
|
||||
'AltGr': 'AltGr',
|
||||
'Multi_key': 'Multi key',
|
||||
'SingleCandidate': 'Single Candidate',
|
||||
'Mode_switch': 'Mode switch',
|
||||
'Dead_Grave': '`',
|
||||
'Dead_Acute': '´',
|
||||
'Dead_Circumflex': '^',
|
||||
'Dead_Tilde': '~',
|
||||
'Dead_Macron': '¯',
|
||||
'Dead_Breve': '˘',
|
||||
'Dead_Abovedot': '˙',
|
||||
'Dead_Diaeresis': '¨',
|
||||
'Dead_Abovering': '˚',
|
||||
'Dead_Doubleacute': '˝',
|
||||
'Dead_Caron': 'ˇ',
|
||||
'Dead_Cedilla': '¸',
|
||||
'Dead_Ogonek': '˛',
|
||||
'Dead_Iota': 'Iota',
|
||||
'Dead_Voiced_Sound': 'Voiced Sound',
|
||||
'Dead_Semivoiced_Sound': 'Semivoiced Sound',
|
||||
'Dead_Belowdot': 'Belowdot',
|
||||
'Dead_Hook': 'Hook',
|
||||
'Dead_Horn': 'Horn',
|
||||
|
||||
'Memo': 'Memo',
|
||||
'ToDoList': 'To Do List',
|
||||
'Calendar': 'Calendar',
|
||||
'ContrastAdjust': 'Contrast Adjust',
|
||||
'LaunchG': 'Launch (G)',
|
||||
'LaunchH': 'Launch (H)',
|
||||
|
||||
'MediaLast': 'Media Last',
|
||||
|
||||
'unknown': 'Unknown',
|
||||
|
||||
# For some keys, we just want a different name
|
||||
'Backtab': 'Tab',
|
||||
'Escape': 'Escape',
|
||||
}
|
||||
# We now build our real special_names dict from the string mapping above.
|
||||
# The reason we don't do this directly is that certain Qt versions don't
|
||||
@ -109,23 +103,14 @@ def _key_to_string(key):
|
||||
special_names = {}
|
||||
for k, v in special_names_str.items():
|
||||
try:
|
||||
special_names[getattr(Qt, k)] = v
|
||||
special_names[getattr(Qt, 'Key_' + k)] = v
|
||||
except AttributeError:
|
||||
pass
|
||||
# Now we check if the key is any special one - if not, we use
|
||||
# QKeySequence::toString.
|
||||
try:
|
||||
|
||||
if key in special_names:
|
||||
return special_names[key]
|
||||
except KeyError:
|
||||
name = QKeySequence(key).toString()
|
||||
morphings = {
|
||||
'Backtab': 'Tab',
|
||||
'Esc': 'Escape',
|
||||
}
|
||||
if name in morphings:
|
||||
return morphings[name]
|
||||
else:
|
||||
return name
|
||||
|
||||
return QKeySequence(key).toString()
|
||||
|
||||
|
||||
class KeyParseError(Exception):
|
||||
|
@ -34,9 +34,9 @@ class Key:
|
||||
# From enum Key in qt5/qtbase/src/corelib/global/qnamespace.h
|
||||
KEYS = [
|
||||
### misc keys
|
||||
Key('Escape', 'Esc'),
|
||||
Key('Escape'), # qutebrowser has a different name from Qt
|
||||
Key('Tab'),
|
||||
Key('Backtab'),
|
||||
Key('Backtab', 'Tab'), # qutebrowser has a different name from Qt
|
||||
Key('Backspace'),
|
||||
Key('Return'),
|
||||
Key('Enter'),
|
||||
@ -56,10 +56,10 @@ KEYS = [
|
||||
Key('PageUp', 'PgUp'),
|
||||
Key('PageDown', 'PgDown'),
|
||||
### modifiers
|
||||
Key('Shift', '\u17c0\udc20'), # FIXME
|
||||
Key('Control', '\u17c0\udc21'), # FIXME
|
||||
Key('Meta', '\u17c0\udc22'), # FIXME
|
||||
Key('Alt', '\u17c0\udc23'), # FIXME
|
||||
Key('Shift'),
|
||||
Key('Control'),
|
||||
Key('Meta'),
|
||||
Key('Alt'),
|
||||
Key('CapsLock'),
|
||||
Key('NumLock'),
|
||||
Key('ScrollLock'),
|
||||
@ -101,17 +101,17 @@ KEYS = [
|
||||
Key('F34'),
|
||||
Key('F35'),
|
||||
### extra keys
|
||||
Key('Super_L', '\u17c0\udc53'), # FIXME
|
||||
Key('Super_R', '\u17c0\udc54'), # FIXME
|
||||
Key('Super_L', 'Super L'),
|
||||
Key('Super_R', 'Super R'),
|
||||
Key('Menu'),
|
||||
Key('Hyper_L', '\u17c0\udc56'), # FIXME
|
||||
Key('Hyper_R', '\u17c0\udc57'), # FIXME
|
||||
Key('Hyper_L', 'Hyper L'),
|
||||
Key('Hyper_R', 'Hyper R'),
|
||||
Key('Help'),
|
||||
Key('Direction_L', '\u17c0\udc59'), # FIXME
|
||||
Key('Direction_R', '\u17c0\udc60'), # FIXME
|
||||
Key('Direction_L', 'Direction L'),
|
||||
Key('Direction_R', 'Direction R'),
|
||||
### 7 bit printable ASCII
|
||||
Key('Space'),
|
||||
Key('Any', 'Space'), # FIXME
|
||||
Key('Any', 'Space'), # Same value
|
||||
Key('Exclam', '!'),
|
||||
Key('QuoteDbl', '"'),
|
||||
Key('NumberSign', '#'),
|
||||
@ -253,15 +253,15 @@ KEYS = [
|
||||
### you are writing your own input method
|
||||
|
||||
### International & multi-key character composition
|
||||
Key('AltGr', '\u17c4\udd03'), # FIXME
|
||||
Key('Multi_key', '\u17c4\udd20'), # FIXME Multi-key character compose
|
||||
Key('AltGr'),
|
||||
Key('Multi_key', 'Multi key'), # Multi-key character compose
|
||||
Key('Codeinput', 'Code input'),
|
||||
Key('SingleCandidate', '\u17c4\udd3c'), # FIXME
|
||||
Key('SingleCandidate', 'Single Candidate'),
|
||||
Key('MultipleCandidate', 'Multiple Candidate'),
|
||||
Key('PreviousCandidate', 'Previous Candidate'),
|
||||
|
||||
### Misc Functions
|
||||
Key('Mode_switch', '\u17c4\udd7e'), # FIXME Character set switch
|
||||
Key('Mode_switch', 'Mode switch'), # Character set switch
|
||||
# Key('script_switch'), # Alias for mode_switch
|
||||
|
||||
### Japanese keyboard support
|
||||
@ -309,25 +309,25 @@ KEYS = [
|
||||
# Key('Hangul_switch', 'Hangul switch'), # Alias for mode_switch
|
||||
|
||||
# dead keys (X keycode - 0xED00 to avoid the conflict),
|
||||
Key('Dead_Grave', '\u17c4\ude50'), # FIXME
|
||||
Key('Dead_Acute', '\u17c4\ude51'), # FIXME
|
||||
Key('Dead_Circumflex', '\u17c4\ude52'), # FIXME
|
||||
Key('Dead_Tilde', '\u17c4\ude53'), # FIXME
|
||||
Key('Dead_Macron', '\u17c4\ude54'), # FIXME
|
||||
Key('Dead_Breve', '\u17c4\ude55'), # FIXME
|
||||
Key('Dead_Abovedot', '\u17c4\ude56'), # FIXME
|
||||
Key('Dead_Diaeresis', '\u17c4\ude57'), # FIXME
|
||||
Key('Dead_Abovering', '\u17c4\ude58'), # FIXME
|
||||
Key('Dead_Doubleacute', '\u17c4\ude59'), # FIXME
|
||||
Key('Dead_Caron', '\u17c4\ude5a'), # FIXME
|
||||
Key('Dead_Cedilla', '\u17c4\ude5b'), # FIXME
|
||||
Key('Dead_Ogonek', '\u17c4\ude5c'), # FIXME
|
||||
Key('Dead_Iota', '\u17c4\ude5d'), # FIXME
|
||||
Key('Dead_Voiced_Sound', '\u17c4\ude5e'), # FIXME
|
||||
Key('Dead_Semivoiced_Sound', '\u17c4\ude5f'), # FIXME
|
||||
Key('Dead_Belowdot', '\u17c4\ude60'), # FIXME
|
||||
Key('Dead_Hook', '\u17c4\ude61'), # FIXME
|
||||
Key('Dead_Horn', '\u17c4\ude62'), # FIXME
|
||||
Key('Dead_Grave', '`'),
|
||||
Key('Dead_Acute', '´'),
|
||||
Key('Dead_Circumflex', '^'),
|
||||
Key('Dead_Tilde', '~'),
|
||||
Key('Dead_Macron', '¯'),
|
||||
Key('Dead_Breve', '˘'),
|
||||
Key('Dead_Abovedot', '˙'),
|
||||
Key('Dead_Diaeresis', '¨'),
|
||||
Key('Dead_Abovering', '˚'),
|
||||
Key('Dead_Doubleacute', '˝'),
|
||||
Key('Dead_Caron', 'ˇ'),
|
||||
Key('Dead_Cedilla', '¸'),
|
||||
Key('Dead_Ogonek', '˛'),
|
||||
Key('Dead_Iota', 'Iota'),
|
||||
Key('Dead_Voiced_Sound', 'Voiced Sound'),
|
||||
Key('Dead_Semivoiced_Sound', 'Semivoiced Sound'),
|
||||
Key('Dead_Belowdot', 'Belowdot'),
|
||||
Key('Dead_Hook', 'Hook'),
|
||||
Key('Dead_Horn', 'Horn'),
|
||||
|
||||
# Not in Qt 5.10, so data may be wrong!
|
||||
Key('Dead_Stroke'),
|
||||
@ -415,7 +415,7 @@ KEYS = [
|
||||
Key('Eject'),
|
||||
Key('ScreenSaver', 'Screensaver'),
|
||||
Key('WWW'),
|
||||
Key('Memo', '\u17c0\udcbc'), # FIXME
|
||||
Key('Memo', 'Memo'),
|
||||
Key('LightBulb'),
|
||||
Key('Shop'),
|
||||
Key('History'),
|
||||
@ -431,7 +431,7 @@ KEYS = [
|
||||
Key('Book'),
|
||||
Key('CD'),
|
||||
Key('Calculator'),
|
||||
Key('ToDoList', '\u17c0\udccc'), # FIXME
|
||||
Key('ToDoList', 'To Do List'),
|
||||
Key('ClearGrab', 'Clear Grab'),
|
||||
Key('Close'),
|
||||
Key('Copy'),
|
||||
@ -455,7 +455,7 @@ KEYS = [
|
||||
Key('Option'),
|
||||
Key('Paste'),
|
||||
Key('Phone'),
|
||||
Key('Calendar', '\u17c0\udce4'), # FIXME
|
||||
Key('Calendar'),
|
||||
Key('Reply'),
|
||||
Key('Reload'),
|
||||
Key('RotateWindows', 'Rotate Windows'),
|
||||
@ -496,10 +496,10 @@ KEYS = [
|
||||
Key('TopMenu', 'Top Menu'),
|
||||
Key('PowerDown', 'Power Down'),
|
||||
Key('Suspend'),
|
||||
Key('ContrastAdjust', '\u17c0\udd0d'), # FIXME
|
||||
Key('ContrastAdjust', 'Contrast Adjust'),
|
||||
|
||||
Key('LaunchG', '\u17c0\udd0e'), # FIXME
|
||||
Key('LaunchH', '\u17c0\udd0f'), # FIXME
|
||||
Key('LaunchG', 'Launch (G)'),
|
||||
Key('LaunchH', 'Launch (H)'),
|
||||
|
||||
Key('TouchpadToggle', 'Touchpad Toggle'),
|
||||
Key('TouchpadOn', 'Touchpad On'),
|
||||
@ -528,7 +528,7 @@ KEYS = [
|
||||
Key('Undo'),
|
||||
Key('Redo'),
|
||||
|
||||
Key('MediaLast', '\u17ff\udfff'), # FIXME
|
||||
Key('MediaLast', 'Media Last'),
|
||||
|
||||
### Keypad navigation keys
|
||||
Key('Select'),
|
||||
@ -562,5 +562,5 @@ KEYS = [
|
||||
Key('Camera', 'Camera Shutter'),
|
||||
Key('CameraFocus', 'Camera Focus'),
|
||||
|
||||
Key('unknown', ''), # FIXME
|
||||
Key('unknown', 'Unknown'),
|
||||
]
|
||||
|
@ -35,43 +35,26 @@ def qt_key(request):
|
||||
return key
|
||||
|
||||
|
||||
def test_new_to_string(qt_key):
|
||||
name = qt_key.attribute if qt_key.name is None else qt_key.name
|
||||
assert keyutils._key_to_string(qt_key.member) == name
|
||||
|
||||
|
||||
class TestKeyToString:
|
||||
|
||||
@pytest.mark.parametrize('key, expected', [
|
||||
(Qt.Key_Blue, 'Blue'),
|
||||
(Qt.Key_Backtab, 'Tab'),
|
||||
(Qt.Key_Escape, 'Escape'),
|
||||
(Qt.Key_A, 'A'),
|
||||
(Qt.Key_degree, '°'),
|
||||
(Qt.Key_Meta, 'Meta'),
|
||||
])
|
||||
@pytest.mark.skipif(True, reason='FIXME')
|
||||
def test_normal(self, key, expected):
|
||||
"""Test a special key where QKeyEvent::toString works incorrectly."""
|
||||
assert keyutils._key_to_string(key) == expected
|
||||
def test_to_string(self, qt_key):
|
||||
name = qt_key.attribute if qt_key.name is None else qt_key.name
|
||||
assert keyutils._key_to_string(qt_key.member) == name
|
||||
|
||||
def test_missing(self, monkeypatch):
|
||||
"""Test with a missing key."""
|
||||
monkeypatch.delattr(keyutils.Qt, 'Key_Blue')
|
||||
# We don't want to test the key which is actually missing - we only
|
||||
# want to know if the mapping still behaves properly.
|
||||
assert keyutils._key_to_string(Qt.Key_A) == 'A'
|
||||
|
||||
@pytest.mark.skipif(True, reason='FIXME')
|
||||
def test_all(self):
|
||||
"""Make sure there's some sensible output for all keys."""
|
||||
for name, value in sorted(vars(Qt).items()):
|
||||
if not isinstance(value, Qt.Key):
|
||||
continue
|
||||
print(name)
|
||||
string = keyutils._key_to_string(value)
|
||||
assert string
|
||||
string.encode('utf-8') # make sure it's encodable
|
||||
"""Make sure all possible keys are in key_data.KEYS."""
|
||||
key_names = {name[len("Key_"):]
|
||||
for name, value in sorted(vars(Qt).items())
|
||||
if isinstance(value, Qt.Key)}
|
||||
key_data_names = {key.attribute for key in sorted(key_data.KEYS)}
|
||||
diff = key_names - key_data_names
|
||||
assert not diff
|
||||
|
||||
|
||||
class TestKeyEventToString:
|
||||
|
Loading…
Reference in New Issue
Block a user