Merge branch 'main' into cloud-iii-s-support

This commit is contained in:
Mark Cockram
2026-01-20 23:05:27 +01:00
committed by GitHub
7 changed files with 44 additions and 12 deletions

15
99-HyperHeadset.rules Normal file
View File

@@ -0,0 +1,15 @@
SUBSYSTEMS=="usb", ATTRS{idProduct}=="018b", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="0696", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="1718", ATTRS{idVendor}=="0951", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="0d93", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="05b7", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="16ea", ATTRS{idVendor}=="0951", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="0c9d", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="0d93", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="018b", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="0696", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="1718", ATTRS{idVendor}=="0951", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="05b7", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="16ea", ATTRS{idVendor}=="0951", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="0c9d", ATTRS{idVendor}=="03f0", MODE="0666"

View File

@@ -6,8 +6,8 @@ A CLI and tray application for monitoring and managing HyperX headsets.
This project is not affiliated with, endorsed by, or associated with HyperX or its parent company in any way. All trademarks and brand names belong to their respective owners.
## Compatibility
The CLI application is compatible with both Linux and MacOS operating systems.
However, the tray application is only functional on Linux.
The CLI application is compatible with both Linux and MacOS operating systems.
However, the tray application is only functional on Linux.
Although it was only tested on Manjaro and Kubuntu with KDE, it should also work on other distribution and desktop environments.
**Supported Headsets**:
@@ -16,6 +16,7 @@ Although it was only tested on Manjaro and Kubuntu with KDE, it should also work
- HyperX Cloud III Wireless
- HyperX Cloud III S Wireless
- HyperX Cloud Stinger 2 Wireless
- HyperX Cloud Flight S
It should be possible to add support for other HyperX headsets.
@@ -64,6 +65,8 @@ SUBSYSTEMS=="usb", ATTRS{idProduct}=="1718", ATTRS{idVendor}=="0951", MODE="0666
SUBSYSTEMS=="usb", ATTRS{idProduct}=="0d93", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="05b7", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="06be", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="16ea", ATTRS{idVendor}=="0951", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="0c9d", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="0d93", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="018b", ATTRS{idVendor}=="03f0", MODE="0666"
@@ -71,6 +74,8 @@ KERNEL=="hidraw*", ATTRS{idProduct}=="0696", ATTRS{idVendor}=="03f0", MODE="0666
KERNEL=="hidraw*", ATTRS{idProduct}=="1718", ATTRS{idVendor}=="0951", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="05b7", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="06be", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="16ea", ATTRS{idVendor}=="0951", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="0c9d", ATTRS{idVendor}=="03f0", MODE="0666"
```
Once created, replug the wireless dongle.
@@ -135,7 +140,7 @@ Options:
```
`hyper_headset` without any arguments will start the tray application with a 3s refresh interval.
Once it's open, hover over the headset icon in the system tray or right-click to view details such as the battery level.
Once it's open, hover over the headset icon in the system tray or right-click to view details such as the battery level.
You can also exit via the right-clock menu.
## Contributing / TODOs

10
hyper-headset.desktop Normal file
View File

@@ -0,0 +1,10 @@
[Desktop Entry]
Type=Application
Name=HyperHeadset
Comment=Monitor and manage HyperX headsets
Exec=/usr/local/bin/hyper_headset
Icon=audio-card
Terminal=false
Categories=AudioVideo;Audio;
StartupNotify=false
X-GNOME-Autostart-enabled=true

View File

@@ -6,8 +6,8 @@ use std::time::Duration;
const HYPERX: u16 = 0x0951;
pub const VENDOR_IDS: [u16; 1] = [HYPERX];
// Possible Cloud II Wireless product IDs
pub const PRODUCT_IDS: [u16; 3] = [0x1718, 0x018B, 0x0b92];
// Possible Cloud II Wireless product IDs (and Cloud Flight S)
pub const PRODUCT_IDS: [u16; 4] = [0x1718, 0x018B, 0x0b92, 0x16EA];
const BASE_PACKET: [u8; 62] = {
let mut tmp = [0u8; 62];
@@ -266,12 +266,15 @@ impl Device for CloudIIWireless {
}
fn prepare_write(&mut self) {
// Attempt to read input report before writing
// This may not work for all devices (e.g., Cloud Flight S),
// so we ignore the error
let mut input_report_buffer = [0u8; 64];
input_report_buffer[0] = 6;
self.state
let _ = self
.state
.hid_device
.get_input_report(&mut input_report_buffer)
.unwrap();
.get_input_report(&mut input_report_buffer);
}
fn allow_passive_refresh(&mut self) -> bool {

View File

@@ -6,7 +6,7 @@ use std::{time::Duration, vec};
const HP: u16 = 0x03F0;
pub const VENDOR_IDS: [u16; 1] = [HP];
pub const PRODUCT_IDS: [u16; 1] = [0x05B7];
pub const PRODUCT_IDS: [u16; 2] = [0x05B7, 0x0c9d]; // Possible Cloud III Wireless product IDs
const BASE_PACKET: [u8; 62] = {
let mut packet = [0; 62];

View File

@@ -17,7 +17,7 @@ use thistermination::TerminationFull;
// Possible vendor IDs [HyperX, HP]
const VENDOR_IDS: [u16; 2] = [0x0951, 0x03F0];
// All supported product IDs
const PRODUCT_IDS: [u16; 7] = [0x1718, 0x018B, 0x0D93, 0x0696, 0x0b92, 0x05B7, 0x06BE];
const PRODUCT_IDS: [u16; 9] = [0x1718, 0x018B, 0x0D93, 0x0696, 0x0b92, 0x05B7, 0x16EA, 0x0c9d, 0x06BE];
const RESPONSE_BUFFER_SIZE: usize = 256;
const RESPONSE_DELAY: Duration = Duration::from_millis(50);
@@ -537,7 +537,7 @@ pub trait Device {
}
responded = true;
}
if !self.get_device_state().connected.is_none_or(|c| c) {
if !matches!(self.get_device_state().connected, Some(true)) {
break;
}
}

View File

@@ -58,7 +58,6 @@ impl Tray for StatusTray {
fn tool_tip(&self) -> ToolTip {
let description = self
.message
.clone()
.lines()
.filter(|l| !l.contains("Unknown"))
.collect::<Vec<&str>>()