Skip to main content

Crate kbd_winit

Crate kbd_winit 

Source
Expand description

Winit key event conversions for kbd.

This crate converts winit’s key events into kbd’s unified types so that window-focused key events (from winit) and global hotkey events (from kbd-global) can feed into the same Dispatcher. This is useful in applications where you want both in-window shortcuts and system-wide hotkeys handled through a single hotkey registry.

Both winit and kbd derive from the W3C UI Events specification, so the variant names are nearly identical — the mapping is mechanical. Winit wraps key codes in a PhysicalKey type and tracks modifiers separately via WindowEvent::ModifiersChanged. The WinitEventExt trait therefore takes ModifiersState as a parameter.

§Extension traits

§Key mapping

winitkbdNotes
KeyCode::KeyAKeyCode::KeyZKey::AKey::ZLetters
KeyCode::Digit0KeyCode::Digit9Key::DIGIT0Key::DIGIT9Digits
KeyCode::F1KeyCode::F35Key::F1Key::F35Function keys
KeyCode::Numpad0KeyCode::Numpad9Key::NUMPAD0Key::NUMPAD9Numpad
KeyCode::Enter, KeyCode::Escape, …Key::ENTER, Key::ESCAPE, …Navigation / editing
KeyCode::ControlLeft, …Key::CONTROL_LEFT, …Modifier keys as triggers
KeyCode::SuperLeft / KeyCode::MetaKey::META_LEFTwinit’s Super = kbd’s Meta
KeyCode::SuperRightKey::META_RIGHT
KeyCode::MediaPlayPause, …Key::MEDIA_PLAY_PAUSE, …Media keys
KeyCode::BrowserBack, …Key::BROWSER_BACK, …Browser keys
KeyCode::Convert, KeyCode::Lang1, …Key::CONVERT, Key::LANG1, …CJK / international
PhysicalKey::Unidentified(_)NoneNo mapping possible

§Modifier mapping

§Usage

Inside winit’s event loop, use WinitEventExt to convert key events directly:

use kbd::prelude::*;
use kbd_winit::WinitEventExt;
use winit::application::ApplicationHandler;
use winit::event::WindowEvent;
use winit::event_loop::{ActiveEventLoop, EventLoop};
use winit::keyboard::ModifiersState;
use winit::window::{Window, WindowId};

struct App {
    modifiers: ModifiersState,
    window: Option<Window>,
}

impl ApplicationHandler for App {
    fn resumed(&mut self, event_loop: &ActiveEventLoop) {
        if self.window.is_none() {
            let attrs = Window::default_attributes().with_title("kbd-winit example");
            self.window = Some(event_loop.create_window(attrs).unwrap());
        }
    }

    fn window_event(&mut self, _event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) {
        match event {
            WindowEvent::ModifiersChanged(mods) => {
                self.modifiers = mods.state();
            }
            WindowEvent::KeyboardInput { event, .. } => {
                if let Some(hotkey) = event.to_hotkey(self.modifiers) {
                    println!("{hotkey}");
                }
            }
            _ => {}
        }
    }
}

let event_loop = EventLoop::new().unwrap();
let mut app = App { modifiers: ModifiersState::empty(), window: None };
event_loop.run_app(&mut app).unwrap();

The individual conversion traits can also be used separately:

use kbd::prelude::*;
use kbd_winit::{WinitKeyExt, WinitModifiersExt};
use winit::keyboard::{KeyCode, ModifiersState, PhysicalKey};

// KeyCode conversion
let key = KeyCode::KeyA.to_key();
assert_eq!(key, Some(Key::A));

// PhysicalKey conversion
let key = PhysicalKey::Code(KeyCode::KeyA).to_key();
assert_eq!(key, Some(Key::A));

// Modifier conversion
let mods = ModifiersState::CONTROL.to_modifiers();
assert_eq!(mods, vec![Modifier::Ctrl]);

Traits§

WinitEventExt
Convert a winit KeyEvent (plus modifier state) to a kbd Hotkey.
WinitKeyExt
Convert a winit key type to a kbd Key.
WinitModifiersExt
Convert winit ModifiersState bitflags to a sorted Vec<Modifier>.

Functions§

winit_key_to_hotkey
Build a Hotkey from a physical key and modifier state.