Input Handling
The libghostty input API provides functions and types for handling keyboard and mouse events.
ghostty_surface_key
Sends a keyboard event to the surface.
bool ghostty_surface_key(
ghostty_surface_t surface,
ghostty_input_key_s key
);
surface
ghostty_surface_t
required
The surface to send the key event to.
key
ghostty_input_key_s
required
The key event data.
Returns: true if the key was handled, false otherwise.
Example:
ghostty_input_key_s key = {
.action = GHOSTTY_ACTION_PRESS,
.mods = GHOSTTY_MODS_CTRL,
.consumed_mods = GHOSTTY_MODS_NONE,
.keycode = GHOSTTY_KEY_C,
.text = "c",
.unshifted_codepoint = 'c',
.composing = false,
};
if (ghostty_surface_key(surface, key)) {
// Key was handled by terminal
}
ghostty_surface_key_is_binding
Checks if a key is bound to an action.
bool ghostty_surface_key_is_binding(
ghostty_surface_t surface,
ghostty_input_key_s key,
ghostty_binding_flags_e* flags
);
surface
ghostty_surface_t
required
The surface to check.
key
ghostty_input_key_s
required
The key to check.
Optional pointer to receive binding flags.
Returns: true if the key is bound to an action.
ghostty_surface_text
Sends text directly to the surface (for IME or pasted text).
void ghostty_surface_text(
ghostty_surface_t surface,
const char* text,
uintptr_t len
);
surface
ghostty_surface_t
required
The surface to send text to.
Length of the text in bytes.
ghostty_surface_preedit
Sends IME pre-edit text to the surface.
void ghostty_surface_preedit(
ghostty_surface_t surface,
const char* text,
uintptr_t len
);
surface
ghostty_surface_t
required
The surface.
ghostty_surface_ime_point
Gets the screen coordinates for IME candidate window positioning.
void ghostty_surface_ime_point(
ghostty_surface_t surface,
double* x,
double* y,
double* width,
double* height
);
surface
ghostty_surface_t
required
The surface.
Pointer to store X coordinate.
Pointer to store Y coordinate.
App-Level Keyboard Functions
ghostty_app_key
Sends a key event at the app level (for global keybindings).
bool ghostty_app_key(
ghostty_app_t app,
ghostty_input_key_s key
);
ghostty_app_key_is_binding
Checks if a key is bound at the app level.
bool ghostty_app_key_is_binding(
ghostty_app_t app,
ghostty_input_key_s key
);
ghostty_app_has_global_keybinds
Checks if the app has any global keybindings.
bool ghostty_app_has_global_keybinds(ghostty_app_t app);
ghostty_app_keyboard_changed
Notifies the app that the keyboard layout has changed.
void ghostty_app_keyboard_changed(ghostty_app_t app);
Sends a mouse button event to the surface.
bool ghostty_surface_mouse_button(
ghostty_surface_t surface,
ghostty_input_mouse_state_e state,
ghostty_input_mouse_button_e button,
ghostty_input_mods_e mods
);
surface
ghostty_surface_t
required
The surface.
state
ghostty_input_mouse_state_e
required
Button state (press or release).
button
ghostty_input_mouse_button_e
required
Which button was pressed.
mods
ghostty_input_mods_e
required
Modifier keys held.
Returns: true if the event was handled.
Example:
if (ghostty_surface_mouse_button(
surface,
GHOSTTY_MOUSE_PRESS,
GHOSTTY_MOUSE_LEFT,
GHOSTTY_MODS_CTRL
)) {
// Click was handled
}
ghostty_surface_mouse_pos
Sends a mouse position update to the surface.
void ghostty_surface_mouse_pos(
ghostty_surface_t surface,
double x,
double y,
ghostty_input_mods_e mods
);
surface
ghostty_surface_t
required
The surface.
mods
ghostty_input_mods_e
required
Modifier keys held.
Sends a mouse scroll event to the surface.
void ghostty_surface_mouse_scroll(
ghostty_surface_t surface,
double delta_x,
double delta_y,
ghostty_input_scroll_mods_t mods
);
surface
ghostty_surface_t
required
The surface.
mods
ghostty_input_scroll_mods_t
required
Scroll modifiers (includes momentum phase information).
ghostty_surface_mouse_pressure
Sends mouse pressure information (for force touch).
void ghostty_surface_mouse_pressure(
ghostty_surface_t surface,
uint32_t stage,
double pressure
);
surface
ghostty_surface_t
required
The surface.
Pressure value (0.0-1.0).
ghostty_surface_mouse_captured
Checks if the terminal has captured the mouse (mouse reporting mode).
bool ghostty_surface_mouse_captured(ghostty_surface_t surface);
Returns: true if the mouse is captured for terminal mouse reporting.
Describes a keyboard event.
typedef struct {
ghostty_input_action_e action;
ghostty_input_mods_e mods;
ghostty_input_mods_e consumed_mods;
uint32_t keycode;
const char* text;
uint32_t unshifted_codepoint;
bool composing;
} ghostty_input_key_s;
The key action (press, release, repeat).
Modifier keys held during the event.
Modifiers consumed by the key translation.
The text produced by the key (UTF-8, null-terminated).
The Unicode codepoint without shift modifier.
Whether this is part of an IME composition.
typedef enum {
GHOSTTY_ACTION_RELEASE,
GHOSTTY_ACTION_PRESS,
GHOSTTY_ACTION_REPEAT,
} ghostty_input_action_e;
Modifier key flags (can be combined with bitwise OR).
typedef enum {
GHOSTTY_MODS_NONE = 0,
GHOSTTY_MODS_SHIFT = 1 << 0,
GHOSTTY_MODS_CTRL = 1 << 1,
GHOSTTY_MODS_ALT = 1 << 2,
GHOSTTY_MODS_SUPER = 1 << 3,
GHOSTTY_MODS_CAPS = 1 << 4,
GHOSTTY_MODS_NUM = 1 << 5,
GHOSTTY_MODS_SHIFT_RIGHT = 1 << 6,
GHOSTTY_MODS_CTRL_RIGHT = 1 << 7,
GHOSTTY_MODS_ALT_RIGHT = 1 << 8,
GHOSTTY_MODS_SUPER_RIGHT = 1 << 9,
} ghostty_input_mods_e;
Example:
// Ctrl+Shift+C
ghostty_input_mods_e mods = GHOSTTY_MODS_CTRL | GHOSTTY_MODS_SHIFT;
// Check if Ctrl is held
if (mods & GHOSTTY_MODS_CTRL) {
// Ctrl is pressed
}
typedef enum {
GHOSTTY_MOUSE_RELEASE,
GHOSTTY_MOUSE_PRESS,
} ghostty_input_mouse_state_e;
typedef enum {
GHOSTTY_MOUSE_UNKNOWN,
GHOSTTY_MOUSE_LEFT,
GHOSTTY_MOUSE_RIGHT,
GHOSTTY_MOUSE_MIDDLE,
GHOSTTY_MOUSE_FOUR,
GHOSTTY_MOUSE_FIVE,
GHOSTTY_MOUSE_SIX,
GHOSTTY_MOUSE_SEVEN,
GHOSTTY_MOUSE_EIGHT,
GHOSTTY_MOUSE_NINE,
GHOSTTY_MOUSE_TEN,
GHOSTTY_MOUSE_ELEVEN,
} ghostty_input_mouse_button_e;
Momentum/inertial scrolling phase.
typedef enum {
GHOSTTY_MOUSE_MOMENTUM_NONE,
GHOSTTY_MOUSE_MOMENTUM_BEGAN,
GHOSTTY_MOUSE_MOMENTUM_STATIONARY,
GHOSTTY_MOUSE_MOMENTUM_CHANGED,
GHOSTTY_MOUSE_MOMENTUM_ENDED,
GHOSTTY_MOUSE_MOMENTUM_CANCELLED,
GHOSTTY_MOUSE_MOMENTUM_MAY_BEGIN,
} ghostty_input_mouse_momentum_e;
Physical key codes based on W3C UI Events KeyboardEvent code values.
typedef enum {
GHOSTTY_KEY_UNIDENTIFIED,
// Writing System Keys
GHOSTTY_KEY_BACKQUOTE,
GHOSTTY_KEY_BACKSLASH,
GHOSTTY_KEY_BRACKET_LEFT,
GHOSTTY_KEY_BRACKET_RIGHT,
GHOSTTY_KEY_COMMA,
GHOSTTY_KEY_DIGIT_0,
// ... through GHOSTTY_KEY_DIGIT_9
GHOSTTY_KEY_A,
// ... through GHOSTTY_KEY_Z
// Functional Keys
GHOSTTY_KEY_ALT_LEFT,
GHOSTTY_KEY_ALT_RIGHT,
GHOSTTY_KEY_BACKSPACE,
GHOSTTY_KEY_CAPS_LOCK,
GHOSTTY_KEY_CONTROL_LEFT,
GHOSTTY_KEY_CONTROL_RIGHT,
GHOSTTY_KEY_ENTER,
GHOSTTY_KEY_META_LEFT,
GHOSTTY_KEY_META_RIGHT,
GHOSTTY_KEY_SHIFT_LEFT,
GHOSTTY_KEY_SHIFT_RIGHT,
GHOSTTY_KEY_SPACE,
GHOSTTY_KEY_TAB,
// Control Pad
GHOSTTY_KEY_DELETE,
GHOSTTY_KEY_END,
GHOSTTY_KEY_HOME,
GHOSTTY_KEY_INSERT,
GHOSTTY_KEY_PAGE_DOWN,
GHOSTTY_KEY_PAGE_UP,
// Arrow Pad
GHOSTTY_KEY_ARROW_DOWN,
GHOSTTY_KEY_ARROW_LEFT,
GHOSTTY_KEY_ARROW_RIGHT,
GHOSTTY_KEY_ARROW_UP,
// Numpad
GHOSTTY_KEY_NUM_LOCK,
GHOSTTY_KEY_NUMPAD_0,
// ... numpad keys
// Function Keys
GHOSTTY_KEY_ESCAPE,
GHOSTTY_KEY_F1,
// ... through GHOSTTY_KEY_F25
// Media Keys
GHOSTTY_KEY_AUDIO_VOLUME_DOWN,
GHOSTTY_KEY_AUDIO_VOLUME_MUTE,
GHOSTTY_KEY_AUDIO_VOLUME_UP,
// ... other media keys
} ghostty_input_key_e;
See ghostty.h for the complete list of key codes.
ghostty_binding_flags_e
Flags for keybinding queries.
typedef enum {
GHOSTTY_BINDING_FLAGS_CONSUMED = 1 << 0,
GHOSTTY_BINDING_FLAGS_ALL = 1 << 1,
GHOSTTY_BINDING_FLAGS_GLOBAL = 1 << 2,
GHOSTTY_BINDING_FLAGS_PERFORMABLE = 1 << 3,
} ghostty_binding_flags_e;
#include <ghostty.h>
// Convert platform modifiers to ghostty modifiers
ghostty_input_mods_e convert_mods(unsigned long platform_mods) {
ghostty_input_mods_e mods = GHOSTTY_MODS_NONE;
if (platform_mods & SHIFT_MASK)
mods |= GHOSTTY_MODS_SHIFT;
if (platform_mods & CONTROL_MASK)
mods |= GHOSTTY_MODS_CTRL;
if (platform_mods & ALT_MASK)
mods |= GHOSTTY_MODS_ALT;
if (platform_mods & SUPER_MASK)
mods |= GHOSTTY_MODS_SUPER;
return mods;
}
// Handle keyboard event
void on_key_press(ghostty_surface_t surface, KeyEvent* event) {
ghostty_input_key_s key = {
.action = event->repeat ? GHOSTTY_ACTION_REPEAT : GHOSTTY_ACTION_PRESS,
.mods = convert_mods(event->modifiers),
.consumed_mods = GHOSTTY_MODS_NONE,
.keycode = event->keycode,
.text = event->text,
.unshifted_codepoint = event->unshifted_char,
.composing = event->is_composing,
};
if (!ghostty_surface_key(surface, key)) {
// Key not handled, maybe handle as app-level shortcut
}
}
// Handle mouse click
void on_mouse_click(ghostty_surface_t surface, MouseEvent* event) {
ghostty_input_mouse_button_e button;
switch (event->button) {
case BUTTON_LEFT: button = GHOSTTY_MOUSE_LEFT; break;
case BUTTON_RIGHT: button = GHOSTTY_MOUSE_RIGHT; break;
case BUTTON_MIDDLE: button = GHOSTTY_MOUSE_MIDDLE; break;
default: button = GHOSTTY_MOUSE_UNKNOWN; break;
}
ghostty_input_mouse_state_e state =
event->pressed ? GHOSTTY_MOUSE_PRESS : GHOSTTY_MOUSE_RELEASE;
ghostty_surface_mouse_button(
surface,
state,
button,
convert_mods(event->modifiers)
);
}
// Handle mouse move
void on_mouse_move(ghostty_surface_t surface, double x, double y, unsigned long mods) {
ghostty_surface_mouse_pos(surface, x, y, convert_mods(mods));
}
// Handle scroll
void on_scroll(ghostty_surface_t surface, double dx, double dy, unsigned long mods) {
ghostty_surface_mouse_scroll(surface, dx, dy, convert_mods(mods));
}
See Also