Huakun

monio-rs

A pure Rust cross-platform input hook library with proper drag detection.

GitHub: https://github.com/HuakunShen/monio

Features

  • Cross-platform: macOS, Windows, and Linux (X11/evdev) support
  • Proper drag detection: Distinguishes MouseDragged from MouseMoved events
  • Event grabbing: Block events from reaching other applications (global hotkeys)
  • Async/Channel support: Non-blocking event receiving with std or tokio channels
  • Event recording & playback: Record and replay macros (requires recorder feature)
  • Input statistics: Analyze typing speed, mouse distance, etc.
  • Display queries: Get monitor info, DPI scale, system settings
  • Pure Rust: No C dependencies (uses native Rust bindings)
  • Event simulation: Programmatically generate keyboard and mouse events
  • Thread-safe: Atomic state tracking for reliable button/modifier detection

The Problem This Solves

Most input hooking libraries report all mouse movement as MouseMoved, even when buttons are held down. This makes implementing drag-and-drop, drawing applications, or gesture recognition difficult.

monio-rs tracks button state globally and emits MouseDragged events when movement occurs while any mouse button is pressed.

Installation

[dependencies]
monio = "0.1"

# With Tokio support
monio = { version = "0.1", features = ["tokio"] }

# With recorder feature (macros)
monio = { version = "0.1", features = ["recorder"] }

# With statistics feature
monio = { version = "0.1", features = ["statistics"] }

# Linux evdev support (works on X11 AND Wayland)
monio = { version = "0.1", features = ["evdev"], default-features = false }

Quick Start

use monio::{listen, Event, EventType};

fn main() {
    listen(|event: &Event| {
        match event.event_type {
            EventType::KeyPressed => {
                if let Some(kb) = &event.keyboard {
                    println!("Key pressed: {:?}", kb.key);
                }
            }
            EventType::MouseDragged => {
                if let Some(mouse) = &event.mouse {
                    println!("Dragging at ({}, {})", mouse.x, mouse.y);
                }
            }
            _ => {}
        }
    }).expect("Failed to start hook");
}

Use Cases

  • Global hotkeys with event blocking
  • Macro recording and playback
  • Input analytics (typing speed, mouse distance)
  • Drag-and-drop implementations
  • Drawing applications
  • Gesture recognition

Published on crates.io

On this page