device: Add PRO X 2 Superstrike mouse support with HITS tuning settings (#3132)
* feat: PRO X 2 Superstrike support with click haptics, actuation point and rapid trigger config support * feat: PRO X 2 Superstrike docs * docs: document PRO X 2 Superstrike features, device entry, and capabilities * fix: code review points # Conflicts: # lib/logitech_receiver/hidpp20_constants.py * Fix the write_key_value for dpi_extended I was playing with the branch from the MR and I wanted to fix the cli stuff, it now properly sets when I use: solaar config 1 dpi_extended X 400 Should be enough Signed-off-by: Shane Fagan <mail@shanefagan.com> * Fix ruff style check --------- Signed-off-by: Shane Fagan <mail@shanefagan.com> Co-authored-by: Shane Fagan <mail@shanefagan.com>
This commit is contained in:
parent
99a403c554
commit
5478224cfa
|
|
@ -0,0 +1,374 @@
|
||||||
|
# Logitech PRO X 2 Superstrike - Solaar CLI Reference
|
||||||
|
|
||||||
|
This document describes all available settings for the Logitech PRO X 2 Superstrike mouse via the Solaar CLI.
|
||||||
|
|
||||||
|
## Device Identification
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| Name | PRO X 2 Superstrike |
|
||||||
|
| WPID | 40BD |
|
||||||
|
| Protocol | HID++ 4.2 |
|
||||||
|
| Kind | mouse |
|
||||||
|
|
||||||
|
## General CLI Syntax
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List all settings for device
|
||||||
|
solaar config <device>
|
||||||
|
|
||||||
|
# Read a specific setting
|
||||||
|
solaar config <device> <setting-name>
|
||||||
|
|
||||||
|
# Write a specific setting
|
||||||
|
solaar config <device> <setting-name> <value>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `<device>` can be:
|
||||||
|
- Device number (e.g., `1`)
|
||||||
|
- Device name (e.g., `"PRO X 2 Superstrike"`)
|
||||||
|
- Serial number (e.g., `A1C55DB2`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Available Settings
|
||||||
|
|
||||||
|
### 1. Onboard Profiles
|
||||||
|
|
||||||
|
Controls whether the device uses its onboard profile or host-controlled settings.
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| Setting Name | `onboard_profiles` |
|
||||||
|
| Type | Choice |
|
||||||
|
| Possible Values | `Disabled`, `Profile 1` |
|
||||||
|
|
||||||
|
**Commands:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Read current value
|
||||||
|
solaar config 1 onboard_profiles
|
||||||
|
|
||||||
|
# Set to disabled (allows host control of DPI, report rate, etc.)
|
||||||
|
solaar config 1 onboard_profiles Disabled
|
||||||
|
|
||||||
|
# Set to Profile 1 (use onboard profile)
|
||||||
|
solaar config 1 onboard_profiles "Profile 1"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Many settings require `onboard_profiles` to be set to `Disabled` to be effective.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Report Rate
|
||||||
|
|
||||||
|
Controls the frequency of device movement reports.
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| Setting Name | `report_rate_extended` |
|
||||||
|
| Type | Choice |
|
||||||
|
| Possible Values | `8ms`, `4ms`, `2ms`, `1ms`, `500us`, `250us`, `125us` |
|
||||||
|
|
||||||
|
**Commands:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Read current value
|
||||||
|
solaar config 1 report_rate_extended
|
||||||
|
|
||||||
|
# Set to 1ms (1000Hz)
|
||||||
|
solaar config 1 report_rate_extended 1ms
|
||||||
|
|
||||||
|
# Set to 500us (2000Hz)
|
||||||
|
solaar config 1 report_rate_extended 500us
|
||||||
|
|
||||||
|
# Set to 125us (8000Hz)
|
||||||
|
solaar config 1 report_rate_extended 125us
|
||||||
|
```
|
||||||
|
|
||||||
|
**Polling Rate Reference:**
|
||||||
|
|
||||||
|
| Value | Polling Rate |
|
||||||
|
|-------|--------------|
|
||||||
|
| `8ms` | 125 Hz |
|
||||||
|
| `4ms` | 250 Hz |
|
||||||
|
| `2ms` | 500 Hz |
|
||||||
|
| `1ms` | 1000 Hz |
|
||||||
|
| `500us` | 2000 Hz |
|
||||||
|
| `250us` | 4000 Hz |
|
||||||
|
| `125us` | 8000 Hz |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Sensitivity (DPI)
|
||||||
|
|
||||||
|
Controls mouse movement sensitivity.
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| Setting Name | `dpi_extended` |
|
||||||
|
| Type | Complex (X, Y, LOD) |
|
||||||
|
| DPI Range | 100 - 32000 |
|
||||||
|
| LOD Values | `LOW`, `HIGH` |
|
||||||
|
|
||||||
|
**Commands:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Read current value
|
||||||
|
solaar config 1 dpi_extended
|
||||||
|
|
||||||
|
# Set DPI (format: {X:<value>, Y:<value>, LOD:<value>})
|
||||||
|
solaar config 1 dpi_extended "{X:800, Y:800, LOD:HIGH}"
|
||||||
|
|
||||||
|
# Set to 1600 DPI
|
||||||
|
solaar config 1 dpi_extended "{X:1600, Y:1600, LOD:HIGH}"
|
||||||
|
|
||||||
|
# Set different X and Y sensitivity
|
||||||
|
solaar config 1 dpi_extended "{X:800, Y:1600, LOD:LOW}"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## HITS Tuning Settings (Hall-Effect Inductive Trigger Switch)
|
||||||
|
|
||||||
|
These settings control the advanced click behavior of the PRO X 2 Superstrike's hall-effect switches.
|
||||||
|
|
||||||
|
### 4. Actuation Point
|
||||||
|
|
||||||
|
Controls how deep the button must be pressed to register a click.
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| Setting Name (Left) | `superstrike-tuning_actuation-0` |
|
||||||
|
| Setting Name (Right) | `superstrike-tuning_actuation-1` |
|
||||||
|
| Type | Range |
|
||||||
|
| Range | 1 - 10 |
|
||||||
|
| Default | 5 |
|
||||||
|
|
||||||
|
**Value Interpretation:**
|
||||||
|
- `1` = Shallowest (hair trigger, minimal press)
|
||||||
|
- `10` = Deepest (full press required)
|
||||||
|
|
||||||
|
**Commands:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Read left button actuation
|
||||||
|
solaar config 1 superstrike-tuning_actuation-0
|
||||||
|
|
||||||
|
# Read right button actuation
|
||||||
|
solaar config 1 superstrike-tuning_actuation-1
|
||||||
|
|
||||||
|
# Set left button to shallow actuation (hair trigger)
|
||||||
|
solaar config 1 superstrike-tuning_actuation-0 1
|
||||||
|
|
||||||
|
# Set left button to deep actuation
|
||||||
|
solaar config 1 superstrike-tuning_actuation-0 10
|
||||||
|
|
||||||
|
# Set right button to medium actuation
|
||||||
|
solaar config 1 superstrike-tuning_actuation-1 5
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Rapid Trigger Level
|
||||||
|
|
||||||
|
Controls the rapid trigger sensitivity, which allows the button to re-actuate quickly after partial release.
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| Setting Name (Left) | `superstrike-tuning_rapid-trigger-level-0` |
|
||||||
|
| Setting Name (Right) | `superstrike-tuning_rapid-trigger-level-1` |
|
||||||
|
| Type | Range |
|
||||||
|
| Range | 1 - 5 |
|
||||||
|
| Default | 3 |
|
||||||
|
|
||||||
|
**Value Interpretation:**
|
||||||
|
- `1` = Fastest (most sensitive, smallest movement to re-trigger)
|
||||||
|
- `5` = Slowest (least sensitive, larger movement needed)
|
||||||
|
|
||||||
|
**Note:** Rapid trigger cannot be disabled on this device. The minimum level is 1.
|
||||||
|
|
||||||
|
**Commands:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Read left button rapid trigger level
|
||||||
|
solaar config 1 superstrike-tuning_rapid-trigger-level-0
|
||||||
|
|
||||||
|
# Read right button rapid trigger level
|
||||||
|
solaar config 1 superstrike-tuning_rapid-trigger-level-1
|
||||||
|
|
||||||
|
# Set left button to fastest rapid trigger
|
||||||
|
solaar config 1 superstrike-tuning_rapid-trigger-level-0 1
|
||||||
|
|
||||||
|
# Set left button to slowest rapid trigger
|
||||||
|
solaar config 1 superstrike-tuning_rapid-trigger-level-0 5
|
||||||
|
|
||||||
|
# Set right button to medium rapid trigger
|
||||||
|
solaar config 1 superstrike-tuning_rapid-trigger-level-1 3
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. Click Haptics
|
||||||
|
|
||||||
|
Controls the intensity of the haptic feedback when clicking.
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| Setting Name (Left) | `superstrike-tuning_haptics-0` |
|
||||||
|
| Setting Name (Right) | `superstrike-tuning_haptics-1` |
|
||||||
|
| Type | Range |
|
||||||
|
| Range | 0 - 5 |
|
||||||
|
| Default | 3 |
|
||||||
|
|
||||||
|
**Value Interpretation:**
|
||||||
|
- `0` = Off (no haptic feedback)
|
||||||
|
- `1` = Minimal
|
||||||
|
- `2` = Light
|
||||||
|
- `3` = Medium
|
||||||
|
- `4` = Strong
|
||||||
|
- `5` = Strongest (maximum haptic feedback)
|
||||||
|
|
||||||
|
**Commands:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Read left button haptics level
|
||||||
|
solaar config 1 superstrike-tuning_haptics-0
|
||||||
|
|
||||||
|
# Read right button haptics level
|
||||||
|
solaar config 1 superstrike-tuning_haptics-1
|
||||||
|
|
||||||
|
# Disable haptics on left button
|
||||||
|
solaar config 1 superstrike-tuning_haptics-0 0
|
||||||
|
|
||||||
|
# Set left button to maximum haptics
|
||||||
|
solaar config 1 superstrike-tuning_haptics-0 5
|
||||||
|
|
||||||
|
# Set right button to medium haptics
|
||||||
|
solaar config 1 superstrike-tuning_haptics-1 3
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Complete Settings Summary
|
||||||
|
|
||||||
|
| Setting | CLI Name | Type | Range/Values | Button-Specific |
|
||||||
|
|---------|----------|------|--------------|-----------------|
|
||||||
|
| Onboard Profiles | `onboard_profiles` | Choice | `Disabled`, `Profile 1` | No |
|
||||||
|
| Report Rate | `report_rate_extended` | Choice | `8ms` to `125us` | No |
|
||||||
|
| Sensitivity | `dpi_extended` | Complex | 100-32000 DPI | No |
|
||||||
|
| Actuation Point | `superstrike-tuning_actuation-{0,1}` | Range | 1-10 | Yes |
|
||||||
|
| Rapid Trigger | `superstrike-tuning_rapid-trigger-level-{0,1}` | Range | 1-5 | Yes |
|
||||||
|
| Click Haptics | `superstrike-tuning_haptics-{0,1}` | Range | 0-5 | Yes |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Batch Configuration Examples
|
||||||
|
|
||||||
|
### Gaming Profile (Fast Response)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# Gaming profile: fast actuation, sensitive rapid trigger, medium haptics
|
||||||
|
|
||||||
|
solaar config 1 onboard_profiles Disabled
|
||||||
|
solaar config 1 report_rate_extended 125us
|
||||||
|
solaar config 1 dpi_extended "{X:800, Y:800, LOD:HIGH}"
|
||||||
|
|
||||||
|
# Left button - hair trigger
|
||||||
|
solaar config 1 superstrike-tuning_actuation-0 1
|
||||||
|
solaar config 1 superstrike-tuning_rapid-trigger-level-0 1
|
||||||
|
solaar config 1 superstrike-tuning_haptics-0 3
|
||||||
|
|
||||||
|
# Right button - hair trigger
|
||||||
|
solaar config 1 superstrike-tuning_actuation-1 1
|
||||||
|
solaar config 1 superstrike-tuning_rapid-trigger-level-1 1
|
||||||
|
solaar config 1 superstrike-tuning_haptics-1 3
|
||||||
|
```
|
||||||
|
|
||||||
|
### Productivity Profile (Comfortable)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# Productivity profile: deeper actuation, slower rapid trigger, strong haptics
|
||||||
|
|
||||||
|
solaar config 1 onboard_profiles Disabled
|
||||||
|
solaar config 1 report_rate_extended 1ms
|
||||||
|
solaar config 1 dpi_extended "{X:1600, Y:1600, LOD:HIGH}"
|
||||||
|
|
||||||
|
# Left button - comfortable click
|
||||||
|
solaar config 1 superstrike-tuning_actuation-0 7
|
||||||
|
solaar config 1 superstrike-tuning_rapid-trigger-level-0 4
|
||||||
|
solaar config 1 superstrike-tuning_haptics-0 5
|
||||||
|
|
||||||
|
# Right button - comfortable click
|
||||||
|
solaar config 1 superstrike-tuning_actuation-1 7
|
||||||
|
solaar config 1 superstrike-tuning_rapid-trigger-level-1 4
|
||||||
|
solaar config 1 superstrike-tuning_haptics-1 5
|
||||||
|
```
|
||||||
|
|
||||||
|
### Silent Profile (No Haptics)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# Silent profile: no haptic feedback
|
||||||
|
|
||||||
|
solaar config 1 superstrike-tuning_haptics-0 0
|
||||||
|
solaar config 1 superstrike-tuning_haptics-1 0
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Programmatic Usage
|
||||||
|
|
||||||
|
### Reading All Settings (JSON-like parsing)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get all settings as output
|
||||||
|
solaar config 1 2>/dev/null | grep "^[a-z]" | while read line; do
|
||||||
|
setting=$(echo "$line" | cut -d'=' -f1 | tr -d ' ')
|
||||||
|
value=$(echo "$line" | cut -d'=' -f2 | tr -d ' ')
|
||||||
|
echo "{\"setting\": \"$setting\", \"value\": \"$value\"}"
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reading a Single Setting Value
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Extract just the value
|
||||||
|
solaar config 1 superstrike-tuning_actuation-0 2>/dev/null | grep "^superstrike" | cut -d'=' -f2 | tr -d ' '
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check if command succeeded
|
||||||
|
if solaar config 1 superstrike-tuning_actuation-0 5 2>/dev/null; then
|
||||||
|
echo "Setting applied successfully"
|
||||||
|
else
|
||||||
|
echo "Failed to apply setting"
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Exit Codes
|
||||||
|
|
||||||
|
| Code | Meaning |
|
||||||
|
|------|---------|
|
||||||
|
| 0 | Success |
|
||||||
|
| 1 | Error (device not found, invalid setting, invalid value) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
1. **Device Discovery**: Use `solaar show` to list all connected devices and their indices.
|
||||||
|
|
||||||
|
2. **Persistence**: Settings are saved to `~/.config/solaar/config.yaml` and automatically reapplied when the device reconnects.
|
||||||
|
|
||||||
|
3. **Onboard Profiles**: When `onboard_profiles` is set to `Profile 1`, some settings (DPI, report rate) are controlled by the device's onboard memory and cannot be changed via Solaar.
|
||||||
|
|
||||||
|
4. **HITS Settings**: The actuation, rapid trigger, and haptics settings are stored in the device and persist across reconnections, regardless of the onboard profile setting.
|
||||||
|
|
||||||
|
5. **Button Index**: `0` = Left button, `1` = Right button.
|
||||||
|
|
@ -188,6 +188,42 @@ Solaar uses the standard US keyboard layout. This currently only matters for th
|
||||||
This is an experimental feature and may be modified or even eliminated.
|
This is an experimental feature and may be modified or even eliminated.
|
||||||
|
|
||||||
|
|
||||||
|
### HITS Tuning (Hall-Effect Inductive Trigger Switch)
|
||||||
|
|
||||||
|
Some gaming mice (such as the PRO X 2 Superstrike) feature hall-effect magnetic switches on their primary buttons instead of traditional mechanical switches. These switches expose tunable parameters via the `SUPERSTRIKE_TUNING` HID++ feature (`0x1B0C`).
|
||||||
|
|
||||||
|
Solaar supports three per-button settings for each primary button (left = 0, right = 1):
|
||||||
|
|
||||||
|
- **Actuation Point** (`superstrike-tuning_actuation-{0,1}`): How deep the button must be pressed to register a click. Range 1–10, where 1 is the shallowest (hair trigger) and 10 is the deepest (full press). Default is 5.
|
||||||
|
- **Rapid Trigger Level** (`superstrike-tuning_rapid-trigger-level-{0,1}`): Sensitivity of rapid re-actuation after partial release. Range 1–5, where 1 is the most sensitive and 5 is the least. This cannot be fully disabled.
|
||||||
|
- **Click Haptics** (`superstrike-tuning_haptics-{0,1}`): Intensity of haptic feedback on click. Range 0–5, where 0 disables haptics and 5 is maximum intensity.
|
||||||
|
|
||||||
|
These settings are written directly to the device and persist across reconnections regardless of the onboard profile state.
|
||||||
|
|
||||||
|
### Extended DPI
|
||||||
|
|
||||||
|
Some gaming mice (such as the PRO X 2 Superstrike) support the `EXTENDED_ADJUSTABLE_DPI` feature (`0x2202`) which allows independent X and Y axis DPI configuration as well as lift-off distance (LOD) control. This is exposed via the `dpi_extended` setting:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solaar config <device> dpi_extended "{X:1600, Y:1600, LOD:HIGH}"
|
||||||
|
```
|
||||||
|
|
||||||
|
LOD values are `LOW` and `HIGH`. DPI range depends on the device sensor (up to 32000 DPI on the PRO X 2 Superstrike).
|
||||||
|
|
||||||
|
### Extended Report Rate
|
||||||
|
|
||||||
|
Some gaming mice (such as the PRO X 2 Superstrike) support the `EXTENDED_ADJUSTABLE_REPORT_RATE` feature (`0x8061`) which enables sub-millisecond polling rates beyond the standard 1 ms (1000 Hz). This is exposed via the `report_rate_extended` setting:
|
||||||
|
|
||||||
|
| Value | Polling Rate |
|
||||||
|
|---------|-------------|
|
||||||
|
| `8ms` | 125 Hz |
|
||||||
|
| `4ms` | 250 Hz |
|
||||||
|
| `2ms` | 500 Hz |
|
||||||
|
| `1ms` | 1000 Hz |
|
||||||
|
| `500us` | 2000 Hz |
|
||||||
|
| `250us` | 4000 Hz |
|
||||||
|
| `125us` | 8000 Hz |
|
||||||
|
|
||||||
### Onboard Profiles
|
### Onboard Profiles
|
||||||
|
|
||||||
Some mice store one or more profiles onboard. An onboard profile controls certain aspects of the behavior of the mouse, including the rate at which the mouse reports movement, the resolution of the the movement reports, what the mouse buttons do, LED effects, and maybe more. Solaar has a setting that switches between profiles or disables all profiles.
|
Some mice store one or more profiles onboard. An onboard profile controls certain aspects of the behavior of the mouse, including the rate at which the mouse reports movement, the resolution of the the movement reports, what the mouse buttons do, LED effects, and maybe more. Solaar has a setting that switches between profiles or disables all profiles.
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,7 @@ so what is important for support is the USB WPID or Bluetooth model ID.
|
||||||
|------------------------------|------|-------|
|
|------------------------------|------|-------|
|
||||||
| G604 Wireless Gaming Mouse | 4085 | 4.2 |
|
| G604 Wireless Gaming Mouse | 4085 | 4.2 |
|
||||||
| PRO X Superlight Wireless | 4093 | 4.2 |
|
| PRO X Superlight Wireless | 4093 | 4.2 |
|
||||||
|
| PRO X 2 Superstrike | 40BD | 4.2 |
|
||||||
|
|
||||||
### Trackballs (Unifying)
|
### Trackballs (Unifying)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
Solaar version 1.1.19
|
||||||
|
|
||||||
|
1: PRO X 2 Superstrike
|
||||||
|
Device path : None
|
||||||
|
WPID : 40BD
|
||||||
|
Codename : PRO X 2 Superstrike
|
||||||
|
Kind : mouse
|
||||||
|
Protocol : HID++ 4.2
|
||||||
|
Report Rate : 1ms
|
||||||
|
Serial number:
|
||||||
|
Model ID: 40BDC0A80000
|
||||||
|
Unit ID:
|
||||||
|
Bootloader: BL2 73.00.B0011
|
||||||
|
Firmware: MPM 42.00.B0011
|
||||||
|
The power switch is located on the base.
|
||||||
|
Supports 36 HID++ 2.0 features:
|
||||||
|
0: ROOT {0000} V0
|
||||||
|
1: FEATURE SET {0001} V0
|
||||||
|
2: DEVICE FW VERSION {0003} V7
|
||||||
|
Firmware: Bootloader BL2 73.00.B0011
|
||||||
|
Firmware: Firmware MPM 42.00.B0011
|
||||||
|
Unit ID: Model ID: 40BDC0A80000 Transport IDs: {'wpid': '40BD', 'usbid': 'C0A8'}
|
||||||
|
3: DEVICE NAME {0005} V5
|
||||||
|
Name: PRO X2 SUPERSTRIKE
|
||||||
|
Kind: mouse
|
||||||
|
4: WIRELESS DEVICE STATUS {1D4B} V0
|
||||||
|
5: CONFIG CHANGE {0020} V0
|
||||||
|
6: UNIFIED BATTERY {1004} V5
|
||||||
|
7: XY STATS {2250} V1
|
||||||
|
8: WHEEL STATS {2251} V0
|
||||||
|
9: EXTENDED ADJUSTABLE DPI {2202} V0
|
||||||
|
Sensitivity (DPI): {X:800, Y:800, LOD:HIGH}
|
||||||
|
10: MODE STATUS {8090} V3
|
||||||
|
11: unknown:80E0 {80E0} V0
|
||||||
|
12: SUPERSTRIKE TUNING {1B0C} V0
|
||||||
|
Left Button Actuation Point: 5
|
||||||
|
Left Button Rapid Trigger Level: 3
|
||||||
|
Left Button Click Haptics: 3
|
||||||
|
Right Button Actuation Point: 5
|
||||||
|
Right Button Rapid Trigger Level: 3
|
||||||
|
Right Button Click Haptics: 3
|
||||||
|
13: EXTENDED ADJUSTABLE REPORT RATE {8061} V0
|
||||||
|
Report Rate: 1ms
|
||||||
|
14: ONBOARD PROFILES {8100} V0
|
||||||
|
Device Mode: On-Board
|
||||||
|
Onboard Profiles: Profile 1
|
||||||
|
15: MOUSE BUTTON SPY {8110} V0
|
||||||
|
16: FORCE PAIRING {1500} V0
|
||||||
|
17: unknown:1801 {1801} V0 internal, hidden
|
||||||
|
18: DEVICE RESET {1802} V0
|
||||||
|
19: unknown:1803 {1803} V0 internal, hidden
|
||||||
|
20: CONFIG DEVICE PROPS {1806} V8
|
||||||
|
21: unknown:1817 {1817} V0 internal, hidden
|
||||||
|
22: OOBSTATE {1805} V0
|
||||||
|
23: unknown:1830 {1830} V0 internal, hidden
|
||||||
|
24: unknown:1877 {1877} V0 internal, hidden
|
||||||
|
25: unknown:9403 {9403} V0 internal, hidden
|
||||||
|
26: unknown:1861 {1861} V0 internal, hidden
|
||||||
|
27: unknown:1890 {1890} V0 internal, hidden
|
||||||
|
28: unknown:18A1 {18A1} V0 internal, hidden
|
||||||
|
29: unknown:1E00 {1E00} V0 hidden
|
||||||
|
30: unknown:1E02 {1E02} V0 internal, hidden
|
||||||
|
31: unknown:1E22 {1E22} V0 internal, hidden
|
||||||
|
32: unknown:1E30 {1E30} V0 internal, hidden
|
||||||
|
33: unknown:1602 {1602} V0
|
||||||
|
34: unknown:1EB0 {1EB0} V0 internal, hidden
|
||||||
|
35: unknown:18B1 {18B1} V0 internal, hidden
|
||||||
|
Battery: discharging.
|
||||||
|
|
||||||
|
SUPERSTRIKE TUNING Feature (0x1B0C)
|
||||||
|
-----------------------------------
|
||||||
|
This feature controls the HITS (Hall-Effect Inductive Trigger Switch) settings
|
||||||
|
for the left and right mouse buttons.
|
||||||
|
|
||||||
|
Capabilities (function 0x00):
|
||||||
|
Byte 0: Flags
|
||||||
|
Byte 1: Button count (3, but only 0 and 1 are accessible)
|
||||||
|
Byte 2: Max actuation value (40)
|
||||||
|
Byte 3: Max rapid trigger value (20)
|
||||||
|
Byte 4: Max haptics value (20)
|
||||||
|
|
||||||
|
Read button settings (function 0x20, param: button_index):
|
||||||
|
Response: [button_index, actuation, rapid_trigger, haptics, ...]
|
||||||
|
- actuation: 4-40 (quantized to multiples of 4)
|
||||||
|
- rapid_trigger: 1-20 (cannot be set to 0)
|
||||||
|
- haptics: 0-20 (quantized to multiples of 4: 0, 4, 8, 12, 16, 20)
|
||||||
|
|
||||||
|
Write button settings (function 0x10):
|
||||||
|
Params: [button_index, actuation, rapid_trigger, haptics]
|
||||||
|
|
||||||
|
Solaar Settings:
|
||||||
|
- superstrike-tuning_actuation-{0,1}: Range 1-10 (maps to device 4-40)
|
||||||
|
- superstrike-tuning_rapid-trigger-level-{0,1}: Range 1-5 (maps to device 1-20)
|
||||||
|
- superstrike-tuning_haptics-{0,1}: Range 0-5 (maps to device 0-20)
|
||||||
|
|
||||||
|
Note: Feature 0x80E0 (unknown:80E0) appears to be a non-functional stub for haptics.
|
||||||
|
Haptics are actually controlled via byte 3 of the SUPERSTRIKE TUNING feature.
|
||||||
|
|
||||||
|
Note: Feature 0x9403 (unknown:9403) appears to be a hidden BHOP (bunny hop) feature
|
||||||
|
that is not accessible via HID++.
|
||||||
|
|
@ -33,6 +33,7 @@ Feature | ID | Status | Notes
|
||||||
`UNIFIED_BATTERY` | `0x1004` | Supported | `get_battery`, read only
|
`UNIFIED_BATTERY` | `0x1004` | Supported | `get_battery`, read only
|
||||||
`CHARGING_CONTROL` | `0x1010` | Unsupported |
|
`CHARGING_CONTROL` | `0x1010` | Unsupported |
|
||||||
`LED_CONTROL` | `0x1300` | Unsupported |
|
`LED_CONTROL` | `0x1300` | Unsupported |
|
||||||
|
`FORCE_PAIRING` | `0x1500` | Unsupported |
|
||||||
`GENERIC_TEST` | `0x1800` | Unsupported |
|
`GENERIC_TEST` | `0x1800` | Unsupported |
|
||||||
`DEVICE_RESET` | `0x1802` | Unsupported |
|
`DEVICE_RESET` | `0x1802` | Unsupported |
|
||||||
`OOBSTATE` | `0x1805` | Unsupported |
|
`OOBSTATE` | `0x1805` | Unsupported |
|
||||||
|
|
@ -49,6 +50,7 @@ Feature | ID | Status | Notes
|
||||||
`REPROG_CONTROLS_V2_2` | `0x1B02` | Unsupported |
|
`REPROG_CONTROLS_V2_2` | `0x1B02` | Unsupported |
|
||||||
`REPROG_CONTROLS_V3` | `0x1B03` | Unsupported |
|
`REPROG_CONTROLS_V3` | `0x1B03` | Unsupported |
|
||||||
`REPROG_CONTROLS_V4` | `0x1B04` | Partial Support | `ReprogrammableKeys`, `DivertKeys`, `MouseGesture`, `get_keys`
|
`REPROG_CONTROLS_V4` | `0x1B04` | Partial Support | `ReprogrammableKeys`, `DivertKeys`, `MouseGesture`, `get_keys`
|
||||||
|
`SUPERSTRIKE_TUNING` | `0x1B0C` | Supported | `SuperstrikeTuning` (actuation point, rapid trigger, click haptics)
|
||||||
`REPORT_HID_USAGE` | `0x1BC0` | Unsupported |
|
`REPORT_HID_USAGE` | `0x1BC0` | Unsupported |
|
||||||
`PERSISTENT_REMAPPABLE_ACTION` | `0x1C00` | Supported | `PersistentRemappableAction`
|
`PERSISTENT_REMAPPABLE_ACTION` | `0x1C00` | Supported | `PersistentRemappableAction`
|
||||||
`WIRELESS_DEVICE_STATUS` | `0x1D4B` | Read only | status reporting from device
|
`WIRELESS_DEVICE_STATUS` | `0x1D4B` | Read only | status reporting from device
|
||||||
|
|
@ -67,9 +69,12 @@ Feature | ID | Status | Notes
|
||||||
`THUMB_WHEEL` | `0x2150` | Supported | `ThumbMode`, `ThumbInvert`
|
`THUMB_WHEEL` | `0x2150` | Supported | `ThumbMode`, `ThumbInvert`
|
||||||
`MOUSE_POINTER` | `0x2200` | Supported | `get_mouse_pointer_info`, read only
|
`MOUSE_POINTER` | `0x2200` | Supported | `get_mouse_pointer_info`, read only
|
||||||
`ADJUSTABLE_DPI` | `0x2201` | Supported | `AdjustableDpi`, `DpiSliding`
|
`ADJUSTABLE_DPI` | `0x2201` | Supported | `AdjustableDpi`, `DpiSliding`
|
||||||
|
`EXTENDED_ADJUSTABLE_DPI` | `0x2202` | Supported | `ExtendedAdjustableDpi` (X/Y DPI + lift-off distance)
|
||||||
`POINTER_SPEED` | `0x2205` | Supported | `PointerSpeed`, `SpeedChange`, `get_pointer_speed_info`
|
`POINTER_SPEED` | `0x2205` | Supported | `PointerSpeed`, `SpeedChange`, `get_pointer_speed_info`
|
||||||
`ANGLE_SNAPPING` | `0x2230` | Unsupported |
|
`ANGLE_SNAPPING` | `0x2230` | Unsupported |
|
||||||
`SURFACE_TUNING` | `0x2240` | Unsupported |
|
`SURFACE_TUNING` | `0x2240` | Unsupported |
|
||||||
|
`XY_STATS` | `0x2250` | Unsupported |
|
||||||
|
`WHEEL_STATS` | `0x2251` | Unsupported |
|
||||||
`HYBRID_TRACKING` | `0x2400` | Unsupported |
|
`HYBRID_TRACKING` | `0x2400` | Unsupported |
|
||||||
`FN_INVERSION` | `0x40A0` | Supported | `FnSwap`
|
`FN_INVERSION` | `0x40A0` | Supported | `FnSwap`
|
||||||
`NEW_FN_INVERSION` | `0x40A2` | Supported | `NewFnSwap`, `get_new_fn_inversion
|
`NEW_FN_INVERSION` | `0x40A2` | Supported | `NewFnSwap`, `get_new_fn_inversion
|
||||||
|
|
@ -101,6 +106,7 @@ Feature | ID | Status | Notes
|
||||||
`MR` | `0x8030` | Supported | `MRKeyLED`
|
`MR` | `0x8030` | Supported | `MRKeyLED`
|
||||||
`BRIGHTNESS_CONTROL` | `0x8040` | Supported | `BrightnessControl`
|
`BRIGHTNESS_CONTROL` | `0x8040` | Supported | `BrightnessControl`
|
||||||
`REPORT_RATE` | `0x8060` | Supported | `ReportRate`
|
`REPORT_RATE` | `0x8060` | Supported | `ReportRate`
|
||||||
|
`EXTENDED_ADJUSTABLE_REPORT_RATE` | `0x8061` | Supported | `report_rate_extended` (sub-millisecond polling up to 8000 Hz)
|
||||||
`COLOR_LED_EFFECTS` | `0x8070` | Supported | `LEDControl`, `LEDZoneSetting`
|
`COLOR_LED_EFFECTS` | `0x8070` | Supported | `LEDControl`, `LEDZoneSetting`
|
||||||
`RGB_EFFECTS` | `0X8071` | Supported | `RGBControl`, `RGBEffectSetting`
|
`RGB_EFFECTS` | `0X8071` | Supported | `RGBControl`, `RGBEffectSetting`
|
||||||
`PER_KEY_LIGHTING` | `0x8080` | Unsupported |
|
`PER_KEY_LIGHTING` | `0x8080` | Unsupported |
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ class SupportedFeature(IntEnum):
|
||||||
REPROG_CONTROLS_V2_2 = 0x1B02 # LogiOptions 2.10.73 features.xml
|
REPROG_CONTROLS_V2_2 = 0x1B02 # LogiOptions 2.10.73 features.xml
|
||||||
REPROG_CONTROLS_V3 = 0x1B03
|
REPROG_CONTROLS_V3 = 0x1B03
|
||||||
REPROG_CONTROLS_V4 = 0x1B04
|
REPROG_CONTROLS_V4 = 0x1B04
|
||||||
|
ANALOG_BUTTONS = 0x1B0C # Analog button tuning (actuation point, rapid trigger, haptics)
|
||||||
FULL_KEY_CUSTOMIZATION = 0x1B05
|
FULL_KEY_CUSTOMIZATION = 0x1B05
|
||||||
CONTROL_LIST = 0x1B10
|
CONTROL_LIST = 0x1B10
|
||||||
SWITCH_SWAPABILITY = 0x1B20
|
SWITCH_SWAPABILITY = 0x1B20
|
||||||
|
|
|
||||||
|
|
@ -1055,10 +1055,15 @@ class ExtendedAdjustableDpi(settings.Setting):
|
||||||
keys = common.NamedInts(X=0, Y=1, LOD=2)
|
keys = common.NamedInts(X=0, Y=1, LOD=2)
|
||||||
|
|
||||||
def write_key_value(self, key, value, save=True):
|
def write_key_value(self, key, value, save=True):
|
||||||
|
# Force a read to populate the full X/Y/LOD dictionary if it's missing (fixes CLI)
|
||||||
|
if not isinstance(self._value, dict):
|
||||||
|
self.read()
|
||||||
|
|
||||||
if isinstance(self._value, dict):
|
if isinstance(self._value, dict):
|
||||||
self._value[key] = value
|
self._value[key] = value
|
||||||
else:
|
else:
|
||||||
self._value = {key: value}
|
self._value = {key: value}
|
||||||
|
|
||||||
result = self.write(self._value, save)
|
result = self.write(self._value, save)
|
||||||
return result[key] if isinstance(result, dict) else result
|
return result[key] if isinstance(result, dict) else result
|
||||||
|
|
||||||
|
|
@ -1809,6 +1814,126 @@ class ForceSensing(settings_new.Settings):
|
||||||
return setting
|
return setting
|
||||||
|
|
||||||
|
|
||||||
|
# Analog button tuning settings (actuation point, rapid trigger, haptics)
|
||||||
|
|
||||||
|
|
||||||
|
class _AnalogButtonActuationRW(settings.FeatureRW):
|
||||||
|
"""RW for analog button actuation point per button."""
|
||||||
|
|
||||||
|
def __init__(self, feature, button_index):
|
||||||
|
super().__init__(feature, read_fnid=0x20, write_fnid=0x10)
|
||||||
|
self.button_index = button_index
|
||||||
|
|
||||||
|
def read(self, device, data_bytes=b""):
|
||||||
|
res = device.feature_request(self.feature, 0x20, self.button_index)
|
||||||
|
if not res:
|
||||||
|
return b"\x14" # default mid-point
|
||||||
|
return bytes([res[1]])
|
||||||
|
|
||||||
|
def write(self, device, data_bytes):
|
||||||
|
current = device.feature_request(self.feature, 0x20, self.button_index)
|
||||||
|
if not current:
|
||||||
|
return None
|
||||||
|
return device.feature_request(self.feature, 0x10, self.button_index, data_bytes[0], current[2], current[3])
|
||||||
|
|
||||||
|
|
||||||
|
class _AnalogButtonRapidTriggerRW(settings.FeatureRW):
|
||||||
|
"""RW for analog button rapid trigger sensitivity per button."""
|
||||||
|
|
||||||
|
def __init__(self, feature, button_index):
|
||||||
|
super().__init__(feature, read_fnid=0x20, write_fnid=0x10)
|
||||||
|
self.button_index = button_index
|
||||||
|
|
||||||
|
def read(self, device, data_bytes=b""):
|
||||||
|
res = device.feature_request(self.feature, 0x20, self.button_index)
|
||||||
|
if not res:
|
||||||
|
return b"\x0a" # default mid-point
|
||||||
|
return bytes([res[2]])
|
||||||
|
|
||||||
|
def write(self, device, data_bytes):
|
||||||
|
current = device.feature_request(self.feature, 0x20, self.button_index)
|
||||||
|
if not current:
|
||||||
|
return None
|
||||||
|
return device.feature_request(self.feature, 0x10, self.button_index, current[1], data_bytes[0], current[3])
|
||||||
|
|
||||||
|
|
||||||
|
class _AnalogButtonHapticsRW(settings.FeatureRW):
|
||||||
|
"""RW for analog button click haptics per button."""
|
||||||
|
|
||||||
|
def __init__(self, feature, button_index):
|
||||||
|
super().__init__(feature, read_fnid=0x20, write_fnid=0x10)
|
||||||
|
self.button_index = button_index
|
||||||
|
|
||||||
|
def read(self, device, data_bytes=b""):
|
||||||
|
res = device.feature_request(self.feature, 0x20, self.button_index)
|
||||||
|
if not res:
|
||||||
|
return b"\x0a" # default mid-point
|
||||||
|
return bytes([res[3]])
|
||||||
|
|
||||||
|
def write(self, device, data_bytes):
|
||||||
|
current = device.feature_request(self.feature, 0x20, self.button_index)
|
||||||
|
if not current:
|
||||||
|
return None
|
||||||
|
return device.feature_request(self.feature, 0x10, self.button_index, current[1], current[2], data_bytes[0])
|
||||||
|
|
||||||
|
|
||||||
|
class AnalogButtonTuning(settings.Setting):
|
||||||
|
"""Analog button tuning: actuation point, rapid trigger, and haptics configuration."""
|
||||||
|
|
||||||
|
name = "analog-button-tuning"
|
||||||
|
label = _("Analog Button Tuning")
|
||||||
|
description = _("Configure analog button settings including actuation point, rapid trigger, and haptics.")
|
||||||
|
feature = _F.ANALOG_BUTTONS
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def build(cls, device):
|
||||||
|
if cls.feature not in device.features:
|
||||||
|
return None
|
||||||
|
# Get capabilities: [flags, button_count, max_actuation, max_rt, max_haptics, ...]
|
||||||
|
caps = device.feature_request(cls.feature, 0x00)
|
||||||
|
if not caps or len(caps) < 5:
|
||||||
|
return None
|
||||||
|
button_count = min(caps[1], 2) # Byte 1 is button count, limit to 2 (left/right)
|
||||||
|
max_actuation = caps[2] if caps[2] > 0 else 40 # Byte 2 is max actuation
|
||||||
|
max_rt_level = caps[3] if caps[3] > 0 else 20 # Byte 3 is max RT level
|
||||||
|
max_haptics = caps[4] if caps[4] > 0 else 20 # Byte 4 is max haptics
|
||||||
|
|
||||||
|
if button_count == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
button_names = [_("Left Button"), _("Right Button")]
|
||||||
|
all_settings = []
|
||||||
|
|
||||||
|
for i in range(button_count):
|
||||||
|
btn_name = button_names[i] if i < len(button_names) else f"Button {i}"
|
||||||
|
|
||||||
|
rw_act = _AnalogButtonActuationRW(cls.feature, i)
|
||||||
|
val_act = settings_validator.RangeValidator(min_value=1, max_value=max_actuation)
|
||||||
|
s_act = settings.Setting(device, rw_act, val_act)
|
||||||
|
s_act.name = f"analog-button-tuning_actuation-{i}"
|
||||||
|
s_act.label = f"{btn_name} Actuation Point"
|
||||||
|
s_act.description = _("Actuation point depth (raw device value).")
|
||||||
|
all_settings.append(s_act)
|
||||||
|
|
||||||
|
rw_rt = _AnalogButtonRapidTriggerRW(cls.feature, i)
|
||||||
|
val_rt = settings_validator.RangeValidator(min_value=1, max_value=max_rt_level)
|
||||||
|
s_rt = settings.Setting(device, rw_rt, val_rt)
|
||||||
|
s_rt.name = f"analog-button-tuning_rapid-trigger-{i}"
|
||||||
|
s_rt.label = f"{btn_name} Rapid Trigger"
|
||||||
|
s_rt.description = _("Rapid trigger sensitivity (raw device value).")
|
||||||
|
all_settings.append(s_rt)
|
||||||
|
|
||||||
|
rw_haptics = _AnalogButtonHapticsRW(cls.feature, i)
|
||||||
|
val_haptics = settings_validator.RangeValidator(min_value=0, max_value=max_haptics)
|
||||||
|
s_haptics = settings.Setting(device, rw_haptics, val_haptics)
|
||||||
|
s_haptics.name = f"analog-button-tuning_haptics-{i}"
|
||||||
|
s_haptics.label = f"{btn_name} Click Haptics"
|
||||||
|
s_haptics.description = _("Click haptic feedback intensity (raw device value, 0=off).")
|
||||||
|
all_settings.append(s_haptics)
|
||||||
|
|
||||||
|
return all_settings if all_settings else None
|
||||||
|
|
||||||
|
|
||||||
class HapticLevel(settings.Setting):
|
class HapticLevel(settings.Setting):
|
||||||
name = "haptic-level"
|
name = "haptic-level"
|
||||||
label = _("Haptic Feedback Level")
|
label = _("Haptic Feedback Level")
|
||||||
|
|
@ -1932,6 +2057,7 @@ SETTINGS: list[settings.Setting] = [
|
||||||
Gesture2Gestures, # working
|
Gesture2Gestures, # working
|
||||||
Gesture2Divert,
|
Gesture2Divert,
|
||||||
Gesture2Params, # working
|
Gesture2Params, # working
|
||||||
|
AnalogButtonTuning,
|
||||||
HapticLevel,
|
HapticLevel,
|
||||||
PlayHapticWaveForm,
|
PlayHapticWaveForm,
|
||||||
Sidetone,
|
Sidetone,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue