diff --git a/lib/logitech_receiver/notifications.py b/lib/logitech_receiver/notifications.py index 9cdff25d..98ad6825 100644 --- a/lib/logitech_receiver/notifications.py +++ b/lib/logitech_receiver/notifications.py @@ -312,7 +312,7 @@ def _process_hidpp10_notification(device, status, n): def _process_feature_notification(device, status, n, feature): if _log.isEnabledFor(_DEBUG): - _log.debug('%s: notification for feature %s, report %s, data %s', device, feature, n.sub_id >> 4, _strhex(n.data)) + _log.debug('%s: notification for feature %s, report %s, data %s', device, feature, n.address >> 4, _strhex(n.data)) if feature == _F.BATTERY_STATUS: if n.address == 0x00: @@ -436,10 +436,10 @@ def _process_feature_notification(device, status, n, feature): ratchet = ord(n.data[:1]) & 0x01 if _log.isEnabledFor(_INFO): _log.info('%s: WHEEL: ratchet: %d', device, ratchet) - from solaar.ui.config_panel import change_setting # prevent circular import + from solaar.ui.config_panel import record_setting # prevent circular import setting = next((s for s in device.settings if s.name == _st.ScrollRatchet.name), None) if setting: - change_setting(device, setting, [2 if ratchet else 1]) + record_setting(device, setting, [2 if ratchet else 1]) else: if _log.isEnabledFor(_INFO): _log.info('%s: unknown WHEEL %s', device, n) diff --git a/lib/logitech_receiver/settings.py b/lib/logitech_receiver/settings.py index 789dccfb..5ba5c616 100644 --- a/lib/logitech_receiver/settings.py +++ b/lib/logitech_receiver/settings.py @@ -292,6 +292,10 @@ class Setting: if self._device.persister and save: self._device.persister[self.name] = self._value if self.persist else None + def update(self, value, save=True): + self._value = value + self._pre_write(save) + def write(self, value, save=True): assert hasattr(self, '_value') assert hasattr(self, '_device') @@ -302,8 +306,7 @@ class Setting: if self._device.online: if self._value != value: - self._value = value - self._pre_write(save) + self.update(value, save) current_value = None if self._validator.needs_current_value: @@ -410,8 +413,7 @@ class Settings(Setting): _log.debug('%s: settings write %r to %s', self.name, map, self._device) if self._device.online: - self._value = map - self._pre_write(save) + self.update(map, save) for key, value in map.items(): data_bytes = self._validator.prepare_write(int(key), value) if data_bytes is not None: @@ -422,6 +424,10 @@ class Settings(Setting): return None return map + def update_key_value(self, key, value, save=True): + self._value[int(key)] = value + self._pre_write(save) + def write_key_value(self, key, value, save=True): assert hasattr(self, '_value') assert hasattr(self, '_device') @@ -437,8 +443,7 @@ class Settings(Setting): try: data_bytes = self._validator.prepare_write(int(key), value) # always need to write to configuration because dictionary is shared and could have changed - self._value[int(key)] = value - self._pre_write(save) + self.update_key_value(key, value, save) except ValueError: data_bytes = value = None if data_bytes is not None: @@ -510,8 +515,7 @@ class LongSettings(Setting): if _log.isEnabledFor(_DEBUG): _log.debug('%s: long settings write %r to %s', self.name, map, self._device) if self._device.online: - self._value = map - self._pre_write(save) + self.update(map, save) for item, value in map.items(): data_bytes_list = self._validator.prepare_write(self._value) if data_bytes_list is not None: @@ -524,6 +528,10 @@ class LongSettings(Setting): return None return map + def update_key_value(self, key, value, save=True): + self._value[int(key)] = value + self._pre_write(save) + def write_key_value(self, item, value, save=True): assert hasattr(self, '_value') assert hasattr(self, '_device') @@ -537,8 +545,7 @@ class LongSettings(Setting): if not self._value: self.read() data_bytes = self._validator.prepare_write_item(item, value) - self._value[int(item)] = value - self._pre_write(save) + self.update_key_value(item, value, save) if data_bytes is not None: if _log.isEnabledFor(_DEBUG): _log.debug('%s: settings prepare item value write(%s,%s) => %r', self.name, item, value, data_bytes) @@ -609,8 +616,7 @@ class BitFieldSetting(Setting): if _log.isEnabledFor(_DEBUG): _log.debug('%s: bit field settings write %r to %s', self.name, map, self._device) if self._device.online: - self._value = map - self._pre_write(save) + self.update(map, save) data_bytes = self._validator.prepare_write(self._value) if data_bytes is not None: if _log.isEnabledFor(_DEBUG): @@ -623,6 +629,10 @@ class BitFieldSetting(Setting): return None return map + def update_key_value(self, key, value, save=True): + self._value[int(key)] = value + self._pre_write(save) + def write_key_value(self, key, value, save=True): assert hasattr(self, '_value') assert hasattr(self, '_device') @@ -636,8 +646,7 @@ class BitFieldSetting(Setting): if not self._value: self.read() value = bool(value) - self._value[int(key)] = value - self._pre_write(save) + self.update_key_value(key, value, save) data_bytes = self._validator.prepare_write(self._value) if data_bytes is not None: @@ -703,8 +712,7 @@ class RangeFieldSetting(Setting): if _log.isEnabledFor(_DEBUG): _log.debug('%s: range field setting write %r to %s', self.name, map, self._device) if self._device.online: - self._value = map - self._pre_write(save) + self.update(map, save) data_bytes = self._validator.prepare_write(self._value) if data_bytes is not None: if _log.isEnabledFor(_DEBUG): diff --git a/lib/solaar/ui/config_panel.py b/lib/solaar/ui/config_panel.py index df1e95df..7e5801d1 100644 --- a/lib/solaar/ui/config_panel.py +++ b/lib/solaar/ui/config_panel.py @@ -715,3 +715,23 @@ def _change_setting(device, setting, values): else: sbox = None _write_async(setting, values[-1], sbox, None, key=values[0] if len(values) > 1 else None) + + +def record_setting(device, setting, values): + """External interface to record a setting that has changed on the device and have the GUI show the change""" + assert device == setting._device + GLib.idle_add(_record_setting, device, setting, values, priority=99) + + +def _record_setting(device, setting, values): + if len(values) > 1: + setting.update_key_value(values[0], values[-1]) + value = {values[0]: values[-1]} + else: + setting.update(values[-1]) + value = values[-1] + device_path = device.receiver.path if device.receiver else device.path + if (device_path, device.number, setting.name) in _items: + sbox = _items[(device_path, device.number, setting.name)] + if sbox: + _update_setting_item(sbox, value)