aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/libghostty-vt/src/input/mouse.zig
blob: fad3ed67af497e9131c5da336137d8d7d398c487 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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),
        );
    }
};