From a01e4b2efeb1f86de77ca26d14fe94b14b73d447 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 10 Sep 2017 22:52:23 -0300 Subject: [PATCH 1/4] hidpp20.py: handle gracefully errors at REPROG_CONTROLS_V4 At least with Anywhere Mouse MX 2, one reprogrammed key fails to read: ERROR [MainThread] logitech_receiver.base: (3) device 3 error on feature request {0829}: 2 = invalid argument That causes "solaar show" to crash. Instead, let's handle errors there gracefully, reporting it as: 7: unknown:00C3 , default: unknown:009C => unknown:00C3 virtual, pos:0, group:4, gmask:0 Signed-off-by: Mauro Carvalho Chehab --- lib/logitech_receiver/hidpp20.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/logitech_receiver/hidpp20.py b/lib/logitech_receiver/hidpp20.py index 8b441b6f..d6494962 100644 --- a/lib/logitech_receiver/hidpp20.py +++ b/lib/logitech_receiver/hidpp20.py @@ -328,13 +328,19 @@ class KeysArray(object): if self.keyversion == 1: self.keys[index] = _ReprogrammableKeyInfo(index, ctrl_id_text, ctrl_task_text, flags) if self.keyversion == 4: - mapped_data = feature_request(self.device, FEATURE.REPROG_CONTROLS_V4, 0x20, key&0xff00, key&0xff) - if mapped_data: - remap_key, remap_flag, remapped = _unpack('!HBH', mapped_data[:5]) - # if key not mapped map it to itself for display - if remapped == 0: - remapped = key - remapped_text = special_keys.CONTROL[remapped] + try: + mapped_data = feature_request(self.device, FEATURE.REPROG_CONTROLS_V4, 0x20, key&0xff00, key&0xff) + if mapped_data: + remap_key, remap_flag, remapped = _unpack('!HBH', mapped_data[:5]) + # if key not mapped map it to itself for display + if remapped == 0: + remapped = key + except Exception: + remapped = key + remap_key = key + remap_flag = 0 + + remapped_text = special_keys.CONTROL[remapped] self.keys[index] = _ReprogrammableKeyInfoV4(index, ctrl_id_text, ctrl_task_text, flags, pos, group, gmask, remapped_text) return self.keys[index] From ea80c6d6390b3a958d6e72c0fdd22ada8c6d3d85 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Sep 2017 07:02:48 -0300 Subject: [PATCH 2/4] ui: notify.py: disable python Notify extension For whatever reason, this doesn't work on Fedora 26: 06:47:05,925 DEBUG [ReceiverListener:hidraw1] logitech_receiver.base: (13) => r[20 02 0100 0000000000000000000000] 06:47:05,925 DEBUG [ReceiverListener:hidraw1] logitech_receiver.notifications: (1.0) custom notification Notification(2,01,00,000000000$ 06:47:05,925 WARNING [ReceiverListener:hidraw1] logitech_receiver.notifications: : unrecognized Notification(2,01,00,000000000000000000000$ 06:47:08,806 ERROR [MainThread] solaar.ui.notify: showing Traceback (most recent call last): File "./devel/solaar/lib/solaar/ui/notify.py", line 145, in show n.show() Error: g-io-error-quark: Error calling StartServiceByName for org.freedesktop.Notifications: Timeout was reached (24) So, disable it. Signed-off-by: Mauro Carvalho Chehab --- lib/solaar/ui/notify.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/solaar/ui/notify.py b/lib/solaar/ui/notify.py index 3bca1049..2fa4eee6 100644 --- a/lib/solaar/ui/notify.py +++ b/lib/solaar/ui/notify.py @@ -35,7 +35,16 @@ try: from gi.repository import Notify # assumed to be working since the import succeeded - available = True + # available = True + + # This is not working on Fedora 26. If fails with: + # ERROR [MainThread] solaar.ui.notify: showing + # File "./solaar/lib/solaar/ui/notify.py", line 145, in show + # n.show() + # Error: g-io-error-quark: Error calling StartServiceByName for org.freedesktop.Notifications: Timeout was reached (24) + + available = False + except (ValueError, ImportError): available = False From a4b71944901410c5bfed5a137ed69cd4323a8ff5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Sep 2017 09:42:44 -0300 Subject: [PATCH 3/4] listener: fix device registration logic The "already_known" var actually doesn't track if the device was already registered or not. That causes race issues at Solaar, causing it to sometimes not detect a device. Change the logic to always call register_new_device if the corresponding events happen, and updating already_known to reflect it. Signed-off-by: Mauro Carvalho Chehab --- lib/solaar/listener.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/solaar/listener.py b/lib/solaar/listener.py index a7f9040d..04efd436 100644 --- a/lib/solaar/listener.py +++ b/lib/solaar/listener.py @@ -183,7 +183,9 @@ class ReceiverListener(_listener.EventsListener): # a device notification assert n.devnumber > 0 and n.devnumber <= self.receiver.max_devices already_known = n.devnumber in self.receiver - if not already_known and n.sub_id == 0x41: + + if n.sub_id == 0x41: + already_known = False dev = self.receiver.register_new_device(n.devnumber, n) else: dev = self.receiver[n.devnumber] From 632d8804be8c5815ab220f3c39ba6b4e7a56b45a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Sep 2017 10:31:37 -0300 Subject: [PATCH 4/4] listener: don't add elements if queue is full When Solaar is loaded, if a large number of events happen, it will lose the register events, as the queue size is too small (16). So, check if the queue is full, in order to avoid losing those important events. Signed-off-by: Mauro Carvalho Chehab --- lib/logitech_receiver/listener.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/logitech_receiver/listener.py b/lib/logitech_receiver/listener.py index 966fc35b..3f665ba7 100644 --- a/lib/logitech_receiver/listener.py +++ b/lib/logitech_receiver/listener.py @@ -222,7 +222,8 @@ class EventsListener(_threading.Thread): if self._active: # and _threading.current_thread() == self: # if _log.isEnabledFor(_DEBUG): # _log.debug("queueing unhandled %s", n) - self._queued_notifications.put(n) + if not self._queued_notifications.full(): + self._queued_notifications.put(n) def __bool__(self): return bool(self._active and self.receiver)