From 5d885f76e75be72d190c0e2cf7f02e45446c721d Mon Sep 17 00:00:00 2001 From: "Peter F. Patel-Schneider" Date: Thu, 15 Apr 2021 16:25:32 -0400 Subject: [PATCH] settings: show potential triggering keys for mouse gesture setting --- lib/logitech_receiver/settings.py | 47 ++++++++++++--------- lib/logitech_receiver/settings_templates.py | 21 ++++++--- lib/solaar/configuration.py | 12 +++++- 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/lib/logitech_receiver/settings.py b/lib/logitech_receiver/settings.py index 93aa2007..1ad31eaf 100644 --- a/lib/logitech_receiver/settings.py +++ b/lib/logitech_receiver/settings.py @@ -1103,13 +1103,14 @@ MouseGestureKeys = [ class DivertedMouseMovementRW(object): - def __init__(self, dpi_name): + def __init__(self, dpi_name, divert_name): self.kind = FeatureRW.kind # pretend to be FeatureRW as required for HID++ 2.0 devices self.dpi_name = dpi_name + self.divert_name = divert_name self.key = None - def read(self, device): # need to return bytes, not a boolean - return b'0x01' if '_divertedMMState' in device.__dict__ else b'0x00' + def read(self, device): # need to return bytes, as if read from device + return _int2bytes(device._divertedMMState.key, 2) if '_divertedMMState' in device.__dict__ else b'\x00\x00' def write(self, device, data_bytes): def handler(device, n): @@ -1123,28 +1124,36 @@ class DivertedMouseMovementRW(object): dx, dy = _unpack('!hh', n.data[:4]) state.handle_move_event(dx, dy) - if bool(data_bytes): # enable + key = _bytes2int(data_bytes) + if key: # enable # Enable HID++ events on moving the mouse while button held - for key_number in MouseGestureKeys: - key_index = device.keys.index(key_number) - self.key = device.keys[key_index] if key_index is not None else None - if self.key and 'raw XY' in self.key.flags: - self.key.set_rawXY_reporting(True) - # Store our variables in the device object - device._divertedMMState = DivertedMouseMovement(device, self.dpi_name, self.key.key) - device.add_notification_handler('diverted-mouse-movement-handler', handler) - return True + self.key = next((k for k in device.keys if k.key == key), None) + if self.key: + self.key.set_rawXY_reporting(True) + divertSetting = next(filter(lambda s: s.name == self.divert_name, device.settings), None) + divertSetting.write_key_value(int(self.key.key), 1) + from solaar.ui import status_changed as _status_changed + _status_changed(device, refresh=True) # update main window + # Store our variables in the device object + device._divertedMMState = DivertedMouseMovement(device, self.dpi_name, self.key.key) + device.add_notification_handler('diverted-mouse-movement-handler', handler) + return True else: - _log.error('cannot enable diverted mouse movement on %s', device) + _log.error('cannot enable diverted mouse movement on %s for key %s', device.name, key) else: # disable + if self.key: + self.key.set_rawXY_reporting(False) + divertSetting = next(filter(lambda s: s.name == self.divert_name, device.settings), None) + divertSetting.write_key_value(int(self.key.key), 0) + from solaar.ui import status_changed as _status_changed + _status_changed(device, refresh=True) # update main window + self.key = None try: device.remove_notification_handler('diverted-mouse-movement-handler') - del device._divertedMMState - if self.key: - self.key.set_rawXY_reporting(False) - self.key = None except Exception: - _log.error('cannot disable diverted mouse movement on %s', device) + pass + if hasattr(device, '_divertedMMState'): + del device._divertedMMState return True diff --git a/lib/logitech_receiver/settings_templates.py b/lib/logitech_receiver/settings_templates.py index 3e3a6db3..b67ecd8f 100644 --- a/lib/logitech_receiver/settings_templates.py +++ b/lib/logitech_receiver/settings_templates.py @@ -541,11 +541,20 @@ def _feature_adjustable_dpi(): def _feature_mouse_gesture_callback(device): # need a gesture button that can send raw XY - for key in _MouseGestureKeys: - key_index = device.keys.index(key) - if key_index is not None and 'raw XY' in device.keys[key_index].flags: - return _BooleanV() - return None + if device.kind == _DK.mouse: + keys = [] + for key in _MouseGestureKeys: + key_index = device.keys.index(key) + dkey = device.keys[key_index] if key_index is not None else None + if dkey is not None and 'raw XY' in dkey.flags and 'divertable' in dkey.flags: + keys.append(dkey.key) + if not keys: # none of the keys designed for this, so look for any key with correct flags + for key in device.keys: + if 'raw XY' in key.flags and 'divertable' in key.flags and 'virtual' not in key.flags: + keys.append(key.key) + if keys: + keys.insert(0, _NamedInt(0, 'Off')) + return _ChoicesV(_NamedInts.list(keys), byte_count=2) def _feature_mouse_gesture(): @@ -554,7 +563,7 @@ def _feature_mouse_gesture(): from .settings import DivertedMouseMovementRW as _DivertedMouseMovementRW return _Setting( _MOUSE_GESTURES, - _DivertedMouseMovementRW(_DPI[0]), + _DivertedMouseMovementRW(_DPI[0], _DIVERT_KEYS[0]), callback=_feature_mouse_gesture_callback, device_kind=(_DK.mouse, ) ) diff --git a/lib/solaar/configuration.py b/lib/solaar/configuration.py index c3f575f0..1fd671be 100644 --- a/lib/solaar/configuration.py +++ b/lib/solaar/configuration.py @@ -59,6 +59,7 @@ def _load(): _log.debug('load => %s', _configuration) _cleanup(_configuration) + _cleanup_load(_configuration) _configuration[_KEY_VERSION] = __version__ return _configuration @@ -99,6 +100,15 @@ def _cleanup(d): _cleanup(value) +def _cleanup_load(d): + # remove boolean values for mouse-gestures + for device in d: + if isinstance(device, dict): + mg = device.get('mouse-gestures', None) + if mg is True or mg is False: + del device['mouse-gestures'] + + class _DeviceEntry(dict): def __init__(self, device, **kwargs): super(_DeviceEntry, self).__init__(**kwargs) @@ -125,7 +135,7 @@ class _DeviceEntry(dict): sensitives = self.get('_sensitive', {}) if sensitives.get(name) != value: sensitives[name] = value - self['_sensitive'] = sensitives + self.__setitem__('_sensitive', sensitives) # This is neccessarily complicate because the same device can be attached in several different ways.