Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package sc-controller for openSUSE:Factory 
checked in at 2022-05-07 23:54:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/sc-controller (Old)
 and      /work/SRC/openSUSE:Factory/.sc-controller.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "sc-controller"

Sat May  7 23:54:17 2022 rev:12 rq:975474 version:0.4.8.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/sc-controller/sc-controller.changes      
2021-09-12 20:09:36.948088884 +0200
+++ /work/SRC/openSUSE:Factory/.sc-controller.new.1538/sc-controller.changes    
2022-05-07 23:54:18.568909609 +0200
@@ -1,0 +2,35 @@
+Fri May  6 18:11:50 UTC 2022 - Jannik Seiler <se...@mosad.xyz>
+
+- Update to 0.4.8.7
+  * AppImage tested on Ubuntu 22.04 LTS, Fedora 35, Fedora 33,
+    Manjaro, and PopOS 21.10
+  * Updated AppImage scripts for setuptools behavior changes and
+    library path changes
+  * Migrate setup.py script to use setuptools rather than distutils.
+    Try to comply with PEP 632 regarding the deprecation of distutils
+  * Fixed Turn Off Controller option for BLE connected controller.
+    Contribution by labsin
+  * Changed feel of rumble emulation support. Period and amplitude of
+    haptics change depending on data in ff_rumble event struct.
+    I find that it feels better
+  * Fixed long packet support for BLE reader. 3 input packet payloads
+    now work in BLE reader
+  * Fixed hotplug detection for BT connected Steam Controller
+  * Added report ID 3 to feature report packets to allow BLE support to
+    work again. Needed to make BLE support work with later versions of BlueZ 
(5.64)
+  * Fixes to allow Bluetooth evdev and HID controllers to appear in
+    controller registration list. Contribution by chewi
+  * Fixed some HID driver and evdev driver crashes. Contribution by Alastor27
+  * Fixed popup positioning and layering (somewhat) on Wayland.
+    Contribution by Supreeeme
+  * Allow deadzone calculations for analog trigger output.
+    Full usable analog trigger range
+  * Fixed Mouse Region output
+  * Small fixes for HID report parsing
+  * Added lowercase VDF button aliases to button dictionary
+  * Properly clamp rotated touchpad coordinates to s16 range
+  * Use proper limits for output 360 axes
+  * Add DS4 v.1 detection to ds4drv driver
+  * Fix display names for mapped X and Y buttons due to busted Linux aliases
+
+-------------------------------------------------------------------

Old:
----
  sc-controller-0.4.8.6.tar.gz

New:
----
  sc-controller-0.4.8.7.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ sc-controller.spec ++++++
--- /var/tmp/diff_new_pack.l390cq/_old  2022-05-07 23:54:19.352910590 +0200
+++ /var/tmp/diff_new_pack.l390cq/_new  2022-05-07 23:54:19.356910595 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package sc-controller
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           sc-controller
-Version:        0.4.8.6
+Version:        0.4.8.7
 Release:        0
 Summary:        User-mode driver and GTK3-based GUI for the Steam Controller
 License:        GPL-2.0-only
@@ -29,6 +29,7 @@
 BuildRequires:  gobject-introspection
 BuildRequires:  hicolor-icon-theme
 BuildRequires:  pkgconfig
+BuildRequires:  python3-setuptools
 BuildRequires:  shared-mime-info
 BuildRequires:  zlib-devel
 BuildRequires:  pkgconfig(python3)

++++++ sc-controller-0.4.8.6.tar.gz -> sc-controller-0.4.8.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/README.md 
new/sc-controller-0.4.8.7/README.md
--- old/sc-controller-0.4.8.6/README.md 2021-09-09 20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/README.md 2022-05-06 18:39:50.000000000 +0200
@@ -43,6 +43,7 @@
   - [python-pylibacl](http://pylibacl.k1024.org/) is recommended
   - [python-evdev](https://python-evdev.readthedocs.io/en/latest/) is strongly 
recommended
   - [python-vdf](https://pypi.org/project/vdf/)
+  - [gtk-layer-shell](https://github.com/wmww/gtk-layer-shell) (Wayland only)
 
 ### Installing
   - Download and extract  [latest 
release](https://github.com/kozec/sc-controller/releases/latest)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/appimage-build.sh 
new/sc-controller-0.4.8.7/appimage-build.sh
--- old/sc-controller-0.4.8.6/appimage-build.sh 2021-09-09 20:00:13.000000000 
+0200
+++ new/sc-controller-0.4.8.7/appimage-build.sh 2022-05-06 18:39:50.000000000 
+0200
@@ -105,7 +105,9 @@
 
 # Build important part
 python3 setup.py build
-python3 setup.py install --prefix ${BUILD_APPDIR}/usr
+
+# Need to use single-version-externally-managed due to setuptools behavior
+python3 setup.py install --single-version-externally-managed --prefix 
${BUILD_APPDIR}/usr --record /dev/null
 
 # Move udev stuff
 mv ${BUILD_APPDIR}/usr/lib/udev/rules.d/69-${APP}.rules ${BUILD_APPDIR}/
@@ -127,12 +129,12 @@
 cp scripts/${APP}.appdata.xml 
${BUILD_APPDIR}/usr/share/metainfo/${APP}.appdata.xml
 
 # Make symlinks
-ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libcemuhook.cpython-39-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libcemuhook.so
-ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libhiddrv.cpython-39-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libhiddrv.so
-ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libremotepad.cpython-39-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libremotepad.so
-ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libsc_by_bt.cpython-39-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libsc_by_bt.so
-ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libuinput.cpython-39-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libuinput.so
-ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/posix1e.cpython-39-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/posix1e.so
+ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libcemuhook.cpython-310-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libcemuhook.so
+ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libhiddrv.cpython-310-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libhiddrv.so
+ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libremotepad.cpython-310-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libremotepad.so
+ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libsc_by_bt.cpython-310-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libsc_by_bt.so
+ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libuinput.cpython-310-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/libuinput.so
+ln -sfr 
${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/posix1e.cpython-310-x86_64-linux-gnu.so
 ${BUILD_APPDIR}/usr/lib64/python${PYTHON_VERSION}/site-packages/posix1e.so
 
 # Copy AppRun script
 cp scripts/appimage-AppRun.sh ${BUILD_APPDIR}/AppRun
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/actions.py 
new/sc-controller-0.4.8.7/scc/actions.py
--- old/sc-controller-0.4.8.6/scc/actions.py    2021-09-09 20:00:13.000000000 
+0200
+++ new/sc-controller-0.4.8.7/scc/actions.py    2022-05-06 18:39:50.000000000 
+0200
@@ -13,7 +13,8 @@
 from scc.tools import circle_to_square, clamp, nameof
 from scc.uinput import Keys, Axes, Rels
 from scc.lib import xwrappers as X
-from scc.constants import STICK_PAD_MIN, STICK_PAD_MAX, STICK_PAD_MIN_HALF
+from scc.constants import (STICK_PAD_MIN, STICK_PAD_MAX, STICK_PAD_MIN_HALF,
+OUTPUT_360_STICK_MIN, OUTPUT_360_STICK_MAX)
 from scc.constants import STICK_PAD_MAX_HALF, TRIGGER_MIN, TRIGGER_HALF
 from scc.constants import HIPFIRE_NORMAL, HIPFIRE_SENSIBLE, HIPFIRE_EXCLUSIVE
 from scc.constants import LEFT, RIGHT, CPAD, STICK, PITCH, YAW, ROLL
@@ -682,7 +683,7 @@
                        # DPAD
                        return int(max(-1, min(1, value)))
                # Everything else
-               return int(max(STICK_PAD_MIN, min(STICK_PAD_MAX, value)))
+               return int(max(OUTPUT_360_STICK_MIN, min(OUTPUT_360_STICK_MAX, 
value)))
        
        
        def axis(self, mapper, position, what):
@@ -1456,8 +1457,9 @@
                Keys.BTN_SELECT : "< Select",
                Keys.BTN_A              : "A Button",
                Keys.BTN_B              : "B Button",
-               Keys.BTN_X              : "X Button",
-               Keys.BTN_Y              : "Y Button",
+               # Work around busted Linux btn aliases
+               Keys.BTN_NORTH  : "X Button",
+               Keys.BTN_WEST   : "Y Button",
                
                Keys.KEY_PREVIOUSSONG   : "<< Song",
                Keys.KEY_STOP                   : "Stop",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/constants.py 
new/sc-controller-0.4.8.7/scc/constants.py
--- old/sc-controller-0.4.8.6/scc/constants.py  2021-09-09 20:00:13.000000000 
+0200
+++ new/sc-controller-0.4.8.7/scc/constants.py  2022-05-06 18:39:50.000000000 
+0200
@@ -28,7 +28,7 @@
 If SC-Controller is updated while daemon is running, DAEMON_VERSION send by
 daemon will differ one one expected by UI and daemon will be forcefully 
restarted.
 """
-DAEMON_VERSION = "0.4.8.6"
+DAEMON_VERSION = "0.4.8.7"
 
 HPERIOD  = 0.02
 LPERIOD  = 0.5
@@ -126,10 +126,14 @@
 
 
 STICK_PAD_MIN = -32768
-STICK_PAD_MAX = 32768
+STICK_PAD_MAX = 32767
 STICK_PAD_MIN_HALF = STICK_PAD_MIN / 3
 STICK_PAD_MAX_HALF = STICK_PAD_MAX / 3
 
+# Take async 360 stick axes into account
+OUTPUT_360_STICK_MAX = 32767
+OUTPUT_360_STICK_MIN = -32768
+
 CPAD_MIN = 0
 CPAD_X_MAX = 1916
 CPAD_Y_MAX = 930
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/device_monitor.py 
new/sc-controller-0.4.8.7/scc/device_monitor.py
--- old/sc-controller-0.4.8.6/scc/device_monitor.py     2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/device_monitor.py     2022-05-06 
18:39:50.000000000 +0200
@@ -8,7 +8,7 @@
 from scc.lib.eudevmonitor import Eudev, Monitor
 from scc.lib.ioctl_opt import IOR
 from ctypes.util import find_library
-import os, ctypes, fcntl, re, logging
+import os, ctypes, fcntl, re, logging, time
 
 log = logging.getLogger("DevMon")
 
@@ -195,6 +195,9 @@
                                return vendor, product
                        # Above method works for anything _but_ SteamController
                        # For that one, following desperate mess is needed
+
+                       # Sleep for 1 second to make sure info is available on 
system
+                       time.sleep(1)
                        node = self._dev_for_hci(syspath)
                        if node:
                                name = node.split("/")[-1]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/drivers/ds4drv.py 
new/sc-controller-0.4.8.7/scc/drivers/ds4drv.py
--- old/sc-controller-0.4.8.6/scc/drivers/ds4drv.py     2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/drivers/ds4drv.py     2022-05-06 
18:39:50.000000000 +0200
@@ -21,6 +21,7 @@
 
 VENDOR_ID = 0x054c
 PRODUCT_ID = 0x09cc
+DS4_V1_PRODUCT_ID = 0x5C4
 
 
 class DS4Controller(HIDController):
@@ -411,10 +412,17 @@
                        # daemon.add_error("ds4", "No access to DS4 device")
        
        if config["drivers"].get("hiddrv") or (HAVE_EVDEV and 
config["drivers"].get("evdevdrv")):
+               # DS4 v.2
                register_hotplug_device(hid_callback, VENDOR_ID, PRODUCT_ID, 
on_failure=fail_cb)
+               # DS4 v.1
+               register_hotplug_device(hid_callback, VENDOR_ID, 
DS4_V1_PRODUCT_ID, on_failure=fail_cb)
                if HAVE_EVDEV and config["drivers"].get("evdevdrv"):
+                       # DS4 v.2
                        daemon.get_device_monitor().add_callback("bluetooth",
                                                        VENDOR_ID, PRODUCT_ID, 
make_evdev_device, None)
+                       # DS4 v.1
+                       daemon.get_device_monitor().add_callback("bluetooth",
+                               VENDOR_ID, DS4_V1_PRODUCT_ID, 
make_evdev_device, None)
                return True
        else:
                log.warning("Neither HID nor Evdev driver is enabled, DS4 
support cannot be enabled.")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/drivers/evdevdrv.py 
new/sc-controller-0.4.8.7/scc/drivers/evdevdrv.py
--- old/sc-controller-0.4.8.6/scc/drivers/evdevdrv.py   2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/drivers/evdevdrv.py   2022-05-06 
18:39:50.000000000 +0200
@@ -34,6 +34,7 @@
 
 EvdevControllerInput = namedtuple('EvdevControllerInput',
        'buttons ltrig rtrig stick_x stick_y lpad_x lpad_y rpad_x rpad_y '
+       'accel_x accel_y accel_z '
        'gpitch groll gyaw q1 q2 q3 q4 '
        'cpad_x cpad_y'
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/drivers/hiddrv.c 
new/sc-controller-0.4.8.7/scc/drivers/hiddrv.c
--- old/sc-controller-0.4.8.6/scc/drivers/hiddrv.c      2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/drivers/hiddrv.c      2022-05-06 
18:39:50.000000000 +0200
@@ -8,7 +8,7 @@
 #define HIDDRV_MODULE_VERSION 5
 PyObject* module;
 
-#define AXIS_COUNT 17
+#define AXIS_COUNT 20
 #define BUTTON_COUNT 32
 
 struct HIDControllerInput {
@@ -26,15 +26,18 @@
        AXIS_STICK_Y = 5,
        AXIS_LTRIG   = 6,
        AXIS_RTRIG   = 7,
-       AXIS_GPITCH  = 8,
-       AXIS_GROLL   = 9,
-       AXIS_GYAW    = 10,
-       AXIS_Q1      = 11,
-       AXIS_Q2      = 12,
-       AXIS_Q3      = 13,
-       AXIS_Q4      = 14,
-       AXIS_CPAD_X  = 15,
-       AXIS_CPAD_Y  = 16,
+       AXIS_ACCEL_X = 8,
+       AXIS_ACCEL_Y = 9,
+       AXIS_ACCEL_Z = 10,
+       AXIS_GPITCH  = 11,
+       AXIS_GROLL   = 12,
+       AXIS_GYAW    = 13,
+       AXIS_Q1      = 14,
+       AXIS_Q2      = 15,
+       AXIS_Q3      = 16,
+       AXIS_Q4      = 17,
+       AXIS_CPAD_X  = 18,
+       AXIS_CPAD_Y  = 19,
        _AxisType_force_int = INT_MAX
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/drivers/hiddrv.py 
new/sc-controller-0.4.8.7/scc/drivers/hiddrv.py
--- old/sc-controller-0.4.8.6/scc/drivers/hiddrv.py     2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/drivers/hiddrv.py     2022-05-06 
18:39:50.000000000 +0200
@@ -23,7 +23,7 @@
 DEV_CLASS_HID = 3
 TRANSFER_TYPE_INTERRUPT = 3
 LIBUSB_DT_REPORT = 0x22
-AXIS_COUNT = 17                # Must match number of axis fields in 
HIDControllerInput and values in AxisType
+AXIS_COUNT = 20                # Must match number of axis fields in 
HIDControllerInput and values in AxisType
 BUTTON_COUNT = 32      # Must match (or be less than) number of bits in 
HIDControllerInput.buttons
 ALLOWED_SIZES = [1, 2, 4, 8, 16, 32]
 SYS_DEVICES = "/sys/devices"
@@ -54,6 +54,9 @@
                ('stick_y', ctypes.c_int32),
                ('ltrig', ctypes.c_int32),
                ('rtrig', ctypes.c_int32),
+               ('accel_x', ctypes.c_int32),
+               ('accel_y', ctypes.c_int32),
+               ('accel_z', ctypes.c_int32),
                ('gpitch', ctypes.c_int32),
                ('groll', ctypes.c_int32),
                ('gyaw', ctypes.c_int32),
@@ -75,15 +78,18 @@
        AXIS_STICK_Y = 5
        AXIS_LTRIG   = 6
        AXIS_RTRIG   = 7
-       AXIS_GPITCH  = 8
-       AXIS_GROLL   = 9
-       AXIS_GYAW    = 10
-       AXIS_Q1      = 11
-       AXIS_Q2      = 12
-       AXIS_Q3      = 13
-       AXIS_Q4      = 14
-       AXIS_CPAD_X  = 15
-       AXIS_CPAD_Y  = 16
+       AXIS_ACCEL_X = 8
+       AXIS_ACCEL_Y = 9
+       AXIS_ACCEL_Z = 10
+       AXIS_GPITCH  = 11
+       AXIS_GROLL   = 12
+       AXIS_GYAW    = 13
+       AXIS_Q1      = 14
+       AXIS_Q2      = 15
+       AXIS_Q3      = 16
+       AXIS_Q4      = 17
+       AXIS_CPAD_X  = 18
+       AXIS_CPAD_Y  = 19
 
 
 class AxisMode(IntEnum):
@@ -234,7 +240,7 @@
                if hid_descriptor is None:
                        hid_descriptor = self.handle.getRawDescriptor(
                                        LIBUSB_DT_REPORT, 0, 512)
-               open("report", "wb").write(b"".join([ chr(x) for x in 
hid_descriptor ]))
+               open("report", "wb").write(bytes([x for x in hid_descriptor ]))
                self._build_hid_decoder(hid_descriptor, config, max_size)
                self._packet_size = self._decoder.packet_size
 
@@ -346,13 +352,13 @@
                                                                if config:
                                                                        target, 
axis_data = self._build_axis_maping(next_axis, config)
                                                                        if 
axis_data:
-                                                                               
axis_data.byte_offset = total / 8
+                                                                               
axis_data.byte_offset = total // 8
                                                                                
axis_data.bit_offset = total % 8
                                                                                
axis_data.size = size
                                                                                
self._decoder.axes[target] = axis_data
                                                                else:
                                                                        
self._decoder.axes[next_axis] = AxisData(mode = AxisMode.AXIS_NO_SCALE)
-                                                                       
self._decoder.axes[next_axis].byte_offset = total / 8
+                                                                       
self._decoder.axes[next_axis].byte_offset = total // 8
                                                                        
self._decoder.axes[next_axis].bit_offset = total % 8
                                                                        
self._decoder.axes[next_axis].size = size
                                                                next_axis = 
next_axis + 1
@@ -367,12 +373,12 @@
                                                        if config:
                                                                target, 
axis_data = self._build_axis_maping(next_axis, config, AxisMode.HATSWITCH)
                                                                if axis_data:
-                                                                       
axis_data.byte_offset = total / 8
+                                                                       
axis_data.byte_offset = total // 8
                                                                        
axis_data.bit_offset = total % 8
                                                                        
self._decoder.axes[target] = axis_data
                                                        else:
                                                                
self._decoder.axes[next_axis] = AxisData(mode = AxisMode.HATSWITCH)
-                                                               
self._decoder.axes[next_axis].byte_offset = total / 8
+                                                               
self._decoder.axes[next_axis].byte_offset = total // 8
                                                                
self._decoder.axes[next_axis].bit_offset = total % 8
                                                                
self._decoder.axes[next_axis].data.hatswitch.min = STICK_PAD_MIN
                                                                
self._decoder.axes[next_axis].data.hatswitch.max = STICK_PAD_MAX
@@ -393,7 +399,7 @@
                                                log.debug("Found %s buttons at 
bit %s", count, total)
                                                self._decoder.buttons = 
ButtonData(
                                                        enabled = True,
-                                                       byte_offset = total / 8,
+                                                       byte_offset = total // 
8,
                                                        bit_offset = total % 8,
                                                        size = buttons_size,
                                                        button_count = count,
@@ -404,7 +410,7 @@
                                                log.debug("Skipped over %s bits 
for %s at bit %s", count * size, kind, total)
                                                total += count * size
 
-               self._decoder.packet_size = total / 8
+               self._decoder.packet_size = total // 8
                if total % 8 > 0:
                        self._decoder.packet_size += 1
                if self._decoder.packet_size > max_size:
@@ -449,7 +455,8 @@
                                log.debug("Loading descriptor from '%s'", 
full_path)
                                temp_list = None
                                with open(full_path, "rb") as read_file:
-                                       temp_list = [ ord(x) for x in 
read_file.read(1024) ]
+                                       temp_list = [ x for x in 
read_file.read(1024)]
+
                                return temp_list
                except Exception as e:
                        log.exception(e)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/drivers/sc_by_bt.c 
new/sc-controller-0.4.8.7/scc/drivers/sc_by_bt.c
--- old/sc-controller-0.4.8.6/scc/drivers/sc_by_bt.c    2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/drivers/sc_by_bt.c    2022-05-06 
18:39:50.000000000 +0200
@@ -17,6 +17,7 @@
 };
 
 #define LONG_PACKET 0x80
+#define SINGLE_PACKET_PAYLOAD_PREFIX 0x40
 #define PACKET_SIZE 20
 
 enum SCButtons {
@@ -116,24 +117,53 @@
 
 /** Returns 1 if state has changed, 2 on read error */
 int read_input(SCByBtCPtr ptr) {
-       if (ptr->long_packet) {
-               // Previous packet had long flag set and this is its 2nd part
-               if (read(ptr->fileno, tmp_buffer, PACKET_SIZE) < PACKET_SIZE)
-                       return 2;
-               memcpy(ptr->buffer + PACKET_SIZE, tmp_buffer + 1, PACKET_SIZE - 
1);
-               ptr->long_packet = 0;
-               //debug_packet(ptr->buffer, PACKET_SIZE * 2);
-       } else {
-               if (read(ptr->fileno, ptr->buffer, PACKET_SIZE) < PACKET_SIZE)
-                       return 2;
-               ptr->long_packet = *((uint8_t*)(ptr->buffer + 1)) == 
LONG_PACKET;
-               if (ptr->long_packet) {
-                       // This is 1st part of long packet
+       if (read(ptr->fileno, tmp_buffer, PACKET_SIZE) < PACKET_SIZE)
+       {
+               return 2;
+       }
+
+       bool inLongPacket = false;
+       bool endPayload = false;
+       bool resetBufferData = false;
+       {
+               char checkPayloadByte = tmp_buffer[1];
+               int currentPacketNum = (int)(checkPayloadByte & 0x0F);
+               //printf("%i\n", currentPacketNum);
+               //bool processPayload = false;
+
+               inLongPacket = ptr->long_packet;
+               if (ptr->long_packet)
+               {
+                       // Will grab 18 bytes from each partial input. Start idx
+                       // offset from 20.
+                       int offset = ((PACKET_SIZE - 2) * currentPacketNum) + 2;
+                       // Skip copying first two bytes in partial input
+                       // (report ID and packet payload byte)
+                       memcpy(ptr->buffer + offset, tmp_buffer + 2, 
PACKET_SIZE - 2);
+               }
+               else
+               {
+                       memcpy(ptr->buffer, tmp_buffer, PACKET_SIZE);
+               }
+
+               endPayload = (checkPayloadByte & SINGLE_PACKET_PAYLOAD_PREFIX) 
== SINGLE_PACKET_PAYLOAD_PREFIX;
+               ptr->long_packet = !endPayload;
+
+               if (!endPayload)
+               {
                        return 0;
                }
-               //debug_packet(ptr->buffer, PACKET_SIZE);
+               else if (inLongPacket && endPayload)
+               {
+                       resetBufferData = true;
+               }
+
+               //if (endPayload)
+               //{
+               //      debug_packet(ptr->buffer, PACKET_SIZE * 
(currentPacketNum+1));
+               //}
        }
-       
+
        struct SCByBtControllerInput* state = &(ptr->state);
        struct SCByBtControllerInput* old_state = &(ptr->old_state);
        
@@ -143,6 +173,12 @@
        char* data = &ptr->buffer[4];
        if ((type & PING) == PING) {
                // PING packet does nothing
+
+               if (resetBufferData)
+               {
+                       memset(ptr->buffer, 0, 256);
+               }
+
                return 0;
        }
        if ((type & BUTTON) == BUTTON) {
@@ -205,6 +241,11 @@
                data += 14;
                */
        }
+
+       if (resetBufferData)
+       {
+               memset(ptr->buffer, 0, 256);
+       }
        
        return rv;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/drivers/sc_by_bt.py 
new/sc-controller-0.4.8.7/scc/drivers/sc_by_bt.py
--- old/sc-controller-0.4.8.6/scc/drivers/sc_by_bt.py   2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/drivers/sc_by_bt.py   2022-05-06 
18:39:50.000000000 +0200
@@ -8,7 +8,7 @@
 """
 
 from scc.lib.hidraw import HIDRaw
-from scc.constants import ControllerFlags
+from scc.constants import ControllerFlags, STICK_PAD_MIN, STICK_PAD_MAX
 from scc.tools import find_library
 from .sc_dongle import SCPacketType, SCPacketLength, SCConfigType
 from .sc_dongle import SCController
@@ -92,12 +92,13 @@
                self.daemon.get_scheduler().schedule(1.0, reconnect)
        
        
-       def _retry_cancel(self, syspath):
+       def _retry_cancel(self, syspath, vendor, product):
                """
                Cancels reconnection scheduled by 'retry'. Called when device 
monitor
                reports controller (as in BT device) being disconencted.
                """
-               self.reconnecting.remove(syspath)
+               if syspath in self.reconnecting:
+                       self.reconnecting.remove(syspath)
        
        
        def new_device_callback(self, syspath, *whatever):
@@ -243,11 +244,20 @@
                """ Flushes all prepared control messages to the device """
                while len(self._cmsg):
                        msg = self._cmsg.pop()
-                       self._hidrawdev.sendFeatureReport(msg)
+                       # Feature report data must be sent with report ID 3
+                       # or Input/output error will occur with later BlueZ 
versions (5.64)
+                       # Does not affect older BlueZ versions
+                       self._hidrawdev.sendFeatureReport(msg, 3)
        
        
        def input(self, idata):
                raise RuntimeError("This shouldn't be called, ever")
+
+       def turnoff(self):
+               super().turnoff()
+               # Need to call flush to make sure packet
+               # is sent to controller
+               self.flush()
        
        
        def close(self, *a):
@@ -269,13 +279,25 @@
                                if self._input_rotation_l and (self._state.type 
& 0x0100) != 0:
                                        lx, ly = self._state.lpad_x, 
self._state.lpad_y
                                        s, c = sin(self._input_rotation_l), 
cos(self._input_rotation_l)
-                                       self._state.lpad_x = int(lx * c - ly * 
s)
-                                       self._state.lpad_y = int(lx * s + ly * 
c)
+
+                                       # Adjust LX for rotation and clamp
+                                       value = int(lx * c - ly * s)
+                                       self._state.lpad_x = max(STICK_PAD_MIN, 
min(STICK_PAD_MAX, value))
+
+                                       # Adjust LY for rotation and clamp
+                                       value = int(lx * s + ly * c)
+                                       self._state.lpad_y = max(STICK_PAD_MIN, 
min(STICK_PAD_MAX, value))
                                if self._input_rotation_r and (self._state.type 
& 0x0200) != 0:
                                        rx, ry = self._state.rpad_x, 
self._state.rpad_y
                                        s, c = sin(self._input_rotation_r), 
cos(self._input_rotation_r)
-                                       self._state.rpad_x = int(rx * c - ry * 
s)
-                                       self._state.rpad_y = int(rx * s + ry * 
c)
+
+                                       # Adjust RX for rotation and clamp
+                                       value = int(rx * c - ry * s)
+                                       self._state.rpad_x = max(STICK_PAD_MIN, 
min(STICK_PAD_MAX, value))
+
+                                       # Adjust RY for rotation and clamp
+                                       value = int(rx * s + ry * c)
+                                       self._state.rpad_y = max(STICK_PAD_MIN, 
min(STICK_PAD_MAX, value))
                                
                                self.mapper.input(self, self._old_state, 
self._state)
                        self.flush()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/drivers/sc_dongle.py 
new/sc-controller-0.4.8.7/scc/drivers/sc_dongle.py
--- old/sc-controller-0.4.8.6/scc/drivers/sc_dongle.py  2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/drivers/sc_dongle.py  2022-05-06 
18:39:50.000000000 +0200
@@ -8,7 +8,7 @@
 
 from scc.lib import IntEnum
 from scc.drivers.usb import USBDevice, register_hotplug_device
-from scc.constants import SCButtons, STICKTILT
+from scc.constants import SCButtons, STICKTILT, STICK_PAD_MIN, STICK_PAD_MAX
 from scc.controller import Controller
 from scc.config import Config
 from collections import namedtuple
@@ -195,16 +195,31 @@
                        #       if (idata.buttons & STICKPRESS) and not 
(idata.buttons & STICKTILT):
                        #               idata = 
ControllerInput.replace(buttons=idata.buttons & ~SCButtons.LPAD)
                        
-                       if self._input_rotation_l:
+                       if self._input_rotation_l or self._input_rotation_r:
                                lx, ly = idata.lpad_x, idata.lpad_y
-                               if idata.buttons & SCButtons.LPADTOUCH:
+                               rx, ry = idata.rpad_x, idata.rpad_y
+
+                               if self._input_rotation_l and idata.buttons & 
SCButtons.LPADTOUCH:
                                        s, c = sin(self._input_rotation_l), 
cos(self._input_rotation_l)
-                                       lx = int(idata.lpad_x * c - 
idata.lpad_y * s)
-                                       ly = int(idata.lpad_x * s + 
idata.lpad_y * c)
-                               s, c = sin(self._input_rotation_r), 
cos(self._input_rotation_r)
-                               rx = int(idata.rpad_x * c - idata.rpad_y * s)
-                               ry = int(idata.rpad_x * s + idata.rpad_y * c)
-                               
+                                       # Adjust LX for rotation and clamp
+                                       value = int(idata.lpad_x * c - 
idata.lpad_y * s)
+                                       lx = max(STICK_PAD_MIN, 
min(STICK_PAD_MAX, value))
+
+                                       # Adjust LY for rotation and clamp
+                                       value = int(idata.lpad_x * s + 
idata.lpad_y * c)
+                                       ly = max(STICK_PAD_MIN, 
min(STICK_PAD_MAX, value))
+
+                               if self._input_rotation_r and idata.buttons & 
SCButtons.RPADTOUCH:
+                                       s, c = sin(self._input_rotation_r), 
cos(self._input_rotation_r)
+
+                                       # Adjust RX for rotation and clamp
+                                       value = int(idata.rpad_x * c - 
idata.rpad_y * s)
+                                       rx = max(STICK_PAD_MIN, 
min(STICK_PAD_MAX, value))
+
+                                       # Adjust RY for rotation and clamp
+                                       value = int(idata.rpad_x * s + 
idata.rpad_y * c)
+                                       ry = max(STICK_PAD_MIN, 
min(STICK_PAD_MAX, value))
+
                                # TODO: This is awfull :(
                                idata = ControllerInput(
                                                idata.type, idata.status, 
idata.seq, idata.buttons,
@@ -214,7 +229,7 @@
                                                idata.gpitch, idata.groll, 
idata.gyaw,
                                                idata.q1, idata.q2, idata.q3, 
idata.q4
                                )
-                       
+
                        self.mapper.input(self, old_state, idata)
        
        
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/foreign/vdf.py 
new/sc-controller-0.4.8.7/scc/foreign/vdf.py
--- old/sc-controller-0.4.8.6/scc/foreign/vdf.py        2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/foreign/vdf.py        2022-05-06 
18:39:50.000000000 +0200
@@ -23,9 +23,14 @@
 class VDFProfile(Profile):
        BUTTON_TO_BUTTON = {
                # maps button keys from vdf file to SCButtons constants
+               # It looks like uppercase button and lowercase button aliases 
are needed
+               'button_a'                      : SCButtons.A,
                'button_A'                      : SCButtons.A,
+               'button_b'                      : SCButtons.B,
                'button_B'                      : SCButtons.B,
+               'button_x'                      : SCButtons.X,
                'button_X'                      : SCButtons.X,
+               'button_y'                      : SCButtons.Y,
                'button_Y'                      : SCButtons.Y,
                'button_back_left'      : SCButtons.LGRIP,
                'button_back_right'     : SCButtons.RGRIP,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/gui/action_editor.py 
new/sc-controller-0.4.8.7/scc/gui/action_editor.py
--- old/sc-controller-0.4.8.6/scc/gui/action_editor.py  2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/gui/action_editor.py  2022-05-06 
18:39:50.000000000 +0200
@@ -70,7 +70,7 @@
                # That way, stuff like Rotation settings is not shown when 
editor
                # is used to edit menu actions.
                Action.AC_BUTTON        : Action.MOD_OSD | Action.MOD_FEEDBACK,
-               Action.AC_TRIGGER       : Action.MOD_OSD | 
Action.MOD_SENSITIVITY | Action.MOD_FEEDBACK,
+               Action.AC_TRIGGER       : Action.MOD_OSD | 
Action.MOD_SENSITIVITY | Action.MOD_FEEDBACK | Action.MOD_DEADZONE,
                Action.AC_STICK         : Action.MOD_OSD | Action.MOD_CLICK | 
Action.MOD_DEADZONE | Action.MOD_ROTATE | Action.MOD_SENSITIVITY | 
Action.MOD_FEEDBACK | Action.MOD_SMOOTH,
                Action.AC_PAD           : Action.MOD_OSD | Action.MOD_CLICK | 
Action.MOD_DEADZONE | Action.MOD_ROTATE | Action.MOD_SENSITIVITY | 
Action.MOD_FEEDBACK | Action.MOD_SMOOTH | Action.MOD_BALL,
                Action.AC_GYRO          : Action.MOD_OSD | 
Action.MOD_SENSITIVITY | Action.MOD_SENS_Z | Action.MOD_DEADZONE | 
Action.MOD_FEEDBACK,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/gui/ae/__init__.py 
new/sc-controller-0.4.8.7/scc/gui/ae/__init__.py
--- old/sc-controller-0.4.8.6/scc/gui/ae/__init__.py    2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/gui/ae/__init__.py    2022-05-06 
18:39:50.000000000 +0200
@@ -105,7 +105,11 @@
        if v is None or type(v) in (int, float, str,):
                return _('(not set)')
        elif isinstance(v, Action):
-               dsc = v.describe(Action.AC_STICK if cls == XYAction else 
Action.AC_BUTTON)
+               if not mode:
+                       dsc = v.describe(Action.AC_STICK if cls == XYAction 
else Action.AC_BUTTON)
+               else:
+                       dsc = v.describe(mode)
+
                if "\n" in dsc:
                        dsc = "<small>" + "\n".join(dsc.split("\n")[0:2]) + 
"</small>"
                return dsc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/gui/ae/trigger.py 
new/sc-controller-0.4.8.7/scc/gui/ae/trigger.py
--- old/sc-controller-0.4.8.6/scc/gui/ae/trigger.py     2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/gui/ae/trigger.py     2022-05-06 
18:39:50.000000000 +0200
@@ -156,9 +156,10 @@
                                        self.set_cb(cb, trigger_style, 1)
                                if full:
                                        
self.builder.get_object("sclFullLevel").set_value(full.press_level)
-                               if isinstance(analog, TriggerAction):
-                                       
self.builder.get_object("sclARangeStart").set_value(analog.press_level)
-                                       
self.builder.get_object("sclARangeEnd").set_value(analog.release_level)
+
+                               if isinstance(analog, AxisAction):
+                                       
self.builder.get_object("sclARangeStart").set_value(analog.min)
+                                       
self.builder.get_object("sclARangeEnd").set_value(analog.max)
                        
                        self._recursing = False
                self.update()
@@ -167,7 +168,7 @@
        def update(self):
                
self.builder.get_object("lblPartPressed").set_label(describe_action(Action.AC_BUTTON,
 ButtonAction, self.half))
                
self.builder.get_object("lblFullPressed").set_label(describe_action(Action.AC_BUTTON,
 ButtonAction, self.full))
-               
self.builder.get_object("lblAnalog").set_label(describe_action(Action.AC_BUTTON,
 AxisAction, self.analog))
+               
self.builder.get_object("lblAnalog").set_label(describe_action(Action.AC_TRIGGER,
 AxisAction, self.analog))
        
        
        def send(self):
@@ -197,9 +198,9 @@
                                analog_start = 
int(self.builder.get_object("sclARangeStart").get_value())
                                analog_end   = 
int(self.builder.get_object("sclARangeEnd").get_value())
                                if analog_start == TRIGGER_MIN and analog_end 
== TRIGGER_MAX:
-                                       actions.append(self.analog)
+                                       
actions.append(AxisAction(self.analog.id))
                                else:
-                                       
actions.append(TriggerAction(analog_start, analog_end, self.analog))
+                                       
actions.append(AxisAction(self.analog.id, analog_start, analog_end))
                
                self.editor.set_action(MultiAction.make(*actions))
        
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/gui/creg/dialog.py 
new/sc-controller-0.4.8.7/scc/gui/creg/dialog.py
--- old/sc-controller-0.4.8.6/scc/gui/creg/dialog.py    2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/gui/creg/dialog.py    2022-05-06 
18:39:50.000000000 +0200
@@ -460,7 +460,9 @@
                        ]
                        self._tester.start()
 
-               if dev.info.vendor == 0 and dev.info.product == 0:
+               # Check VID+PID info and whether HID driver support is enabled
+               if (dev.info.vendor == 0 and dev.info.product == 0 or
+                       not self.app.config["drivers"].get("hiddrv")):
                        # Not an USB device, skip HID test altogether
                        retry_with_evdev(None, 0)
                else:
@@ -740,7 +742,9 @@
                for fname in evdev.list_devices():
                        dev = evdev.InputDevice(fname)
                        is_gamepad = 
ControllerRegistration.does_he_looks_like_a_gamepad(dev)
-                       if not dev.phys:
+                       # bustype 3 is BUS_USB, which is the type used for 
emulated
+                       # gamepads. phys is blank for BUS_BLUETOOTH devices.
+                       if dev.info.bustype == 3 and not dev.phys:
                                # Skipping over virtual devices so list doesn't 
show
                                # gamepads emulated by SCC
                                continue
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/gui/menu_editor.py 
new/sc-controller-0.4.8.7/scc/gui/menu_editor.py
--- old/sc-controller-0.4.8.6/scc/gui/menu_editor.py    2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/gui/menu_editor.py    2022-05-06 
18:39:50.000000000 +0200
@@ -235,7 +235,7 @@
                
        
        def on_entName_changed(self, *a):
-               id = 
self.builder.get_object("entName").get_text().decode("utf-8")
+               id = self.builder.get_object("entName").get_text()
                if len(id.strip()) == 0:
                        self._bad_id_no_id()
                        return
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/lib/hidparse.py 
new/sc-controller-0.4.8.7/scc/lib/hidparse.py
--- old/sc-controller-0.4.8.6/scc/lib/hidparse.py       2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/lib/hidparse.py       2022-05-06 
18:39:50.000000000 +0200
@@ -70,7 +70,7 @@
        
        def __new__(cls, value):
                if value not in cls._CACHE:
-                       cls._CACHE[value] = object.__new__(cls, value)
+                       cls._CACHE[value] = object.__new__(cls)
                return cls._CACHE[value]
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/lib/xwrappers.py 
new/sc-controller-0.4.8.7/scc/lib/xwrappers.py
--- old/sc-controller-0.4.8.6/scc/lib/xwrappers.py      2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/lib/xwrappers.py      2022-05-06 
18:39:50.000000000 +0200
@@ -331,7 +331,7 @@
        Returns (nitems, property) of specified window or (-1, None) if 
anything fails.
        Returned 'property' is POINTER(c_void_p) and has to be freed using 
X.free().
        """
-       prop_atom = intern_atom(dpy, bytes(prop_name, "utf-8"), False)
+       prop_atom = intern_atom(dpy, prop_name, False)
        type_return, format_return = Atom(), Atom()
        nitems, bytes_after = c_ulong(), c_ulong()
        prop = c_void_p()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/mapper.py 
new/sc-controller-0.4.8.7/scc/mapper.py
--- old/sc-controller-0.4.8.6/scc/mapper.py     2021-09-09 20:00:13.000000000 
+0200
+++ new/sc-controller-0.4.8.7/scc/mapper.py     2022-05-06 18:39:50.000000000 
+0200
@@ -104,13 +104,34 @@
        
        
        def _rumble_ready(self, fd, event):
+               # Taken from Steam Controller Singer project
+               # https://gitlab.com/Pilatomic/SteamControllerSinger
+               STEAM_CONTROLLER_MAGIC_PERIOD_RATIO = 495483.0
                ef = self.gamepad.ff_read()
                if ef:  # tale of...
+                       period_command = 0
+                       amplitude = 0
+                       if ef.level != 0:
+                               tempRatio = ef.level / 32767.5
+                               period_command = ((6000 - 25000) * tempRatio + 
25000)
+                               amplitude = ((900 - 600) * tempRatio + 600);
+
+                       raw_period = period_command / 
STEAM_CONTROLLER_MAGIC_PERIOD_RATIO
+                       #duration_seconds = 1
+                       duration_seconds = ef.duration / 1000.0 * ef.repetitions
+                       count = 0
+                       if raw_period != 0:
+                               count = min(int(duration_seconds * 1.5 / 
raw_period), 0x7FFF)
+
+                       #log.debug(f"{ef.level} {ef.duration} {ef.repetitions} 
{count}")
                        self.send_feedback(HapticData(
                                HapticPos.BOTH,
-                               period = 32760,
-                               amplitude = max(0, ef.level),
-                               count = min(0x7FFF, ef.duration * 
ef.repetitions / 30)
+                               period = period_command,
+                               amplitude = amplitude,
+                               count = count,
+                               #period = 20000,
+                               #amplitude = max(0, ef.level),
+                               #count = min(0x7FFF, ef.duration * 
ef.repetitions / 30)
                        ))
        
        
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/modifiers.py 
new/sc-controller-0.4.8.7/scc/modifiers.py
--- old/sc-controller-0.4.8.6/scc/modifiers.py  2021-09-09 20:00:13.000000000 
+0200
+++ new/sc-controller-0.4.8.7/scc/modifiers.py  2022-05-06 18:39:50.000000000 
+0200
@@ -423,6 +423,10 @@
        
        def set_speed(self, x, y, *a):
                self.speed = (x, y)
+               if self.action and (isinstance(self.action, CircularModifier)
+                       and hasattr(self.action, "set_speed")):
+                       self.action.set_speed(x, y, *a)
+
                # Reset calculated x and y velocities
                self._xvel = 0.0
                self._yvel = 0.0
@@ -710,7 +714,20 @@
                
                angle = atan2(x, y)
                return distance * sin(angle), distance * cos(angle)
-       
+
+       def _convert_trigger_stick_range(self, position, trigger_range):
+               result = clamp(0,
+                   (position / trigger_range) * STICK_PAD_MAX,
+                   STICK_PAD_MAX)
+
+               return result
+
+       def _convert_stick_trigger_range(self, position):
+               result = clamp(0,
+                   (position / STICK_PAD_MAX) * TRIGGER_MAX,
+                   TRIGGER_MAX)
+
+               return result
        
        @staticmethod
        def decode(data, a, *b):
@@ -769,9 +786,19 @@
        
        
        def trigger(self, mapper, position, old_position):
-               position = self._convert(position, 0, TRIGGER_MAX)
+               # Need to convert trigger value to stick range for deadzone 
modifier
+               # calcs to work as intended
+               position = self._convert_trigger_stick_range(position, 
TRIGGER_MAX)
+
+               # Perform dead zone calculations
+               position = self._convert(position, 0, STICK_PAD_MAX)
+
+               # Convert calculated stick position value back to applicable
+               # position in trigger range
+               position = self._convert_stick_trigger_range(position[0])
+               # Invoke trigger action with new value
                return self.action.trigger(mapper, position, old_position)
-       
+
        
        def axis(self, mapper, position, what):
                position = self._convert(position, 0, STICK_PAD_MAX)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/osd/__init__.py 
new/sc-controller-0.4.8.7/scc/osd/__init__.py
--- old/sc-controller-0.4.8.6/scc/osd/__init__.py       2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scc/osd/__init__.py       2022-05-06 
18:39:50.000000000 +0200
@@ -37,7 +37,7 @@
        EPILOG = ""
        css_provider = None                     # Used by staticmethods
        
-       def __init__(self, wmclass):
+       def __init__(self, wmclass, layer = None):
                Gtk.Window.__init__(self)
                OSDWindow._apply_css(Config())
                
@@ -56,10 +56,13 @@
                        from gi.repository import GtkLayerShell
                        if GtkLayerShell.is_supported():
                                self.using_wlroots=True
+                               self.x_layer_anchor = GtkLayerShell.Edge.LEFT
+                               self.y_layer_anchor = GtkLayerShell.Edge.BOTTOM
                                GtkLayerShell.init_for_window(self)
-                               GtkLayerShell.set_layer(self, 
GtkLayerShell.Layer.TOP)
-                               GtkLayerShell.set_anchor(self, 
GtkLayerShell.Edge.LEFT, True)
-                               GtkLayerShell.set_anchor(self, 
GtkLayerShell.Edge.BOTTOM, True)
+                               GtkLayerShell.set_layer(self, layer if layer is 
not None else GtkLayerShell.Layer.TOP)
+                               GtkLayerShell.set_anchor(self, 
self.x_layer_anchor, True)
+                               GtkLayerShell.set_anchor(self, 
self.y_layer_anchor, True)
+                               self.layer_shell = GtkLayerShell
                except (ImportError):
                        pass
                if not self.using_wlroots:
@@ -210,12 +213,26 @@
                self.get_window().set_override_redirect(True)
                
                x, y = self.compute_position()
-               if x < 0:       # Negative X position is counted from right 
border
-                       x = Gdk.Screen.width() - self.get_allocated_width() + x 
+ 1
-               if y < 0:       # Negative Y position is counted from bottom 
border
-                       y = Gdk.Screen.height() - self.get_allocated_height() + 
y + 1
-               
-               self.move(x, y)
+               if self.using_wlroots:
+                       if x < 0:
+                               self.layer_shell.set_anchor(self, 
self.x_layer_anchor, False)
+                               self.x_layer_anchor = 
self.layer_shell.Edge.RIGHT
+                               self.layer_shell.set_anchor(self, 
self.x_layer_anchor, True)
+                               x = -x
+                       if y < 0:
+                               self.layer_shell.set_anchor(self, 
self.y_layer_anchor, False)
+                               self.y_layer_anchor = 
self.layer_shell.Edge.BOTTOM
+                               self.layer_shell.set_anchor(self, 
self.y_layer_anchor, True)
+                               y = -y
+                       self.layer_shell.set_margin(self, self.x_layer_anchor, 
x)
+                       self.layer_shell.set_margin(self, self.y_layer_anchor, 
y)
+               else: # X11
+                       if x < 0:       # Negative X position is counted from 
right border
+                               x = Gdk.Screen.width() - 
self.get_allocated_width() + x + 1
+                       if y < 0:       # Negative Y position is counted from 
bottom border
+                               y = Gdk.Screen.height() - 
self.get_allocated_height() + y + 1
+                       self.move(x, y)
+
                Gtk.Window.show(self)
                self.make_window_clicktrough()
        
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/osd/menu.py 
new/sc-controller-0.4.8.7/scc/osd/menu.py
--- old/sc-controller-0.4.8.6/scc/osd/menu.py   2021-09-09 20:00:13.000000000 
+0200
+++ new/sc-controller-0.4.8.7/scc/osd/menu.py   2022-05-06 18:39:50.000000000 
+0200
@@ -41,8 +41,8 @@
        PREFER_BW_ICONS = True
        
        
-       def __init__(self, cls="osd-menu"):
-               OSDWindow.__init__(self, cls)
+       def __init__(self, cls="osd-menu", layer = None):
+               OSDWindow.__init__(self, cls, layer)
                self.daemon = None
                self.config = None
                self.feedback = None
@@ -71,7 +71,6 @@
                self._confirm_with = 'A'
                self._cancel_with = 'B'
        
-       
        def set_is_submenu(self):
                """
                Marks menu as submenu. This changes behaviour of some methods,
@@ -468,13 +467,20 @@
                        self._selected = self._submenu._selected
                        self.quit(self._submenu.get_exit_code())
                self._submenu = None
+               if self.using_wlroots:
+                       self.layer_shell.set_layer(self, 
self.layer_shell.Layer.OVERLAY)
        
        
        def show_submenu(self, trash, trash2, trash3, menuitem):
                """ Called when user chooses menu item pointing to submenu """
                filename = find_menu(menuitem.filename)
                if filename:
-                       self._submenu = self.__class__()
+                       layer = None
+                       if self.using_wlroots:
+                               if self.layer_shell.is_supported(): 
+                                       layer = self.layer_shell.Layer.OVERLAY
+                                       self.layer_shell.set_layer(self, 
self.layer_shell.Layer.TOP)
+                       self._submenu = self.__class__(layer = layer)
                        sub_pos = list(self.position)
                        for i in (0, 1):
                                sub_pos[i] = (sub_pos[i] - self.SUBMENU_OFFSET
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/sccdaemon.py 
new/sc-controller-0.4.8.7/scc/sccdaemon.py
--- old/sc-controller-0.4.8.6/scc/sccdaemon.py  2021-09-09 20:00:13.000000000 
+0200
+++ new/sc-controller-0.4.8.7/scc/sccdaemon.py  2022-05-06 18:39:50.000000000 
+0200
@@ -328,7 +328,7 @@
        def on_sa_area(self, mapper, action, x1, y1, x2, y2):
                """ Called when *AreaAction has OSD enabled """
                with self.lock:
-                       self._osd('area', '-x', x1, '-y', y1, '--width', x2-x1, 
'--height', y2-y1)
+                       self._osd('area', '-x', str(x1), '-y', str(y1), 
'--width', str(x2-x1), '--height', str(y2-y1))
        
        
        def on_sa_clear_osd(self, *a):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scc/uinput.c 
new/sc-controller-0.4.8.7/scc/uinput.c
--- old/sc-controller-0.4.8.6/scc/uinput.c      2021-09-09 20:00:13.000000000 
+0200
+++ new/sc-controller-0.4.8.7/scc/uinput.c      2022-05-06 18:39:50.000000000 
+0200
@@ -401,11 +401,13 @@
                                                                        // 
supposed to play, effect properties are updated on the fly.
                                                                        if 
(!ff_effects[rv]->continuous_rumble) {
                                                                                
ff_effects[rv]->continuous_rumble = true;
+                                                                               
ff_effects[rv]->repetitions = 1;
                                                                                
RUMBLE_DEBUG("CONTINUOUS RUMBLE enabled on %i\n", rv);
                                                                        }
                                                                } else if 
(ff_effects[rv]->continuous_rumble) {
                                                                        
RUMBLE_DEBUG("CONTINUOUS RUMBLE disabled on %i\n", rv);
                                                                        
ff_effects[rv]->continuous_rumble = false;
+                                                                       
ff_effects[rv]->repetitions = 0;
                                                                }
                                                                
RUMBLE_DEBUG("FF_PLAY -> %i (type %i, lvl %i, dur. %i, reps. %i)\n", event.code,
                                                                        
ff_effects[rv]->type, ff_effects[rv]->level, ff_effects[rv]->duration,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/scripts/appimage-AppRun.sh 
new/sc-controller-0.4.8.7/scripts/appimage-AppRun.sh
--- old/sc-controller-0.4.8.6/scripts/appimage-AppRun.sh        2021-09-09 
20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/scripts/appimage-AppRun.sh        2022-05-06 
18:39:50.000000000 +0200
@@ -4,8 +4,8 @@
 export LD_LIBRARY_PATH=${APPDIR}/usr/lib64:$LD_LIBRARY_PATH
 export GI_TYPELIB_PATH=${APPDIR}/usr/lib/girepository-1.0
 export GDK_PIXBUF_MODULEDIR=${APPDIR}/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders
-export PYTHONPATH=${APPDIR}/usr/lib/python3.9/site-packages:$PYTHONPATH
-export PYTHONPATH=${APPDIR}/usr/lib64/python3.9/site-packages:$PYTHONPATH
+export PYTHONPATH=${APPDIR}/usr/lib/python3.10/site-packages:$PYTHONPATH
+export PYTHONPATH=${APPDIR}/usr/lib64/python3.10/site-packages:$PYTHONPATH
 export SCC_SHARED=${APPDIR}/usr/share/scc
 
 function dependency_check_failed() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sc-controller-0.4.8.6/setup.py 
new/sc-controller-0.4.8.7/setup.py
--- old/sc-controller-0.4.8.6/setup.py  2021-09-09 20:00:13.000000000 +0200
+++ new/sc-controller-0.4.8.7/setup.py  2022-05-06 18:39:50.000000000 +0200
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-from distutils.core import setup, Extension
+#!/usr/bin/env python3
+from setuptools import setup, Extension
 from scc.constants import DAEMON_VERSION
 import glob
 

Reply via email to