Files
ghostty/src/input/mouse.zig
Mitchell Hashimoto 9b35c2bb65 vt: add mouse encoding C API
Expose the internal mouse encoding functionality through the C API,
following the same pattern as the existing key encoding API. This
allows external consumers of libvt to encode mouse events into
terminal escape sequences (X10, UTF-8, SGR, URxvt, SGR-Pixels).

The API is split into two opaque handle types: GhosttyMouseEvent
for building normalized mouse events (action, button, modifiers,
position) and GhosttyMouseEncoder for converting those events into
escape sequences. The encoder is configured via a setopt interface
supporting tracking mode, output format, renderer geometry, button
state, and optional motion deduplication by last cell.

Encoder state can also be bulk-configured from a terminal handle
via ghostty_mouse_encoder_setopt_from_terminal. Failed encodes due
to insufficient buffer space report the required size without
mutating deduplication state.
2026-03-15 20:09:54 -07:00

111 lines
3.2 KiB
Zig

const std = @import("std");
/// The type of action associated with a mouse event. This is different
/// from ButtonState because button state is simply the current state
/// of a mouse button but an action is something that triggers via
/// an GUI event and supports more.
pub const Action = enum(c_int) { press, release, motion };
/// The state of a mouse button.
///
/// This is backed by a c_int so we can use this as-is for our embedding API.
///
/// IMPORTANT: Any changes here update include/ghostty.h
pub const ButtonState = enum(c_int) {
release,
press,
};
/// Possible mouse buttons. We only track up to 11 because that's the maximum
/// button input that terminal mouse tracking handles without becoming
/// ambiguous.
///
/// Its a bit silly to name numbers like this but given its a restricted
/// set, it feels better than passing around raw numeric literals.
///
/// This is backed by a c_int so we can use this as-is for our embedding API.
///
/// IMPORTANT: Any changes here update include/ghostty.h
pub const Button = enum(c_int) {
const Self = @This();
/// The maximum value in this enum. This can be used to create a densely
/// packed array, for example.
pub const max = max: {
var cur = 0;
for (@typeInfo(Self).@"enum".fields) |field| {
if (field.value > cur) cur = field.value;
}
break :max cur;
};
unknown = 0,
left = 1,
right = 2,
middle = 3,
four = 4,
five = 5,
six = 6,
seven = 7,
eight = 8,
nine = 9,
ten = 10,
eleven = 11,
};
/// The "momentum" of a mouse scroll event. This matches the macOS events
/// because it is the only reliable source right now of momentum events.
/// This is used to handle "inertial scrolling" (i.e. flicking).
///
/// https://developer.apple.com/documentation/appkit/nseventphase
pub const Momentum = enum(u3) {
none = 0,
began = 1,
stationary = 2,
changed = 3,
ended = 4,
cancelled = 5,
may_begin = 6,
};
/// The pressure stage of a pressure-sensitive input device.
///
/// This currently only supports the stages that macOS supports.
pub const PressureStage = enum(u2) {
/// The input device is unpressed.
none = 0,
/// The input device is pressed a normal amount. On macOS trackpads,
/// this is after a "click".
normal = 1,
/// The input device is pressed a deep amount. On macOS trackpads,
/// this is after a "force click".
deep = 2,
};
/// The bitmask for mods for scroll events.
pub const ScrollMods = packed struct(u8) {
/// True if this is a high-precision scroll event. For example, Apple
/// devices such as Magic Mouse, trackpads, etc. are high-precision
/// and send very detailed scroll events.
precision: bool = false,
/// The momentum phase (if available, supported) of the scroll event.
/// This is used to handle "inertial scrolling" (i.e. flicking).
momentum: Momentum = .none,
_padding: u4 = 0,
// For our own understanding
test {
const testing = std.testing;
try testing.expectEqual(@as(u8, @bitCast(ScrollMods{})), @as(u8, 0b0));
try testing.expectEqual(
@as(u8, @bitCast(ScrollMods{ .precision = true })),
@as(u8, 0b0000_0001),
);
}
};