Support for Logitech MX Master Mice

Hi Andreas, I’m a very happy user of BetterTouchTool and was delighted to see your recent improvements to Logitech device support after the recent Logi Options+ oopsie.

I wanted to report some issues I’ve experienced when creating triggers for my MX Ergo mouse.

  • I can’t override the “Precision Mode” button that sits by the trackball. When pressed, it swaps between 2 DPI levels for the trackball (seemingly hardware-driven, as it works with no Logi software installed). I was able to override this button in Logi Options+, but cannot do so in BTT
  • Events for the left/right tilt of the scroll wheel come through as “Scroll Left” and “Scroll Right”. Unfortunately these overlap with Shift+scroll up/down behavior, which I use to actually scroll left and right (I override the wheel tilt behavior to do other things)

Here’s a Logitech debug log where I pressed each button in succession (if that matters?), precision mode, then left tilt, then right tilt.

Log
LOGI LOG: ========================================
LOGI LOG: BTT Logitech Debug Information
LOGI LOG: Timestamp: 2026-01-07 11:39:56
LOGI LOG: macOS: Version 26.1 (Build 25B78)
LOGI LOG: ========================================
LOGI LOG: 
LOGI LOG: Step 1: Stopping Logitech Manager...
LOGI LOG: BTTLogitechManager: Stopping...
LOGI LOG: BTTLogitechManager: Setting ONBOARD mode on 6 device(s) before shutdown...
LOGI LOG: BTTLogitechManager: ✅ ONBOARD mode set on 0 device(s), skipped 6 (shutdown complete)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88bf2f4e0 for deviceIndex 1 (remaining protocols for this device: 5)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 1)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88bf2f4e0 for deviceIndex 1 (remaining protocols for this device: 5)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 1)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88c8612c0 for deviceIndex 2 (remaining protocols for this device: 4)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 2)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88c8612c0 for deviceIndex 2 (remaining protocols for this device: 4)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 2)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88c861500 for deviceIndex 3 (remaining protocols for this device: 3)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 3)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88c861500 for deviceIndex 3 (remaining protocols for this device: 3)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 3)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88c861b60 for deviceIndex 4 (remaining protocols for this device: 2)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 4)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88c861b60 for deviceIndex 4 (remaining protocols for this device: 2)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 4)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88c863cc0 for deviceIndex 5 (remaining protocols for this device: 1)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 5)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88c863cc0 for deviceIndex 5 (remaining protocols for this device: 1)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 5)
LOGI LOG: BTTHIDPPProtocol: ❌ Unregistered protocol 0x88c861fe0 for deviceIndex 6 (remaining protocols for this device: 0)
LOGI LOG: BTTHIDPPProtocol: Last protocol for this device - will unregister callback
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 6)
LOGI LOG: BTTHIDPPProtocol: Skipping all IOKit cleanup (shared device for receiver slot 6)
LOGI LOG: BTTLogitechManager: Stopped
LOGI LOG: Step 2: Restarting Logitech Manager...
LOGI LOG: BTTLogitechManager: Starting device discovery...
LOGI LOG: BTTLogitechManager: Started successfully
LOGI LOG: Step 3: Calling initializeLogitechMice...
LOGI LOG: BTTLogitechManager: Already running
LOGI LOG: 
==============================================
LOGI LOG: BTTLogitechManager: Scanning for Logitech Devices
LOGI LOG: ==============================================

LOGI LOG: No Logitech HID++ devices found.
LOGI LOG: 
💡 Make sure your device is:
LOGI LOG:    • Connected via USB, Bluetooth, or Unifying Receiver
LOGI LOG:    • Powered on
LOGI LOG:    • Using HID++ 2.0 protocol (most recent Logitech mice/keyboards)
LOGI LOG: Step 4: Waiting 5 seconds for device initialization...
LOGI LOG: BTTLogitechManager: Found HID interface - USB Receiver - Interface: 1, Usage Page: 0x0001, Usage: 0x0002
LOGI LOG: BTTLogitechManager: Skipping interface (Usage Page: 0x0001, Usage: 0x0002, Interface: 1)
LOGI LOG: BTTLogitechManager: Found HID interface - USB Receiver - Interface: 0, Usage Page: 0x0001, Usage: 0x0006
LOGI LOG: BTTLogitechManager: Skipping interface (Usage Page: 0x0001, Usage: 0x0006, Interface: 0)
LOGI LOG: BTTLogitechManager: Found HID interface - USB Receiver - Interface: 2, Usage Page: 0xFF00, Usage: 0x0001
LOGI LOG: BTTLogitechManager: ✅ Accepted - Vendor-specific HID++ interface (Interface 2)
LOGI LOG: BTTLogitechManager: Device connected - USB Receiver (046d:c52b)
LOGI LOG: BTTLogitechManager: 🔌 Receiver detected - setting up for slot enumeration...
LOGI LOG: BTTLogitechManager: Setting up receiver input callbacks...
LOGI LOG: BTTLogitechManager: ✓ Receiver callbacks registered and device opened
LOGI LOG: BTTLogitechManager: Enabling receiver notifications (flags: 0x000900)...
LOGI LOG: BTTLogitechManager: Sent HID++ 1.0 command: 10 FF 80 00 00 09 00
LOGI LOG: BTTLogitechManager: Enumerating receiver slots (simplified approach)...
LOGI LOG: BTTLogitechManager: Starting sequential slot enumeration (slots 1-6)...
LOGI LOG: BTTLogitechManager: Checking receiver slot 1...
LOGI LOG: BTTLogitechManager: Creating device for receiver slot 1...
LOGI LOG: BTTLogitechManager: Receiver retain count for slot 1: 3
LOGI LOG: BTTHIDPPDevice: Initializing with deviceIndex=1, IOHIDDevice retain count=3
LOGI LOG: BTTHIDPPDevice: Receiver slot 1 - using receiver IDs: 046d:c52b
LOGI LOG: Unknown device: USB Receiver (Slot) (046d:c52b) - using feature discovery, deviceIndex: 1, transport: USB
LOGI LOG: BTTHIDPPProtocol: Starting protocol (deviceIndex: 1, isSharedDevice: 1)...
LOGI LOG: BTTHIDPPProtocol: ✅ Registered protocol 0x88990f900 for deviceIndex 1 (total protocols for this device: 1)
LOGI LOG: BTTHIDPPProtocol: Shared device - skipping open/schedule (already done by receiver setup)
LOGI LOG: BTTHIDPPProtocol: First protocol for this receiver - registering shared input callback
LOGI LOG: BTTHIDPPProtocol: Supports short reports: YES, long reports: YES
LOGI LOG: BTTLogitechManager: Created device for slot 1, discovering features...
LOGI LOG: BTTHIDPPFeatureCache: ✅ Found cached features for 046d:c52b:slot1 (cached 2026-01-07 17:06:57 +0000)
LOGI LOG: BTTHIDPPDevice: ⚡ Using cached features for USB Receiver (Slot) (36 features)
LOGI LOG: BTTHIDPPProtocol: Pre-populated feature cache with 36 features
LOGI LOG: BTTHIDPPDevice: Cached protocol: 4.5
LOGI LOG: BTTHIDPPProtocol: ✅ Registered event handler for feature 0x1B04 (protocol 0x88990f900, deviceIndex 1)
LOGI LOG:    Total event handlers registered: 1
LOGI LOG: Button Manager supported
LOGI LOG: Battery Monitor supported
LOGI LOG: Checking scroll wheel features...
LOGI LOG:   SmartShift (0x2110): ❌ NO
LOGI LOG:   SmartShift Enhanced (0x2111): ❌ NO
LOGI LOG:   HiRes Wheel (0x2121): ❌ NO
LOGI LOG:   Thumbwheel (0x2150): ❌ NO
LOGI LOG:   Wheel Analytics (0x2250): ❌ NO
LOGI LOG:   Wheel Mode Status (0x2251): ❌ NO
LOGI LOG: No scroll wheel features supported
LOGI LOG: Pointer Speed Manager initialized (0x2205)
LOGI LOG: BTTHIDPPDevice: Device type confirmed as MOUSE (has mouse-specific features)
LOGI LOG: Applying default device configuration...
LOGI LOG: 🔍 Attempting to query device name via HID++ feature 0x0005...
LOGI LOG: ✅ Device supports feature 0x0005, querying name length...
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x03, address=0x08
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x03, func=0x00)
LOGI LOG: Device name length: 31 bytes
LOGI LOG: Reading device name chunk at offset 0/31...
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x03, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x03, func=0x01)
LOGI LOG: Read 16 bytes: "MX Ergo Multi-De"
LOGI LOG: Reading device name chunk at offset 16/31...
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x03, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x03, func=0x01)
LOGI LOG: Read 15 bytes: "vice Trackball "
LOGI LOG: 📝 Device name assembled: "MX Ergo Multi-Device Trackball " (31 bytes)
LOGI LOG: ✅ Device name from HID++: MX Ergo Multi-Device Trackball 
LOGI LOG: BTTLogitechManager: 📝 Device name updated to: MX Ergo Multi-Device Trackball 
LOGI LOG: BTTLogitechManager: ✅ Device ready - MX Ergo Multi-Device Trackball  (Protocol 4.5)
LOGI LOG: BTTLogitechManager: ✅ Device ready in slot 1 - MX Ergo Multi-Device Trackball  (Protocol 4.5)
LOGI LOG: BTTLogitechManager: Checking receiver slot 2...
LOGI LOG: BTTHIDPPProtocol: ❌ No protocol instance found for device index 255 (0xFF), reportID=0x10
LOGI LOG: BTTHIDPPProtocol: Registry has 1 protocols for this device: (
    1
)
LOGI LOG:    - Device index 1 → protocol 0x88990f900
LOGI LOG: BTTLogitechManager: Creating device for receiver slot 2...
LOGI LOG: BTTLogitechManager: Receiver retain count for slot 2: 5
LOGI LOG: BTTHIDPPDevice: Initializing with deviceIndex=2, IOHIDDevice retain count=5
LOGI LOG: BTTHIDPPDevice: Receiver slot 2 - using receiver IDs: 046d:c52b
LOGI LOG: Unknown device: USB Receiver (Slot) (046d:c52b) - using feature discovery, deviceIndex: 2, transport: USB
LOGI LOG: BTTHIDPPProtocol: Starting protocol (deviceIndex: 2, isSharedDevice: 1)...
LOGI LOG: BTTHIDPPProtocol: ✅ Registered protocol 0x88990f660 for deviceIndex 2 (total protocols for this device: 2)
LOGI LOG: BTTHIDPPProtocol: Shared device - skipping open/schedule (already done by receiver setup)
LOGI LOG: BTTHIDPPProtocol: Input callback already registered by another slot - reusing it
LOGI LOG: BTTHIDPPProtocol: Supports short reports: YES, long reports: YES
LOGI LOG: BTTLogitechManager: Created device for slot 2, discovering features...
LOGI LOG: BTTHIDPPFeatureCache: ❌ No cached features for 046d:c52b:slot2
LOGI LOG: BTTHIDPPDevice: 🔍 No cached features for USB Receiver (Slot), performing full discovery...
LOGI LOG: BTTHIDPPProtocol: Detecting protocol version (deviceIndex: 2)...
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x02, sub_id(featureIdx)=0x8F, address=0x00
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ❌ Protocol version detection failed: HID++ error: 0x09
LOGI LOG: BTTLogitechManager: ❌ Feature discovery failed for slot 2: HID++ error: 0x09
LOGI LOG: BTTLogitechManager: Checking receiver slot 3...
LOGI LOG: BTTHIDPPProtocol: ❌ No protocol instance found for device index 255 (0xFF), reportID=0x11
LOGI LOG: BTTHIDPPProtocol: Registry has 2 protocols for this device: (
    1,
    2
)
LOGI LOG:    - Device index 1 → protocol 0x88990f900
LOGI LOG:    - Device index 2 → protocol 0x88990f660
LOGI LOG: BTTLogitechManager: Creating device for receiver slot 3...
LOGI LOG: BTTLogitechManager: Receiver retain count for slot 3: 7
LOGI LOG: BTTHIDPPDevice: Initializing with deviceIndex=3, IOHIDDevice retain count=7
LOGI LOG: BTTHIDPPDevice: Receiver slot 3 - using receiver IDs: 046d:c52b
LOGI LOG: Unknown device: USB Receiver (Slot) (046d:c52b) - using feature discovery, deviceIndex: 3, transport: USB
LOGI LOG: BTTHIDPPProtocol: Starting protocol (deviceIndex: 3, isSharedDevice: 1)...
LOGI LOG: BTTHIDPPProtocol: ✅ Registered protocol 0x88990f5a0 for deviceIndex 3 (total protocols for this device: 3)
LOGI LOG: BTTHIDPPProtocol: Shared device - skipping open/schedule (already done by receiver setup)
LOGI LOG: BTTHIDPPProtocol: Input callback already registered by another slot - reusing it
LOGI LOG: BTTHIDPPProtocol: Supports short reports: YES, long reports: YES
LOGI LOG: BTTLogitechManager: Created device for slot 3, discovering features...
LOGI LOG: BTTHIDPPFeatureCache: ❌ No cached features for 046d:c52b:slot3
LOGI LOG: BTTHIDPPDevice: 🔍 No cached features for USB Receiver (Slot), performing full discovery...
LOGI LOG: BTTHIDPPProtocol: Detecting protocol version (deviceIndex: 3)...
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x03, sub_id(featureIdx)=0x8F, address=0x00
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ❌ Protocol version detection failed: HID++ error: 0x09
LOGI LOG: BTTLogitechManager: ❌ Feature discovery failed for slot 3: HID++ error: 0x09
LOGI LOG: BTTLogitechManager: Checking receiver slot 4...
LOGI LOG: BTTHIDPPProtocol: ❌ No protocol instance found for device index 255 (0xFF), reportID=0x11
LOGI LOG: BTTHIDPPProtocol: Registry has 3 protocols for this device: (
    3,
    1,
    2
)
LOGI LOG:    - Device index 3 → protocol 0x88990f5a0
LOGI LOG:    - Device index 1 → protocol 0x88990f900
LOGI LOG:    - Device index 2 → protocol 0x88990f660
LOGI LOG: BTTLogitechManager: Creating device for receiver slot 4...
LOGI LOG: BTTLogitechManager: Receiver retain count for slot 4: 9
LOGI LOG: BTTHIDPPDevice: Initializing with deviceIndex=4, IOHIDDevice retain count=9
LOGI LOG: BTTHIDPPDevice: Receiver slot 4 - using receiver IDs: 046d:c52b
LOGI LOG: Unknown device: USB Receiver (Slot) (046d:c52b) - using feature discovery, deviceIndex: 4, transport: USB
LOGI LOG: BTTHIDPPProtocol: Starting protocol (deviceIndex: 4, isSharedDevice: 1)...
LOGI LOG: BTTHIDPPProtocol: ✅ Registered protocol 0x88990f7e0 for deviceIndex 4 (total protocols for this device: 4)
LOGI LOG: BTTHIDPPProtocol: Shared device - skipping open/schedule (already done by receiver setup)
LOGI LOG: BTTHIDPPProtocol: Input callback already registered by another slot - reusing it
LOGI LOG: BTTHIDPPProtocol: Supports short reports: YES, long reports: YES
LOGI LOG: BTTLogitechManager: Created device for slot 4, discovering features...
LOGI LOG: BTTHIDPPFeatureCache: ❌ No cached features for 046d:c52b:slot4
LOGI LOG: BTTHIDPPDevice: 🔍 No cached features for USB Receiver (Slot), performing full discovery...
LOGI LOG: BTTHIDPPProtocol: Detecting protocol version (deviceIndex: 4)...
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x04, sub_id(featureIdx)=0x8F, address=0x00
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ❌ Protocol version detection failed: HID++ error: 0x09
LOGI LOG: BTTLogitechManager: ❌ Feature discovery failed for slot 4: HID++ error: 0x09
LOGI LOG: BTTLogitechManager: Checking receiver slot 5...
LOGI LOG: BTTHIDPPProtocol: ❌ No protocol instance found for device index 255 (0xFF), reportID=0x10
LOGI LOG: BTTHIDPPProtocol: Registry has 4 protocols for this device: (
    3,
    2,
    1,
    4
)
LOGI LOG:    - Device index 3 → protocol 0x88990f5a0
LOGI LOG:    - Device index 2 → protocol 0x88990f660
LOGI LOG:    - Device index 1 → protocol 0x88990f900
LOGI LOG:    - Device index 4 → protocol 0x88990f7e0
LOGI LOG: BTTLogitechManager: Creating device for receiver slot 5...
LOGI LOG: BTTLogitechManager: Receiver retain count for slot 5: 11
LOGI LOG: BTTHIDPPDevice: Initializing with deviceIndex=5, IOHIDDevice retain count=11
LOGI LOG: BTTHIDPPDevice: Receiver slot 5 - using receiver IDs: 046d:c52b
LOGI LOG: Unknown device: USB Receiver (Slot) (046d:c52b) - using feature discovery, deviceIndex: 5, transport: USB
LOGI LOG: BTTHIDPPProtocol: Starting protocol (deviceIndex: 5, isSharedDevice: 1)...
LOGI LOG: BTTHIDPPProtocol: ✅ Registered protocol 0x8899ca040 for deviceIndex 5 (total protocols for this device: 5)
LOGI LOG: BTTHIDPPProtocol: Shared device - skipping open/schedule (already done by receiver setup)
LOGI LOG: BTTHIDPPProtocol: Input callback already registered by another slot - reusing it
LOGI LOG: BTTHIDPPProtocol: Supports short reports: YES, long reports: YES
LOGI LOG: BTTLogitechManager: Created device for slot 5, discovering features...
LOGI LOG: BTTHIDPPFeatureCache: ❌ No cached features for 046d:c52b:slot5
LOGI LOG: BTTHIDPPDevice: 🔍 No cached features for USB Receiver (Slot), performing full discovery...
LOGI LOG: BTTHIDPPProtocol: Detecting protocol version (deviceIndex: 5)...
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x05, sub_id(featureIdx)=0x8F, address=0x00
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ❌ Protocol version detection failed: HID++ error: 0x09
LOGI LOG: BTTLogitechManager: ❌ Feature discovery failed for slot 5: HID++ error: 0x09
LOGI LOG: BTTLogitechManager: Checking receiver slot 6...
LOGI LOG: BTTHIDPPProtocol: ❌ No protocol instance found for device index 255 (0xFF), reportID=0x10
LOGI LOG: BTTHIDPPProtocol: Registry has 5 protocols for this device: (
    3,
    2,
    5,
    1,
    4
)
LOGI LOG:    - Device index 3 → protocol 0x88990f5a0
LOGI LOG:    - Device index 2 → protocol 0x88990f660
LOGI LOG:    - Device index 5 → protocol 0x8899ca040
LOGI LOG:    - Device index 1 → protocol 0x88990f900
LOGI LOG:    - Device index 4 → protocol 0x88990f7e0
LOGI LOG: BTTLogitechManager: Creating device for receiver slot 6...
LOGI LOG: BTTLogitechManager: Receiver retain count for slot 6: 13
LOGI LOG: BTTHIDPPDevice: Initializing with deviceIndex=6, IOHIDDevice retain count=13
LOGI LOG: BTTHIDPPDevice: Receiver slot 6 - using receiver IDs: 046d:c52b
LOGI LOG: Unknown device: USB Receiver (Slot) (046d:c52b) - using feature discovery, deviceIndex: 6, transport: USB
LOGI LOG: BTTHIDPPProtocol: Starting protocol (deviceIndex: 6, isSharedDevice: 1)...
LOGI LOG: BTTHIDPPProtocol: ✅ Registered protocol 0x88990f840 for deviceIndex 6 (total protocols for this device: 6)
LOGI LOG: BTTHIDPPProtocol: Shared device - skipping open/schedule (already done by receiver setup)
LOGI LOG: BTTHIDPPProtocol: Input callback already registered by another slot - reusing it
LOGI LOG: BTTHIDPPProtocol: Supports short reports: YES, long reports: YES
LOGI LOG: BTTLogitechManager: Created device for slot 6, discovering features...
LOGI LOG: BTTHIDPPFeatureCache: ❌ No cached features for 046d:c52b:slot6
LOGI LOG: BTTHIDPPDevice: 🔍 No cached features for USB Receiver (Slot), performing full discovery...
LOGI LOG: BTTHIDPPProtocol: Detecting protocol version (deviceIndex: 6)...
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x06, sub_id(featureIdx)=0x8F, address=0x00
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ❌ Protocol version detection failed: HID++ error: 0x09
LOGI LOG: BTTLogitechManager: ❌ Feature discovery failed for slot 6: HID++ error: 0x09
LOGI LOG: BTTLogitechManager: ✅ Finished enumerating all receiver slots
LOGI LOG: BTTLogitechManager: ✅ Set macOS pointer settings for 'MX Ergo Multi-Device Trackball ' (IOHIDDevice: 0x046D:0xC52B): speed=0.50, accel=10.00
LOGI LOG: BTTLogitechManager: Quick setup for 'MX Ergo Multi-Device Trackball '...
LOGI LOG: BTTLogitechManager: ✅ Device 'MX Ergo Multi-Device Trackball ' is ready, proceeding with quick setup
LOGI LOG: BTTLogitechManager: No scroll wheel manager, skipping hi-res scroll
LOGI LOG: BTTLogitechManager: No scroll wheel manager, skipping scroll wheel un-divert
LOGI LOG: BTTLogitechManager: ❌ Device 'MX Ergo Multi-Device Trackball ' does not support DPI control
LOGI LOG: BTTLogitechManager: ⚠️  DPI setup failed: Device 'MX Ergo Multi-Device Trackball ' does not support DPI control
LOGI LOG: BTTLogitechManager: ❌ Device 'MX Ergo Multi-Device Trackball ' does not support report rate control
LOGI LOG: BTTLogitechManager: ⚠️  Report rate setup failed: Device 'MX Ergo Multi-Device Trackball ' does not support report rate control
LOGI LOG: BTTLogitechManager: ✅ Quick setup complete for 'MX Ergo Multi-Device Trackball '
LOGI LOG: BTTLogitechManager: Already running
LOGI LOG: 
==============================================
LOGI LOG: BTTLogitechManager: Scanning for Logitech Devices
LOGI LOG: ==============================================

LOGI LOG: Found 1 Logitech device(s):

LOGI LOG: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LOGI LOG: Device 1: MX Ergo Multi-Device Trackball 
LOGI LOG: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LOGI LOG: 📋 Basic Information:
LOGI LOG:    Vendor ID:     0x046d (Logitech)
LOGI LOG:    Product ID:    0xc52b
LOGI LOG:    Database:      ⚠️  Unknown device (will use feature discovery)
LOGI LOG:    Device Index:  1 (0x01)
LOGI LOG: 
🔌 Protocol Information:
LOGI LOG:    HID++ Version: 4.5
LOGI LOG:    Status:        ✅ Ready
LOGI LOG: 
✨ Supported Features:
LOGI LOG:    DPI Control:         ❌ NO
LOGI LOG:    Button Diversion:    ✅ YES ⭐
LOGI LOG:    LED Control:         ❌ NO
LOGI LOG:    Onboard Profiles:    ❌ NO
LOGI LOG:    Report Rate:         ❌ NO
LOGI LOG:    Battery Monitoring:  ✅ YES
LOGI LOG: 
LOGI LOG: ==============================================
LOGI LOG: Scan complete. Found 1 device(s).
LOGI LOG: ==============================================

LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x08
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 2 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x00)
LOGI LOG: BTTHIDPPButtonManager: 📊 Device reports 9 keys/buttons to enumerate
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x08, address=0x08
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 2 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x08, func=0x00)
LOGI LOG: 
🔋 Battery:
LOGI LOG:    Level:        50%
LOGI LOG:    Status:       Discharging
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x01)
LOGI LOG: BTTHIDPPButtonManager: 📋 [0] Key/Button 0x0050: flags=0x11 [MouseBtn|Reprog] divertable=0 virtual=0
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x28
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x02)
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x01)
LOGI LOG: BTTHIDPPButtonManager: 📋 [1] Key/Button 0x0051: flags=0x11 [MouseBtn|Reprog] divertable=0 virtual=0
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x28
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x02)
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x01)
LOGI LOG: BTTHIDPPButtonManager: 📋 [2] Key/Button 0x0052: flags=0x71 [MouseBtn|Reprog|DIVERT|Persist] divertable=1 virtual=0
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x28
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x02)
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x01)
LOGI LOG: BTTHIDPPButtonManager: 📋 [3] Key/Button 0x0053: flags=0x71 [MouseBtn|Reprog|DIVERT|Persist] divertable=1 virtual=0
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x28
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x02)
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x01)
LOGI LOG: BTTHIDPPButtonManager: 📋 [4] Key/Button 0x0056: flags=0x71 [MouseBtn|Reprog|DIVERT|Persist] divertable=1 virtual=0
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x28
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x02)
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x01)
LOGI LOG: BTTHIDPPButtonManager: 📋 [5] Key/Button 0x00ED: flags=0x71 [MouseBtn|Reprog|DIVERT|Persist] divertable=1 virtual=0
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x28
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x02)
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x01)
LOGI LOG: BTTHIDPPButtonManager: 📋 [6] Key/Button 0x005B: flags=0x71 [MouseBtn|Reprog|DIVERT|Persist] divertable=1 virtual=0
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x28
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x02)
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x01)
LOGI LOG: BTTHIDPPButtonManager: 📋 [7] Key/Button 0x005D: flags=0x71 [MouseBtn|Reprog|DIVERT|Persist] divertable=1 virtual=0
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x28
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x02)
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x18
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x01)
LOGI LOG: BTTHIDPPButtonManager: 📋 [8] Key/Button 0x00D7: flags=0xA0 [DIVERT|VIRTUAL] divertable=1 virtual=1
LOGI LOG: BTTHIDPPProtocol: 🔍 INCOMING MESSAGE: deviceIdx=0x01, sub_id(featureIdx)=0x0A, address=0x28
LOGI LOG: BTTHIDPPProtocol: 🔍 Checking 1 pending requests for match
LOGI LOG: BTTHIDPPProtocol: ✅ Matched to pending request (feat=0x0A, func=0x02)
LOGI LOG: 
🖱️  Buttons:
LOGI LOG:    Total:        9 buttons
LOGI LOG:    Available for diversion:
LOGI LOG:       Button at position 0 (controlId: 0x0050)
LOGI LOG:       Button at position 0 (controlId: 0x0051)
LOGI LOG:       Button at position 0 (controlId: 0x0052)
LOGI LOG:       Button at position 0 (controlId: 0x0053)
LOGI LOG:       Button at position 0 (controlId: 0x0056)
LOGI LOG:       Button at position 0 (controlId: 0x00ED)
LOGI LOG:       Button at position 0 (controlId: 0x005B)
LOGI LOG:       Button at position 0 (controlId: 0x005D)
LOGI LOG:       Button at position 0 (controlId: 0x00D7)
LOGI LOG: BTTLogitechManager: ✅ Set macOS pointer settings for 'MX Ergo Multi-Device Trackball ' (IOHIDDevice: 0x046D:0xC52B): speed=0.50, accel=10.00
LOGI LOG: BTTLogitechManager: Quick setup for 'MX Ergo Multi-Device Trackball '...
LOGI LOG: BTTLogitechManager: ✅ Device 'MX Ergo Multi-Device Trackball ' is ready, proceeding with quick setup
LOGI LOG: BTTLogitechManager: No scroll wheel manager, skipping hi-res scroll
LOGI LOG: BTTLogitechManager: No scroll wheel manager, skipping scroll wheel un-divert
LOGI LOG: BTTLogitechManager: ❌ Device 'MX Ergo Multi-Device Trackball ' does not support DPI control
LOGI LOG: BTTLogitechManager: ⚠️  DPI setup failed: Device 'MX Ergo Multi-Device Trackball ' does not support DPI control
LOGI LOG: BTTLogitechManager: ❌ Device 'MX Ergo Multi-Device Trackball ' does not support report rate control
LOGI LOG: BTTLogitechManager: ⚠️  Report rate setup failed: Device 'MX Ergo Multi-Device Trackball ' does not support report rate control
LOGI LOG: BTTLogitechManager: ✅ Quick setup complete for 'MX Ergo Multi-Device Trackball '
LOGI LOG: 
LOGI LOG: ========================================
LOGI LOG: Connected Devices Summary:
LOGI LOG: ========================================
LOGI LOG:   - MX Ergo Multi-Device Trackball  (VID:0x046d PID:0xc52b) Ready:YES Type:Mouse
LOGI LOG:   - USB Receiver (Slot) (VID:0x046d PID:0xc52b) Ready:NO Type:Mouse
LOGI LOG:   - USB Receiver (Slot) (VID:0x046d PID:0xc52b) Ready:NO Type:Mouse
LOGI LOG:   - USB Receiver (Slot) (VID:0x046d PID:0xc52b) Ready:NO Type:Mouse
LOGI LOG:   - USB Receiver (Slot) (VID:0x046d PID:0xc52b) Ready:NO Type:Mouse
LOGI LOG:   - USB Receiver (Slot) (VID:0x046d PID:0xc52b) Ready:NO Type:Mouse
LOGI LOG: ========================================
LOGI LOG: End of Debug Information
LOGI LOG: ========================================

After turning some settings off and on (like the high level mouse event recognition) and restarting BTT a couple times, now the Left Tilt comes through as Button 7 and no longer conflicts with Scroll Left. Right Tilt still always comes through as Scroll Right, though. I can’t find any way to manually select Button 7, etc, as a trigger unfortunately.