Repository: Textualize/textual

Issue:
Windows duplicates Escape key input.
Have you checked closed issues? https://github.com/Textualize/textual/issues?q=is%3Aissue+is%3Aclosed

Please give a brief but clear explanation of the issue. If you can, include a complete working example that demonstrates the bug. **Check it can run without modifications.**

It will be helpful if you run the following command and paste the results:

```
textual diagnose
```

Feel free to add screenshots and / or videos. These can be very helpful!

To reproduce run `textual keys` and press some keys. Pressing `Esc` shows two keys, other keys show only once:
![image](https://github.com/Textualize/textual/assets/70932/4adb33af-6a9e-405e-bf68-3224a6322dc3)

I think the problem is with https://github.com/Textualize/textual/blob/0ad03f3731ae922d1faa6852e14ea60e6932b198/src/textual/drivers/win32.py#L267C64-L267C64 

This line processes both the key down and the key up events for `esc` which results in it appearing as two keys in the input. Simply changing the line to read `if key_event.bKeyDown:` appears to fix the issue as `escape` now only appears once in the input and other keys such as function keys continue to work as before.


<!-- This is valid Markdown, please paste the following directly in to a GitHub issue -->
# Textual Diagnostics

## Versions

| Name    | Value  |
|---------|--------|
| Textual | 0.47.1 |
| Rich    | 13.7.0 |

## Python

| Name           | Value
       |
|----------------|---------------------------------------------------------------------------------------------------------|
| Version        | 3.12.1
       |
| Implementation | CPython
       |
| Compiler       | MSC v.1937 64 bit (AMD64)
       |
| Executable     | C:\Users\dunca\AppData\Local\pypoetry\Cache\virtualenvs\dwarf-copier-_FteSHy5-py3.12\Scripts\python.exe |

## Operating System

| Name    | Value      |
|---------|------------|
| System  | Windows    |
| Release | 11         |
| Version | 10.0.22621 |

## Terminal

| Name                 | Value            |
|----------------------|------------------|
| Terminal Application | Windows Terminal |
| TERM                 | *Not set*        |
| COLORTERM            | *Not set*        |
| FORCE_COLOR          | *Not set*        |
| NO_COLOR             | *Not set*        |

## Rich Console options

| Name           | Value                |
|----------------|----------------------|
| size           | width=116, height=30 |
| legacy_windows | False                |
| min_width      | 1                    |
| max_width      | 116                  |
| is_terminal    | True                 |
| encoding       | utf-8                |
| max_height     | 30                   |
| justify        | None                 |
| overflow       | None                 |
| no_wrap        | False                |
| highlight      | None                 |
| markup         | None                 |
| height         | None                 |



Discussion:
Hey, thanks for opening this issue and for doing some investigation beforehand.
We'll add this to our backlog!
In To Do. Suspect @kupuguy is correct about the root cause.

Resolving patch:
diff --git a/src/textual/drivers/win32.py b/src/textual/drivers/win32.py
--- a/src/textual/drivers/win32.py
+++ b/src/textual/drivers/win32.py
@@ -264,7 +264,7 @@ def run(self) -> None:
                         # Key event, store unicode char in keys list
                         key_event = input_record.Event.KeyEvent
                         key = key_event.uChar.UnicodeChar
-                        if key_event.bKeyDown or key == "\x1b":
+                        if key_event.bKeyDown:
                             if (
                                 key_event.dwControlKeyState
                                 and key_event.wVirtualKeyCode == 0


Test patch: