@@ -102,6 +102,10 @@ def __init__(self, err: int | None, descr: str | None = None) -> None:
102102MOVE_DOWN = "\x1b [{}B"
103103CLEAR = "\x1b [H\x1b [J"
104104
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+
105109
106110class _error (Exception ):
107111 pass
@@ -407,31 +411,37 @@ def get_event(self, block: bool = True) -> Event | None:
407411 continue
408412 return None
409413
410- key = rec .Event .KeyEvent .uChar .UnicodeChar
414+ key_event = rec .Event .KeyEvent
415+ raw_key = key = key_event .uChar .UnicodeChar
411416
412- if rec . Event . KeyEvent . uChar . UnicodeChar == "\r " :
413- # Make enter make unix-like
417+ if key == "\r " :
418+ # Make enter unix-like
414419 return Event (evt = "key" , data = "\n " , raw = b"\n " )
415- elif rec . Event . KeyEvent .wVirtualKeyCode == 8 :
420+ elif key_event .wVirtualKeyCode == 8 :
416421 # 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 " :
422+ key = "backspace"
423+ elif key == "\x00 " :
423424 # Handle special keys like arrow keys and translate them into the appropriate command
424- code = VK_MAP .get (rec .Event .KeyEvent .wVirtualKeyCode )
425- if code :
426- return Event (
427- evt = "key" , data = code , raw = rec .Event .KeyEvent .uChar .UnicodeChar
428- )
425+ key = VK_MAP .get (key_event .wVirtualKeyCode )
426+ if key :
427+ if key_event .dwControlKeyState & CTRL_ACTIVE :
428+ key = f"ctrl { key } "
429+ elif key_event .dwControlKeyState & ALT_ACTIVE :
430+ # queue the key, return the meta command
431+ self .event_queue .insert (0 , Event (evt = "key" , data = key , raw = key ))
432+ return Event (evt = "key" , data = "\033 " ) # keymap.py uses this for meta
433+ return Event (evt = "key" , data = key , raw = key )
429434 if block :
430435 continue
431436
432437 return None
433438
434- return Event (evt = "key" , data = key , raw = rec .Event .KeyEvent .uChar .UnicodeChar )
439+ if key_event .dwControlKeyState & ALT_ACTIVE :
440+ # queue the key, return the meta command
441+ self .event_queue .insert (0 , Event (evt = "key" , data = key , raw = raw_key ))
442+ return Event (evt = "key" , data = "\033 " ) # keymap.py uses this for meta
443+
444+ return Event (evt = "key" , data = key , raw = raw_key )
435445
436446 def push_char (self , char : int | bytes ) -> None :
437447 """
0 commit comments