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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// SPDX-FileCopyrightText: Copyright (c) 2026 Mike Li/Mikewolfli/Wei Li(mikewolfli@163.com)
// SPDX-License-Identifier: MIT
//! Named key codes for the values a control actually branches on.
//!
//! # The defect this closes
//!
//! `Event::KeyPress { key, .. }` carries a raw `u32`, and control handlers compared it against
//! **literals** — `*key == 13`, `*key == 27`, `*key == 40`. Across the crate that was 19 files
//! spelling the same numbers, and the numbers say nothing about what they mean: a reader has to know
//! that 27 is Escape and 40 is Down, and the compiler cannot catch a typo like `37`/`47`. It also
//! made the tab/enter and escape conventions unsearchable — `grep '== 27'` finds some Escape
//! handlers and misses the ones spelled `0x1b`.
//!
//! # Why constants here and not the `Key` enum
//!
//! [`crate::shortcut::Key`] is the *semantic* vocabulary (it has a `Key::Enter` variant and a
//! `Key::from_key_code` parser), and a handler that wants to *name* a key should use it. But a
//! handler comparing `Event::KeyPress.key` would then have to call `Key::from_key_code(key)` on every
//! event — a `match` over ~120 arms per keystroke, in the hot path of the event loop, to answer a
//! question the caller already knows the shape of ("is this Enter?").
//!
//! So these are the cheap, exact form for the common case: `u32` literals with names, one
//! definition of each value, no parsing. A control whose condition is *semantic* ("is this the
//! shortcut's key?") still goes through `Key`; a control asking "is this Enter?" gets a constant.
//!
//! # Why these values
//!
//! They are the framework's own key-code convention, and each one is the value
//! [`crate::shortcut::Key::from_key_code`] maps to the matching variant — so a constant and its
//! `Key` spelling cannot disagree. `tests/event/key_codes_agree_with_the_shortcut_parser_test.rs`
//! asserts exactly that pairing, which is what keeps this table from drifting into a second
//! convention (principle #54).
/// The Enter key.
///
/// Also the **line feed** code, which some hosts deliver for the numeric keypad's Enter: the
/// framework treats `10` and `13` as one key (`Key::Enter` maps both), and the handlers that
/// checked for both before this module existed checked them because of exactly that.
pub const ENTER: u32 = 13;
/// The line-feed form of Enter, delivered by some hosts for the keypad's Enter key.
///
/// Separate from [`ENTER`] because a handler must accept *both* to be correct, and writing
/// `key == ENTER || key == LINE_FEED` says that where `13 || 10` did not.
pub const LINE_FEED: u32 = 10;
/// The Escape key.
pub const ESCAPE: u32 = 27;
/// The Backspace key.
pub const BACKSPACE: u32 = 8;
/// The Delete (forward-delete) key.
pub const DELETE: u32 = 46;
/// The space bar.
pub const SPACE: u32 = 32;
/// The Tab key.
pub const TAB: u32 = 9;
/// The Left arrow key.
pub const LEFT: u32 = 37;
/// The Up arrow key.
pub const UP: u32 = 38;
/// The Right arrow key.
pub const RIGHT: u32 = 39;
/// The Down arrow key.
pub const DOWN: u32 = 40;
/// The Home key.
pub const HOME: u32 = 36;
/// The End key.
pub const END: u32 = 35;
/// The Page Up key.
pub const PAGE_UP: u32 = 33;
/// The Page Down key.
pub const PAGE_DOWN: u32 = 34;