Skip to content
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

Limited support for international keyboard layouts. #2745

Open
gitpicard opened this issue Mar 9, 2024 · 4 comments
Open

Limited support for international keyboard layouts. #2745

gitpicard opened this issue Mar 9, 2024 · 4 comments
Labels

Comments

@gitpicard
Copy link

Currently, pygame has very little to no support for keyboard layouts besides English. For example, on a French keyboard, the typical WASD is ZQSD and on my layout (German), the Z and the Y are flipped from the English layout. If a game is written to use key codes to trigger actions, this causes problem with people using keyboards other then the one the game was written with. Often the controls are awkward or almost unusable. Yes, the game developer can provide rebindable controls but this is a poor user experience when a user boots up the game for the first time and goes to play and the controls are whacky before they realize they need to change them. The first moments are critical for a game making a good impression and the game should start with the correct control map. This is why games should usually use scan codes which unlike key codes are independent of keyboard layouts. The Z scan code is always the exact same physical key in the same spot no matter the layout. Pygame does allow us to get the scan code from the key input events which is enough to correctly set up input but it does not fully solve the issue. If a game wants to render instructions to the screen, or have a settings menu with rewindable keys, etc. there is no way to figure out what letter is on a physical key. So you can't draw instructions saying "press W, A, S, D to move" on a English computer and "press Z, Q, S, D to move" on a French computer! SDL2 already provides all the functions we need to support this.

I am suggesting (and I am willing to do the work) that pygame adds two new functions: pygame.key.scan_to_key and pygame.key.key_to_scan. They will just take a key code or a scan code and convert them to the opposite. SDL2 already provides those functions via SDL_GetKeyFromScancode and SDL_GetScancodeFromKey. Should be an easy inclusion.

I will start working on this, let me know if anyone wants any other functions or different behavior or if there would be zero intentions to accept my future pull request.

@ankith26
Copy link
Member

As I don't have any experience with any international keyboard layouts, I'm not understanding how adding these functions helps, but I'd love to see your PR and figure out.

@Starbuck5
Copy link
Member

@gitpicard Are you aware that pygame-ce key events come with the scancodes already? Would this fix your problem?

if event.type == pygame.KEYDOWN:
    if event.scancode == pygame.KSCAN_0:
        print("GOT 0")

It's very uncommon to see anyone using this, I don't think it's really a well known thing to do, I was thinking the other about maybe we should make more examples using scancodes instead of keycodes, maybe it has advantages for things. I'd have to think about it more myself.

@gitpicard
Copy link
Author

@Starbuck5 yes, I am aware of that and I can use that for most things. Where it fails is when you are trying to use any of the non-event keyboard functions before the event has ever fired. Take for example a start screen that says: press space to start. If the game has bindable controls, that text needs to change depending on what key is set as the control for it. If the key has not been pressed before (which it would not have been at a start screen), you can't take the scan code and get the key code which you need to get the key name to display in the instructions... I have looked at this problem for a while, there is no way to get around providing functions to translate key code to scan code. SDL2 even provides those functions for us. We just need to implement it (which I have actually already done, I need to make a pull request for this).

The start screen is obviously a stupid example but you can understand the limitations of the current system from this. It is not possible to associate a key code to a scan code unless you get an event for it. Which means you can not determine what a given key is before it is pressed. This causes problem when trying to make a tutorial, a settings screen with rebindable controls, etc.

@ankith26 simple, let me give a simple example. WASD. Super common control layout to walk right? Go on Google and look up a French keyboard layout... look at where WASD are, WASD are super awful terrible controls on French keyboards. They use ZQSD instead. Currently, pygame maps to the location of the key that has a W symbol on it. That is what a key code does. A scan code maps to the physical location of the keyboard. Basically pretending that every keyboard is a US one. This is nice because that means that a WASD control automatically becomes ZQSD on a French keyboard. There are so many keyboard layouts it is impossible to detect and auto change them all (not to mention that pygame provides no way to tell which keyboard layout is in use as well). The problem is that there is no way in pygame to tell what symbol is on a scan key. Basically, on the physical keyboard, on the key that is a W on a US keyboard, there is no way to know that on the users keyboard it is actually a Z for example. This makes it impossible to make tutorials or show text on screen that tells the user to press a certain key, etc.

There is a workaround using the event system but that assumes that the user has already pressed the key you need. So on start up you would have to tell the user to press every single key on their keyboard... basically every framework supports this feature. SDL2 already does, we just need bindings for it (which I have written already).

Before I make a pull request, how does pygame provide type hints to IDEs like Pycharm? Do we have stub files somewhere because I need to modify those?

@ankith26
Copy link
Member

Thanks for the explanations.

The stubs are located here that you would need to modify in your PR to reflect the code changes.

In addition to these stubs, you would need to also updates the docs and tests accordingly

@MyreMylar MyreMylar added the key pygame.key label May 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants