Giter VIP home page Giter VIP logo

mechy-keyboard's Introduction

github og image (1)

Installation

MacOS

  1. Download the latest release from the releases page
  2. Download the .app file
  3. Move the file to the Applications folder
  4. Open the app

Ubuntu 24.04 (only on X11)

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)

  1. Install prerequisites
sudo apt install libfuse2
  1. Download the latest release from the releases page
  2. Download .AppImage file
  3. Make the file executable
# Replace the file name with the one you downloaded
chmod +x mechy-keyboard-1.0.0-amd64.AppImage
  1. Run the file with sudo
# Replace the file name with the one you downloaded
./mechy-keyboard-1.0.0-amd64.AppImage

Features

⚡️ Fast & lightweight

  • 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.

1️⃣5️⃣ soundpacks

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!

🚫🔊📦 No pre-installed soundpacks

Just download the soundpacks you want from the UI.

🎧 Immersive sound

  • 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.

🔐 Privacy

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.

References

Thanks to

Checklist

  • 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

Technical details

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

  1. Soundpacks come from Mechvibes.
  2. Each soundpack is a zip file with the following structure (for now):
    • soundpack-name/
      • config.json: metadata about the soundpack
      • sound.ogg: the sound file
  3. I download the soundpacks from Mechvibes, compress them and upload them to github repo as a .zip file.

Key listener

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.

  1. As listen function from Fufesou rdev fork is blocking I need to spawn a new thread in order to listen to the key events.
  2. 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

  1. 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).
  2. 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.

Development

Tauri development requisites: https://tauri.app/v1/guides/getting-started/prerequisites/

Linux

Ubuntu 24.04

  1. 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

mechy-keyboard's People

Contributors

juliankominovic avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.