- Download the latest release from the releases page
- Download the .app file
- Move the file to the Applications folder
- Open the app
The app is not compatible with Wayland. If you are using Wayland, you need to switch to X11. You can do it by logging out and selecting X11 in the login screen. (google it, it's easy)
- Install prerequisites
sudo apt install libfuse2
- Download the latest release from the releases page
- Download .AppImage file
- Make the file executable
# Replace the file name with the one you downloaded
chmod +x mechy-keyboard-1.0.0-amd64.AppImage
- Run the file with sudo
# Replace the file name with the one you downloaded
./mechy-keyboard-1.0.0-amd64.AppImage
- Made in Tauri: the app is made with Tauri, a fast and secure way to build web apps with Rust as backend. The app is ultra-lightweight and blazing fast.
- Powered by Rust: all the heavy lifting is done by Rust, a fast and safe language.
- Instant sound: the sound is played instantly when you press a key. No delay after the sound is loaded.
- No stuttering: the sound is played smoothly without any stuttering.
- No lag: the app is responsive and doesn't lag when you press keys.
- No audio glitches: the sound is played without any glitches.
Thanks to Mechvibes soundpacks for the amazing sounds.
- Cherry MX Black - ABS keycaps
- Cherry MX Black - PBT keycaps
- Cherry MX Blue - ABS keycaps
- Cherry MX Blue - PBT keycaps
- Cherry MX Brown - ABS keycaps
- Cherry MX Brown - PBT keycaps
- Cherry MX Red - ABS keycaps
- Cherry MX Red - PBT keycaps
- Creams
- EG Crystal Purple
- EG Oreo
- Glorious panda
- Model FXT
- Topre Purple Hybrid - PBT keycaps
- More to come!
Just download the soundpacks you want from the UI.
- 3D Sound: sound is played in 3D space by panning the sounds when needed. Keys on the left sound on the left, keys on the right sound on the right, keys in the middle sound on the center. The sound is also played below you.
- Little variations: each key press has a little variation in pitch, speed and volume to make it sound more natural.
- Key down and key up sounds: we don't just play the sound when the key is pressed, we also play a more soft sound when the key is released to make it sound more realistic.
I know this kind of software can be a privacy concern. That's why I made sure to respect your privacy:
- No data collection: we don't collect any data from you. We don't even have a server to store your data 😜.
- No hidden keyloggers: we don't log your keypresses. You can check the source code if you want to make sure. We don't have anything to hide.
- Can run offline: you can run the app without an internet connection after you download your favorite soundpacks.
- No ads: we don't show you ads. We don't have any incentive to show you ads. We just want to make a cool app for you.
I'm working on a way to block the app from accessing the internet. However I'm not sure if it's possible with Tauri. If you know how to do it, please let me know.
- Async tauri runtime example
- Tauri async commands conflict with std::sync::Mutex
- Tauri async commands official documentation
- Kira Rust backend agnostic library for the audio server manager
- Mechvibes for the soundpacks and the inspiration. Check their website.
- Check Rusty vibes. I took some inspiration from it and source code also 😜.
- Rustdesk rdev fork that fixes a macOS crash bug and some other bugs.
- Fooocus for AI logo generation
- IOPaint an open source AI objects remover to fix some artifacts in the generated logos
- Upscayl to scale the generated logos up to 4k
- Adobe AI background remover
- tints.dev for the color palette
- Support newer Mechvibes soundpack schemas
- Add new soundpacks
- Give credit to the soundpacks authors
- Use standard folders
- logs
- app data
- app cache
- Download soundpacks from CDN
- Click sounds
- Change the soundpack
- Change the volume
- Random mode: mixup a bunch of soundpacks
- Key up sound
- 3D sound
- Key press variation
- Key down sound
- Shortcut for muting
- Shortcut for changing volume
- Shortcut for changing soundpack
- Tray icon
- Minimize to tray
- Implement menubar features (like changing soundpack, volume, etc) on macOS
- Open on startup
- Block internet access
- Add soundpacks metadata
- Implement tags
- Implement search
- Implement sorting
- Test on Windows
- Test on Linux
- Test on macOS
- Reduce the app size
- Optimize the app
- Add a way to report bugs
- Add a way to request features
This app is a mere excuse to learn Rust and Tauri. The source code may not be large, although it required a lot of research and testing to make it work. In this few houndred lines of code you will find a lot of interesting things such as:
- Tauri commands
- Tauri window management
- Rust async
- Multithreading
- Mutexes
- Audio management
- Soundpacks come from Mechvibes.
- Each soundpack is a zip file with the following structure (for now):
soundpack-name/
config.json
: metadata about the soundpacksound.ogg
: the sound file
- I download the soundpacks from Mechvibes, compress them and upload them to github repo as a .zip file.
I know this is a privacy concern because the app listens to your key events. That's why I'm going to explain how the key listener works. This is probably the most important part of the app.
I'm using Fufesou rdev fork. Rust crate here.
rdev is a Rust library that allows you to listen to key events. It's a simple library that listens to key and mouse events.
- As listen function from Fufesou rdev fork is blocking I need to spawn a new thread in order to listen to the key events.
- I'm going to explain how it works. The thread code is the following:
// Spawn a new thread to avoid blocking the main thread (UI thread and Tauri's runtime)
thread::spawn(|| {
// Listen to IO events
// This listener now is listen for your mouse & keyboard events
if let Err(error) = listen(move |event| match event.event_type {
// When a key is pressed
EventType::KeyPress(key) => {
// KEY_PRESSED is a mutable mutex that contains a list of keys that are currently pressed
// With this method we avoid playing the sound multiple times when the key is pressed and held
let mut keys_pressed_lock = KEYS_PRESSED.lock().unwrap();
// If the key is already pressed, we do nothing and prevent the sound from playing
if keys_pressed_lock.contains(&key) {
drop(keys_pressed_lock);
return;
} else {
// If the key is not pressed, we add it to the list
keys_pressed_lock.push(key);
drop(keys_pressed_lock);
}
// This line do the magic
tauri::async_runtime::block_on(async {
// SOUNDPACK is a mutable mutex that contains the Soundpack struct with the sound data
// Here we are passing the key to the play_sound function and a boolean to indicate if the sound is a key up sound
SOUNDPACK.lock().await.play_sound(key, false);
});
}
// When a key is released
EventType::KeyRelease(key) => {
let mut keys_pressed_lock = KEYS_PRESSED.lock().unwrap();
// We remove the key from the list of keys that are currently pressed
keys_pressed_lock.retain(|&x| x != key);
tauri::async_runtime::block_on(async {
// We play the key up sound
SOUNDPACK.lock().await.play_sound(key, true);
});
}
// We don't care about other events such as mouse clicks, mouse movements, mouse scrolls, etc
_ => {}
}) {
error!("Error: {:?}", error)
}
});
You can check the main.rs file here
- To keep things responsive we avoid doing heavy operations in the previous thread so we don't block it. Sound were already prepared in the
choose_soundpack
tauri command which is called by the frontend when the app starts (I'm 99% sure this will change in the future). - So when a key is pressed, we just play the sound. We don't load the sound, we just play it. This is why the app is so fast and responsive.
Tauri development requisites: https://tauri.app/v1/guides/getting-started/prerequisites/
- Install prerequisites
sudo apt-get update
sudo apt-get install build-essential pkg-config libglib2.0-dev libpango1.0-dev libgdk-pixbuf2.0-dev libatk-bridge2.0 libsoup2.4-dev libgtk-3-dev curl wget file libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev javascriptcoregtk-4.1 libsoup-3.0 webkit2gtk-4.1 libwebkit2gtk-4.0-dev