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

Add a way to differentiate Left and Right Shift, Alt, and Control keys #1387

Closed
krscott opened this issue Aug 19, 2020 · 7 comments · Fixed by godotengine/godot#80231
Closed
Milestone

Comments

@krscott
Copy link

krscott commented Aug 19, 2020

Describe the project you are working on:
A pinball-style game with left and right flippers.

Describe the problem or limitation you are having in your project:
I would like the option of using the left and right Shift keys as left and right paddles for users with tenkeyless or shorter keyboards, however, the Input Map treats these keys both as "Shift", and the InputEventKey scancode is 16777237 for both keys.

Describe the feature / enhancement and how it helps to overcome the problem or limitation:
If there was a way to differentiate left and right Shift keys, it would be possible to use these keys for separate functions.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
I can imagine two ways to solve this issue:

  1. Add KEY_RIGHT_SHIFT, KEY_RIGHT_ALT, KEY_RIGHT_CONTROL to the KeyList enum.
func _input(ev):
  if ev is InputEventKey:
    match ev.scancode:
      KEY_SHIFT:
        print("left shift")
      KEY_RIGHT_SHIFT:
        print("right shift")
  1. Add a location field to InputEventKey with a new enum for left/right. This would preserve the current functionality of KEY_SHIFT, etc., but probably would require more changes to get working with the Input Map menu.
func _input(ev):
  if ev is InputEventKey and ev.scancode == KEY_SHIFT:
    match ev.location:
      MULTIKEY_LOCATION_LEFT:
        print("left shift")
      MULTIKEY_LOCATION_RIGHT:
        print("right shift")

If this enhancement will not be used often, can it be worked around with a few lines of script?:
I'm not aware of any possible way to work around this issue in GDScript.

Is there a reason why this should be core and not an add-on in the asset library?:
This feature would require adding to the GlobalScope KeyList enum or adding an enum to InputEventKey.

@KoBeWi
Copy link
Member

KoBeWi commented Aug 19, 2020

The first solution is better and 4.0 is a good chance to add it.
Someone already made an attempt to implement this: godotengine/godot#27991

@bojidar-bg
Copy link

Note: As implementing (1) will definitely break compatibility, there is no point in leaving a constant named KEY_SHIFT, instead both constant names should include the location, as in KEY_LEFT_SHIFT and KEY_RIGHT_SHIFT.

@TheDuriel
Copy link

There should be all three, KEY_SHIFT, left, and right.
Otherwise you are asking people to do redundant work when they want to use shift, and not a specific side.

(Thus would mean that pressing shift emitts two events, not just one. But that should be fine.)

Also, if any of this is done for shift. It needs to be done for CTL, ALT and mac/win keys as well.

@krscott
Copy link
Author

krscott commented Aug 20, 2020

@TheDuriel This would require more work for other cases, though. For instance, an in-game menu that asks a user for a keybinding would need to handle every possible case of double-events, whereas now it only needs to save the scancode. I think that most use cases where the code doesn't care which modifier key is for handling combos (e.g. Ctrl+S), but this would still be possible by reading the modifier value in InputEventWithModifiers.

Maybe these new behaviors could be configurable in the project settings and just let the author decide if they want separate LEFT/RIGHT scancodes or not.

@TheDuriel
Copy link

TheDuriel commented Aug 20, 2020

I don't see how this would require more work. Right now the proposal is to split them anyways, and make treating them generally impossible.

What I'm proposing that we let BOTH happen. Pressing a modifier sends the modifer key, and the left or right variant. One press, two events. No compatibility problems.

@Sauermann
Copy link

This is also discussed in godotengine/godot#3347

@romlok
Copy link

romlok commented Jul 31, 2023

Is there even any workaround for this right now?

For all of Shift, Ctrl, Alt and Meta ("windows"), all the functions and properties of an InputEventKey make the physical keys indistinguishable as far as I can tell?

I would much rather see a partial solution where it becomes possible to distinguish between the keys - even with a hack - than to wait for someone to implement a satisfactory complete solution, which would have to wait until a next major version anyway.

So absent anything like this already existing that I've missed, I'd like to reiterate and push for something more like the OP's second suggestion as an interim solution:

func _input(ev):
  if ev is InputEventKey and ev.keycode == KEY_SHIFT:
    match ev.location:
      MULTIKEY_LOCATION_LEFT:
        print("left shift")
      MULTIKEY_LOCATION_RIGHT:
        print("right shift")

AFAICT it should be far simpler and easier to implement (and backport), and could be released as part of a minor version, rather than waiting for the next compatibility-breaking release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment