WebExeBuilder Documentation

register

Category: Global Hotkeys

Namespace: web.hotkey.register

Description

Registers a system-wide global hotkey with Windows. Once registered, the hotkey fires web.events.onHotkey whenever the key combination is pressed — even if the app is minimized, hidden in the system tray, or another application has focus.

Syntax

const success = await web.hotkey.register({
    id: 1,
    key: 'H',
    modifiers: 'ctrl+alt',
    passthrough: false   // optional, default false
});

Parameters

Parameter Type Required Default Description
id integer Yes Unique hotkey identifier, >= 1. Used to identify which hotkey fired in the onHotkey callback. No upper limit.
key string Yes The key to listen for. See Supported Keys below.
modifiers string No '' One or more modifier keys joined with +. Omit or pass '' for no modifier. See Supported Modifiers below.
passthrough boolean No false When true, uses a low-level keyboard hook (WH_KEYBOARD_LL) instead of RegisterHotKey. The key is not consumed — it still reaches whatever application currently has focus. Useful for soundboards where you want sounds to play while the user is typing in another app. See Passthrough Mode below.

Supported Modifiers

Combine any of these with +:

Modifier Description
ctrl Ctrl key
alt Alt key
shift Shift key
win Windows key

Examples: 'ctrl+alt', 'ctrl+shift', 'alt+shift', 'ctrl+alt+shift', 'win'

Passing '' or omitting modifiers registers the hotkey with no modifier (MOD_NONE) — the hotkey fires whenever that key is pressed anywhere in Windows, regardless of other keys held. Useful for soundboards and gaming overlays where you want raw key presses to trigger actions.

Supported Keys

Letters: A through Z

Digits: 0 through 9

Function keys: F1 through F12

Special keys:

Key name Description
SPACE Spacebar
ENTER or RETURN Enter key
ESC or ESCAPE Escape key
TAB Tab key
DELETE Delete key
INSERT Insert key
HOME Home key
END End key
PAGEUP Page Up key
PAGEDOWN Page Down key
UP Up arrow
DOWN Down arrow
LEFT Left arrow
RIGHT Right arrow

Key names are case-insensitive'h', 'H', and 'Home' all work.

Returns

booleantrue if the hotkey was registered successfully, false if the key combination is already taken by another application.

Note: Returns false, does NOT throw an error. Always check the return value.

Examples

Basic — register a single hotkey

document.addEventListener('DOMContentLoaded', async () => {
    web.events.onHotkey = function(id) {
        if (id === 1) alert('Ctrl+Alt+H was pressed!');
    };

    await web.hotkey.register({ id: 1, key: 'H', modifiers: 'ctrl+alt' });
});

Restore app from minimized — bring to front with a hotkey

document.addEventListener('DOMContentLoaded', async () => {
    // Pressing Ctrl+Shift+R anywhere in Windows restores this app
    web.events.onHotkey = async function(id) {
        if (id === 1) {
            await web.app.windowRestore();
        }
    };

    const ok = await web.hotkey.register({ id: 1, key: 'R', modifiers: 'ctrl+shift' });
    if (ok) {
        console.log('Press Ctrl+Shift+R to restore this app from anywhere');
    }
});

Multiple hotkeys — different actions per key

document.addEventListener('DOMContentLoaded', async () => {
    web.events.onHotkey = async function(id) {
        switch (id) {
            case 1:
                // Bring app to front
                await web.app.windowRestore();
                break;
            case 2:
                // Quick-capture clipboard text
                const text = await web.clipboard.readText();
                addToLog(text);
                break;
            case 3:
                // Toggle app visibility
                const state = await web.window.getState();
                if (state === 'minimized') {
                    await web.app.windowRestore();
                } else {
                    await web.app.windowMinimize();
                }
                break;
        }
    };

    await web.hotkey.register({ id: 1, key: 'F12', modifiers: 'ctrl+shift' });
    await web.hotkey.register({ id: 2, key: 'C', modifiers: 'ctrl+alt' });
    await web.hotkey.register({ id: 3, key: 'H', modifiers: 'ctrl+alt' });
});

Handle registration failure gracefully

const ok = await web.hotkey.register({ id: 1, key: 'SPACE', modifiers: 'ctrl+alt' });
if (!ok) {
    // Try a fallback key combination
    const ok2 = await web.hotkey.register({ id: 1, key: 'SPACE', modifiers: 'ctrl+shift' });
    if (!ok2) {
        console.log('Could not register any hotkey — all combos taken');
    }
}

Re-register with a different key — user-configurable hotkey

// If id 1 is already registered, calling register again with the same id
// automatically unregisters the old key combo first, then registers the new one.
// No need to call unregister() manually.
await web.hotkey.register({ id: 1, key: 'H', modifiers: 'ctrl+alt' });
// ...later, user changes preference...
await web.hotkey.register({ id: 1, key: 'J', modifiers: 'ctrl+alt' });
// Now Ctrl+Alt+J fires id 1, Ctrl+Alt+H is released

Soundboard / gaming overlay — register many bare keys with no modifiers

// Register every bound key as a no-modifier global hotkey.
// Fires even when the app is minimized behind a full-screen game.
const soundMap = { 1: 'kick', 2: 'snare', 3: 'hihat', 4: 'laser' };

web.events.onHotkey = function(id) {
    playSound(soundMap[id]);
};

await web.hotkey.register({ id: 1, key: 'Q', modifiers: '' });
await web.hotkey.register({ id: 2, key: 'W', modifiers: '' });
await web.hotkey.register({ id: 3, key: 'E', modifiers: '' });
await web.hotkey.register({ id: 4, key: 'R', modifiers: '' });
// ...register as many as you need

⚠️ Bare key hotkeys steal the key from every app. Use this pattern only for dedicated hardware (macro pads, stream decks, numpads) or when the app is in an exclusive "hotkey mode" that the user explicitly enables and can toggle off.

Passthrough mode — sounds play while still typing in another app

// With passthrough: true the key is observed via WH_KEYBOARD_LL.
// The sound fires but the keypress is NOT consumed — 's' still types in Word/Notepad.
web.events.onHotkey = function(id) {
    playSound(soundMap[id]);
};

await web.hotkey.register({ id: 1, key: 'Q', modifiers: '', passthrough: true });
await web.hotkey.register({ id: 2, key: 'W', modifiers: '', passthrough: true });
await web.hotkey.register({ id: 3, key: 'E', modifiers: '', passthrough: true });

Passthrough Mode

By default (passthrough: false) the hotkey is registered with Windows RegisterHotKey. This intercepts the key — it never reaches the foreground application. This is intentional for most hotkey use cases (shortcuts, restore-from-tray, etc.) but is undesirable when the user is actively typing.

When passthrough: true:

  • The key is watched via a low-level keyboard hook (WH_KEYBOARD_LL) instead of RegisterHotKey
  • web.events.onHotkey fires normally when the key is pressed in any app
  • The key is not consumed — it still reaches the focused application (e.g. types s into Word)
  • When your own app has focus, the browser's keydown event already fires — the hook skips firing the callback to avoid double-triggering
  • modifiers is ignored in passthrough mode (the hook fires on bare VK code only)
  • unregister and unregisterAll work the same for passthrough and standard hotkeys
Mode Key consumed? Works in background? Modifier support
Standard (passthrough: false) Yes — key stolen from other apps Yes Yes
Passthrough (passthrough: true) No — key reaches foreground app Yes No

Notes

  • If you register an ID that's already registered, the old key combo is automatically unregistered and replaced with the new one
  • Key combinations claimed by Windows itself (like Ctrl+Alt+Delete) or by other running applications will cause register to return false
  • Common "safe" combinations with modifiers: Ctrl+Alt+<letter>, Ctrl+Shift+F<n>, Win+Shift+<letter>
  • No-modifier hotkeys (modifiers: '') are supported and useful for gaming/soundboard use cases, but they intercept the key globally — use with care
  • The hotkey fires regardless of which application has focus — this is a Windows-level feature, not a browser feature
  • All hotkeys are automatically cleaned up when the app exits