Repository: pwr-Solaar/Solaar

Issue:
solaar 1.0.1 loses receiver occasionally
**Information**

- Solaar version: 1.0.1 from late December 2019
- Distribution: github

**Describe the bug**

Pairing a M310 mouse results in Solaar not showing the receiver until it has been unplugged and plugged back in.  However, this happens only occasionally.  The problem appears to be linked to an assertion failure in window.py.

This may be related to #444 and #493

**To Reproduce**
Steps to reproduce the behavior:
1. Start Solaar
2. Pair M310 mouse (new style)


**Additional context**

```
peter.patel@2030008406L:~/Samsung/github/Solaar$ bin/solaar

(solaar:5523): Gdk-CRITICAL **: 09:58:43.893:
gdk_window_thaw_toplevel_updates: assertion 'window-
> update_and_descendants_freeze_count > 0' failed
Traceback (most recent call last):
  File "/home/peter.patel/Samsung/github/Solaar/lib/solaar/ui/__init__.py", line 165, in _status_changed
    window.update(device, need_popup)
  File "/home/peter.patel/Samsung/github/Solaar/lib/solaar/ui/window.py", line 771, in update
    assert item
AssertionError
Traceback (most recent call last):
  File "/home/peter.patel/Samsung/github/Solaar/lib/solaar/ui/__init__.py", line 165, in _status_changed
    window.update(device, need_popup)
  File "/home/peter.patel/Samsung/github/Solaar/lib/solaar/ui/window.py", line 771, in update
    assert item
AssertionError
Traceback (most recent call last):
  File "/home/peter.patel/Samsung/github/Solaar/lib/solaar/ui/__init__.py", line 165, in _status_changed
    window.update(device, need_popup)
  File "/home/peter.patel/Samsung/github/Solaar/lib/solaar/ui/window.py", line 771, in update
    assert item
AssertionError
Traceback (most recent call last):
  File "/home/peter.patel/Samsung/github/Solaar/lib/solaar/ui/pair_window.py", line 75, in _check_lock_state
    if receiver.status.get(_K.ERROR):
AttributeError: 'unicode' object has no attribute 'get'
Traceback (most recent call last):
  File "/home/peter.patel/Samsung/github/Solaar/lib/solaar/ui/pair_window.py", line 120, in _finish
    receiver.status.new_device = None
AttributeError: 'unicode' object has no attribute 'new_device'
```


Discussion:
Similar problem with a MX Master, Ubuntu 19.10 and solaar 1.0.1.

I find these errors in the log (`solaar --debug`): 

```
15:16:50,304     INFO [ReceiverListener:hidraw0] solaar.listener: Notification(2,41,04,B26040) triggered new device <PairedDevice(2,4060,MX Master)> (mouse)
15:16:50,445    ERROR [ReceiverListener:hidraw0] logitech_receiver.base: write failed, assuming handle 15 no longer available
15:16:50,446    ERROR [ReceiverListener:hidraw0] logitech_receiver.listener: processing Notification(2,41,04,B26040)
Traceback (most recent call last):
  File "/usr/share/solaar/lib/logitech_receiver/listener.py", line 185, in run
    self._notifications_callback(n)
  File "/usr/share/solaar/lib/solaar/listener.py", line 213, in _notifications_handler
    configuration.attach_to(dev)
  File "/usr/share/solaar/lib/solaar/configuration.py", line 130, in attach_to
    for s in device.settings:
  File "/usr/share/solaar/lib/logitech_receiver/receiver.py", line 254, in settings
    _check_feature_settings(self, self._settings)
  File "/usr/share/solaar/lib/logitech_receiver/settings_templates.py", line 390, in check_feature_settings
    check_feature(_FN_SWAP[0],       _F.K375S_FN_INVERSION, 'k375s_fn_swap')
  File "/usr/share/solaar/lib/logitech_receiver/settings_templates.py", line 374, in check_feature
    if not featureId in device.features:
  File "/usr/share/solaar/lib/logitech_receiver/hidpp20.py", line 260, in __contains__
    reply = self.device.request(0x0000, _pack('!H', ivalue))
  File "/usr/share/solaar/lib/logitech_receiver/receiver.py", line 281, in request
    return _base.request(self.receiver.handle, self.number, request_id, *params)
  File "/usr/share/solaar/lib/logitech_receiver/base.py", line 340, in request
    write(ihandle, devnumber, request_data)
  File "/usr/share/solaar/lib/logitech_receiver/base.py", line 171, in write
    raise NoReceiver(reason=reason)
NoReceiver: {'reason': OSError(32, 'Broken pipe')}
15:16:50,447  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unrecognized Notification(2,42,00,0000000000000000000000)
15:16:50,447  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unrecognized Notification(2,02,00,00963FFA00000000000000) for feature DEVICE FW VERSION (index 02)
15:16:50,457     INFO [ReceiverListener:hidraw0] solaar.listener: Notification(2,41,04,B26040) triggered new device <PairedDevice(2,4060,MX Master)> (mouse)
15:16:50,458    ERROR [ReceiverListener:hidraw0] logitech_receiver.base: read failed, assuming receiver 15 no longer available
15:16:50,458    ERROR [ReceiverListener:hidraw0] logitech_receiver.listener: processing Notification(2,41,04,B26040)
Traceback (most recent call last):
  File "/usr/share/solaar/lib/logitech_receiver/listener.py", line 185, in run
    self._notifications_callback(n)
  File "/usr/share/solaar/lib/solaar/listener.py", line 213, in _notifications_handler
    configuration.attach_to(dev)
  File "/usr/share/solaar/lib/solaar/configuration.py", line 130, in attach_to
    for s in device.settings:
  File "/usr/share/solaar/lib/logitech_receiver/receiver.py", line 254, in settings
    _check_feature_settings(self, self._settings)
  File "/usr/share/solaar/lib/logitech_receiver/settings_templates.py", line 384, in check_feature_settings
    check_feature(_HI_RES_SCROLL[0], _F.HI_RES_SCROLLING)
  File "/usr/share/solaar/lib/logitech_receiver/settings_templates.py", line 374, in check_feature
    if not featureId in device.features:
  File "/usr/share/solaar/lib/logitech_receiver/hidpp20.py", line 260, in __contains__
    reply = self.device.request(0x0000, _pack('!H', ivalue))
  File "/usr/share/solaar/lib/logitech_receiver/receiver.py", line 281, in request
    return _base.request(self.receiver.handle, self.number, request_id, *params)
  File "/usr/share/solaar/lib/logitech_receiver/base.py", line 339, in request
    _skip_incoming(handle, ihandle, notifications_hook)
  File "/usr/share/solaar/lib/logitech_receiver/base.py", line 246, in _skip_incoming
    raise NoReceiver(reason=reason)
NoReceiver: {'reason': error(9, 'Bad file descriptor')}
15:16:50,458  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unrecognized Notification(2,42,00,0000000000000000000000)
15:16:50,458  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unrecognized Notification(2,02,00,0018E1FB00000000000000) for feature DEVICE FW VERSION (index 02)
15:16:50,459     INFO [ReceiverListener:hidraw0] solaar.listener: status_changed <PairedDevice(2,4060,MX Master)>: paired online, {'BATTERY LEVEL': 90, 'BATTERY CHARGING': False, 'BATTERY STATUS': None, 'LINK ENCRYPTED': True, 'ERROR': None} (0) 
15:16:50,459  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unrecognized Notification(2,02,00,0007100000000000000000) for feature DEVICE FW VERSION (index 02)
15:16:50,459  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unrecognized Notification(2,02,00,00FF0F0000000000000000) for feature DEVICE FW VERSION (index 02)
15:16:50,459  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unknown BATTERY Notification(2,06,10,0404C0280A0000000000000000000000)
15:16:50,459  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unknown WHEEL Notification(2,0D,20,02000000000000000000000000000000)
15:16:50,460  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unrecognized Notification(2,02,00,0000100000000000000000) for feature DEVICE FW VERSION (index 02)
15:16:50,460     INFO [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: WHEEL: res: 0 periods: 8 delta V:3072
15:16:50,460  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unrecognized Notification(2,02,00,00F18F0000000000000000) for feature DEVICE FW VERSION (index 02)
15:16:50,460  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unrecognized Notification(2,02,00,00382F0100000000000000) for feature DEVICE FW VERSION (index 02)
15:16:50,460  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(2,4060,MX Master)>: unrecognized Notification(2,02,00,00B8FFFF00000000000000) for feature DEVICE FW VERSION (index 02)
15:16:50,461    ERROR [ReceiverListener:hidraw0] logitech_receiver.base: read failed, assuming handle 15 no longer available
15:16:50,461  WARNING [ReceiverListener:hidraw0] logitech_receiver.listener: receiver disconnected
15:16:50,461     INFO [ReceiverListener:hidraw0] solaar.listener: <UnifyingReceiver(/dev/hidraw0,15)>: notifications listener has stopped
15:16:54,457  WARNING [MainThread] logitech_receiver.base: timeout (4.01/4.00) on device 2 request {000C} params [2205]
Traceback (most recent call last):
  File "/usr/share/solaar/lib/solaar/ui/__init__.py", line 165, in _status_changed
    window.update(device, need_popup)
  File "/usr/share/solaar/lib/solaar/ui/window.py", line 820, in update
    _update_info_panel(device, full=full_update)
  File "/usr/share/solaar/lib/solaar/ui/window.py", line 701, in _update_info_panel
    _update_device_panel(device, _info._device, _info._buttons, full)
  File "/usr/share/solaar/lib/solaar/ui/window.py", line 672, in _update_device_panel
    _config_panel.update(device, is_online)
  File "/usr/share/solaar/lib/solaar/ui/config_panel.py", line 206, in update
    for s in device.settings:
  File "/usr/share/solaar/lib/logitech_receiver/receiver.py", line 254, in settings
    _check_feature_settings(self, self._settings)
  File "/usr/share/solaar/lib/logitech_receiver/settings_templates.py", line 393, in check_feature_settings
    check_feature(_SMART_SHIFT[0],   _F.SMART_SHIFT)
  File "/usr/share/solaar/lib/logitech_receiver/settings_templates.py", line 374, in check_feature
    if not featureId in device.features:
  File "/usr/share/solaar/lib/logitech_receiver/hidpp20.py", line 249, in __contains__
    if self._check():
  File "/usr/share/solaar/lib/logitech_receiver/hidpp20.py", line 189, in _check
    assert self.device
AssertionError
Traceback (most recent call last):
  File "/usr/share/solaar/lib/solaar/ui/__init__.py", line 165, in _status_changed
    window.update(device, need_popup)
  File "/usr/share/solaar/lib/solaar/ui/window.py", line 792, in update
    assert device.receiver
AssertionError
```
@johanricher Can you try the version of Solaar in this repository?   This problem may have been fixed by one of the recent updates to Solaar.  I haven't seen the problem for a while myself.
@pfps I installed with `pip install --user .` as (I think?) instructed here: https://pwr-solaar.github.io/Solaar/installation. Solaar now runs normally and doesn't lose the connection with the mouse anymore. (This is after less than one hour of use so I reserve the possibility to change this outcome.)

Another important thing:

> This problem may have been fixed by one of the recent updates to Solaar.

I installed a "1.0.1" version from the master branch of the repo but this is a different, newer version than the "1.0.1" version released via all the usual channels ([Github](https://github.com/pwr-Solaar/Solaar/releases), Ubuntu, etc.).

This can cause problems for people to actually know and tell which version they're using. How can we fix people's bugs if we're not sure the version they're running?
> This can cause problems for people to actually know and tell which version they're using. How can we fix people's bugs if we're not sure the version they're running?

Agreed.  If you have cloned Solaar then you can do `git describe --tag`.  I see `1.0.1-88-g079f2da` which I think means commit g079f2da, 88 commits after tag 1.0.1.
 It would be nice to have this information available in the distributed versions of Solaar.

Resolving patch:
diff --git a/lib/solaar/ui/window.py b/lib/solaar/ui/window.py
--- a/lib/solaar/ui/window.py
+++ b/lib/solaar/ui/window.py
@@ -783,7 +783,6 @@ def update(device, need_popup=False):
 		# receiver
 		is_alive = bool(device)
 		item = _receiver_row(device.path, device if is_alive else None)
-		assert item
 
 		if is_alive and item:
 			was_pairing = bool(_model.get_value(item, _COLUMN.STATUS_ICON))


Test patch: