Repository: pwr-Solaar/Solaar

Issue:
Empty gestures rule is not working
**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): `solaar 1.1.4`
- Distribution: PPA
- Kernel version (ex. `uname -srmo`): `Linux 5.15.0-46-generic x86_64 GNU/Linux`
- Output of `solaar show`:

<details>

```
Solaar version 1.1.4

USB and Bluetooth Devices

  1: MX Master 3 Wireless Mouse
     Device path  : /dev/hidraw0
     USB id       : 046d:B023
     Codename     : MX Master 3
     Kind         : mouse
     Protocol     : HID++ 4.5
     Serial number:
     Model ID:      B02340820000
     Unit ID:       0252C55E
        Bootloader: BOT 95.01.B0015
          Firmware: MPM 19.01.B0015
             Other:
     Supports 30 HID++ 2.0 features:
         0: ROOT                   {0000} V0
         1: FEATURE SET            {0001} V0
         2: DEVICE FW VERSION      {0003} V3
            Firmware: Bootloader BOT 95.01.B0015 00006A9CA89D
            Firmware: Firmware MPM 19.01.B0015 B0236A9CA89D
            Firmware: Other
            Unit ID: 0252C55E  Model ID: B02340820000  Transport IDs: {'btleid': 'B023', 'wpid': '4082'}
         3: DEVICE NAME            {0005} V0
            Name: Wireless Mouse MX Master 3
            Kind: mouse
         4: WIRELESS DEVICE STATUS {1D4B} V0
         5: RESET                  {0020} V0
         6: CRYPTO ID              {0021} V1
         7: DEVICE FRIENDLY NAME   {0007} V0
            Friendly Name: MX Master 3
         8: BATTERY STATUS         {1000} V1
            Battery: 50%, discharging, next level 20%.
         9: REPROG CONTROLS V4     {1B04} V4
            Key/Button Actions (saved): {Left Button:Left Click, Right Button:Right Click, Middle Button:Mouse Middle Button, Back Button:Mouse Back Button, Forward Button:Mouse Forward Button, Mouse Gesture Button:Gesture Button Navigation, Smart Shift:Smart Shift}
            Key/Button Actions        : {Left Button:Left Click, Right Button:Right Click, Middle Button:Mouse Middle Button, Back Button:Mouse Back Button, Forward Button:Mouse Forward Button, Mouse Gesture Button:Gesture Button Navigation, Smart Shift:Smart Shift}
            Key/Button Diversion (saved): {Middle Button:Regular, Back Button:Regular, Forward Button:Regular, Mouse Gesture Button:Mouse Gestures, Smart Shift:Regular}
            Key/Button Diversion        : {Middle Button:Regular, Back Button:Regular, Forward Button:Regular, Mouse Gesture Button:Diverted, Smart Shift:Regular}
        10: CHANGE HOST            {1814} V1
            Change Host        : 1:ThinkPad
        11: XY STATS               {2250} V1
        12: ADJUSTABLE DPI         {2201} V1
            Sensitivity (DPI) (saved): 1000
            Sensitivity (DPI)        : 1000
        13: SMART SHIFT            {2110} V0
            Scroll Wheel Rachet (saved): 10
            Scroll Wheel Rachet        : 10
        14: HIRES WHEEL            {2121} V1
            Multiplier: 15
            Has invert: Normal wheel motion
            Has ratchet switch: Normal wheel mode
            High resolution mode
            HID notification
            Scroll Wheel Direction (saved): False
            Scroll Wheel Direction        : False
            Scroll Wheel Resolution (saved): True
            Scroll Wheel Resolution        : True
            Scroll Wheel Diversion (saved): False
            Scroll Wheel Diversion        : False
        15: THUMB WHEEL            {2150} V0
            Thumb Wheel Direction (saved): False
            Thumb Wheel Direction        : False
            Thumb Wheel Diversion (saved): False
            Thumb Wheel Diversion        : False
        16: WHEEL STATS            {2251} V0
        17: DFUCONTROL SIGNED      {00C2} V0
        18: DEVICE RESET           {1802} V0    internal, hidden
        19: unknown:1803           {1803} V0    internal, hidden
        20: CONFIG DEVICE PROPS    {1806} V6    internal, hidden
        21: unknown:1813           {1813} V0    internal, hidden
        22: OOBSTATE               {1805} V0    internal, hidden
        23: unknown:1830           {1830} V0    internal, hidden
        24: unknown:18A1           {18A1} V0    internal, hidden
        25: unknown:1E00           {1E00} V0    hidden
        26: unknown:1EB0           {1EB0} V0    internal, hidden
        27: unknown:1861           {1861} V0    internal, hidden
        28: unknown:9300           {9300} V0    internal, hidden
        29: unknown:9001           {9001} V0    internal, hidden
     Has 8 reprogrammable keys:
         0: Left Button               , default: Left Click                  => Left Click
             mse, analytics key events, pos:0, group:1, group mask:g1
             reporting: default
         1: Right Button              , default: Right Click                 => Right Click
             mse, analytics key events, pos:0, group:1, group mask:g1
             reporting: default
         2: Middle Button             , default: Mouse Middle Button         => Mouse Middle Button
             mse, reprogrammable, divertable, raw XY, analytics key events, pos:0, group:3, group mask:g1,g2,g3
             reporting: default
         3: Back Button               , default: Mouse Back Button           => Mouse Back Button
             mse, reprogrammable, divertable, raw XY, analytics key events, pos:0, group:2, group mask:g1,g2
             reporting: default
         4: Forward Button            , default: Mouse Forward Button        => Mouse Forward Button
             mse, reprogrammable, divertable, raw XY, analytics key events, pos:0, group:2, group mask:g1,g2
             reporting: default
         5: Mouse Gesture Button      , default: Gesture Button Navigation   => Gesture Button Navigation
             mse, reprogrammable, divertable, raw XY, analytics key events, pos:0, group:3, group mask:g1,g2,g3
             reporting: diverted, raw XY diverted
         6: Smart Shift               , default: Smart Shift                 => Smart Shift
             mse, reprogrammable, divertable, raw XY, analytics key events, pos:0, group:3, group mask:g1,g2,g3
             reporting: default
         7: Virtual Gesture Button    , default: Virtual Gesture Button      => Virtual Gesture Button
             divertable, virtual, raw XY, force raw XY, pos:0, group:4, group mask:empty
             reporting: default
     Battery: 50%, discharging, next level 20%.
```
</details>

- Contents of `~/.config/solaar/config.yaml`:

<details>

```
- 1.1.4
- _NAME: MX Master 3 Wireless Mouse
  _absent: [hi-res-scroll, lowres-scroll-mode, onboard_profiles, report_rate, pointer_speed, speed-change, backlight, backlight-timed, fn-swap, persistent-remappable-keys,
    disable-keyboard-keys, divert-crown, crown-smooth, divert-gkeys, m-key-leds, mr-key-led, multiplatform, gesture2-gestures, gesture2-divert, gesture2-params,
    sidetone, equalizer]
  _battery: 4096
  _modelId: B02340820000
  _sensitive: {change-host: false, divert-keys: false, mouse-gestures: false, reprogrammable-keys: false}
  _unitId: 0252C55E
  change-host: null
  divert-keys: {82: 0, 83: 0, 86: 0, 195: 2, 196: 0}
  dpi: 1000
  dpi-sliding: 0
  hires-scroll-mode: false
  hires-smooth-invert: false
  hires-smooth-resolution: true
  reprogrammable-keys: {80: 80, 81: 81, 82: 82, 83: 83, 86: 86, 195: 195, 196: 196}
  smart-shift: 10
  thumb-scroll-invert: false
  thumb-scroll-mode: false
- _NAME: G305 Lightspeed Wireless Gaming Mouse
  _absent: [hi-res-scroll, lowres-scroll-mode, hires-smooth-invert, hires-smooth-resolution, hires-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: 4096
  _modelId: '407400000000'
  _serial: 4D6708BA
  _unitId: 513D1069
  _wpid: '4074'
  dpi: 3200
  onboard_profiles: 1
  report_rate: 1
- _NAME: G305 Lightspeed Wireless Gaming Mouse
  _absent: [hi-res-scroll, lowres-scroll-mode, hires-smooth-invert, hires-smooth-resolution, hires-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: 4096
  _modelId: '407400000000'
  _serial: 4D6708BA
  _unitId: 513D1069
  _wpid: '4074'
  dpi: 3200
  onboard_profiles: 1
  report_rate: 1

```

</details>


- Contents of `~/.config/solaar/rules.yaml`:

<details>

```
%YAML 1.3
---
- Rule:
  - MouseGesture: Mouse Left
  - KeyPress:
    - [Super_L, Shift_L, Up]
    - click
- Rule:
  - MouseGesture: Mouse Right
  - KeyPress:
    - [Super_L, Shift_L, Down]
    - click
- Rule:
  - MouseGesture: Mouse Up
  - KeyPress:
    - [Super_L, a]
    - click
- Rule:
  - MouseGesture: Mouse Down
  - KeyPress:
    - [Super_L, d]
    - click
- Rule:
  - MouseGesture: []
  - KeyPress:
    - [Super_L, s]
    - click
...
```
</details>


- Logs from Solaar:

<details>

```
9:59:13,501,501     INFO [MainThread] root: language en_US (UTF-8), translations path None
2022-08-31 19:59:13,721,721     INFO [MainThread] logitech_receiver.diversion: GDK Keymap set up
2022-08-31 19:59:13,727,727     INFO [MainThread] logitech_receiver.diversion: loaded 1 rules from /home/ilyachch/.config/solaar/rules.yaml
2022-08-31 19:59:13,760,760     INFO [MainThread] solaar.upower: connected to system dbus, watching for suspend/resume events
2022-08-31 19:59:13,832,832     INFO [MainThread] solaar.ui.notify: starting desktop notifications
2022-08-31 19:59:13,916,916     INFO [MainThread] solaar.listener: starting receiver listening threads
2022-08-31 19:59:13,918,918     INFO [MainThread] solaar.listener: receiver event add DeviceInfo(path='/dev/hidraw0', vendor_id='046D', product_id='B023', serial='dc:e4:66:31:75:49', release=None, manufacturer=None, product=None, interface=None, driver='logitech-hidpp-device', bus_id=5, isDevice=True)
2022-08-31 19:59:13,919,919     INFO [MainThread] logitech_receiver.base: New lock 13
2022-08-31 19:59:14,750,750     INFO [MainThread] solaar.listener: status_changed <Device(255,B023,MX Master 3 Wireless Mouse,)>: paired online, {'BATTERY LEVEL': 50, 'BATTERY STATUS': NamedInt(0, 'discharging'), 'BATTERY NEXT LEVEL': 20, 'BATTERY VOLTAGE': None, 'BATTERY CHARGING': False, 'ERROR': None} (0)
2022-08-31 19:59:15,110,110     INFO [MainThread] logitech_receiver.status: <Device(255,B023,MX Master 3 Wireless Mouse,)> pushing device settings [<Setting([feature:toggle] MX Master 3:hires-smooth-invert=None)>, <Setting([feature:toggle] MX Master 3:hires-smooth-resolution=None)>, <Setting([feature:toggle] MX Master 3:hires-scroll-mode=None)>, <Setting([feature:range] MX Master 3:smart-shift=None)>, <Setting([feature:toggle] MX Master 3:thumb-scroll-invert=None)>, <Setting([feature:toggle] MX Master 3:thumb-scroll-mode=None)>, <Setting([feature:choice] MX Master 3:dpi=None)>, <Setting([feature:map choice] MX Master 3:reprogrammable-keys=None)>, <Setting([feature:map choice] MX Master 3:divert-keys=None)>, <Setting([feature:choice] MX Master 3:change-host=None)>]
2022-08-31 19:59:15,538,538     INFO [MainThread] solaar.listener: status_changed <Device(255,B023,MX Master 3 Wireless Mouse,)>: paired online, {'BATTERY LEVEL': 50, 'BATTERY STATUS': NamedInt(0, 'discharging'), 'BATTERY NEXT LEVEL': 20, 'BATTERY VOLTAGE': None, 'BATTERY CHARGING': False, 'ERROR': None} (0) initialization
2022-08-31 19:59:15,538,538     INFO [ReceiverListener:hidraw0] logitech_receiver.listener: started with <Device(255,B023,MX Master 3 Wireless Mouse,)> (13)
2022-08-31 19:59:15,539,539     INFO [ReceiverListener:hidraw0] solaar.listener: <Device(255,B023,MX Master 3 Wireless Mouse,)>: notifications listener has started (13)
2022-08-31 19:59:15,539,539     INFO [ReceiverListener:hidraw0] solaar.listener: status_changed <Device(255,B023,MX Master 3 Wireless Mouse,)>: paired online, {'BATTERY LEVEL': 50, 'BATTERY STATUS': NamedInt(0, 'discharging'), 'BATTERY NEXT LEVEL': 20, 'BATTERY VOLTAGE': None, 'BATTERY CHARGING': False, 'ERROR': None, 'NOTIFICATION FLAGS': False} (0)
2022-08-31 19:59:26,780,780     INFO [ReceiverListener:hidraw0] logitech_receiver.settings_templates: mouse gesture notification [NamedInt(195, 'Mouse Gesture Button')]
2022-08-31 19:59:32,473,473     INFO [ReceiverListener:hidraw0] logitech_receiver.settings_templates: mouse gesture notification [NamedInt(195, 'Mouse Gesture Button')]
2022-08-31 19:59:36,860,860     INFO [ReceiverListener:hidraw0] logitech_receiver.settings_templates: mouse gesture notification [NamedInt(195, 'Mouse Gesture Button')]
2022-08-31 19:59:42,808,808     INFO [ReceiverListener:hidraw0] logitech_receiver.settings_templates: mouse gesture notification [NamedInt(195, 'Mouse Gesture Button'), 0, 0, 3, 0, 0, 4]
2022-08-31 19:59:55,896,896     INFO [ReceiverListener:hidraw0] logitech_receiver.settings_templates: mouse gesture notification [NamedInt(195, 'Mouse Gesture Button')]
2022-08-31 19:59:57,606,606     INFO [ReceiverListener:hidraw0] logitech_receiver.settings_templates: mouse gesture notification [NamedInt(195, 'Mouse Gesture Button'), 0, 0, 8]
2022-08-31 19:59:57,608,608     INFO [MainThread] logitech_receiver.diversion: XKB display set up
2022-08-31 19:59:57,609,609     INFO [MainThread] logitech_receiver.diversion: KeyPress action: ['Super_L', 'd'] click, group 0, modifiers 0
2022-08-31 19:59:57,661,661     INFO [MainThread] logitech_receiver.diversion: X11 library loaded and display set up
2022-08-31 19:59:59,773,773     INFO [ReceiverListener:hidraw0] logitech_receiver.settings_templates: mouse gesture notification [NamedInt(195, 'Mouse Gesture Button'), 0, 0, -8]
2022-08-31 19:59:59,774,774     INFO [MainThread] logitech_receiver.diversion: KeyPress action: ['Super_L', 'a'] click, group 0, modifiers 0
```

</details>

**Describe the bug**

```
- Rule:
  - MouseGesture: []
  - KeyPress:
    - [Super_L, s]
    - click
```

This rule is not working - I'm trying to configure mouse on just gesture button click (without movement) to emulate keypress. But this case is ignored.
Option to configure this rule as gesture button press or release is not working - it overlaps with gestures requiring mouse moving


**Additional context**
It was working in one of previous versions.


Discussion:
Yes, that's a bug introduced by a recent change.

Resolving patch:
diff --git a/lib/logitech_receiver/diversion.py b/lib/logitech_receiver/diversion.py
--- a/lib/logitech_receiver/diversion.py
+++ b/lib/logitech_receiver/diversion.py
@@ -806,15 +806,13 @@ def evaluate(self, feature, notification, device, status, last_result):
         if feature == _F.MOUSE_GESTURE:
             d = notification.data
             data = _unpack('!' + (int(len(d) / 2) * 'h'), d)
-            data_offset = 0
-            for m in self.movements:
-                if data_offset == 0:
-                    data_offset += 1
-                    if m not in self.MOVEMENTS:  # matching against initiating key
-                        if m != str(_CONTROL[data[0]]):
-                            return False
-                        else:
-                            continue
+            data_offset = 1
+            movement_offset = 0
+            if self.movements and self.movements[0] not in self.MOVEMENTS:  # matching against initiating key
+                movement_offset = 1
+                if self.movements[0] != str(_CONTROL[data[0]]):
+                    return False
+            for m in self.movements[movement_offset:]:
                 if data_offset >= len(data):
                     return False
                 if data[data_offset] == 0:
diff --git a/lib/logitech_receiver/settings_templates.py b/lib/logitech_receiver/settings_templates.py
--- a/lib/logitech_receiver/settings_templates.py
+++ b/lib/logitech_receiver/settings_templates.py
@@ -586,7 +586,7 @@ def move_action(self, dx, dy):
             if self.device.features.get_feature_version(_F.REPROG_CONTROLS_V4) >= 5 and self.starting:
                 self.starting = False  # hack to ignore strange first movement report from MX Master 3S
                 return
-            if self.lastEv is not None and now - self.lastEv > 50.:
+            if self.lastEv is not None and now - self.lastEv > 200.:
                 self.push_mouse_event()
             dpi = self.dpiSetting.read() if self.dpiSetting else 1000
             dx = float(dx) / float(dpi) * 15.  # This multiplier yields a more-or-less DPI-independent dx of about 5/cm


Test patch: