Repository: pwr-Solaar/Solaar

Issue:
Small popup issue when loading the system using the G903 and a Powerplay
**Information**
<!-- Make sure that your issue is not one of the known issues in the Solaar documentation at https://pwr-solaar.github.io/Solaar/ -->
<!-- Do not bother opening an issue for a version older than 1.1.0.  Upgrade to the latest version and see if your issue persists. -->
<!-- If you not running the current version of Solaar, strongly consider upgrading to the newest version. -->
- Solaar version (`solaar --version` or `git describe --tags` if cloned from this repository):
- Distribution: Ubuntu 22.10
- Kernel version (ex. `uname -srmo`): `KERNEL VERSION HERE`
- Output of `solaar show`:

Linux 5.19.0-26-generic x86_64 GNU/Linux

<details>

```
luis@xtreme:~$ solaar show
solaar version 1.1.8rc3+git1940-4e7b6b3

USB and Bluetooth Devices

  1: G935 Gaming Headset
     Device path  : /dev/hidraw6
     USB id       : 046d:0A87
     Codename     : G935 Headset
     Kind         : headset
     Protocol     : HID++ 4.2
     Serial number: 
     Model ID:      000000000A87
     Unit ID:       FFFFFFFF
          Firmware: U1  29.00.B0012
     Supports 9 HID++ 2.0 features:
         0: ROOT                   {0000} V0     
         1: FEATURE SET            {0001} V0     
         2: DEVICE FW VERSION      {0003} V2     
            Firmware: Firmware U1  29.00.B0012 0A87
            Unit ID: FFFFFFFF  Model ID: 000000000A87  Transport IDs: {'btid': '0000', 'btleid': '0000'}
         3: DEVICE NAME            {0005} V0     
            Name: G935 Gaming Headset
            Kind: None
         4: COLOR LED EFFECTS      {8070} V0     
         5: GKEY                   {8010} V0     
            Divert G Keys (saved): False
            Divert G Keys        : False
         6: EQUALIZER              {8310} V0     
         7: SIDETONE               {8300} V0     
            Sidetone (saved): 0
            Sidetone        : 0
         8: ADC MEASUREMENT        {1F20} V0     
            Battery status unavailable.
     Battery status unavailable.
Lightspeed Receiver
  Device path  : /dev/hidraw10
  USB id       : 046d:C53A
  Serial       : 4E4E9946
    Firmware   : 40.01.B0007
    Bootloader : 02.09
    Other      : AA.CA
  Has 2 paired device(s) out of a maximum of 1.
  Notifications: wireless, software present (0x000900)
  Device activity counters: (empty)

  1: G903 LIGHTSPEED Wireless Gaming Mouse w/ HERO
     Device path  : /dev/hidraw13
     WPID         : 4087
     Codename     : G903 LS
     Kind         : mouse
     Protocol     : HID++ 4.2
     Polling rate : 1 ms (1000Hz)
     Serial number: 3EF038B9
     Model ID:      4087C0910000
     Unit ID:       3EF038B9
        Bootloader: BL1 06.01.B0013
          Firmware: MPM 23.01.B0013
             Other: 
     The power switch is located on the base.
     Supports 31 HID++ 2.0 features:
         0: ROOT                   {0000} V0     
         1: FEATURE SET            {0001} V0     
         2: DEVICE FW VERSION      {0003} V2     
            Firmware: Bootloader BL1 06.01.B0013 0000047072FE
            Firmware: Firmware MPM 23.01.B0013 4087047072FE
            Firmware: Other   
            Unit ID: 3EF038B9  Model ID: 4087C0910000  Transport IDs: {'wpid': '4087', 'usbid': 'C091'}
         3: DEVICE NAME            {0005} V0     
            Name: G903 LIGHTSPEED Wireless Gaming Mouse w/ HERO
            Kind: mouse
         4: WIRELESS DEVICE STATUS {1D4B} V0     
         5: CONFIG CHANGE          {0020} V0     
         6: BATTERY VOLTAGE        {1001} V2     
            Battery: 90% 4079mV , discharging.
         7: RGB EFFECTS            {8071} V0     
         8: ONBOARD PROFILES       {8100} V0     
            Device Mode: On-Board
            Onboard Profiles (saved): Enable
            Onboard Profiles        : Enable
         9: MOUSE BUTTON SPY       {8110} V0     
        10: REPORT RATE            {8060} V0     
            Polling Rate (ms): 1
            Polling Rate (ms) (saved): 1
            Polling Rate (ms)        : 1
        11: ADJUSTABLE DPI         {2201} V1     
            Sensitivity (DPI) (saved): 6400
            Sensitivity (DPI)        : 6400
        12: DFUCONTROL SIGNED      {00C2} V0     
        13: DEVICE RESET           {1802} V0    internal, hidden 
        14: unknown:1803           {1803} V0    internal, hidden 
        15: OOBSTATE               {1805} V0    internal, hidden 
        16: CONFIG DEVICE PROPS    {1806} V4    internal, hidden 
        17: unknown:1811           {1811} V0    internal, hidden 
        18: unknown:1830           {1830} V0    internal, hidden 
        19: unknown:1890           {1890} V4    internal, hidden 
        20: unknown:1891           {1891} V4    internal, hidden 
        21: unknown:18A1           {18A1} V0    internal, hidden 
        22: unknown:1801           {1801} V0    internal, hidden 
        23: unknown:18B1           {18B1} V0    internal, hidden 
        24: unknown:1DF3           {1DF3} V0    internal, hidden 
        25: unknown:1E00           {1E00} V0    hidden 
        26: unknown:1EB0           {1EB0} V0    internal, hidden 
        27: unknown:1863           {1863} V0    internal, hidden 
        28: unknown:1E22           {1E22} V0    internal, hidden 
        29: HIRES WHEEL            {2121} V0     
            Multiplier: 8
            Has invert: Normal wheel motion
            Has ratchet switch: Normal wheel mode
            Low resolution mode
            HID notification
            Scroll Wheel Direction (saved): False
            Scroll Wheel Direction        : False
            Scroll Wheel Resolution (saved): False
            Scroll Wheel Resolution        : False
            Scroll Wheel Diversion (saved): False
            Scroll Wheel Diversion        : False
        30: unknown:18C0           {18C0} V0    internal, hidden 
     Battery: 90% 4079mV , discharging.

  7: Candy companion chip
     Device path  : /dev/hidraw14
     Codename     : Candy
     Kind         : touchpad
     Protocol     : HID++ 4.2
     Serial number: 4E4E9946
     Model ID:      405F00000000
     Unit ID:       34304713
          Firmware: CC  07.00.B0010
        Bootloader: BOT 32.00.B0010
     Supports 12 HID++ 2.0 features:
         0: ROOT                   {0000} V0     
         1: FEATURE SET            {0001} V0     
         2: DEVICE FW VERSION      {0003} V2     
            Firmware: Firmware CC  07.00.B0010 405F
            Firmware: Bootloader BOT 32.00.B0010 405F
            Unit ID: 34304713  Model ID: 405F00000000  Transport IDs: {'wpid': '405F'}
         3: DEVICE NAME            {0005} V0     
            Name: Candy companion chip
            Kind: touchpad
         4: unknown:18A1           {18A1} V0    internal, hidden 
         5: unknown:1E00           {1E00} V0    hidden 
         6: unknown:1EB0           {1EB0} V0    internal, hidden 
         7: DFUCONTROL SIGNED      {00C2} V0     
         8: unknown:1801           {1801} V0    internal, hidden 
         9: DEVICE RESET           {1802} V0    internal, hidden 
        10: unknown:1803           {1803} V0    internal, hidden 
        11: COLOR LED EFFECTS      {8070} V4     
     Battery status unavailable.
```
</details>

- Contents of `~/.config/solaar/config.yaml` (or `~/.config/solaar/config.json` if `~/.config/solaar/config.yaml` not present):

<details>

```
- 1.1.8rc3+git1940-4e7b6b3
- _NAME: G903 LIGHTSPEED Wireless Gaming Mouse w/ HERO
  _absent: [hi-res-scroll, lowres-scroll-mode, smart-shift, thumb-scroll-invert, thumb-scroll-mode, pointer_speed, speed-change, backlight, backlight-timed,
    fn-swap, reprogrammable-keys, persistent-remappable-keys, divert-keys, disable-keyboard-keys, crown-smooth, divert-crown, divert-gkeys, m-key-leds,
    mr-key-led, multiplatform, change-host, gesture2-gestures, gesture2-divert, gesture2-params, sidetone, equalizer]
  _battery: 4097
  _modelId: 4087C0910000
  _sensitive: {hires-smooth-resolution: true}
  _serial: A9C5F99B
  _unitId: A9C5F99B
  _wpid: '4087'
  dpi: 3200
  hires-scroll-mode: false
  hires-smooth-invert: false
  hires-smooth-resolution: false
  onboard_profiles: 1
  report_rate: 1
- _NAME: G903 LIGHTSPEED Wireless Gaming Mouse w/ HERO
  _absent: [hi-res-scroll, lowres-scroll-mode, smart-shift, thumb-scroll-invert, thumb-scroll-mode, pointer_speed, speed-change, backlight, backlight-timed,
    fn-swap, reprogrammable-keys, persistent-remappable-keys, divert-keys, disable-keyboard-keys, crown-smooth, divert-crown, divert-gkeys, m-key-leds,
    mr-key-led, multiplatform, change-host, gesture2-gestures, gesture2-divert, gesture2-params, sidetone, equalizer, scroll-ratchet]
  _battery: 4097
  _modelId: 4087C0910000
  _sensitive: {hires-smooth-resolution: true}
  _serial: 3EF038B9
  _unitId: 3EF038B9
  _wpid: '4087'
  dpi: 6400
  hires-scroll-mode: false
  hires-smooth-invert: false
  hires-smooth-resolution: false
  onboard_profiles: 1
  report_rate: 1
- _NAME: Candy companion chip
  _absent: [hi-res-scroll, lowres-scroll-mode, hires-smooth-invert, hires-smooth-resolution, hires-scroll-mode, smart-shift, thumb-scroll-invert, thumb-scroll-mode,
    onboard_profiles, report_rate, pointer_speed, dpi, speed-change, backlight, backlight-timed, fn-swap, reprogrammable-keys, persistent-remappable-keys,
    divert-keys, disable-keyboard-keys, crown-smooth, divert-crown, divert-gkeys, m-key-leds, mr-key-led, multiplatform, change-host, gesture2-gestures,
    gesture2-divert, gesture2-params, sidetone, equalizer, scroll-ratchet]
  _battery: 0
  _modelId: 405F00000000
  _serial: 4E4E9946
  _unitId: '34304713'
  _wpid: 405F
- _NAME: G903 Hero Gaming Mouse
  _absent: [hi-res-scroll, lowres-scroll-mode, smart-shift, thumb-scroll-invert, thumb-scroll-mode, pointer_speed, speed-change, backlight, backlight-timed,
    fn-swap, reprogrammable-keys, persistent-remappable-keys, divert-keys, disable-keyboard-keys, crown-smooth, divert-crown, divert-gkeys, m-key-leds,
    mr-key-led, multiplatform, change-host, gesture2-gestures, gesture2-divert, gesture2-params, sidetone, equalizer]
  _battery: 4097
  _modelId: 4087C0910000
  _unitId: A9C5F99B
  dpi: 3200
  hires-scroll-mode: false
  hires-smooth-invert: false
  hires-smooth-resolution: true
  onboard_profiles: 1
  report_rate: 1
- _NAME: G935 Gaming Headset
  _absent: [hi-res-scroll, lowres-scroll-mode, hires-smooth-invert, hires-smooth-resolution, hires-scroll-mode, smart-shift, thumb-scroll-invert, thumb-scroll-mode,
    onboard_profiles, report_rate, pointer_speed, dpi, speed-change, backlight, backlight-timed, fn-swap, reprogrammable-keys, persistent-remappable-keys,
    divert-keys, disable-keyboard-keys, crown-smooth, divert-crown, m-key-leds, mr-key-led, multiplatform, change-host, gesture2-gestures, gesture2-divert,
    gesture2-params, equalizer, scroll-ratchet]
  _battery: 0
  _modelId: 000000000A87
  _unitId: FFFFFFFF
  divert-gkeys: false
  sidetone: 0
- _NAME: Candy companion chip
  _absent: [hi-res-scroll, lowres-scroll-mode, hires-smooth-invert, hires-smooth-resolution, hires-scroll-mode, smart-shift, thumb-scroll-invert, thumb-scroll-mode,
    onboard_profiles, report_rate, pointer_speed, dpi, speed-change, backlight, backlight-timed, fn-swap, reprogrammable-keys, persistent-remappable-keys,
    divert-keys, disable-keyboard-keys, crown-smooth, divert-crown, divert-gkeys, m-key-leds, mr-key-led, multiplatform, change-host, gesture2-gestures,
    gesture2-divert, gesture2-params, sidetone, equalizer]
  _battery: 0
  _modelId: 405F00000000
  _serial: 981F96BE
  _unitId: 3031470A
  _wpid: 405F
```
</details>


- Errors or warrnings from Solaar:
<!-- Under normal operation Solaar keeps a log of warning and error messages in ~/.tmp
while it is running as a file starting with 'Solaar'.
If this file is not available or does not have useful information you can
run Solaar as `solaar -dd`, after killing any running Solaar processes to
have Solaar log informational, warning, and error messages to stdout. -->


**Describe the bug**
A clear and concise description of what the bug is.

A popup shows whenever I reboot the computer that says:

A receiver dev/hidraw2 but did not have permission to open it


**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Screenshots**
If applicable, add screenshots to help explain your problem.

This is the popup

![image](https://user-images.githubusercontent.com/29236/207410853-e5e359c1-457d-4b21-b010-1d9e4da86c66.png)

This is the menu with the Logitech Powerplay. Even though I can connect the G903 to its own Receiver, the powerplay also offers the option of connecting the G903 to it so I can save one usb slot on the PC, meaning I can connect the G903 to the Powerplay receiver and both would use the same usb connection.

![image](https://user-images.githubusercontent.com/29236/207411160-546312ef-60e0-49df-a36a-285824287140.png)


This is how it looks connected directly to the Powerplay receiver:

![image](https://user-images.githubusercontent.com/29236/207411244-b2e1a069-23a0-4318-bb35-e35c9abe5fa2.png)


Also, it confused me when I saw Candy instead of Logitech Powerplay


**Additional context**
Add any other context about the problem here.



Discussion:
The popup is created when Solaar finds a device that it thinks it should connect to but it can't open the /dev/hidrawN file for it.

There are several potential causes but the most likely one is that Solaar is running at a time when permissions are not correctly set up for the /dev/hidrawN node (shown in the output of  `solaar show`) for the headset.  Run `ls -l /dev/hidraw*` and look to see whether there is a + on the line for the headset.  If there is no + there, then something weird is going on.  Try disconnecting and reconnecting the headset.  If this works then the above cause almost certainly the correct one.   Terminate Solaar and start it up again.  If it works correctly then the above cause is even more likely the correct one.

The solution is then likely to be to start up Solaar a bit later.   I don't know how you have Solaar starting up but it is best to only start Solaar after user login and after window system start.


The Logitech PowerPlay is a strange device.  As far as Solaar can see, it is a Lightspeed Receiver plus the Candy touchpad.   Logitech software may provide a different name for the device's parts but Solaar is using what the parts identify themselves as.  The Candy touchpad is also connected to the receiver using an unusual device number.


> The popup is created when Solaar finds a device that it thinks it should connect to but it can't open the /dev/hidrawN file for it.
> 
> There are several potential causes but the most likely one is that Solaar is running at a time when permissions are not correctly set up for the /dev/hidrawN node (shown in the output of `solaar show`) for the headset. Run `ls -l /dev/hidraw*` and look to see whether there is a + on the line for the headset. If there is no + there, then something weird is going on. Try disconnecting and reconnecting the headset. If this works then the above cause almost certainly the correct one. Terminate Solaar and start it up again. If it works correctly then the above cause is even more likely the correct one.
> 
> The solution is then likely to be to start up Solaar a bit later. I don't know how you have Solaar starting up but it is best to only start Solaar after user login and after window system start.
> 
> The Logitech PowerPlay is a strange device. As far as Solaar can see, it is a Lightspeed Receiver plus the Candy touchpad. Logitech software may provide a different name for the device's parts but Solaar is using what the parts identify themselves as. The Candy touchpad is also connected to the receiver using an unusual device number.

Thank you so much for a thorough reply. Here is the image about the hidraw devices

![image](https://user-images.githubusercontent.com/29236/207433045-64a6c012-e237-4966-95ed-ec39cabad498.png)

So yes, it has a + sign
I followed your advice, so on the startup application app I did the following:

bash -c "sleep 2 && solaar --window=hide"

And now it does not show. Thank you friend.
How do you start up Solaar?
You type start in the gnome search and get the startup application (I know we can do it with run and rc and etc... but I am lazy:

![image](https://user-images.githubusercontent.com/29236/207623302-b71e3ec1-1016-4d9f-9869-a663e764549b.png)


Then you select solaar here:

![image](https://user-images.githubusercontent.com/29236/207623419-86378cbf-01b1-4b11-b7f8-79adc3ffd7b1.png)

Lastly just edit the code. I had to push it to 5 seconds this time:

![image](https://user-images.githubusercontent.com/29236/207623536-94ffc1d5-8019-409b-af9a-af4eafe8bb88.png)


This is still a bug, like, maybe an option that does not show the popup until X amount of retries during a certain amount of time. Instead of failing on the first one would help.
I've never seen this problem before.  It may be related to how Gnome or Wayland does things.  But it does seem worthwhile to retry and only complain if the retries fail.

Resolving patch:
diff --git a/lib/solaar/listener.py b/lib/solaar/listener.py
--- a/lib/solaar/listener.py
+++ b/lib/solaar/listener.py
@@ -16,6 +16,7 @@
 ## with this program; if not, write to the Free Software Foundation, Inc.,
 ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
+import errno as _errno
 import time
 
 from collections import namedtuple
@@ -24,6 +25,8 @@
 from logging import WARNING as _WARNING
 from logging import getLogger
 
+import gi
+
 from logitech_receiver import Device, Receiver
 from logitech_receiver import base as _base
 from logitech_receiver import hidpp10 as _hidpp10
@@ -33,6 +36,9 @@
 
 from . import configuration
 
+gi.require_version('Gtk', '3.0')  # NOQA: E402
+from gi.repository import GLib  # NOQA: E402 # isort:skip
+
 # from solaar.i18n import _
 
 _log = getLogger(__name__)
@@ -373,6 +379,28 @@ def setup_scanner(status_changed_callback, error_callback):
     _base.notify_on_receivers_glib(_process_receiver_event)
 
 
+def _process_add(device_info, retry):
+    try:
+        _start(device_info)
+    except OSError as e:
+        if e.errno == _errno.EACCES:
+            try:
+                import subprocess
+                output = subprocess.check_output(['/usr/bin/getfacl', '-p', device_info.path], text=True)
+                if _log.isEnabledFor(_WARNING):
+                    _log.warning('Missing permissions on %s\n%s.', device_info.path, output)
+            except Exception:
+                pass
+            if retry:
+                GLib.timeout_add(2000.0, _process_add, device_info, retry - 1)
+            else:
+                _error_callback('permissions', device_info.path)
+        else:
+            _error_callback('nodevice', device_info.path)
+    except _base.NoReceiver:
+        _error_callback('nodevice', device_info.path)
+
+
 # receiver add/remove events will start/stop listener threads
 def _process_receiver_event(action, device_info):
     assert action is not None
@@ -388,22 +416,7 @@ def _process_receiver_event(action, device_info):
         assert isinstance(l, ReceiverListener)
         l.stop()
 
-    if action == 'add':
-        # a new receiver device was detected
-        try:
-            _start(device_info)
-        except OSError:
-            # permission error, ignore this path for now
-            # If receiver has extended ACL but not writable then it is for another seat.
-            # (It would be easier to use pylibacl but adding the pylibacl dependencies
-            # for this special case is not good.)
-            try:
-                import re
-                import subprocess
-                output = subprocess.check_output(['/usr/bin/getfacl', '-p', device_info.path])
-                if not re.search(b'user:.+:', output):
-                    _error_callback('permissions', device_info.path)
-            except Exception:
-                _error_callback('permissions', device_info.path)
-        except _base.NoReceiver:
-            _error_callback('nodevice', device_info.path)
+    if action == 'add':  # a new device was detected
+        _process_add(device_info, 3)
+
+    return False
diff --git a/lib/solaar/ui/__init__.py b/lib/solaar/ui/__init__.py
--- a/lib/solaar/ui/__init__.py
+++ b/lib/solaar/ui/__init__.py
@@ -51,14 +51,14 @@ def _error_dialog(reason, object):
     if reason == 'permissions':
         title = _('Permissions error')
         text = (
-            _('Found a Logitech Receiver (%s), but did not have permission to open it.') % object + '\n\n' +
-            _("If you've just installed Solaar, try removing the receiver and plugging it back in.")
+            _('Found a Logitech receiver or device (%s), but did not have permission to open it.') % object + '\n\n' +
+            _("If you've just installed Solaar, try disconnecting the receiver or device and then reconnecting it.")
         )
     elif reason == 'nodevice':
         title = _('Cannot connect to device error')
         text = (
             _('Found a Logitech receiver or device at %s, but encountered an error connecting to it.') % object + '\n\n' +
-            _('Try removing the device and plugging it back in or turning it off and then on.')
+            _('Try disconnecting the device and then reconnecting it or turning it off and then on.')
         )
     elif reason == 'unpair':
         title = _('Unpairing failed')


Test patch: