adabraka-gpui 0.4.0

Adabraka's GPU-accelerated UI framework (fork of GPUI from Zed - github.com/zed-industries/zed)
Documentation
use anyhow::Result;
use windows::Win32::{
    Foundation::HWND,
    UI::Input::KeyboardAndMouse::{
        RegisterHotKey, UnregisterHotKey, HOT_KEY_MODIFIERS, MOD_ALT, MOD_CONTROL, MOD_SHIFT,
        MOD_WIN, VIRTUAL_KEY, VK_BACK, VK_DELETE, VK_DOWN, VK_END, VK_ESCAPE, VK_F1, VK_F10,
        VK_F11, VK_F12, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_HOME, VK_INSERT,
        VK_LEFT, VK_NEXT, VK_PRIOR, VK_RETURN, VK_RIGHT, VK_SPACE, VK_TAB, VK_UP,
    },
};

use crate::Keystroke;

pub(crate) fn register(hwnd: HWND, id: u32, keystroke: &Keystroke) -> Result<()> {
    let modifiers = map_modifiers(keystroke);
    let vk = map_key_to_vk(&keystroke.key)?;

    unsafe {
        RegisterHotKey(Some(hwnd), id as i32, modifiers, vk.0 as u32)
            .map_err(|e| anyhow::anyhow!("Failed to register hotkey {}: {}", id, e))
    }
}

pub(crate) fn unregister(hwnd: HWND, id: u32) {
    unsafe {
        let _ = UnregisterHotKey(Some(hwnd), id as i32);
    }
}

fn map_modifiers(keystroke: &Keystroke) -> HOT_KEY_MODIFIERS {
    let mut mods = HOT_KEY_MODIFIERS(0);
    if keystroke.modifiers.alt {
        mods |= MOD_ALT;
    }
    if keystroke.modifiers.control {
        mods |= MOD_CONTROL;
    }
    if keystroke.modifiers.shift {
        mods |= MOD_SHIFT;
    }
    if keystroke.modifiers.platform {
        mods |= MOD_WIN;
    }
    mods
}

fn map_key_to_vk(key: &str) -> Result<VIRTUAL_KEY> {
    let vk = match key.to_lowercase().as_str() {
        "a" => VIRTUAL_KEY(0x41),
        "b" => VIRTUAL_KEY(0x42),
        "c" => VIRTUAL_KEY(0x43),
        "d" => VIRTUAL_KEY(0x44),
        "e" => VIRTUAL_KEY(0x45),
        "f" => VIRTUAL_KEY(0x46),
        "g" => VIRTUAL_KEY(0x47),
        "h" => VIRTUAL_KEY(0x48),
        "i" => VIRTUAL_KEY(0x49),
        "j" => VIRTUAL_KEY(0x4A),
        "k" => VIRTUAL_KEY(0x4B),
        "l" => VIRTUAL_KEY(0x4C),
        "m" => VIRTUAL_KEY(0x4D),
        "n" => VIRTUAL_KEY(0x4E),
        "o" => VIRTUAL_KEY(0x4F),
        "p" => VIRTUAL_KEY(0x50),
        "q" => VIRTUAL_KEY(0x51),
        "r" => VIRTUAL_KEY(0x52),
        "s" => VIRTUAL_KEY(0x53),
        "t" => VIRTUAL_KEY(0x54),
        "u" => VIRTUAL_KEY(0x55),
        "v" => VIRTUAL_KEY(0x56),
        "w" => VIRTUAL_KEY(0x57),
        "x" => VIRTUAL_KEY(0x58),
        "y" => VIRTUAL_KEY(0x59),
        "z" => VIRTUAL_KEY(0x5A),
        "0" => VIRTUAL_KEY(0x30),
        "1" => VIRTUAL_KEY(0x31),
        "2" => VIRTUAL_KEY(0x32),
        "3" => VIRTUAL_KEY(0x33),
        "4" => VIRTUAL_KEY(0x34),
        "5" => VIRTUAL_KEY(0x35),
        "6" => VIRTUAL_KEY(0x36),
        "7" => VIRTUAL_KEY(0x37),
        "8" => VIRTUAL_KEY(0x38),
        "9" => VIRTUAL_KEY(0x39),
        "f1" => VK_F1,
        "f2" => VK_F2,
        "f3" => VK_F3,
        "f4" => VK_F4,
        "f5" => VK_F5,
        "f6" => VK_F6,
        "f7" => VK_F7,
        "f8" => VK_F8,
        "f9" => VK_F9,
        "f10" => VK_F10,
        "f11" => VK_F11,
        "f12" => VK_F12,
        "space" | " " => VK_SPACE,
        "enter" | "return" => VK_RETURN,
        "tab" => VK_TAB,
        "escape" | "esc" => VK_ESCAPE,
        "backspace" => VK_BACK,
        "delete" => VK_DELETE,
        "insert" => VK_INSERT,
        "home" => VK_HOME,
        "end" => VK_END,
        "pageup" => VK_PRIOR,
        "pagedown" => VK_NEXT,
        "up" => VK_UP,
        "down" => VK_DOWN,
        "left" => VK_LEFT,
        "right" => VK_RIGHT,
        other => {
            if other.len() == 1 {
                let ch = other.chars().next().unwrap().to_ascii_uppercase();
                VIRTUAL_KEY(ch as u16)
            } else {
                return Err(anyhow::anyhow!(
                    "Unsupported key for global hotkey: {}",
                    other
                ));
            }
        }
    };
    Ok(vk)
}