Skip to content

ext_shortcuts

The ext_shortcuts crate provides global keyboard shortcut registration for Forge applications through the runtime:shortcuts module.

Overview

ext_shortcuts handles:

  • Global hotkeys - System-wide keyboard shortcuts
  • Shortcut registration - Register/unregister shortcuts
  • Modifier keys - Ctrl, Alt, Shift, Meta/Cmd
  • Key combinations - Multi-key shortcuts
  • Conflict detection - Handle existing shortcuts

Module: runtime:shortcuts

import {
register,
unregister,
unregisterAll,
isRegistered
} from "runtime:shortcuts";

Key Types

Error Types

enum ShortcutsErrorCode {
Generic = 10000,
RegisterFailed = 10001,
UnregisterFailed = 10002,
AlreadyRegistered = 10003,
InvalidShortcut = 10004,
ConflictingShortcut = 10005,
}
struct ShortcutsError {
code: ShortcutsErrorCode,
message: String,
}

Shortcut Types

struct Shortcut {
id: u32,
accelerator: String,
callback: ShortcutCallback,
}
struct ShortcutEvent {
id: u32,
accelerator: String,
timestamp: u64,
}
enum Modifier {
Ctrl,
Alt,
Shift,
Meta, // Cmd on macOS, Win on Windows
Super, // Win key
}
struct ShortcutState {
shortcuts: HashMap<u32, Shortcut>,
next_id: u32,
}

Operations

OpTypeScriptDescription
op_shortcuts_registerregister(accelerator, callback)Register shortcut
op_shortcuts_unregisterunregister(id)Remove shortcut
op_shortcuts_unregister_allunregisterAll()Remove all shortcuts
op_shortcuts_is_registeredisRegistered(accelerator)Check if registered

Usage Examples

Basic Registration

import { register, unregister } from "runtime:shortcuts";
// Register Ctrl+Shift+P (Cmd+Shift+P on macOS)
const shortcut = await register("CmdOrCtrl+Shift+P", () => {
console.log("Command palette triggered!");
showCommandPalette();
});
// Later: unregister
await unregister(shortcut.id);

Multiple Shortcuts

import { register, unregisterAll } from "runtime:shortcuts";
// Register multiple shortcuts
await register("CmdOrCtrl+N", () => createNewDocument());
await register("CmdOrCtrl+O", () => openDocument());
await register("CmdOrCtrl+S", () => saveDocument());
await register("CmdOrCtrl+Shift+S", () => saveDocumentAs());
await register("CmdOrCtrl+W", () => closeDocument());
// Cleanup on exit
await unregisterAll();

Media Keys

import { register } from "runtime:shortcuts";
await register("MediaPlayPause", () => togglePlayback());
await register("MediaNextTrack", () => nextTrack());
await register("MediaPreviousTrack", () => previousTrack());
await register("MediaStop", () => stopPlayback());

Function Keys

import { register } from "runtime:shortcuts";
await register("F5", () => refresh());
await register("Ctrl+F5", () => hardRefresh());
await register("F11", () => toggleFullscreen());
await register("F12", () => openDevTools());

Accelerator Format

FormatExampleDescription
Single keyF1, A, SpaceSingle key press
With modifierCtrl+A, Alt+F4Modifier + key
Multiple modifiersCtrl+Shift+SMultiple modifiers
Cross-platformCmdOrCtrl+CCmd on macOS, Ctrl elsewhere
Special keysMediaPlayPause, VolumeUpMedia/system keys

Modifier Keys

ModifiermacOSWindows/Linux
Cmd⌘ Command-
Ctrl⌃ ControlCtrl
Alt⌥ OptionAlt
Shift⇧ ShiftShift
Meta⌘ CommandWin
CmdOrCtrl⌘ CommandCtrl

File Structure

crates/ext_shortcuts/
├── src/
│ └── lib.rs # Extension implementation
├── ts/
│ └── init.ts # TypeScript module shim
├── build.rs # forge-weld build configuration
└── Cargo.toml

Rust Implementation

Operations are annotated with forge-weld macros for automatic TypeScript binding generation:

src/lib.rs
use deno_core::{op2, Extension, OpState};
use forge_weld_macro::{weld_op, weld_struct};
use serde::{Deserialize, Serialize};
#[weld_struct]
#[derive(Debug, Serialize)]
pub struct ShortcutHandle {
pub id: u32,
pub accelerator: String,
}
#[weld_op(async)]
#[op2(async)]
#[serde]
pub async fn op_shortcuts_register(
state: Rc<RefCell<OpState>>,
#[string] accelerator: String,
) -> Result<ShortcutHandle, ShortcutsError> {
// implementation
}

Build Configuration

build.rs
use forge_weld::ExtensionBuilder;
fn main() {
ExtensionBuilder::new("runtime_shortcuts", "runtime:shortcuts")
.ts_path("ts/init.ts")
.ops(&["op_shortcuts_register", "op_shortcuts_unregister", "op_shortcuts_is_registered"])
.generate_sdk_module("sdk")
.use_inventory_types()
.build()
.expect("Failed to build runtime_shortcuts extension");
}

Dependencies

DependencyPurpose
deno_coreOp definitions
global-hotkeyCross-platform hotkeys
serdeSerialization
tokioAsync runtime
forge-weldBuild-time code generation
forge-weld-macro#[weld_op], #[weld_struct] macros
linkmeCompile-time symbol collection