when osu sound i guess

feat: hotkey for toggling

ptr.pet fcfe3ce9 7d4e376a

verified
Changed files
+65 -31
src
+65 -31
src/main.rs
···
let mut previously_held_keys = HashSet::<Keycode>::new();
let mut key_press_times = HashMap::<Keycode, std::time::Instant>::new();
let mut last_sound_time = std::time::Instant::now();
+
let mut sounds_enabled = true; // Toggle for enabling/disabling sounds
let initial_delay = Duration::from_millis(500); // Wait 500ms before starting to repeat
let repeat_interval = Duration::from_millis(50); // Then repeat every 50ms
···
loop {
let currently_held_keys: HashSet<Keycode> = state.query_keymap().into_iter().collect();
-
// Track when keys were first pressed
-
for key in &currently_held_keys {
-
if !previously_held_keys.contains(key) {
-
// Key just pressed, record the time and play initial sound
-
key_press_times.insert(*key, std::time::Instant::now());
-
play_sound_for_key(*key);
-
}
-
}
+
// Check for toggle hotkey (Ctrl + Alt + L/R Shift + C)
+
let hotkey_combo = [
+
[Keycode::LControl, Keycode::RControl], // Either left or right control
+
[Keycode::LAlt, Keycode::RAlt], // Either left or right alt
+
[Keycode::LShift, Keycode::RShift], // Either left or right shift
+
[Keycode::C, Keycode::C], // C key (duplicated for array consistency)
+
];
-
// Remove timing info for released keys
-
key_press_times.retain(|key, _| currently_held_keys.contains(key));
+
let check_hotkey = |current: &HashSet<Keycode>, previous: &HashSet<Keycode>| {
+
hotkey_combo.iter().all(|key_group| {
+
key_group
+
.iter()
+
.any(|key| current.contains(key) || previous.contains(key))
+
})
+
};
-
// Play repeating sounds every 50ms, but only after initial delay
-
if last_sound_time.elapsed() >= repeat_interval {
-
let now = std::time::Instant::now();
+
let hotkey_active = check_hotkey(&currently_held_keys, &previously_held_keys);
+
let hotkey_was_active = check_hotkey(&previously_held_keys, &HashSet::new());
+
+
if hotkey_active && !hotkey_was_active {
+
sounds_enabled = !sounds_enabled;
+
}
+
+
// Only process sound logic if sounds are enabled
+
if sounds_enabled {
+
// Track when keys were first pressed
for key in &currently_held_keys {
-
if matches!(
-
key,
-
Keycode::LShift
-
| Keycode::RShift
-
| Keycode::LControl
-
| Keycode::RControl
-
| Keycode::RAlt
-
| Keycode::LAlt
-
| Keycode::RMeta
-
| Keycode::LMeta
-
| Keycode::CapsLock
-
) {
-
continue;
+
if !previously_held_keys.contains(key) {
+
// Key just pressed, record the time and play initial sound
+
key_press_times.insert(*key, std::time::Instant::now());
+
play_sound_for_key(*key);
}
-
if let Some(press_time) = key_press_times.get(key) {
-
// Only repeat if key has been held longer than initial delay
-
if now.duration_since(*press_time) >= initial_delay {
-
play_sound_for_key(*key);
+
}
+
+
// Remove timing info for released keys
+
key_press_times.retain(|key, _| currently_held_keys.contains(key));
+
+
// Play repeating sounds every 50ms, but only after initial delay
+
if last_sound_time.elapsed() >= repeat_interval {
+
let now = std::time::Instant::now();
+
for key in &currently_held_keys {
+
if is_modifier_key(key) {
+
continue;
+
}
+
if let Some(press_time) = key_press_times.get(key) {
+
// Only repeat if key has been held longer than initial delay
+
if now.duration_since(*press_time) >= initial_delay {
+
play_sound_for_key(*key);
+
}
}
}
+
last_sound_time = now;
}
-
last_sound_time = now;
+
} else {
+
// Clear key press times when sounds are disabled to avoid stale data
+
key_press_times.clear();
}
previously_held_keys = currently_held_keys;
···
std::thread::sleep(Duration::from_millis(5));
}
}
+
+
fn is_modifier_key(key: &Keycode) -> bool {
+
matches!(
+
key,
+
Keycode::LShift
+
| Keycode::RShift
+
| Keycode::LControl
+
| Keycode::RControl
+
| Keycode::RAlt
+
| Keycode::LAlt
+
| Keycode::RMeta
+
| Keycode::LMeta
+
| Keycode::CapsLock
+
)
+
}