diff --git a/app/receiver.py b/app/receiver.py index 2627bd20..ca3431af 100644 --- a/app/receiver.py +++ b/app/receiver.py @@ -4,6 +4,7 @@ from logging import getLogger as _Logger from struct import pack as _pack +from time import sleep as _sleep from logitech.unifying_receiver import base as _base from logitech.unifying_receiver import api as _api @@ -136,7 +137,7 @@ class DeviceInfo(_api.PairedDevice): self.LOG.debug("status %d => %d", self._status, new_status) urgent = new_status < STATUS.CONNECTED or self._status < STATUS.CONNECTED self._status = new_status - self._listener.status_changed_callback(self, urgent) + self._listener.status_changed(self, urgent) if new_status < STATUS.CONNECTED: self.props.clear() @@ -158,7 +159,11 @@ class DeviceInfo(_api.PairedDevice): @property def name(self): if self._name is None: - if self._status >= STATUS.CONNECTED: + if self._status < STATUS.CONNECTED: + codename = self.codename + if codename in NAMES: + self._name, self._kind = NAMES[codename] + else: self._name = _api.get_device_name(self.handle, self.number, self.features) return self._name or self.codename @@ -168,7 +173,7 @@ class DeviceInfo(_api.PairedDevice): if self._status < STATUS.CONNECTED: codename = self.codename if codename in NAMES: - self._kind = NAMES[codename][-1] + self._name, self._kind = NAMES[codename] else: self._kind = _api.get_device_kind(self.handle, self.number, self.features) return self._kind or '?' @@ -216,7 +221,7 @@ class DeviceInfo(_api.PairedDevice): self.props.update(status[1]) if self.status == status[0]: if p != self.props: - self._listener.status_changed_callback(self) + self._listener.status_changed(self) else: self.status = status[0] return True @@ -249,7 +254,7 @@ class ReceiverListener(_EventsListener): """Keeps the status of a Unifying Receiver. """ - def __init__(self, receiver, status_changed_callback): + def __init__(self, receiver, status_changed_callback=None): super(ReceiverListener, self).__init__(receiver.handle, self._events_handler) self.receiver = receiver @@ -258,7 +263,7 @@ class ReceiverListener(_EventsListener): self.events_filter = None self.events_handler = None - self.status_changed_callback = status_changed_callback or (lambda reason, urgent=False: None) + self.status_changed_callback = status_changed_callback receiver.kind = receiver.name receiver.devices = {} @@ -280,7 +285,11 @@ class ReceiverListener(_EventsListener): self.LOG.debug("status %d => %d", self.receiver.status, new_status) self.receiver.status = new_status self.receiver.status_text = _RECEIVER_STATUS_NAME[new_status] - self.status_changed_callback(self.receiver, True) + self.status_changed(None, True) + + def status_changed(self, device=None, urgent=False): + if self.status_changed_callback: + self.status_changed_callback(self.receiver, device, urgent) def _device_status_from(self, event): state_code = ord(event.data[2:3]) & 0xF0 @@ -337,7 +346,7 @@ class ReceiverListener(_EventsListener): dev = DeviceInfo(self, event.devnumber, event.data[4:5], status) self.LOG.info("new device %s", dev) - self.status_changed_callback(dev, True) + self.status_changed(dev, True) return dev def unpair_device(self, device): @@ -362,6 +371,8 @@ class ReceiverListener(_EventsListener): if receiver: rl = ReceiverListener(receiver, status_changed_callback) rl.start() + while not rl._active: + _sleep(0.1) return rl # @@ -369,6 +380,7 @@ class ReceiverListener(_EventsListener): # class _DUMMY_RECEIVER(object): + __slots__ = ['name', 'max_devices', 'status', 'status_text', 'devices'] name = _api.Receiver.name max_devices = _api.Receiver.max_devices status = STATUS.UNAVAILABLE diff --git a/app/solaar.py b/app/solaar.py index b7af4bf1..acc231f2 100644 --- a/app/solaar.py +++ b/app/solaar.py @@ -69,18 +69,19 @@ if __name__ == '__main__': listener = None notify_missing = True - def status_changed(reason, urgent=False): - global listener - receiver = DUMMY if listener is None else listener.receiver - ui.update(receiver, icon, window, reason) + def status_changed(receiver, device=None, urgent=False): + ui.update(receiver, icon, window, device) if ui.notify.available and urgent: - ui.notify.show(reason) - if not listener: - listener = None - GObject.timeout_add(3000, check_for_listener) + ui.notify.show(device or receiver) - def check_for_listener(): + global listener + if not listener: + GObject.timeout_add(5000, check_for_listener) + listener = None + + def check_for_listener(retry=True): global listener, notify_missing + if listener is None: listener = ReceiverListener.open(status_changed) if listener is None: @@ -88,14 +89,14 @@ if __name__ == '__main__': if notify_missing: status_changed(DUMMY, True) notify_missing = False - return True + return retry # print ("opened receiver", listener, listener.receiver) - pairing.state = pairing.State(listener) notify_missing = True - status_changed(listener.receiver, True) + pairing.state = pairing.State(listener) + status_changed(listener.receiver, None, True) - check_for_listener() + GObject.timeout_add(100, check_for_listener, False) Gtk.main() if listener is not None: diff --git a/app/ui/main_window.py b/app/ui/main_window.py index 5853cb2b..b241180a 100644 --- a/app/ui/main_window.py +++ b/app/ui/main_window.py @@ -37,10 +37,12 @@ def _toggle_info(action, label_widget, box_widget, frame): def _make_receiver_box(name): frame = Gtk.Frame() frame._device = None + frame.set_name(name) - icon = Gtk.Image.new_from_icon_name(name, _SMALL_DEVICE_ICON_SIZE) + icon_name = ui.get_icon(name, 'preferences-desktop-peripherals') + icon = Gtk.Image.new_from_icon_name(icon_name, _SMALL_DEVICE_ICON_SIZE) - label = Gtk.Label('Initializing...') + label = Gtk.Label('Scanning...') label.set_name('label') label.set_alignment(0, 0.5) @@ -83,8 +85,10 @@ def _make_receiver_box(name): def _make_device_box(index): frame = Gtk.Frame() frame._device = None + frame.set_name(_PLACEHOLDER) - icon = Gtk.Image.new_from_icon_name('image-missing', _DEVICE_ICON_SIZE) + icon_name = 'preferences-desktop-peripherals' + icon = Gtk.Image.new_from_icon_name(icon_name, _DEVICE_ICON_SIZE) icon.set_name('icon') icon.set_alignment(0.5, 0) @@ -222,7 +226,8 @@ def _update_device_box(frame, dev): if frame.get_name() != dev.name: frame.set_name(dev.name) - icon.set_from_icon_name(ui.get_icon(dev.name, dev.kind), _DEVICE_ICON_SIZE) + icon_name = ui.get_icon(dev.name, dev.kind) + icon.set_from_icon_name(icon_name, _DEVICE_ICON_SIZE) label.set_markup('' + dev.name + '') status = ui.find_children(frame, 'status') @@ -274,14 +279,14 @@ def _update_device_box(frame, dev): frame.set_visible(True) -def update(window, receiver, device): - print ("update", receiver, receiver.status, device) +def update(window, receiver, device=None): + # print ("update", receiver, receiver.status, device) window.set_icon_name(ui.appicon(receiver.status)) vbox = window.get_child() frames = list(vbox.get_children()) - if id(device) == id(receiver): + if device is None: _update_receiver_box(frames[0], receiver) if receiver.status < STATUS.CONNECTED: for frame in frames[1:]: diff --git a/lib/logitech/unifying_receiver/api.py b/lib/logitech/unifying_receiver/api.py index 263996ab..39aa36b0 100644 --- a/lib/logitech/unifying_receiver/api.py +++ b/lib/logitech/unifying_receiver/api.py @@ -77,8 +77,7 @@ class Receiver(object): self._firmware = None def close(self): - handle = self.handle - self.handle = 0 + handle, self.handle = self.handle, 0 return (handle and _base.close(handle)) @property diff --git a/lib/logitech/unifying_receiver/listener.py b/lib/logitech/unifying_receiver/listener.py index eaf171c9..0a3ef737 100644 --- a/lib/logitech/unifying_receiver/listener.py +++ b/lib/logitech/unifying_receiver/listener.py @@ -102,9 +102,9 @@ class EventsListener(_Thread): self._events.put(event) _base.request_context = None - _base.close(self._handle) + handle, self._handle = self._handle, 0 + _base.close(handle) _log.debug("stopped") - self._handle = 0 def stop(self): """Tells the listener to stop as soon as possible.""" diff --git a/share/icons/hicolor/128x128/devices/Unifying Receiver.png b/share/icons/hicolor/128x128/devices/Unifying Receiver.png deleted file mode 100644 index b08fff9e..00000000 Binary files a/share/icons/hicolor/128x128/devices/Unifying Receiver.png and /dev/null differ