device: remove status from Device and Receiver
This commit is contained in:
parent
a1418cd834
commit
9c5ba6445e
|
@ -77,7 +77,8 @@ class Device:
|
|||
self.hidpp_short = device_info.hidpp_short if device_info else None
|
||||
self.hidpp_long = device_info.hidpp_long if device_info else None
|
||||
self.bluetooth = device_info.bus_id == 0x0005 if device_info else False # Bluetooth needs long messages
|
||||
self.setting_callback = setting_callback
|
||||
self.setting_callback = setting_callback # for changes to settings
|
||||
self.status_callback = None # for changes to other potentially visible aspects
|
||||
self.wpid = pairing_info["wpid"] if pairing_info else None # the Wireless PID is unique per device model
|
||||
self._kind = pairing_info["kind"] if pairing_info else None # mouse, keyboard, etc (see hidpp10.DEVICE_KIND)
|
||||
self._serial = pairing_info["serial"] if pairing_info else None # serial number (an 8-char hex string)
|
||||
|
@ -412,7 +413,6 @@ class Device:
|
|||
def changed(self, active=None, alert=ALERT.NONE, reason=None, push=False):
|
||||
"""The status of the device had changed, so invoke the status callback.
|
||||
Also push notifications and settings to the device when necessary."""
|
||||
changed_callback = self.status._changed_callback
|
||||
if active is not None:
|
||||
self.online = active
|
||||
was_active, self._active = self._active, active
|
||||
|
@ -434,7 +434,8 @@ class Device:
|
|||
settings.apply_all_settings(self)
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("device %d changed: active=%s %s", self.number, self._active, self.battery_info)
|
||||
changed_callback(self, alert, reason)
|
||||
if self.status_callback is not None:
|
||||
self.status_callback(self, alert, reason)
|
||||
|
||||
def add_notification_handler(self, id: str, fn):
|
||||
"""Adds the notification handling callback `fn` to this device under name `id`.
|
||||
|
|
|
@ -495,20 +495,20 @@ class Rule(RuleComponent):
|
|||
source = "(" + self.source + ")" if self.source else ""
|
||||
return "Rule%s[%s]" % (source, ", ".join([c.__str__() for c in self.components]))
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate rule: %s", self)
|
||||
result = True
|
||||
for component in self.components:
|
||||
result = component.evaluate(feature, notification, device, status, result)
|
||||
result = component.evaluate(feature, notification, device, result)
|
||||
if not isinstance(component, Action) and result is None:
|
||||
return None
|
||||
if isinstance(component, Condition) and not result:
|
||||
return result
|
||||
return result
|
||||
|
||||
def once(self, feature, notification, device, status, last_result):
|
||||
self.evaluate(feature, notification, device, status, last_result)
|
||||
def once(self, feature, notification, device, last_result):
|
||||
self.evaluate(feature, notification, device, last_result)
|
||||
return False
|
||||
|
||||
def data(self):
|
||||
|
@ -522,7 +522,7 @@ class Condition(RuleComponent):
|
|||
def __str__(self):
|
||||
return "CONDITION"
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
return False
|
||||
|
@ -538,10 +538,10 @@ class Not(Condition):
|
|||
def __str__(self):
|
||||
return "Not: " + str(self.component)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
result = self.component.evaluate(feature, notification, device, status, last_result)
|
||||
result = self.component.evaluate(feature, notification, device, last_result)
|
||||
return None if result is None else not result
|
||||
|
||||
def data(self):
|
||||
|
@ -555,12 +555,12 @@ class Or(Condition):
|
|||
def __str__(self):
|
||||
return "Or: [" + ", ".join(str(c) for c in self.components) + "]"
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
result = False
|
||||
for component in self.components:
|
||||
result = component.evaluate(feature, notification, device, status, last_result)
|
||||
result = component.evaluate(feature, notification, device, last_result)
|
||||
if not isinstance(component, Action) and result is None:
|
||||
return None
|
||||
if isinstance(component, Condition) and result:
|
||||
|
@ -578,12 +578,12 @@ class And(Condition):
|
|||
def __str__(self):
|
||||
return "And: [" + ", ".join(str(c) for c in self.components) + "]"
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
result = True
|
||||
for component in self.components:
|
||||
result = component.evaluate(feature, notification, device, status, last_result)
|
||||
result = component.evaluate(feature, notification, device, last_result)
|
||||
if not isinstance(component, Action) and result is None:
|
||||
return None
|
||||
if isinstance(component, Condition) and not result:
|
||||
|
@ -657,7 +657,7 @@ class Process(Condition):
|
|||
def __str__(self):
|
||||
return "Process: " + str(self.process)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
if not isinstance(self.process, str):
|
||||
|
@ -688,7 +688,7 @@ class MouseProcess(Condition):
|
|||
def __str__(self):
|
||||
return "MouseProcess: " + str(self.process)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
if not isinstance(self.process, str):
|
||||
|
@ -712,7 +712,7 @@ class Feature(Condition):
|
|||
def __str__(self):
|
||||
return "Feature: " + str(self.feature)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
return feature == self.feature
|
||||
|
@ -733,7 +733,7 @@ class Report(Condition):
|
|||
def __str__(self):
|
||||
return "Report: " + str(self.report)
|
||||
|
||||
def evaluate(self, report, notification, device, status, last_result):
|
||||
def evaluate(self, report, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
return (notification.address >> 4) == self.report
|
||||
|
@ -755,7 +755,7 @@ class Setting(Condition):
|
|||
def __str__(self):
|
||||
return "Setting: " + " ".join([str(a) for a in self.args])
|
||||
|
||||
def evaluate(self, report, notification, device, status, last_result):
|
||||
def evaluate(self, report, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
if len(self.args) < 3:
|
||||
|
@ -806,7 +806,7 @@ class Modifiers(Condition):
|
|||
def __str__(self):
|
||||
return "Modifiers: " + str(self.desired)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
if gkeymap:
|
||||
|
@ -863,7 +863,7 @@ class Key(Condition):
|
|||
def __str__(self):
|
||||
return "Key: %s (%s)" % ((str(self.key) if self.key else "None"), self.action)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
return bool(self.key and self.key == (key_down if self.action == self.DOWN else key_up))
|
||||
|
@ -895,7 +895,7 @@ class KeyIsDown(Condition):
|
|||
def __str__(self):
|
||||
return "KeyIsDown: %s" % (str(self.key) if self.key else "None")
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
return key_is_down(self.key)
|
||||
|
@ -949,7 +949,7 @@ class Test(Condition):
|
|||
def __str__(self):
|
||||
return "Test: " + str(self.test)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
return self.function(feature, notification.address, notification.data, self.parameter)
|
||||
|
@ -979,7 +979,7 @@ class TestBytes(Condition):
|
|||
def __str__(self):
|
||||
return "TestBytes: " + str(self.test)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
return self.function(feature, notification.address, notification.data)
|
||||
|
@ -1012,7 +1012,7 @@ class MouseGesture(Condition):
|
|||
def __str__(self):
|
||||
return "MouseGesture: " + " ".join(self.movements)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
if feature == _F.MOUSE_GESTURE:
|
||||
|
@ -1054,7 +1054,7 @@ class Active(Condition):
|
|||
def __str__(self):
|
||||
return "Active: " + str(self.devID)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
dev = device.find(self.devID)
|
||||
|
@ -1075,7 +1075,7 @@ class Device(Condition):
|
|||
def __str__(self):
|
||||
return "Device: " + str(self.devID)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
return device.unitId == self.devID or device.serial == self.devID
|
||||
|
@ -1095,7 +1095,7 @@ class Host(Condition):
|
|||
def __str__(self):
|
||||
return "Host: " + str(self.host)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluate condition: %s", self)
|
||||
hostname = socket.getfqdn()
|
||||
|
@ -1109,7 +1109,7 @@ class Action(RuleComponent):
|
|||
def __init__(self, *args):
|
||||
pass
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
return None
|
||||
|
||||
|
||||
|
@ -1189,7 +1189,7 @@ class KeyPress(Action):
|
|||
simulate_key(keycode, _KEY_RELEASE)
|
||||
self.mods(level, modifiers, _KEY_RELEASE)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if gkeymap:
|
||||
current = gkeymap.get_modifier_state()
|
||||
if logger.isEnabledFor(logging.INFO):
|
||||
|
@ -1209,10 +1209,10 @@ class KeyPress(Action):
|
|||
|
||||
# KeyDown is dangerous as the key can auto-repeat and make your system unusable
|
||||
# class KeyDown(KeyPress):
|
||||
# def evaluate(self, feature, notification, device, status, last_result):
|
||||
# def evaluate(self, feature, notification, device, last_result):
|
||||
# super().keyDown(self.keys, current_key_modifiers)
|
||||
# class KeyUp(KeyPress):
|
||||
# def evaluate(self, feature, notification, device, status, last_result):
|
||||
# def evaluate(self, feature, notification, device, last_result):
|
||||
# super().keyUp(self.keys, current_key_modifiers)
|
||||
|
||||
|
||||
|
@ -1229,7 +1229,7 @@ class MouseScroll(Action):
|
|||
def __str__(self):
|
||||
return "MouseScroll: " + " ".join([str(a) for a in self.amounts])
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
amounts = self.amounts
|
||||
if isinstance(last_result, numbers.Number):
|
||||
amounts = [math.floor(last_result * a) for a in self.amounts]
|
||||
|
@ -1268,7 +1268,7 @@ class MouseClick(Action):
|
|||
def __str__(self):
|
||||
return "MouseClick: %s (%d)" % (self.button, self.count)
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.INFO):
|
||||
logger.info("MouseClick action: %d %s" % (self.count, self.button))
|
||||
if self.button and self.count:
|
||||
|
@ -1292,7 +1292,7 @@ class Set(Action):
|
|||
def __str__(self):
|
||||
return "Set: " + " ".join([str(a) for a in self.args])
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if len(self.args) < 3:
|
||||
return None
|
||||
if logger.isEnabledFor(logging.INFO):
|
||||
|
@ -1335,7 +1335,7 @@ class Execute(Action):
|
|||
def __str__(self):
|
||||
return "Execute: " + " ".join([a for a in self.args])
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if logger.isEnabledFor(logging.INFO):
|
||||
logger.info("Execute action: %s", self.args)
|
||||
subprocess.Popen(self.args)
|
||||
|
@ -1366,9 +1366,9 @@ class Later(Action):
|
|||
def __str__(self):
|
||||
return "Later: [" + str(self.delay) + ", " + ", ".join(str(c) for c in self.components) + "]"
|
||||
|
||||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
def evaluate(self, feature, notification, device, last_result):
|
||||
if self.delay and self.rule:
|
||||
GLib.timeout_add_seconds(self.delay, Rule.once, self.rule, feature, notification, device, status, last_result)
|
||||
GLib.timeout_add_seconds(self.delay, Rule.once, self.rule, feature, notification, device, last_result)
|
||||
return None
|
||||
|
||||
def data(self):
|
||||
|
@ -1435,14 +1435,14 @@ def key_is_down(key):
|
|||
return key in keys_down
|
||||
|
||||
|
||||
def evaluate_rules(feature, notification, device, status):
|
||||
def evaluate_rules(feature, notification, device):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("evaluating rules on %s", notification)
|
||||
rules.evaluate(feature, notification, device, status, True)
|
||||
rules.evaluate(feature, notification, device, True)
|
||||
|
||||
|
||||
# process a notification
|
||||
def process_notification(device, status, notification, feature):
|
||||
def process_notification(device, notification, feature):
|
||||
global keys_down, g_keys_down, m_keys_down, mr_key_down, key_down, key_up, thumb_wheel_displacement
|
||||
key_down, key_up = None, None
|
||||
# need to keep track of keys that are down to find a new key down
|
||||
|
@ -1487,7 +1487,7 @@ def process_notification(device, status, notification, feature):
|
|||
thumb_wheel_displacement = 0
|
||||
thumb_wheel_displacement += signed(notification.data[0:2])
|
||||
|
||||
GLib.idle_add(evaluate_rules, feature, notification, device, status)
|
||||
GLib.idle_add(evaluate_rules, feature, notification, device)
|
||||
|
||||
|
||||
_XDG_CONFIG_HOME = _os.environ.get("XDG_CONFIG_HOME") or _path.expanduser(_path.join("~", ".config"))
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
# Handles incoming events from the receiver/devices, updating the related
|
||||
# status object as appropriate.
|
||||
# Handles incoming events from the receiver/devices, updating the object as appropriate.
|
||||
|
||||
import logging
|
||||
import threading as _threading
|
||||
|
@ -29,10 +28,10 @@ from . import hidpp10_constants as _hidpp10_constants
|
|||
from . import hidpp20_constants as _hidpp20_constants
|
||||
from . import settings_templates as _st
|
||||
from .base import DJ_MESSAGE_ID as _DJ_MESSAGE_ID
|
||||
from .common import ALERT as _ALERT
|
||||
from .common import Battery as _Battery
|
||||
from .common import strhex as _strhex
|
||||
from .i18n import _
|
||||
from .status import ALERT as _ALERT
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -49,17 +48,12 @@ def process(device, notification):
|
|||
assert device
|
||||
assert notification
|
||||
|
||||
assert hasattr(device, "status")
|
||||
status = device.status
|
||||
assert status is not None
|
||||
|
||||
if not device.isDevice:
|
||||
return _process_receiver_notification(device, status, notification)
|
||||
|
||||
return _process_device_notification(device, status, notification)
|
||||
return _process_receiver_notification(device, notification)
|
||||
return _process_device_notification(device, notification)
|
||||
|
||||
|
||||
def _process_receiver_notification(receiver, status, n):
|
||||
def _process_receiver_notification(receiver, n):
|
||||
# supposedly only 0x4x notifications arrive for the receiver
|
||||
assert n.sub_id & 0x40 == 0x40
|
||||
|
||||
|
@ -148,7 +142,7 @@ def _process_receiver_notification(receiver, status, n):
|
|||
logger.warning("%s: unhandled notification %s", receiver, n)
|
||||
|
||||
|
||||
def _process_device_notification(device, status, n):
|
||||
def _process_device_notification(device, n):
|
||||
# incoming packets with SubId >= 0x80 are supposedly replies from HID++ 1.0 requests, should never get here
|
||||
assert n.sub_id & 0x80 == 0
|
||||
|
||||
|
@ -163,9 +157,9 @@ def _process_device_notification(device, status, n):
|
|||
# 0x40 to 0x7F appear to be HID++ 1.0 or DJ notifications
|
||||
if n.sub_id >= 0x40:
|
||||
if n.report_id == _DJ_MESSAGE_ID:
|
||||
return _process_dj_notification(device, status, n)
|
||||
return _process_dj_notification(device, n)
|
||||
else:
|
||||
return _process_hidpp10_notification(device, status, n)
|
||||
return _process_hidpp10_notification(device, n)
|
||||
|
||||
# These notifications are from the device itself, so it must be active
|
||||
device.online = True
|
||||
|
@ -174,7 +168,7 @@ def _process_device_notification(device, status, n):
|
|||
|
||||
# some custom battery events for HID++ 1.0 devices
|
||||
if device.protocol < 2.0:
|
||||
return _process_hidpp10_custom_notification(device, status, n)
|
||||
return _process_hidpp10_custom_notification(device, n)
|
||||
|
||||
# assuming 0x00 to 0x3F are feature (HID++ 2.0) notifications
|
||||
if not device.features:
|
||||
|
@ -186,10 +180,10 @@ def _process_device_notification(device, status, n):
|
|||
logger.warning("%s: notification from invalid feature index %02X: %s", device, n.sub_id, n)
|
||||
return False
|
||||
|
||||
return _process_feature_notification(device, status, n, feature)
|
||||
return _process_feature_notification(device, n, feature)
|
||||
|
||||
|
||||
def _process_dj_notification(device, status, n):
|
||||
def _process_dj_notification(device, n):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("%s (%s) DJ %s", device, device.protocol, n)
|
||||
|
||||
|
@ -215,7 +209,7 @@ def _process_dj_notification(device, status, n):
|
|||
logger.warning("%s: unrecognized DJ %s", device, n)
|
||||
|
||||
|
||||
def _process_hidpp10_custom_notification(device, status, n):
|
||||
def _process_hidpp10_custom_notification(device, n):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("%s (%s) custom notification %s", device, device.protocol, n)
|
||||
|
||||
|
@ -228,7 +222,7 @@ def _process_hidpp10_custom_notification(device, status, n):
|
|||
logger.warning("%s: unrecognized %s", device, n)
|
||||
|
||||
|
||||
def _process_hidpp10_notification(device, status, n):
|
||||
def _process_hidpp10_notification(device, n):
|
||||
if n.sub_id == 0x40: # device unpairing
|
||||
if n.address == 0x02:
|
||||
# device un-paired
|
||||
|
@ -236,7 +230,7 @@ def _process_hidpp10_notification(device, status, n):
|
|||
if device.number in device.receiver:
|
||||
del device.receiver[device.number]
|
||||
device.changed(active=False, alert=_ALERT.ALL, reason=_("unpaired"))
|
||||
device.status = None
|
||||
## device.status = None
|
||||
else:
|
||||
logger.warning("%s: disconnection with unknown type %02X: %s", device, n.address, n)
|
||||
return True
|
||||
|
@ -289,7 +283,7 @@ def _process_hidpp10_notification(device, status, n):
|
|||
logger.warning("%s: unrecognized %s", device, n)
|
||||
|
||||
|
||||
def _process_feature_notification(device, status, n, feature):
|
||||
def _process_feature_notification(device, n, feature):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("%s: notification for feature %s, report %s, data %s", device, feature, n.address >> 4, _strhex(n.data))
|
||||
|
||||
|
@ -440,5 +434,5 @@ def _process_feature_notification(device, status, n, feature):
|
|||
device.setting_callback(device, _st.AdjustableDpi, [profile.resolutions[resolution_index]])
|
||||
break
|
||||
|
||||
_diversion.process_notification(device, status, n, feature)
|
||||
_diversion.process_notification(device, n, feature)
|
||||
return True
|
||||
|
|
|
@ -66,7 +66,8 @@ class Receiver:
|
|||
self.handle = handle
|
||||
self.path = path
|
||||
self.product_id = product_id
|
||||
self.setting_callback = setting_callback
|
||||
self.setting_callback = setting_callback # for changes to settings
|
||||
self.status_callback = None # for changes to other potentially visible aspects
|
||||
self.receiver_kind = receiver_kind
|
||||
self.serial = None
|
||||
self.max_devices = None
|
||||
|
@ -105,7 +106,8 @@ class Receiver:
|
|||
|
||||
def changed(self, alert=ALERT.NOTIFICATION, reason=None):
|
||||
"""The status of the device had changed, so invoke the status callback"""
|
||||
self.status._changed_callback(self, alert=alert, reason=reason)
|
||||
if self.status_callback is not None:
|
||||
self.status_callback(self, alert=alert, reason=reason)
|
||||
|
||||
@property
|
||||
def firmware(self):
|
||||
|
|
|
@ -841,7 +841,7 @@ class MouseGesturesXY(_RawXYProcessing):
|
|||
logger.info("mouse gesture notification %s", self.data)
|
||||
payload = _pack("!" + (len(self.data) * "h"), *self.data)
|
||||
notification = _HIDPP_Notification(0, 0, 0, 0, payload)
|
||||
_process_notification(self.device, self.device.status, notification, _F.MOUSE_GESTURE)
|
||||
_process_notification(self.device, notification, _F.MOUSE_GESTURE)
|
||||
self.fsmState = "idle"
|
||||
|
||||
def move_action(self, dx, dy):
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
## Copyright (C) 2012-2013 Daniel Pavel
|
||||
## Copyright (C) 2014-2024 Solaar Contributors https://pwr-solaar.github.io/Solaar/
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 2 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License along
|
||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
import logging
|
||||
|
||||
from . import hidpp10
|
||||
from . import hidpp10_constants as _hidpp10_constants
|
||||
from .common import NamedInts
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_R = _hidpp10_constants.REGISTERS
|
||||
|
||||
_hidpp10 = hidpp10.Hidpp10()
|
||||
|
||||
ALERT = NamedInts(NONE=0x00, NOTIFICATION=0x01, SHOW_WINDOW=0x02, ATTENTION=0x04, ALL=0xFF)
|
||||
|
||||
|
||||
def attach_to(device, changed_callback):
|
||||
assert device
|
||||
assert changed_callback
|
||||
|
||||
if not hasattr(device, "status") or device.status is None:
|
||||
if not device.isDevice:
|
||||
device.status = ReceiverStatus(device, changed_callback)
|
||||
else:
|
||||
device.status = DeviceStatus(device, changed_callback)
|
||||
|
||||
|
||||
class ReceiverStatus:
|
||||
"""The 'runtime' status of a receiver, currently vestigial."""
|
||||
|
||||
def __init__(self, receiver, changed_callback):
|
||||
assert receiver
|
||||
self._receiver = receiver
|
||||
assert changed_callback
|
||||
self._changed_callback = changed_callback
|
||||
|
||||
|
||||
class DeviceStatus:
|
||||
"""Holds the 'runtime' status of a peripheral
|
||||
Currently _active, battery, link_encrypted, notification_flags, error
|
||||
Updates mostly come from incoming notification events from the device itself.
|
||||
"""
|
||||
|
||||
def __init__(self, device, changed_callback):
|
||||
assert device
|
||||
self._device = device
|
||||
assert changed_callback
|
||||
self._changed_callback = changed_callback
|
||||
self._active = None # is the device active?
|
||||
|
||||
def __bool__(self):
|
||||
return bool(self._active)
|
||||
|
||||
__nonzero__ = __bool__
|
|
@ -20,7 +20,6 @@ from logitech_receiver import base as _base
|
|||
from logitech_receiver import hidpp10
|
||||
from logitech_receiver import hidpp10_constants as _hidpp10_constants
|
||||
from logitech_receiver import notifications as _notifications
|
||||
from logitech_receiver import status as _status
|
||||
|
||||
_hidpp10 = hidpp10.Hidpp10()
|
||||
_R = _hidpp10_constants.REGISTERS
|
||||
|
@ -38,7 +37,6 @@ def run(receivers, args, find_receiver, _ignore):
|
|||
receiver = receivers[0]
|
||||
|
||||
assert receiver
|
||||
receiver.status = _status.ReceiverStatus(receiver, lambda *args, **kwargs: None)
|
||||
|
||||
# check if it's necessary to set the notification flags
|
||||
old_notification_flags = _hidpp10.get_notification_flags(receiver) or 0
|
||||
|
|
|
@ -31,7 +31,6 @@ from logitech_receiver import exceptions
|
|||
from logitech_receiver import hidpp10_constants as _hidpp10_constants
|
||||
from logitech_receiver import listener as _listener
|
||||
from logitech_receiver import notifications as _notifications
|
||||
from logitech_receiver import status as _status
|
||||
|
||||
from . import configuration
|
||||
|
||||
|
@ -44,15 +43,13 @@ _R = _hidpp10_constants.REGISTERS
|
|||
_IR = _hidpp10_constants.INFO_SUBREGISTERS
|
||||
|
||||
|
||||
_GHOST_DEVICE = namedtuple("_GHOST_DEVICE", ("receiver", "number", "name", "kind", "status", "online"))
|
||||
_GHOST_DEVICE = namedtuple("_GHOST_DEVICE", ("receiver", "number", "name", "kind", "online"))
|
||||
_GHOST_DEVICE.__bool__ = lambda self: False
|
||||
_GHOST_DEVICE.__nonzero__ = _GHOST_DEVICE.__bool__
|
||||
|
||||
|
||||
def _ghost(device):
|
||||
return _GHOST_DEVICE(
|
||||
receiver=device.receiver, number=device.number, name=device.name, kind=device.kind, status=None, online=False
|
||||
)
|
||||
return _GHOST_DEVICE(receiver=device.receiver, number=device.number, name=device.name, kind=device.kind, online=False)
|
||||
|
||||
|
||||
class ReceiverListener(_listener.EventsListener):
|
||||
|
@ -62,7 +59,7 @@ class ReceiverListener(_listener.EventsListener):
|
|||
assert status_changed_callback
|
||||
super().__init__(receiver, self._notifications_handler)
|
||||
self.status_changed_callback = status_changed_callback
|
||||
_status.attach_to(receiver, self._status_changed)
|
||||
receiver.status_callback = self._status_changed
|
||||
|
||||
def has_started(self):
|
||||
if logger.isEnabledFor(logging.INFO):
|
||||
|
@ -95,32 +92,30 @@ class ReceiverListener(_listener.EventsListener):
|
|||
logger.exception("closing receiver %s" % r.path)
|
||||
self.status_changed_callback(r)
|
||||
|
||||
def _status_changed(self, device, alert=_status.ALERT.NONE, reason=None):
|
||||
def _status_changed(self, device, alert=None, reason=None):
|
||||
assert device is not None
|
||||
if logger.isEnabledFor(logging.INFO):
|
||||
try:
|
||||
device.ping()
|
||||
if device.kind is None:
|
||||
logger.info(
|
||||
"status_changed %r: %s, %s (%X) %s",
|
||||
"status_changed %r: %s (%X) %s",
|
||||
device,
|
||||
"present" if bool(device) else "removed",
|
||||
device.status,
|
||||
alert,
|
||||
alert if alert is not None else 0,
|
||||
reason or "",
|
||||
)
|
||||
else:
|
||||
device.ping()
|
||||
logger.info(
|
||||
"status_changed %r: %s %s, %s (%X) %s",
|
||||
"status_changed %r: %s %s (%X) %s",
|
||||
device,
|
||||
"paired" if bool(device) else "unpaired",
|
||||
"online" if device.online else "offline",
|
||||
device.status,
|
||||
alert,
|
||||
alert if alert is not None else 0,
|
||||
reason or "",
|
||||
)
|
||||
except Exception:
|
||||
logger.info("status_changed for unknown device")
|
||||
except Exception as e:
|
||||
logger.info("status_changed for unknown device: %s", e)
|
||||
|
||||
if device.kind is None:
|
||||
assert device == self.receiver
|
||||
|
@ -214,14 +209,10 @@ class ReceiverListener(_listener.EventsListener):
|
|||
# If there are saved configs, bring the device's settings up-to-date.
|
||||
# They will be applied when the device is marked as online.
|
||||
configuration.attach_to(dev)
|
||||
_status.attach_to(dev, self._status_changed)
|
||||
dev.status_callback = self._status_changed
|
||||
# the receiver changed status as well
|
||||
self._status_changed(self.receiver)
|
||||
|
||||
if not hasattr(dev, "status") or dev.status is None:
|
||||
# notification before device status set up - don't process it
|
||||
logger.warning("%s before device %s has status", n, dev)
|
||||
else:
|
||||
_notifications.process(dev, n)
|
||||
|
||||
if self.receiver.pairing.lock_open and not already_known:
|
||||
|
@ -297,8 +288,8 @@ def ping_all(resuming=False):
|
|||
count = listener_thread.receiver.count()
|
||||
if count:
|
||||
for dev in listener_thread.receiver:
|
||||
if resuming and hasattr(dev, "status"):
|
||||
dev.status._active = None # ensure that settings are pushed
|
||||
if resuming:
|
||||
dev._active = None # ensure that settings are pushed
|
||||
if dev.ping():
|
||||
dev.changed(active=True, push=True)
|
||||
listener_thread._status_changed(dev)
|
||||
|
|
|
@ -19,7 +19,7 @@ import logging
|
|||
import gi
|
||||
import yaml as _yaml
|
||||
|
||||
from logitech_receiver.status import ALERT
|
||||
from logitech_receiver.common import ALERT
|
||||
|
||||
from solaar.i18n import _
|
||||
from solaar.ui.config_panel import change_setting, record_setting
|
||||
|
@ -115,6 +115,8 @@ def _status_changed(device, alert, reason, refresh=False):
|
|||
assert device is not None
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("status changed: %s (%s) %s", device, alert, reason)
|
||||
if alert is None:
|
||||
alert = ALERT.NONE
|
||||
|
||||
tray.update(device)
|
||||
if alert & ALERT.ATTENTION:
|
||||
|
|
|
@ -113,20 +113,21 @@ if available:
|
|||
|
||||
if reason:
|
||||
message = reason
|
||||
elif dev.status is None:
|
||||
message = _("unpaired")
|
||||
elif bool(dev.status):
|
||||
message = dev.status_string() or _("connected")
|
||||
else:
|
||||
message = _("offline")
|
||||
message = _("unspecified reason")
|
||||
# elif dev.status is None:
|
||||
# message = _("unpaired")
|
||||
# elif bool(dev.status):
|
||||
# message = dev.status_string() or _("connected")
|
||||
# else:
|
||||
# message = _("offline")
|
||||
|
||||
# we need to use the filename here because the notifications daemon
|
||||
# is an external application that does not know about our icon sets
|
||||
icon_file = _icons.device_icon_file(dev.name, dev.kind) if icon is None else _icons.icon_file(icon)
|
||||
|
||||
n.update(summary, message, icon_file)
|
||||
urgency = Notify.Urgency.LOW if dev.status else Notify.Urgency.NORMAL
|
||||
n.set_urgency(urgency)
|
||||
n.set_urgency(Notify.Urgency.NORMAL)
|
||||
n.set_hint("desktop-entry", GLib.Variant("s", NAME.lower()))
|
||||
if progress:
|
||||
n.set_hint("value", GLib.Variant("i", progress))
|
||||
|
|
|
@ -420,7 +420,7 @@ def _remove_receiver(receiver):
|
|||
|
||||
|
||||
def _update_menu_item(index, device):
|
||||
if device is None or device.status is None:
|
||||
if device is None:
|
||||
logger.warning("updating an inactive device %s, assuming disconnected", device)
|
||||
return None
|
||||
|
||||
|
|
Loading…
Reference in New Issue