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

hotkeys.mddocs/

0

# Hotkeys

1

2

Registration and management of complex keyboard shortcuts, including multi-step hotkey sequences, global hotkey detection, and advanced hotkey remapping capabilities. The keyboard package provides comprehensive hotkey functionality that works system-wide regardless of application focus.

3

4

## Capabilities

5

6

### Hotkey Registration

7

8

Register callbacks to be executed when specific key combinations are pressed.

9

10

```python { .api }

11

def add_hotkey(hotkey, callback, args=(), suppress=False, timeout=1, trigger_on_release=False):

12

"""

13

Invokes a callback every time a hotkey is pressed. The hotkey must be in

14

the format 'ctrl+shift+a, s'. This would trigger when the user holds ctrl,

15

shift and "a" at once, releases, and then presses "s".

16

17

Parameters:

18

- hotkey: Hotkey string (e.g., 'ctrl+c', 'ctrl+shift+a, s')

19

- callback: Function to call when hotkey is triggered

20

- args: Optional arguments to pass to callback

21

- suppress: If True, prevent hotkey from reaching other applications

22

- timeout: Seconds allowed between steps in multi-step hotkeys

23

- trigger_on_release: If True, trigger on key release instead of press

24

25

Returns:

26

Function to remove the hotkey

27

28

Examples:

29

- add_hotkey('ctrl+c', copy_function)

30

- add_hotkey('f1', show_help)

31

- add_hotkey('ctrl+shift+s, ctrl+v', special_paste)

32

"""

33

34

def register_hotkey(hotkey, callback, args=(), suppress=False, timeout=1, trigger_on_release=False):

35

"""Alias for add_hotkey()."""

36

```

37

38

### Hotkey Removal

39

40

Remove previously registered hotkeys by hotkey string or callback reference.

41

42

```python { .api }

43

def remove_hotkey(hotkey_or_callback):

44

"""

45

Removes a previously hooked hotkey. Must be called with the hotkey string

46

used in add_hotkey() or the callback function.

47

48

Parameters:

49

- hotkey_or_callback: Hotkey string or callback function to remove

50

"""

51

52

def clear_hotkey(hotkey_or_callback):

53

"""Alias for remove_hotkey()."""

54

55

def unregister_hotkey(hotkey_or_callback):

56

"""Alias for remove_hotkey()."""

57

58

def unhook_all_hotkeys():

59

"""

60

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

61

recorders and waits.

62

"""

63

64

def clear_all_hotkeys():

65

"""Alias for unhook_all_hotkeys()."""

66

67

def remove_all_hotkeys():

68

"""Alias for unhook_all_hotkeys()."""

69

70

def unregister_all_hotkeys():

71

"""Alias for unhook_all_hotkeys()."""

72

```

73

74

### Hotkey Remapping

75

76

Remap hotkeys to other hotkey combinations with optional suppression.

77

78

```python { .api }

79

def remap_hotkey(src, dst, suppress=True, trigger_on_release=False):

80

"""

81

Whenever the hotkey src is pressed, suppress it and send dst instead.

82

83

Parameters:

84

- src: Source hotkey to remap

85

- dst: Destination hotkey to send instead

86

- suppress: If True, suppress the original hotkey

87

- trigger_on_release: If True, trigger on key release

88

89

Returns:

90

Function to remove the remapping

91

92

Example:

93

remap_hotkey('alt+w', 'ctrl+up') # Remap Alt+W to Ctrl+Up

94

"""

95

96

def unremap_hotkey(hotkey):

97

"""Alias for remove_hotkey()."""

98

```

99

100

### Hotkey Utilities

101

102

Utility functions for working with hotkey strings and current key states.

103

104

```python { .api }

105

def get_hotkey_name(names=None):

106

"""

107

Returns a string representation of hotkey from the given key names, or

108

the currently pressed keys if not given.

109

110

Parameters:

111

- names: List of key names (optional, uses currently pressed keys if None)

112

113

Returns:

114

str: Standardized hotkey string

115

116

Example:

117

get_hotkey_name(['ctrl', 'shift', 'a']) # Returns 'ctrl+shift+a'

118

"""

119

120

def parse_hotkey_combinations(hotkey):

121

"""

122

Parses a user-provided hotkey. Instead of each step being a list of the

123

different scan codes for each key, each step is a list of all possible

124

combinations of those scan codes.

125

126

Parameters:

127

- hotkey: Hotkey string to parse

128

129

Returns:

130

tuple: All possible scan code combinations for the hotkey

131

"""

132

```

133

134

## Usage Examples

135

136

### Basic Hotkey Registration

137

138

```python

139

import keyboard

140

141

def on_ctrl_c():

142

print('Ctrl+C was pressed!')

143

144

def on_f1():

145

print('F1 Help key pressed!')

146

147

def on_custom_hotkey():

148

print('Custom hotkey Ctrl+Shift+H pressed!')

149

150

# Register hotkeys

151

keyboard.add_hotkey('ctrl+c', on_ctrl_c)

152

keyboard.add_hotkey('f1', on_f1)

153

keyboard.add_hotkey('ctrl+shift+h', on_custom_hotkey)

154

155

print('Hotkeys registered. Press ESC to exit.')

156

keyboard.wait('esc')

157

158

# Clean up

159

keyboard.unhook_all_hotkeys()

160

```

161

162

### Hotkeys with Arguments

163

164

```python

165

import keyboard

166

167

def show_message(msg, count=1):

168

for i in range(count):

169

print(f'{msg} ({i+1})')

170

171

# Hotkey with arguments

172

keyboard.add_hotkey('f2', show_message, args=('Hello from F2!', 3))

173

keyboard.add_hotkey('f3', show_message, args=('Quick message',))

174

175

keyboard.wait('esc')

176

keyboard.unhook_all_hotkeys()

177

```

178

179

### Multi-Step Hotkeys

180

181

```python

182

import keyboard

183

184

def konami_code():

185

print('Konami code activated!')

186

187

def quick_save():

188

print('Quick save sequence activated!')

189

190

# Multi-step hotkey sequences

191

keyboard.add_hotkey('up, up, down, down, left, right, left, right, b, a', konami_code)

192

keyboard.add_hotkey('ctrl+s, ctrl+s', quick_save, timeout=2) # Double Ctrl+S within 2 seconds

193

194

keyboard.wait('esc')

195

keyboard.unhook_all_hotkeys()

196

```

197

198

### Hotkey Suppression

199

200

```python

201

import keyboard

202

203

def custom_alt_f4():

204

print('Alt+F4 intercepted! Custom close behavior.')

205

# Could implement custom confirmation dialog here

206

return False # Suppress the original Alt+F4

207

208

# Suppress Alt+F4 and replace with custom behavior

209

keyboard.add_hotkey('alt+f4', custom_alt_f4, suppress=True)

210

211

print('Alt+F4 is now intercepted. Press ESC to exit.')

212

keyboard.wait('esc')

213

keyboard.unhook_all_hotkeys()

214

```

215

216

### Dynamic Hotkey Management

217

218

```python

219

import keyboard

220

221

hotkey_callbacks = {}

222

223

def register_dynamic_hotkey(hotkey_str, message):

224

def callback():

225

print(f'Dynamic hotkey: {message}')

226

227

remove_func = keyboard.add_hotkey(hotkey_str, callback)

228

hotkey_callbacks[hotkey_str] = remove_func

229

print(f'Registered: {hotkey_str}')

230

231

def unregister_dynamic_hotkey(hotkey_str):

232

if hotkey_str in hotkey_callbacks:

233

hotkey_callbacks[hotkey_str]() # Call remove function

234

del hotkey_callbacks[hotkey_str]

235

print(f'Unregistered: {hotkey_str}')

236

237

# Register some dynamic hotkeys

238

register_dynamic_hotkey('f5', 'Refresh action')

239

register_dynamic_hotkey('f6', 'Toggle action')

240

register_dynamic_hotkey('ctrl+1', 'Workspace 1')

241

242

print('Dynamic hotkeys registered. Press F9 to remove F5, F10 to exit.')

243

244

def remove_f5():

245

unregister_dynamic_hotkey('f5')

246

247

keyboard.add_hotkey('f9', remove_f5)

248

keyboard.wait('f10')

249

250

# Clean up all remaining hotkeys

251

for remove_func in hotkey_callbacks.values():

252

remove_func()

253

```

254

255

### Hotkey Remapping

256

257

```python

258

import keyboard

259

260

# Remap Windows key combinations for different workflow

261

remove_remap1 = keyboard.remap_hotkey('win+l', 'ctrl+alt+l') # Custom lock

262

remove_remap2 = keyboard.remap_hotkey('win+d', 'alt+tab') # Show desktop -> Alt+Tab

263

264

# Remap for left-handed users

265

remove_remap3 = keyboard.remap_hotkey('ctrl+c', 'ctrl+insert') # Alternative copy

266

remove_remap4 = keyboard.remap_hotkey('ctrl+v', 'shift+insert') # Alternative paste

267

268

print('Hotkey remapping active. Press ESC to exit.')

269

keyboard.wait('esc')

270

271

# Remove all remappings

272

remove_remap1()

273

remove_remap2()

274

remove_remap3()

275

remove_remap4()

276

```

277

278

### Context-Sensitive Hotkeys

279

280

```python

281

import keyboard

282

283

class HotkeyManager:

284

def __init__(self):

285

self.mode = 'normal'

286

self.hotkeys = {}

287

self.setup_mode_hotkeys()

288

289

def setup_mode_hotkeys(self):

290

# Mode switching

291

self.hotkeys['f12'] = keyboard.add_hotkey('f12', self.toggle_mode)

292

293

# Context-sensitive hotkeys

294

self.hotkeys['1'] = keyboard.add_hotkey('1', self.handle_1_key)

295

self.hotkeys['2'] = keyboard.add_hotkey('2', self.handle_2_key)

296

297

def toggle_mode(self):

298

self.mode = 'editing' if self.mode == 'normal' else 'normal'

299

print(f'Switched to {self.mode} mode')

300

301

def handle_1_key(self):

302

if self.mode == 'normal':

303

print('Normal mode: Action 1')

304

else:

305

print('Editing mode: Edit action 1')

306

307

def handle_2_key(self):

308

if self.mode == 'normal':

309

print('Normal mode: Action 2')

310

else:

311

print('Editing mode: Edit action 2')

312

313

def cleanup(self):

314

for remove_func in self.hotkeys.values():

315

remove_func()

316

317

# Usage

318

manager = HotkeyManager()

319

print('Context-sensitive hotkeys active. F12 to toggle mode, ESC to exit.')

320

keyboard.wait('esc')

321

manager.cleanup()

322

```

323

324

## Advanced Hotkey Features

325

326

### Timeout Control

327

328

```python

329

import keyboard

330

331

def slow_sequence():

332

print('Slow sequence completed!')

333

334

def fast_sequence():

335

print('Fast sequence completed!')

336

337

# Different timeout values for different sequences

338

keyboard.add_hotkey('ctrl+a, ctrl+b', slow_sequence, timeout=5) # 5 seconds allowed

339

keyboard.add_hotkey('ctrl+x, ctrl+y', fast_sequence, timeout=0.5) # 0.5 seconds allowed

340

341

keyboard.wait('esc')

342

keyboard.unhook_all_hotkeys()

343

```

344

345

### Release-Triggered Hotkeys

346

347

```python

348

import keyboard

349

350

def on_key_release():

351

print('Hotkey triggered on release!')

352

353

def on_key_press():

354

print('Hotkey triggered on press!')

355

356

# Compare press vs release triggering

357

keyboard.add_hotkey('f7', on_key_press, trigger_on_release=False)

358

keyboard.add_hotkey('f8', on_key_release, trigger_on_release=True)

359

360

keyboard.wait('esc')

361

keyboard.unhook_all_hotkeys()

362

```

363

364

## Hotkey String Format

365

366

### Single Key Hotkeys

367

- `'f1'` - Function keys

368

- `'a'` - Letter keys

369

- `'space'` - Named keys

370

- `'enter'` - Special keys

371

372

### Modifier Combinations

373

- `'ctrl+c'` - Single modifier

374

- `'ctrl+shift+a'` - Multiple modifiers

375

- `'alt+f4'` - Case insensitive

376

377

### Multi-Step Sequences

378

- `'ctrl+k, ctrl+c'` - Visual Studio style

379

- `'ctrl+x, ctrl+c'` - Emacs style

380

- `'g, g'` - Vim style (double key)

381

382

### Special Key Names

383

- `'plus'` for '+' symbol

384

- `'comma'` for ',' symbol

385

- `'space'` for spacebar

386

- `'left ctrl'` / `'right ctrl'` for sided modifiers

387

388

## Error Handling

389

390

Hotkey registration may fail due to:

391

- Invalid hotkey format strings

392

- Platform limitations (Linux requires root for global hotkeys)

393

- Conflicting hotkey registrations

394

- System security restrictions

395

396

The package will raise `ValueError` for invalid hotkey strings and may silently fail to register hotkeys in restricted environments.

397

398

## Performance Considerations

399

400

- Hotkeys with many modifiers are more expensive to detect

401

- Multi-step hotkeys require state tracking and timeout management

402

- Suppressed hotkeys add processing overhead

403

- Large numbers of registered hotkeys can impact system responsiveness

404

405

For optimal performance:

406

- Use specific hotkeys rather than broad key hooks when possible

407

- Remove unused hotkeys promptly

408

- Avoid overlapping hotkey patterns that could cause conflicts