summaryrefslogtreecommitdiff
path: root/qutebrowser/keyinput/keyutils.py
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2019-09-10 12:23:36 +0200
committerFlorian Bruhin <me@the-compiler.org>2019-09-10 12:23:36 +0200
commitdb60aef3d28cc2ed1ffe138fc9f800b284e13ab7 (patch)
treea90195f34cd18b88ca9008a0a988b58d8c4b8cd4 /qutebrowser/keyinput/keyutils.py
parentc7675a89a271f6f6a39e58439a758fbbd5dcd9f0 (diff)
parente9057c33227387c42f68bb4115be8ae239ee4d01 (diff)
downloadqutebrowser-db60aef3d28cc2ed1ffe138fc9f800b284e13ab7.tar.gz
qutebrowser-db60aef3d28cc2ed1ffe138fc9f800b284e13ab7.zip
Merge remote-tracking branch 'origin/pr/4536'
Diffstat (limited to 'qutebrowser/keyinput/keyutils.py')
-rw-r--r--qutebrowser/keyinput/keyutils.py137
1 files changed, 75 insertions, 62 deletions
diff --git a/qutebrowser/keyinput/keyutils.py b/qutebrowser/keyinput/keyutils.py
index a10be8642..63c1e3ce2 100644
--- a/qutebrowser/keyinput/keyutils.py
+++ b/qutebrowser/keyinput/keyutils.py
@@ -20,6 +20,7 @@
"""Our own QKeySequence-like class and related utilities."""
import itertools
+import typing
import attr
from PyQt5.QtCore import Qt, QEvent
@@ -38,63 +39,15 @@ _MODIFIER_MAP = {
}
-def _assert_plain_key(key):
- """Make sure this is a key without KeyboardModifiers mixed in."""
- assert not key & Qt.KeyboardModifierMask, hex(key)
-
-
-def _assert_plain_modifier(key):
- """Make sure this is a modifier without a key mixed in."""
- assert not key & ~Qt.KeyboardModifierMask, hex(key)
-
-
-def _is_printable(key):
- _assert_plain_key(key)
- 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,
- Qt.KeypadModifier])
-
-
-def is_modifier_key(key):
- """Test whether the given key is a modifier.
-
- This only considers keys which are part of Qt::KeyboardModifiers, i.e.
- which would interrupt a key chain like "yY" when handled.
- """
- _assert_plain_key(key)
- return key in _MODIFIER_MAP
+_SPECIAL_NAMES = {}
-def _check_valid_utf8(s, data):
- """Make sure the given string is valid UTF-8.
+def _build_special_names():
+ """Build _SPECIAL_NAMES dict from the special_names_str mapping below.
- Makes sure there are no chars where Qt did fall back to weird UTF-16
- surrogates.
+ The reason we don't do this directly is that certain Qt versions don't have
+ all the keys, so we want to ignore AttributeErrors.
"""
- try:
- s.encode('utf-8')
- except UnicodeEncodeError as e: # pragma: no cover
- raise ValueError("Invalid encoding in 0x{:x} -> {}: {}"
- .format(data, s, e))
-
-
-def _key_to_string(key):
- """Convert a Qt::Key member to a meaningful name.
-
- Args:
- key: A Qt::Key member.
-
- Return:
- A name of the key as a string.
- """
- _assert_plain_key(key)
special_names_str = {
# Some keys handled in a weird way by QKeySequence::toString.
# See https://bugreports.qt.io/browse/QTBUG-40030
@@ -183,19 +136,79 @@ def _key_to_string(key):
# For some keys, we just want a different name
'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
- # have all the keys, so we want to ignore AttributeErrors.
- special_names = {}
+
for k, v in special_names_str.items():
try:
- special_names[getattr(Qt, 'Key_' + k)] = v
+ _SPECIAL_NAMES[getattr(Qt, 'Key_' + k)] = v
except AttributeError:
pass
- special_names[0x0] = 'nil'
+ _SPECIAL_NAMES[0x0] = 'nil'
+
+
+if not _SPECIAL_NAMES:
+ _build_special_names()
+
+
+def _assert_plain_key(key):
+ """Make sure this is a key without KeyboardModifiers mixed in."""
+ assert not key & Qt.KeyboardModifierMask, hex(key)
+
+
+def _assert_plain_modifier(key):
+ """Make sure this is a modifier without a key mixed in."""
+ assert not key & ~Qt.KeyboardModifierMask, hex(key)
+
+
+def _is_printable(key):
+ _assert_plain_key(key)
+ 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,
+ Qt.KeypadModifier])
+
+
+def is_modifier_key(key):
+ """Test whether the given key is a modifier.
+
+ This only considers keys which are part of Qt::KeyboardModifiers, i.e.
+ which would interrupt a key chain like "yY" when handled.
+ """
+ _assert_plain_key(key)
+ return key in _MODIFIER_MAP
+
+
+def _check_valid_utf8(s, data):
+ """Make sure the given string is valid UTF-8.
+
+ Makes sure there are no chars where Qt did fall back to weird UTF-16
+ surrogates.
+ """
+ try:
+ s.encode('utf-8')
+ except UnicodeEncodeError as e: # pragma: no cover
+ raise ValueError("Invalid encoding in 0x{:x} -> {}: {}"
+ .format(data, s, e))
+
+
+def _key_to_string(key):
+ """Convert a Qt::Key member to a meaningful name.
+
+ Args:
+ key: A Qt::Key member.
+
+ Return:
+ A name of the key as a string.
+ """
+ _assert_plain_key(key)
- if key in special_names:
- return special_names[key]
+ if key in _SPECIAL_NAMES:
+ return _SPECIAL_NAMES[key]
result = QKeySequence(key).toString()
_check_valid_utf8(result, key)
@@ -569,7 +582,7 @@ class KeySequence:
keys = [key & ~modifiers for key in self._iter_keys()]
return self.__class__(*keys)
- def with_mappings(self, mappings):
+ def with_mappings(self, mappings: typing.Mapping):
"""Get a new KeySequence with the given mappings applied."""
keys = []
for key in self._iter_keys():