receiver: optimize ReprogrammableKey in hidpp20
This commit is contained in:
parent
cb14c2eec9
commit
9315b3fcdb
|
@ -439,10 +439,6 @@ class ReprogrammableKeyV4(ReprogrammableKey):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def remappable_to(self) -> List[_NamedInt]:
|
def remappable_to(self) -> List[_NamedInt]:
|
||||||
# this flag is only to show in UI, ignore in Solaar
|
|
||||||
# if special_keys.KEY_FLAG.reprogrammable not in self.flags:
|
|
||||||
# return []
|
|
||||||
|
|
||||||
self._device.keys._ensure_all_keys_queried()
|
self._device.keys._ensure_all_keys_queried()
|
||||||
ret = []
|
ret = []
|
||||||
if self.group_mask != []: # only keys with a non-zero gmask are remappable
|
if self.group_mask != []: # only keys with a non-zero gmask are remappable
|
||||||
|
@ -454,7 +450,6 @@ class ReprogrammableKeyV4(ReprogrammableKey):
|
||||||
tgt_task = _NamedInt(tgt_cid, tgt_task)
|
tgt_task = _NamedInt(tgt_cid, tgt_task)
|
||||||
if tgt_task != self.default_task: # don't put itself in twice
|
if tgt_task != self.default_task: # don't put itself in twice
|
||||||
ret.append(tgt_task)
|
ret.append(tgt_task)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -464,8 +459,7 @@ class ReprogrammableKeyV4(ReprogrammableKey):
|
||||||
return special_keys.MAPPING_FLAG.flag_names(self._mapping_flags)
|
return special_keys.MAPPING_FLAG.flag_names(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."""
|
||||||
until a HID++ configuration reset occurs."""
|
|
||||||
flags = {special_keys.MAPPING_FLAG.diverted: value}
|
flags = {special_keys.MAPPING_FLAG.diverted: value}
|
||||||
self._setCidReporting(flags=flags)
|
self._setCidReporting(flags=flags)
|
||||||
|
|
||||||
|
@ -475,23 +469,17 @@ class ReprogrammableKeyV4(ReprogrammableKey):
|
||||||
self._setCidReporting(flags=flags)
|
self._setCidReporting(flags=flags)
|
||||||
|
|
||||||
def set_rawXY_reporting(self, value: bool):
|
def set_rawXY_reporting(self, value: bool):
|
||||||
"""If set, the mouse reports all its raw XY events while this control is pressed
|
"""If set, the mouse temporarilty reports all its raw XY events while this control is pressed as HID++ events."""
|
||||||
as HID++ events. Gets cleared on a HID++ configuration reset."""
|
|
||||||
flags = {special_keys.MAPPING_FLAG.raw_XY_diverted: value}
|
flags = {special_keys.MAPPING_FLAG.raw_XY_diverted: value}
|
||||||
self._setCidReporting(flags=flags)
|
self._setCidReporting(flags=flags)
|
||||||
|
|
||||||
def remap(self, to: _NamedInt):
|
def remap(self, to: _NamedInt):
|
||||||
"""Remaps this control to another action."""
|
"""Temporarily remaps this control to another action."""
|
||||||
self._setCidReporting(remap=int(to))
|
self._setCidReporting(remap=int(to))
|
||||||
|
|
||||||
def _getCidReporting(self):
|
def _getCidReporting(self):
|
||||||
try:
|
try:
|
||||||
mapped_data = feature_request(
|
mapped_data = feature_request(self._device, FEATURE.REPROG_CONTROLS_V4, 0x20, *tuple(_pack('!H', self._cid)))
|
||||||
self._device,
|
|
||||||
FEATURE.REPROG_CONTROLS_V4,
|
|
||||||
0x20,
|
|
||||||
*tuple(_pack('!H', self._cid)),
|
|
||||||
)
|
|
||||||
if mapped_data:
|
if mapped_data:
|
||||||
cid, mapping_flags_1, mapped_to = _unpack('!HBH', mapped_data[:5])
|
cid, mapping_flags_1, mapped_to = _unpack('!HBH', mapped_data[:5])
|
||||||
if cid != self._cid and _log.isEnabledFor(_WARNING):
|
if cid != self._cid and _log.isEnabledFor(_WARNING):
|
||||||
|
@ -515,9 +503,7 @@ class ReprogrammableKeyV4(ReprogrammableKey):
|
||||||
self._mapped_to = self._cid
|
self._mapped_to = self._cid
|
||||||
|
|
||||||
def _setCidReporting(self, flags=None, remap=0):
|
def _setCidReporting(self, flags=None, remap=0):
|
||||||
"""Sends a `setCidReporting` request with the given parameters to the control. Raises
|
"""Sends a `setCidReporting` request with the given parameters. Raises an exception if the parameters are invalid.
|
||||||
an exception if the parameters are invalid.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
- flags {Dict[_NamedInt,bool]} -- a dictionary of which mapping flags to set/unset
|
- flags {Dict[_NamedInt,bool]} -- a dictionary of which mapping flags to set/unset
|
||||||
- remap {int} -- which control ID to remap to; or 0 to keep current mapping
|
- remap {int} -- which control ID to remap to; or 0 to keep current mapping
|
||||||
|
@ -525,8 +511,7 @@ class ReprogrammableKeyV4(ReprogrammableKey):
|
||||||
flags = flags if flags else {} # See flake8 B006
|
flags = flags if flags else {} # See flake8 B006
|
||||||
|
|
||||||
# if special_keys.MAPPING_FLAG.raw_XY_diverted in flags and flags[special_keys.MAPPING_FLAG.raw_XY_diverted]:
|
# if special_keys.MAPPING_FLAG.raw_XY_diverted in flags and flags[special_keys.MAPPING_FLAG.raw_XY_diverted]:
|
||||||
# We need diversion to report raw XY, so divert temporarily
|
# We need diversion to report raw XY, so divert temporarily (since XY reporting is also temporary)
|
||||||
# (since XY reporting is also temporary)
|
|
||||||
# flags[special_keys.MAPPING_FLAG.diverted] = True
|
# flags[special_keys.MAPPING_FLAG.diverted] = True
|
||||||
# if special_keys.MAPPING_FLAG.diverted in flags and not flags[special_keys.MAPPING_FLAG.diverted]:
|
# if special_keys.MAPPING_FLAG.diverted in flags and not flags[special_keys.MAPPING_FLAG.diverted]:
|
||||||
# flags[special_keys.MAPPING_FLAG.raw_XY_diverted] = False
|
# flags[special_keys.MAPPING_FLAG.raw_XY_diverted] = False
|
||||||
|
@ -547,35 +532,28 @@ class ReprogrammableKeyV4(ReprogrammableKey):
|
||||||
msg=f'Tried to set mapping flag "{f}" on control "{self.key}" ' +
|
msg=f'Tried to set mapping flag "{f}" on control "{self.key}" ' +
|
||||||
f'which does not support "{FLAG_TO_CAPABILITY[f]}" on device {self._device}.'
|
f'which does not support "{FLAG_TO_CAPABILITY[f]}" on device {self._device}.'
|
||||||
)
|
)
|
||||||
|
|
||||||
bfield |= int(f) if v else 0
|
bfield |= int(f) if v else 0
|
||||||
bfield |= int(f) << 1 # The 'Xvalid' bit
|
bfield |= int(f) << 1 # The 'Xvalid' bit
|
||||||
|
if self._mapping_flags: # update flags if already read
|
||||||
|
if v:
|
||||||
|
self._mapping_flags |= int(f)
|
||||||
|
else:
|
||||||
|
self._mapping_flags &= ~int(f)
|
||||||
|
|
||||||
if remap != 0 and remap not in self.remappable_to:
|
if remap != 0 and remap not in self.remappable_to:
|
||||||
raise FeatureNotSupported(
|
raise FeatureNotSupported(
|
||||||
msg=f'Tried to remap control "{self.key}" to a control ID {remap} which it is not remappable to ' +
|
msg=f'Tried to remap control "{self.key}" to a control ID {remap} which it is not remappable to ' +
|
||||||
f'on device {self._device}.'
|
f'on device {self._device}.'
|
||||||
)
|
)
|
||||||
|
if remap != 0: # update mapping if changing (even if not already read)
|
||||||
|
self._mapped_to = remap
|
||||||
|
|
||||||
pkt = tuple(
|
pkt = tuple(_pack('!HBH', self._cid, bfield & 0xff, remap))
|
||||||
_pack(
|
# TODO: to fully support version 4 of REPROG_CONTROLS_V4, append `(bfield >> 8) & 0xff` here.
|
||||||
'!HBH',
|
# But older devices might behave oddly given that byte, so we don't send it.
|
||||||
self._cid,
|
|
||||||
bfield & 0xff,
|
|
||||||
remap,
|
|
||||||
# TODO: to fully support version 4 of REPROG_CONTROLS_V4, append
|
|
||||||
# another byte `(bfield >> 8) & 0xff` here. But older devices
|
|
||||||
# might behave oddly given that byte, so we don't send it.
|
|
||||||
)
|
|
||||||
)
|
|
||||||
ret = feature_request(self._device, FEATURE.REPROG_CONTROLS_V4, 0x30, *pkt)
|
ret = feature_request(self._device, FEATURE.REPROG_CONTROLS_V4, 0x30, *pkt)
|
||||||
if ret is None or _unpack('!BBBBB', ret[:5]) != pkt and _log.isEnabledFor(_WARNING):
|
if ret is None or _unpack('!BBBBB', ret[:5]) != pkt and _log.isEnabledFor(_WARNING):
|
||||||
_log.warn(
|
_log.warn(f"REPROG_CONTROLS_v4 setCidReporting on device {self._device} didn't echo request packet.")
|
||||||
f"REPROG_CONTROLS_v4 endpoint setCidReporting on device {self._device} should echo request packet, but didn't."
|
|
||||||
)
|
|
||||||
|
|
||||||
# update knowledge of mapping
|
|
||||||
self._getCidReporting()
|
|
||||||
|
|
||||||
|
|
||||||
class KeysArray:
|
class KeysArray:
|
||||||
|
@ -658,12 +636,6 @@ class KeysArray:
|
||||||
if k is not None and int(value) == int(k.key):
|
if k is not None and int(value) == int(k.key):
|
||||||
return index
|
return index
|
||||||
|
|
||||||
for index, k in enumerate(self.keys):
|
|
||||||
if k is None:
|
|
||||||
k = self.__getitem__(index)
|
|
||||||
if k is not None:
|
|
||||||
return index
|
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for k in range(0, len(self.keys)):
|
for k in range(0, len(self.keys)):
|
||||||
yield self.__getitem__(k)
|
yield self.__getitem__(k)
|
||||||
|
|
Loading…
Reference in New Issue