Fix KeyFlag conversion
This commit is contained in:
parent
6903eeefcd
commit
ad3916e1b8
|
@ -260,8 +260,8 @@ class ReprogrammableKey:
|
||||||
return NamedInt(self._cid, task)
|
return NamedInt(self._cid, task)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def flags(self) -> List[str]:
|
def flags(self) -> KeyFlag:
|
||||||
return list(common.flag_names(KeyFlag, self._flags))
|
return KeyFlag(self._flags)
|
||||||
|
|
||||||
|
|
||||||
class ReprogrammableKeyV4(ReprogrammableKey):
|
class ReprogrammableKeyV4(ReprogrammableKey):
|
||||||
|
@ -321,10 +321,10 @@ class ReprogrammableKeyV4(ReprogrammableKey):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mapping_flags(self) -> List[str]:
|
def mapping_flags(self) -> MappingFlag:
|
||||||
if self._mapping_flags is None:
|
if self._mapping_flags is None:
|
||||||
self._getCidReporting()
|
self._getCidReporting()
|
||||||
return list(common.flag_names(MappingFlag, self._mapping_flags))
|
return MappingFlag(self._mapping_flags)
|
||||||
|
|
||||||
def set_diverted(self, value: bool):
|
def set_diverted(self, value: bool):
|
||||||
"""If set, the control is diverted temporarily and reports presses as HID++ events."""
|
"""If set, the control is diverted temporarily and reports presses as HID++ events."""
|
||||||
|
@ -407,7 +407,7 @@ class ReprogrammableKeyV4(ReprogrammableKey):
|
||||||
|
|
||||||
bfield = 0
|
bfield = 0
|
||||||
for f, v in flags.items():
|
for f, v in flags.items():
|
||||||
key_flag = FLAG_TO_CAPABILITY[f].name.lower()
|
key_flag = FLAG_TO_CAPABILITY[f]
|
||||||
if v and key_flag not in self.flags:
|
if v and key_flag not in self.flags:
|
||||||
raise exceptions.FeatureNotSupported(
|
raise exceptions.FeatureNotSupported(
|
||||||
msg=f'Tried to set mapping flag "{f}" on control "{self.key}" '
|
msg=f'Tried to set mapping flag "{f}" on control "{self.key}" '
|
||||||
|
|
|
@ -38,6 +38,8 @@ from . import settings
|
||||||
from . import settings_validator
|
from . import settings_validator
|
||||||
from . import special_keys
|
from . import special_keys
|
||||||
from .hidpp10_constants import Registers
|
from .hidpp10_constants import Registers
|
||||||
|
from .hidpp20 import KeyFlag
|
||||||
|
from .hidpp20 import MappingFlag
|
||||||
from .hidpp20_constants import GestureId
|
from .hidpp20_constants import GestureId
|
||||||
from .hidpp20_constants import ParamId
|
from .hidpp20_constants import ParamId
|
||||||
|
|
||||||
|
@ -898,7 +900,7 @@ class DivertKeys(settings.Settings):
|
||||||
def read(self, device, key):
|
def read(self, device, key):
|
||||||
key_index = device.keys.index(key)
|
key_index = device.keys.index(key)
|
||||||
key_struct = device.keys[key_index]
|
key_struct = device.keys[key_index]
|
||||||
return b"\x00\x00\x01" if "diverted" in key_struct.mapping_flags else b"\x00\x00\x00"
|
return b"\x00\x00\x01" if MappingFlag.DIVERTED in key_struct.mapping_flags else b"\x00\x00\x00"
|
||||||
|
|
||||||
def write(self, device, key, data_bytes):
|
def write(self, device, key, data_bytes):
|
||||||
key_index = device.keys.index(key)
|
key_index = device.keys.index(key)
|
||||||
|
@ -926,20 +928,20 @@ class DivertKeys(settings.Settings):
|
||||||
sliding = gestures = None
|
sliding = gestures = None
|
||||||
choices = {}
|
choices = {}
|
||||||
if device.keys:
|
if device.keys:
|
||||||
for k in device.keys:
|
for key in device.keys:
|
||||||
if "divertable" in k.flags and "virtual" not in k.flags:
|
if KeyFlag.DIVERTABLE in key.flags and KeyFlag.VIRTUAL not in key.flags:
|
||||||
if "raw XY" in k.flags:
|
if KeyFlag.RAW_XY in key.flags:
|
||||||
choices[k.key] = setting_class.choices_gesture
|
choices[key.key] = setting_class.choices_gesture
|
||||||
if gestures is None:
|
if gestures is None:
|
||||||
gestures = MouseGesturesXY(device, name="MouseGestures")
|
gestures = MouseGesturesXY(device, name="MouseGestures")
|
||||||
if _F.ADJUSTABLE_DPI in device.features:
|
if _F.ADJUSTABLE_DPI in device.features:
|
||||||
choices[k.key] = setting_class.choices_universe
|
choices[key.key] = setting_class.choices_universe
|
||||||
if sliding is None:
|
if sliding is None:
|
||||||
sliding = DpiSlidingXY(
|
sliding = DpiSlidingXY(
|
||||||
device, name="DpiSliding", show_notification=desktop_notifications.show
|
device, name="DpiSliding", show_notification=desktop_notifications.show
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
choices[k.key] = setting_class.choices_divert
|
choices[key.key] = setting_class.choices_divert
|
||||||
if not choices:
|
if not choices:
|
||||||
return None
|
return None
|
||||||
validator = cls(choices, key_byte_count=2, byte_count=1, mask=0x01)
|
validator = cls(choices, key_byte_count=2, byte_count=1, mask=0x01)
|
||||||
|
@ -1111,7 +1113,7 @@ class SpeedChange(settings.Setting):
|
||||||
def build(cls, setting_class, device):
|
def build(cls, setting_class, device):
|
||||||
key_index = device.keys.index(special_keys.CONTROL.DPI_Change)
|
key_index = device.keys.index(special_keys.CONTROL.DPI_Change)
|
||||||
key = device.keys[key_index] if key_index is not None else None
|
key = device.keys[key_index] if key_index is not None else None
|
||||||
if key is not None and "divertable" in key.flags:
|
if key is not None and KeyFlag.DIVERTABLE in key.flags:
|
||||||
keys = [setting_class.choices_extra, key.key]
|
keys = [setting_class.choices_extra, key.key]
|
||||||
return cls(choices=common.NamedInts.list(keys), byte_count=2)
|
return cls(choices=common.NamedInts.list(keys), byte_count=2)
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,6 @@ def _print_device(dev, num=None):
|
||||||
print(" %2d: %-26s, default: %-27s => %-26s" % (k.index, k.key, k.default_task, k.mapped_to))
|
print(" %2d: %-26s, default: %-27s => %-26s" % (k.index, k.key, k.default_task, k.mapped_to))
|
||||||
gmask_fmt = ",".join(k.group_mask)
|
gmask_fmt = ",".join(k.group_mask)
|
||||||
gmask_fmt = gmask_fmt if gmask_fmt else "empty"
|
gmask_fmt = gmask_fmt if gmask_fmt else "empty"
|
||||||
print(f" {', '.join(k.flags)}, pos:{int(k.pos)}, group:{int(k.group):1}, group mask:{gmask_fmt}")
|
|
||||||
flag_names = list(common.flag_names(hidpp20.KeyFlag, k.flags.value))
|
flag_names = list(common.flag_names(hidpp20.KeyFlag, k.flags.value))
|
||||||
print(
|
print(
|
||||||
f" {', '.join(flag_names)}, pos:{int(k.pos)}, group:{int(k.group):1}, group mask:{gmask_fmt}"
|
f" {', '.join(flag_names)}, pos:{int(k.pos)}, group:{int(k.group):1}, group mask:{gmask_fmt}"
|
||||||
|
|
|
@ -22,6 +22,7 @@ from logitech_receiver import exceptions
|
||||||
from logitech_receiver import hidpp20
|
from logitech_receiver import hidpp20
|
||||||
from logitech_receiver import hidpp20_constants
|
from logitech_receiver import hidpp20_constants
|
||||||
from logitech_receiver import special_keys
|
from logitech_receiver import special_keys
|
||||||
|
from logitech_receiver.hidpp20 import KeyFlag
|
||||||
from logitech_receiver.hidpp20_constants import GestureId
|
from logitech_receiver.hidpp20_constants import GestureId
|
||||||
|
|
||||||
from . import fake_hidpp
|
from . import fake_hidpp
|
||||||
|
@ -154,13 +155,13 @@ def test_FeaturesArray_getitem(device, expected0, expected1, expected2, expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"device, index, cid, task_id, flags, default_task, flag_names",
|
"device, index, cid, task_id, flags, default_task, expected_flags",
|
||||||
[
|
[
|
||||||
(device_standard, 2, 1, 1, 0x30, "Volume Up", ["reprogrammable", "divertable"]),
|
(device_standard, 2, 1, 1, 0x30, "Volume Up", KeyFlag.REPROGRAMMABLE | KeyFlag.DIVERTABLE),
|
||||||
(device_standard, 1, 2, 2, 0x20, "Volume Down", ["divertable"]),
|
(device_standard, 1, 2, 2, 0x20, "Volume Down", KeyFlag.DIVERTABLE),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_reprogrammable_key_key(device, index, cid, task_id, flags, default_task, flag_names):
|
def test_reprogrammable_key_key(device, index, cid, task_id, flags, default_task, expected_flags):
|
||||||
key = hidpp20.ReprogrammableKey(device, index, cid, task_id, flags)
|
key = hidpp20.ReprogrammableKey(device, index, cid, task_id, flags)
|
||||||
|
|
||||||
assert key._device == device
|
assert key._device == device
|
||||||
|
@ -170,14 +171,38 @@ def test_reprogrammable_key_key(device, index, cid, task_id, flags, default_task
|
||||||
assert key._flags == flags
|
assert key._flags == flags
|
||||||
assert key.key == special_keys.CONTROL[cid]
|
assert key.key == special_keys.CONTROL[cid]
|
||||||
assert key.default_task == common.NamedInt(cid, default_task)
|
assert key.default_task == common.NamedInt(cid, default_task)
|
||||||
assert sorted(list(key.flags)) == sorted(flag_names)
|
assert key.flags == expected_flags
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"device, index, cid, task_id, flags, pos, group, gmask, default_task, flag_names, group_names",
|
"device, index, cid, task_id, flags, pos, group, gmask, default_task, expected_flags, group_names",
|
||||||
[
|
[
|
||||||
(device_standard, 1, 0x51, 0x39, 0x60, 0, 1, 1, "Right Click", ["divertable", "persistently divertable"], ["g1"]),
|
(
|
||||||
(device_standard, 2, 0x52, 0x3A, 0x11, 1, 2, 3, "Mouse Middle Button", ["mse", "reprogrammable"], ["g1", "g2"]),
|
device_standard,
|
||||||
|
1,
|
||||||
|
0x51,
|
||||||
|
0x39,
|
||||||
|
0x60,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"Right Click",
|
||||||
|
KeyFlag.DIVERTABLE | KeyFlag.PERSISTENTLY_DIVERTABLE,
|
||||||
|
["g1"],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_standard,
|
||||||
|
2,
|
||||||
|
0x52,
|
||||||
|
0x3A,
|
||||||
|
0x11,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
"Mouse Middle Button",
|
||||||
|
KeyFlag.MSE | KeyFlag.REPROGRAMMABLE,
|
||||||
|
["g1", "g2"],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
device_standard,
|
device_standard,
|
||||||
3,
|
3,
|
||||||
|
@ -188,13 +213,13 @@ def test_reprogrammable_key_key(device, index, cid, task_id, flags, default_task
|
||||||
2,
|
2,
|
||||||
7,
|
7,
|
||||||
"Mouse Back Button",
|
"Mouse Back Button",
|
||||||
["reprogrammable", "raw_xy"],
|
KeyFlag.REPROGRAMMABLE | KeyFlag.RAW_XY,
|
||||||
["g1", "g2", "g3"],
|
["g1", "g2", "g3"],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_reprogrammable_key_v4_key(
|
def test_reprogrammable_key_v4_key(
|
||||||
device, index, cid, task_id, flags, pos, group, gmask, default_task, flag_names, group_names
|
device, index, cid, task_id, flags, pos, group, gmask, default_task, expected_flags, group_names
|
||||||
):
|
):
|
||||||
key = hidpp20.ReprogrammableKeyV4(device, index, cid, task_id, flags, pos, group, gmask)
|
key = hidpp20.ReprogrammableKeyV4(device, index, cid, task_id, flags, pos, group, gmask)
|
||||||
|
|
||||||
|
@ -208,21 +233,21 @@ def test_reprogrammable_key_v4_key(
|
||||||
assert key._gmask == gmask
|
assert key._gmask == gmask
|
||||||
assert key.key == special_keys.CONTROL[cid]
|
assert key.key == special_keys.CONTROL[cid]
|
||||||
assert key.default_task == common.NamedInt(cid, default_task)
|
assert key.default_task == common.NamedInt(cid, default_task)
|
||||||
assert sorted(list(key.flags)) == sorted(flag_names)
|
assert key.flags == expected_flags
|
||||||
assert list(key.group_mask) == group_names
|
assert list(key.group_mask) == group_names
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"responses, index, mapped_to, remappable_to, mapping_flags",
|
"responses, index, mapped_to, remappable_to, expected_mapping_flags",
|
||||||
[
|
[
|
||||||
(fake_hidpp.responses_key, 1, "Right Click", common.UnsortedNamedInts(Right_Click=81, Left_Click=80), []),
|
(fake_hidpp.responses_key, 1, "Right Click", common.UnsortedNamedInts(Right_Click=81, Left_Click=80), MappingFlag(0)),
|
||||||
(fake_hidpp.responses_key, 2, "Left Click", None, ["diverted"]),
|
(fake_hidpp.responses_key, 2, "Left Click", None, MappingFlag.DIVERTED),
|
||||||
(fake_hidpp.responses_key, 3, "Mouse Back Button", None, ["diverted", "persistently diverted"]),
|
(fake_hidpp.responses_key, 3, "Mouse Back Button", None, MappingFlag.DIVERTED | MappingFlag.PERSISTENTLY_DIVERTED),
|
||||||
(fake_hidpp.responses_key, 4, "Mouse Forward Button", None, ["diverted", "raw XY diverted"]),
|
(fake_hidpp.responses_key, 4, "Mouse Forward Button", None, MappingFlag.DIVERTED | MappingFlag.RAW_XY_DIVERTED),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
# these fields need access all the key data, so start by setting up a device and its key data
|
# these fields need access all the key data, so start by setting up a device and its key data
|
||||||
def test_reprogrammable_key_v4_query(responses, index, mapped_to, remappable_to, mapping_flags):
|
def test_reprogrammable_key_v4_query(responses, index, mapped_to, remappable_to, expected_mapping_flags):
|
||||||
device = fake_hidpp.Device(
|
device = fake_hidpp.Device(
|
||||||
"KEY", responses=responses, feature=hidpp20_constants.SupportedFeature.REPROG_CONTROLS_V4, offset=5
|
"KEY", responses=responses, feature=hidpp20_constants.SupportedFeature.REPROG_CONTROLS_V4, offset=5
|
||||||
)
|
)
|
||||||
|
@ -232,7 +257,7 @@ def test_reprogrammable_key_v4_query(responses, index, mapped_to, remappable_to,
|
||||||
|
|
||||||
assert key.mapped_to == mapped_to
|
assert key.mapped_to == mapped_to
|
||||||
assert (key.remappable_to == remappable_to) or remappable_to is None
|
assert (key.remappable_to == remappable_to) or remappable_to is None
|
||||||
assert list(key.mapping_flags) == mapping_flags
|
assert key.mapping_flags == expected_mapping_flags
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
@ -244,7 +269,7 @@ def test_reprogrammable_key_v4_query(responses, index, mapped_to, remappable_to,
|
||||||
(fake_hidpp.responses_key, 4, False, False, False, 0x50, ["0056020000", "0056080000", "0056200000", "0056000050"]),
|
(fake_hidpp.responses_key, 4, False, False, False, 0x50, ["0056020000", "0056080000", "0056200000", "0056000050"]),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_ReprogrammableKeyV4_set(responses, index, diverted, persistently_diverted, rawXY_reporting, remap, sets, mocker):
|
def test_reprogrammable_key_v4_set(responses, index, diverted, persistently_diverted, rawXY_reporting, remap, sets, mocker):
|
||||||
responses += [fake_hidpp.Response(r, 0x530, r) for r in sets]
|
responses += [fake_hidpp.Response(r, 0x530, r) for r in sets]
|
||||||
device = fake_hidpp.Device(
|
device = fake_hidpp.Device(
|
||||||
"KEY", responses=responses, feature=hidpp20_constants.SupportedFeature.REPROG_CONTROLS_V4, offset=5
|
"KEY", responses=responses, feature=hidpp20_constants.SupportedFeature.REPROG_CONTROLS_V4, offset=5
|
||||||
|
@ -254,21 +279,21 @@ def test_ReprogrammableKeyV4_set(responses, index, diverted, persistently_divert
|
||||||
spy_request = mocker.spy(device, "request")
|
spy_request = mocker.spy(device, "request")
|
||||||
|
|
||||||
key = device.keys[index]
|
key = device.keys[index]
|
||||||
_mapping_flags = list(key.mapping_flags)
|
_mapping_flags = key.mapping_flags
|
||||||
|
|
||||||
if hidpp20.KeyFlag.DIVERTABLE in key.flags or not diverted:
|
if hidpp20.KeyFlag.DIVERTABLE in key.flags or not diverted:
|
||||||
key.set_diverted(diverted)
|
key.set_diverted(diverted)
|
||||||
else:
|
else:
|
||||||
with pytest.raises(exceptions.FeatureNotSupported):
|
with pytest.raises(exceptions.FeatureNotSupported):
|
||||||
key.set_diverted(diverted)
|
key.set_diverted(diverted)
|
||||||
assert ("diverted" in list(key.mapping_flags)) == (diverted and hidpp20.KeyFlag.DIVERTABLE in key.flags)
|
assert (MappingFlag.DIVERTED in key.mapping_flags) == (diverted and hidpp20.KeyFlag.DIVERTABLE in key.flags)
|
||||||
|
|
||||||
if hidpp20.KeyFlag.PERSISTENTLY_DIVERTABLE in key.flags or not persistently_diverted:
|
if hidpp20.KeyFlag.PERSISTENTLY_DIVERTABLE in key.flags or not persistently_diverted:
|
||||||
key.set_persistently_diverted(persistently_diverted)
|
key.set_persistently_diverted(persistently_diverted)
|
||||||
else:
|
else:
|
||||||
with pytest.raises(exceptions.FeatureNotSupported):
|
with pytest.raises(exceptions.FeatureNotSupported):
|
||||||
key.set_persistently_diverted(persistently_diverted)
|
key.set_persistently_diverted(persistently_diverted)
|
||||||
assert (hidpp20.KeyFlag.PERSISTENTLY_DIVERTABLE in key.mapping_flags) == (
|
assert (hidpp20.MappingFlag.PERSISTENTLY_DIVERTED in key.mapping_flags) == (
|
||||||
persistently_diverted and hidpp20.KeyFlag.PERSISTENTLY_DIVERTABLE in key.flags
|
persistently_diverted and hidpp20.KeyFlag.PERSISTENTLY_DIVERTABLE in key.flags
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -277,7 +302,7 @@ def test_ReprogrammableKeyV4_set(responses, index, diverted, persistently_divert
|
||||||
else:
|
else:
|
||||||
with pytest.raises(exceptions.FeatureNotSupported):
|
with pytest.raises(exceptions.FeatureNotSupported):
|
||||||
key.set_rawXY_reporting(rawXY_reporting)
|
key.set_rawXY_reporting(rawXY_reporting)
|
||||||
assert ("raw XY diverted" in list(key.mapping_flags)) == (rawXY_reporting and hidpp20.KeyFlag.RAW_XY in key.flags)
|
assert (MappingFlag.RAW_XY_DIVERTED in key.mapping_flags) == (rawXY_reporting and hidpp20.KeyFlag.RAW_XY in key.flags)
|
||||||
|
|
||||||
if remap in key.remappable_to or remap == 0:
|
if remap in key.remappable_to or remap == 0:
|
||||||
key.remap(remap)
|
key.remap(remap)
|
||||||
|
|
Loading…
Reference in New Issue