or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

hotkeys.mdindex.mdinteractive-input.mdkey-simulation.mdkeyboard-events.mdrecording-playback.mdtext-processing.md

keyboard-events.mddocs/

0

# Keyboard Events

1

2

Global keyboard event monitoring and hooking system for capturing all keyboard activity system-wide. The keyboard package provides comprehensive event handling that works regardless of window focus, supporting both blocking and non-blocking event capture with filtering capabilities.

3

4

## Capabilities

5

6

### Global Event Hooking

7

8

Install global listeners that capture all keyboard events from all keyboards connected to the system.

9

10

```python { .api }

11

def hook(callback, suppress=False, on_remove=lambda: None):

12

"""

13

Installs a global listener on all available keyboards, invoking callback

14

each time a key is pressed or released.

15

16

Parameters:

17

- callback: Function to call with KeyboardEvent

18

- suppress: If True, suppresses the key from reaching other applications

19

- on_remove: Function called when hook is removed

20

21

Returns:

22

Function to remove the hook

23

"""

24

25

def unhook(remove):

26

"""

27

Removes a previously added hook, either by callback or by the return value

28

of hook().

29

30

Parameters:

31

- remove: Hook callback or remove function returned by hook()

32

"""

33

34

def unhook_all():

35

"""

36

Removes all keyboard hooks in use, including hotkeys, abbreviations, word

37

listeners, recorders and waits.

38

"""

39

```

40

41

### Event Type Filtering

42

43

Filter events by press or release actions.

44

45

```python { .api }

46

def on_press(callback, suppress=False):

47

"""

48

Invokes callback for every KEY_DOWN event.

49

50

Parameters:

51

- callback: Function to call with KeyboardEvent

52

- suppress: If True, suppresses the key from reaching other applications

53

54

Returns:

55

Function to remove the hook

56

"""

57

58

def on_release(callback, suppress=False):

59

"""

60

Invokes callback for every KEY_UP event.

61

62

Parameters:

63

- callback: Function to call with KeyboardEvent

64

- suppress: If True, suppresses the key from reaching other applications

65

66

Returns:

67

Function to remove the hook

68

"""

69

```

70

71

### Specific Key Hooking

72

73

Hook events for individual keys rather than all keyboard activity.

74

75

```python { .api }

76

def hook_key(key, callback, suppress=False):

77

"""

78

Hooks key up and key down events for a single key. Returns the event handler

79

created. To remove a hooked key use unhook_key(key) or unhook_key(handler).

80

81

Parameters:

82

- key: Key name, scan code, or key object to hook

83

- callback: Function to call with KeyboardEvent

84

- suppress: If True, suppresses the key from reaching other applications

85

86

Returns:

87

Function to remove the hook

88

"""

89

90

def on_press_key(key, callback, suppress=False):

91

"""

92

Invokes callback for KEY_DOWN event related to the given key.

93

94

Parameters:

95

- key: Key name, scan code, or key object to hook

96

- callback: Function to call with KeyboardEvent

97

- suppress: If True, suppresses the key from reaching other applications

98

99

Returns:

100

Function to remove the hook

101

"""

102

103

def on_release_key(key, callback, suppress=False):

104

"""

105

Invokes callback for KEY_UP event related to the given key.

106

107

Parameters:

108

- key: Key name, scan code, or key object to hook

109

- callback: Function to call with KeyboardEvent

110

- suppress: If True, suppresses the key from reaching other applications

111

112

Returns:

113

Function to remove the hook

114

"""

115

```

116

117

### Key Blocking and Filtering

118

119

Prevent specific keys from reaching other applications.

120

121

```python { .api }

122

def block_key(key):

123

"""

124

Suppresses all key events of the given key, regardless of modifiers.

125

126

Parameters:

127

- key: Key name, scan code, or key object to block

128

129

Returns:

130

Function to remove the block

131

"""

132

133

# Alias for removing key blocks

134

unblock_key = unhook_key # Remove key block (alias for unhook_key)

135

```

136

137

## Usage Examples

138

139

### Basic Event Monitoring

140

141

```python

142

import keyboard

143

144

def on_key_event(event):

145

print(f'Key {event.name} was {"pressed" if event.event_type == "down" else "released"}')

146

print(f'Scan code: {event.scan_code}, Time: {event.time}')

147

148

# Install global hook

149

remove_hook = keyboard.hook(on_key_event)

150

151

# Let it run for a while

152

keyboard.wait('esc')

153

154

# Clean up

155

remove_hook()

156

```

157

158

### Press-Only Monitoring

159

160

```python

161

import keyboard

162

163

def on_key_press(event):

164

print(f'Key pressed: {event.name}')

165

if event.name in ['ctrl', 'alt', 'shift']:

166

print('Modifier key detected!')

167

168

keyboard.on_press(on_key_press)

169

keyboard.wait('esc')

170

```

171

172

### Specific Key Monitoring

173

174

```python

175

import keyboard

176

177

def on_space_press(event):

178

print('Space bar pressed!')

179

180

def on_enter_press(event):

181

print('Enter key pressed!')

182

183

# Hook specific keys

184

keyboard.on_press_key('space', on_space_press)

185

keyboard.on_press_key('enter', on_enter_press)

186

187

keyboard.wait('esc')

188

keyboard.unhook_all()

189

```

190

191

### Key Blocking

192

193

```python

194

import keyboard

195

196

# Block the Windows key

197

remove_block = keyboard.block_key('windows')

198

199

print('Windows key is now blocked. Press ESC to exit.')

200

keyboard.wait('esc')

201

202

# Restore the Windows key

203

remove_block()

204

```

205

206

### Event Suppression

207

208

```python

209

import keyboard

210

211

def log_and_suppress(event):

212

print(f'Intercepted: {event.name}')

213

return False # Suppress the event

214

215

# Suppress all 'a' key presses

216

keyboard.hook_key('a', log_and_suppress, suppress=True)

217

218

print('All "a" key presses are now suppressed. Press ESC to exit.')

219

keyboard.wait('esc')

220

keyboard.unhook_all()

221

```

222

223

## Event Object Details

224

225

```python { .api }

226

class KeyboardEvent:

227

"""

228

Represents a keyboard event with complete timing and key information.

229

"""

230

event_type: str # 'down' for press, 'up' for release

231

scan_code: int # Physical key identifier (hardware-specific)

232

name: str # Human-readable key name (e.g., 'a', 'space', 'ctrl')

233

time: float # Event timestamp in seconds since epoch

234

device: int # Device identifier (None on Windows)

235

modifiers: list # List of active modifier keys

236

is_keypad: bool # True if key is from numeric keypad

237

238

def to_json(self, ensure_ascii=False) -> str:

239

"""Serialize event to JSON string."""

240

```

241

242

### Event Constants

243

244

```python { .api }

245

KEY_DOWN: str = 'down' # Event type for key press

246

KEY_UP: str = 'up' # Event type for key release

247

```

248

249

## Key Names and Normalization

250

251

The keyboard package normalizes key names for consistent cross-platform behavior:

252

253

```python { .api }

254

def normalize_name(name: str) -> str:

255

"""

256

Given a key name (e.g. "LEFT CONTROL"), clean up the string and convert to

257

the canonical representation (e.g. "left ctrl") if one is known.

258

259

Parameters:

260

- name: Raw key name to normalize

261

262

Returns:

263

Normalized key name

264

"""

265

```

266

267

Common key name mappings:

268

- `'return'``'enter'`

269

- `'control'``'ctrl'`

270

- `'left arrow'``'left'`

271

- `'spacebar'``'space'`

272

- `'escape'``'esc'`

273

274

## Platform-Specific Behavior

275

276

### Windows

277

- Full event suppression support

278

- Device identification unavailable (`event.device == None`)

279

- Complete modifier key detection

280

281

### Linux

282

- Requires root privileges for global hooks

283

- Media keys may appear nameless or not at all

284

- Event suppression not supported

285

286

### macOS

287

- Experimental support with some limitations

288

- Requires pyobjc dependency

289

- Limited event suppression capabilities

290

291

## Error Handling

292

293

Event hooks can fail if:

294

- Insufficient privileges (Linux requires root)

295

- Platform limitations (macOS experimental support)

296

- System security restrictions (some games may swallow events)

297

298

The package will raise `OSError` for unsupported platforms and may silently fail to capture events in restricted environments.