zed-industries / zed

Code at the speed of thought – Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.
https://zed.dev
Other
39.79k stars 2.08k forks source link

(GPUI on Windows) Zed assumes keycodes originate from US Keyboards, causing mismatches in characters #12811

Open agamcsama opened 1 month ago

agamcsama commented 1 month ago

Check for existing issues

Describe the bug / provide steps to reproduce it

I am using a keyboard with a British ISO layout. I am having issues with the following characters: ' ~ ` When I am typing them into the buffer, they work as usual. However when trying to use keymaps with them, they do the actions of other binds: ctrl-' -> ctrl-~ ctrl-~ -> ctrl-' ctrl-` -> Nothing

When testing, it seems that https://www.keyboardtester.com/tester.html recieves my inputs just like Zed does when handling keymaps, pressing ' returns ~, ~ returns ' and ` doesn't even show up.

Environment

Zed: v0.140.0 (Zed Dev e829a8c3b0564bc902cc0d0a530099be7f0f036e) OS: Windows 10.0.22631 Memory: 31.8 GiB Architecture: x86_64

If applicable, add mockups / screenshots to help explain present your vision of the feature

No response

If applicable, attach your ~/Library/Logs/Zed/Zed.log file to this issue.

No response

agamcsama commented 1 month ago

After some digging, I have found a similar issue online.

The important part is that keycodes can refer to different characters on different platforms. I have found the line of code that assigns the keycode of 192 to `, however this is only true for US ANSI Keyboards, not others such as British ISO keyboards.

Here is a line of code where GPUI interprets the 192 keycode as a ` , which is incorrect behaviour. It should check, and return different characters for different keyboards, where the same keycodes can refer to different characters. https://github.com/zed-industries/zed/blob/e829a8c3b0564bc902cc0d0a530099be7f0f036e/crates/gpui/src/platform/windows/events.rs#L1272

agamcsama commented 1 month ago

I think the intended way to do this on windows would be to use the MapVirtualKeyW function (docs).

Though I am not experienced with the win32 api, I've found a crude way to replace the match statement that seems to fix the issue:

char::from_u32(MapVirtualKeyW(code as u32, MAPVK_VK_TO_CHAR)).map(String::from)

I will start working on a pull request.