Make sure keys with modifiers get handled as special
This commit is contained in:
parent
c7cccf4ba0
commit
ebb373ccad
@ -48,11 +48,19 @@ def _assert_plain_modifier(key):
|
|||||||
assert not key & ~Qt.KeyboardModifierMask, hex(key)
|
assert not key & ~Qt.KeyboardModifierMask, hex(key)
|
||||||
|
|
||||||
|
|
||||||
def is_printable(key):
|
def _is_printable(key):
|
||||||
_assert_plain_key(key)
|
_assert_plain_key(key)
|
||||||
return key <= 0xff and key not in [Qt.Key_Space, 0x0]
|
return key <= 0xff and key not in [Qt.Key_Space, 0x0]
|
||||||
|
|
||||||
|
|
||||||
|
def is_special(key, modifiers):
|
||||||
|
"""Check whether this key requires special key syntax."""
|
||||||
|
_assert_plain_key(key)
|
||||||
|
_assert_plain_modifier(modifiers)
|
||||||
|
return not (_is_printable(key) and
|
||||||
|
modifiers in [Qt.ShiftModifier, Qt.NoModifier])
|
||||||
|
|
||||||
|
|
||||||
def is_modifier_key(key):
|
def is_modifier_key(key):
|
||||||
"""Test whether the given key is a modifier.
|
"""Test whether the given key is a modifier.
|
||||||
|
|
||||||
@ -277,7 +285,7 @@ class KeyInfo:
|
|||||||
if self.key in _MODIFIER_MAP:
|
if self.key in _MODIFIER_MAP:
|
||||||
# Don't return e.g. <Shift+Shift>
|
# Don't return e.g. <Shift+Shift>
|
||||||
modifiers &= ~_MODIFIER_MAP[self.key]
|
modifiers &= ~_MODIFIER_MAP[self.key]
|
||||||
elif is_printable(self.key):
|
elif _is_printable(self.key):
|
||||||
# "normal" binding
|
# "normal" binding
|
||||||
if not key_string: # pragma: no cover
|
if not key_string: # pragma: no cover
|
||||||
raise ValueError("Got empty string for key 0x{:x}!"
|
raise ValueError("Got empty string for key 0x{:x}!"
|
||||||
@ -285,14 +293,17 @@ class KeyInfo:
|
|||||||
|
|
||||||
assert len(key_string) == 1, key_string
|
assert len(key_string) == 1, key_string
|
||||||
if self.modifiers == Qt.ShiftModifier:
|
if self.modifiers == Qt.ShiftModifier:
|
||||||
|
assert not is_special(self.key, self.modifiers)
|
||||||
return key_string.upper()
|
return key_string.upper()
|
||||||
elif self.modifiers == Qt.NoModifier:
|
elif self.modifiers == Qt.NoModifier:
|
||||||
|
assert not is_special(self.key, self.modifiers)
|
||||||
return key_string.lower()
|
return key_string.lower()
|
||||||
else:
|
else:
|
||||||
# Use special binding syntax, but <Ctrl-a> instead of <Ctrl-A>
|
# Use special binding syntax, but <Ctrl-a> instead of <Ctrl-A>
|
||||||
key_string = key_string.lower()
|
key_string = key_string.lower()
|
||||||
|
|
||||||
# "special" binding
|
# "special" binding
|
||||||
|
assert is_special(self.key, self.modifiers)
|
||||||
modifier_string = _modifiers_to_string(modifiers)
|
modifier_string = _modifiers_to_string(modifiers)
|
||||||
return '<{}{}>'.format(modifier_string, key_string)
|
return '<{}{}>'.format(modifier_string, key_string)
|
||||||
|
|
||||||
@ -309,7 +320,7 @@ class KeyInfo:
|
|||||||
|
|
||||||
if self.key in control:
|
if self.key in control:
|
||||||
return control[self.key]
|
return control[self.key]
|
||||||
elif not is_printable(self.key):
|
elif not _is_printable(self.key):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
text = QKeySequence(self.key).toString()
|
text = QKeySequence(self.key).toString()
|
||||||
@ -490,7 +501,7 @@ class KeySequence:
|
|||||||
# In addition, Shift also *is* relevant when other modifiers are
|
# In addition, Shift also *is* relevant when other modifiers are
|
||||||
# involved. Shift-Ctrl-X should not be equivalent to Ctrl-X.
|
# involved. Shift-Ctrl-X should not be equivalent to Ctrl-X.
|
||||||
if (modifiers == Qt.ShiftModifier and
|
if (modifiers == Qt.ShiftModifier and
|
||||||
is_printable(ev.key()) and
|
_is_printable(ev.key()) and
|
||||||
not ev.text().isupper()):
|
not ev.text().isupper()):
|
||||||
modifiers = Qt.KeyboardModifiers()
|
modifiers = Qt.KeyboardModifiers()
|
||||||
|
|
||||||
|
@ -264,8 +264,7 @@ class HintKeyParser(CommandKeyParser):
|
|||||||
if dry_run:
|
if dry_run:
|
||||||
return dry_run_match
|
return dry_run_match
|
||||||
|
|
||||||
if (not keyutils.is_printable(e.key()) and
|
if keyutils.is_special(e.key(), e.modifiers()):
|
||||||
dry_run_match == QKeySequence.NoMatch):
|
|
||||||
log.keyboard.debug("Got special key, clearing keychain")
|
log.keyboard.debug("Got special key, clearing keychain")
|
||||||
self.clear_keystring()
|
self.clear_keystring()
|
||||||
|
|
||||||
@ -346,7 +345,7 @@ class RegisterKeyParser(CommandKeyParser):
|
|||||||
if match or dry_run:
|
if match or dry_run:
|
||||||
return match
|
return match
|
||||||
|
|
||||||
if not keyutils.is_printable(e.key()):
|
if keyutils.is_special(e.key(), e.modifiers()):
|
||||||
# this is not a proper register key, let it pass and keep going
|
# this is not a proper register key, let it pass and keep going
|
||||||
return QKeySequence.NoMatch
|
return QKeySequence.NoMatch
|
||||||
|
|
||||||
|
@ -469,7 +469,19 @@ def test_key_info_to_int():
|
|||||||
(Qt.Key_X, True),
|
(Qt.Key_X, True),
|
||||||
])
|
])
|
||||||
def test_is_printable(key, printable):
|
def test_is_printable(key, printable):
|
||||||
assert keyutils.is_printable(key) == printable
|
assert keyutils._is_printable(key) == printable
|
||||||
|
assert keyutils.is_special(key, Qt.NoModifier) != printable
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('key, modifiers, special', [
|
||||||
|
(Qt.Key_Escape, Qt.NoModifier, True),
|
||||||
|
(Qt.Key_Escape, Qt.ShiftModifier, True),
|
||||||
|
(Qt.Key_Escape, Qt.ControlModifier, True),
|
||||||
|
(Qt.Key_X, Qt.ControlModifier, True),
|
||||||
|
(Qt.Key_X, Qt.NoModifier, False),
|
||||||
|
])
|
||||||
|
def test_is_special(key, modifiers, special):
|
||||||
|
assert keyutils.is_special(key, modifiers) == special
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('key, ismodifier', [
|
@pytest.mark.parametrize('key, ismodifier', [
|
||||||
@ -484,7 +496,7 @@ def test_is_modifier_key(key, ismodifier):
|
|||||||
@pytest.mark.parametrize('func', [
|
@pytest.mark.parametrize('func', [
|
||||||
keyutils._assert_plain_key,
|
keyutils._assert_plain_key,
|
||||||
keyutils._assert_plain_modifier,
|
keyutils._assert_plain_modifier,
|
||||||
keyutils.is_printable,
|
keyutils._is_printable,
|
||||||
keyutils.is_modifier_key,
|
keyutils.is_modifier_key,
|
||||||
keyutils._key_to_string,
|
keyutils._key_to_string,
|
||||||
keyutils._modifiers_to_string,
|
keyutils._modifiers_to_string,
|
||||||
|
Loading…
Reference in New Issue
Block a user