kbd_global/lib.rs
1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3//! Global hotkey runtime for `kbd`.
4//!
5//! Threaded engine, device management, and backend selection for Linux.
6//! The library handles platform complexity — evdev, portal, permissions,
7//! hotplug, virtual devices — so callers describe what patterns they care
8//! about and what should happen.
9//!
10//! # Quick start
11//!
12//! ```rust,no_run
13//! use kbd::prelude::*;
14//! use kbd_global::HotkeyManager;
15//!
16//! let manager = HotkeyManager::new()?;
17//!
18//! let _guard = manager.register(
19//! Hotkey::new(Key::C).modifier(Modifier::Ctrl).modifier(Modifier::Shift),
20//! || println!("fired"),
21//! )?;
22//! # Ok::<(), kbd_global::Error>(())
23//! ```
24//!
25//! # Concepts
26//!
27//! Four concepts cover the library's surface:
28//!
29//! - **Keys** — physical keys on a keyboard ([`Key`](kbd::key::Key), [`Modifier`](kbd::hotkey::Modifier), [`Hotkey`](kbd::hotkey::Hotkey))
30//! - **Bindings** — "when this pattern matches, do that" ([`Action`](kbd::action::Action), [`BindingOptions`](kbd::binding::BindingOptions))
31//! - **Layers** — named groups of bindings, stackable ([`Layer`](kbd::layer::Layer), [`LayerOptions`](kbd::layer::LayerOptions))
32//! - **Grab mode** — exclusive device capture for interception and remapping
33//!
34//! # Architecture
35//!
36//! [`HotkeyManager`] is the public API. Internally it sends commands to a
37//! dedicated engine thread over an `mpsc` channel, with an `eventfd` wake
38//! mechanism to interrupt `poll()`. All mutable state lives in the engine —
39//! no locks, no shared mutation.
40//!
41//! ```text
42//! ┌──────────────────┐ Command ┌──────────────────┐
43//! │ HotkeyManager │ ─────────────► │ Engine thread │
44//! │ (command sender) │ ◄───────────── │ (event loop) │
45//! └──────────────────┘ Reply └──────────────────┘
46//! │
47//! poll(devices + wake_fd)
48//! ```
49//!
50//! # Lifecycle
51//!
52//! 1. Create a manager with [`HotkeyManager::new()`] or [`HotkeyManager::builder()`]
53//! 2. Register hotkeys with [`HotkeyManager::register()`] — returns a [`BindingGuard`]
54//! 3. Optionally define and push [`Layer`](kbd::layer::Layer)s for context-dependent bindings
55//! 4. The engine thread processes key events and fires callbacks
56//! 5. Drop the [`BindingGuard`] to unregister, or call [`BindingGuard::unregister()`]
57//! 6. Drop the manager (or call [`HotkeyManager::shutdown()`]) to stop
58//!
59//! # Backend selection
60//!
61//! Currently only [`Backend::Evdev`] is available — it reads `/dev/input/event*`
62//! directly and works on Wayland, X11, and TTY. Your user must be in the
63//! `input` group:
64//!
65//! ```bash
66//! sudo usermod -aG input $USER
67//! ```
68//!
69//! Use the builder for explicit backend selection:
70//!
71//! ```rust,no_run
72//! use kbd_global::{Backend, HotkeyManager};
73//!
74//! let manager = HotkeyManager::builder()
75//! .backend(Backend::Evdev)
76//! .build()?;
77//! # Ok::<(), kbd_global::Error>(())
78//! ```
79//!
80//! # Feature flags
81//!
82//! | Feature | Effect |
83//! |---------|--------|
84//! | `grab` | Enables exclusive device capture via `EVIOCGRAB` with uinput forwarding for non-hotkey events |
85//! | `serde` | Adds `Serialize`/`Deserialize` to key and hotkey types (via [`kbd`]) |
86//!
87//! # See also
88//!
89//! - [`kbd`] — core dispatch engine, key types, and layer logic
90
91mod backend;
92mod binding_guard;
93mod engine;
94mod error;
95mod manager;
96
97/// Which input backend to use.
98pub use crate::backend::Backend;
99/// RAII guard that keeps a binding alive until dropped.
100pub use crate::binding_guard::BindingGuard;
101/// Error type for all kbd-global operations.
102pub use crate::error::Error;
103/// The main entry point — manages the engine thread and hotkey registration.
104pub use crate::manager::HotkeyManager;
105/// Builder for configuring backend and runtime options before starting.
106pub use crate::manager::HotkeyManagerBuilder;