@@ -102,6 +102,11 @@ def __init__(self, err: int | None, descr: str | None = None) -> None:
102
102
MOVE_DOWN = "\x1b [{}B"
103
103
CLEAR = "\x1b [H\x1b [J"
104
104
105
+ # State of control keys: https://learn.microsoft.com/en-us/windows/console/key-event-record-str
106
+ ALT_ACTIVE = 0x01 | 0x02
107
+ CTRL_ACTIVE = 0x04 | 0x08
108
+ CTRL_OR_ALT_ACTIVE = ALT_ACTIVE | CTRL_ACTIVE
109
+
105
110
106
111
class _error (Exception ):
107
112
pass
@@ -407,31 +412,33 @@ def get_event(self, block: bool = True) -> Event | None:
407
412
continue
408
413
return None
409
414
410
- key = rec .Event .KeyEvent .uChar .UnicodeChar
415
+ key_event = rec .Event .KeyEvent
416
+ raw_key = key = key_event .uChar .UnicodeChar
411
417
412
- if rec . Event . KeyEvent . uChar . UnicodeChar == "\r " :
413
- # Make enter make unix-like
418
+ if key == "\r " :
419
+ # Make enter unix-like
414
420
return Event (evt = "key" , data = "\n " , raw = b"\n " )
415
- elif rec . Event . KeyEvent .wVirtualKeyCode == 8 :
421
+ elif key_event .wVirtualKeyCode == 8 :
416
422
# Turn backspace directly into the command
417
- return Event (
418
- evt = "key" ,
419
- data = "backspace" ,
420
- raw = rec .Event .KeyEvent .uChar .UnicodeChar ,
421
- )
422
- elif rec .Event .KeyEvent .uChar .UnicodeChar == "\x00 " :
423
+ key = "backspace"
424
+ elif key == "\x00 " :
423
425
# Handle special keys like arrow keys and translate them into the appropriate command
424
- code = VK_MAP .get (rec . Event . KeyEvent .wVirtualKeyCode )
426
+ code = VK_MAP .get (key_event .wVirtualKeyCode )
425
427
if code :
426
- return Event (
427
- evt = "key" , data = code , raw = rec . Event . KeyEvent . uChar . UnicodeChar
428
- )
428
+ if code in ( "left" , "right" ) and ( ctrlstate := key_event . dwControlKeyState ) and ctrlstate & CTRL_OR_ALT_ACTIVE :
429
+ code = f"ctrl { code } "
430
+ return Event ( evt = "key" , data = code , raw = key )
429
431
if block :
430
432
continue
431
433
432
434
return None
433
435
434
- return Event (evt = "key" , data = key , raw = rec .Event .KeyEvent .uChar .UnicodeChar )
436
+ if (ctrlstate := key_event .dwControlKeyState ) and ctrlstate & ALT_ACTIVE :
437
+ # first send meta, then send the key
438
+ self .event_queue .insert (0 , Event (evt = "key" , data = key , raw = raw_key ))
439
+ return Event (evt = "key" , data = "\033 " ) # keymap.py uses this for meta
440
+
441
+ return Event (evt = "key" , data = key , raw = raw_key )
435
442
436
443
def push_char (self , char : int | bytes ) -> None :
437
444
"""
0 commit comments