-
-
Notifications
You must be signed in to change notification settings - Fork 35k
gh-127947: Repeat PyREPL key events on Windows when wRepeatCount > 1 #127948
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
975bf7b
215894d
50f260a
655a98e
e77c89d
825ccaf
72e380d
a68e045
ebe00f0
1f7bf1f
fa12c70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -346,7 +346,7 @@ def move_cursor(self, x: int, y: int) -> None: | |
| raise ValueError(f"Bad cursor position {x}, {y}") | ||
|
|
||
| if y < self.__offset or y >= self.__offset + self.height: | ||
| self.event_queue.insert(0, Event("scroll", "")) | ||
| self.event_queue.appendleft(Event("scroll", "")) | ||
| else: | ||
| self._move_relative(x, y) | ||
| self.__posxy = x, y | ||
|
|
@@ -411,37 +411,47 @@ def get_event(self, block: bool = True) -> Event | None: | |
| continue | ||
| return None | ||
|
|
||
| key_event = rec.Event.KeyEvent | ||
| raw_key = key = key_event.uChar.UnicodeChar | ||
|
|
||
| if key == "\r": | ||
| # Make enter unix-like | ||
| return Event(evt="key", data="\n", raw=b"\n") | ||
| elif key_event.wVirtualKeyCode == 8: | ||
| # Turn backspace directly into the command | ||
| key = "backspace" | ||
| elif key == "\x00": | ||
| # Handle special keys like arrow keys and translate them into the appropriate command | ||
| key = VK_MAP.get(key_event.wVirtualKeyCode) | ||
| if key: | ||
| if key_event.dwControlKeyState & CTRL_ACTIVE: | ||
| key = f"ctrl {key}" | ||
| elif key_event.dwControlKeyState & ALT_ACTIVE: | ||
| # queue the key, return the meta command | ||
| self.event_queue.insert(0, Event(evt="key", data=key, raw=key)) | ||
| return Event(evt="key", data="\033") # keymap.py uses this for meta | ||
| return Event(evt="key", data=key, raw=key) | ||
| if block: | ||
| continue | ||
| event = self._event_from_keyevent(rec.Event.KeyEvent) | ||
|
|
||
| if event is not None: | ||
| # Queue this key event to be repeated if wRepeatCount > 1, such as when a 'dead key' is pressed twice | ||
| for _ in range(rec.Event.KeyEvent.wRepeatCount - 1): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens when a key with |
||
| self.event_queue.appendleft(event) | ||
| elif block: | ||
| # The key event didn't actually type a character, block until next event | ||
| continue | ||
|
|
||
| return event | ||
|
|
||
| def _event_from_keyevent(self, key_event: KeyEvent) -> Event | None: | ||
| raw_key = key = key_event.uChar.UnicodeChar | ||
|
|
||
| if key == "\r": | ||
| # Make enter unix-like | ||
| return Event(evt="key", data="\n", raw=b"\n") | ||
| elif key_event.wVirtualKeyCode == 8: | ||
| # Turn backspace directly into the command | ||
| key = "backspace" | ||
| elif key == "\x00": | ||
| # Handle special keys like arrow keys and translate them into the appropriate command | ||
| key = VK_MAP.get(key_event.wVirtualKeyCode) | ||
| if key: | ||
| if key_event.dwControlKeyState & CTRL_ACTIVE: | ||
| key = f"ctrl {key}" | ||
| elif key_event.dwControlKeyState & ALT_ACTIVE: | ||
| # queue the key, return the meta command | ||
| self.event_queue.appendleft(Event(evt="key", data=key, raw=key)) | ||
| return Event(evt="key", data="\033") # keymap.py uses this for meta | ||
| return Event(evt="key", data=key, raw=key) | ||
|
|
||
| return None | ||
| return None | ||
|
|
||
| if key_event.dwControlKeyState & ALT_ACTIVE: | ||
| # queue the key, return the meta command | ||
| self.event_queue.insert(0, Event(evt="key", data=key, raw=raw_key)) | ||
| return Event(evt="key", data="\033") # keymap.py uses this for meta | ||
| if key_event.dwControlKeyState & ALT_ACTIVE: | ||
| # queue the key, return the meta command | ||
| self.event_queue.appendleft(Event(evt="key", data=key, raw=raw_key)) | ||
| return Event(evt="key", data="\033") # keymap.py uses this for meta | ||
|
|
||
| return Event(evt="key", data=key, raw=raw_key) | ||
| return Event(evt="key", data=key, raw=raw_key) | ||
|
|
||
| def push_char(self, char: int | bytes) -> None: | ||
| """ | ||
|
|
@@ -489,7 +499,7 @@ def wait(self, timeout: float | None) -> bool: | |
| # Poor man's Windows select loop | ||
| start_time = time.time() | ||
| while True: | ||
| if msvcrt.kbhit(): # type: ignore[attr-defined] | ||
| if msvcrt.kbhit() or self.event_queue: # type: ignore[attr-defined] | ||
| return True | ||
| if timeout and time.time() - start_time > timeout / 1000: | ||
| return False | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Fix double dead key presses in PyREPL being typed just once into Windows Terminal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only repeats the returned
Escevent forALT_ACTIVEkeys.Alt+awithwRepeatCount == 2becomesEsc, a, Esc, so we lose the seconda. Can we repeat the full translated sequence here?