Silk.NET icon indicating copy to clipboard operation
Silk.NET copied to clipboard

Missing keyboard input functionality

Open ThomasMiz opened this issue 4 years ago • 11 comments

There currently doesn't appear to be a way to properly detect some keys for keyboard typing input.

The Keyboard.KeyChar provides the characters typed, and keys such as Enter, Backspace, Tab, Delete can be detected via KeyDown. However, if the user is pressing down on the backspace key, the only thing we can register with this system is a single backspace press, and no repeats.

Looking at the GLFW input guide, there aren't just "key down" and "key up" actions, but there's also a "key repeat" action which we're probably ignoring.

We should try to present all these parameters in our KeyChar, KeyDown and KeyUp events.

ThomasMiz avatar Jan 04 '21 16:01 ThomasMiz

I'm not that familiarized with SILK but it seems that the event is being purposely ignored in GlfwKeyboard.cs, line 49

        _handle = events.Handle;
        events.Char += _char = (_, c) => KeyChar?.Invoke(this, (char) c);
        events.Key += _key = (_, key, code, action, mods) =>
            (action switch
            {
                InputAction.Press => KeyDown,
                InputAction.Release => KeyUp,
                InputAction.Repeat => null,
                _ => null
            })?.Invoke(this, ConvertKey(key), code);`

SanFlan avatar Jan 04 '21 20:01 SanFlan

I think it's a good idea to propose some changes to the input events so we can pass all these parameters to the user of the library.

We'll have to add more parameters to the KeyDown & other events, which will mean everyone will have to add them to their event handlers as well. It might be a good idea to do as OpenTK and aggregate all these parameters into a single struct called KeyEventArgs or something like that, which will be the sole parameter of these events:

public readonly struct KeyEventArgs
{
    public Key Key { get; }
    public int KeyCode { get; }
    public bool IsRepeat { get; }
    public ModifierKeys ModifiersKeys { get; }
    // And any other param which we might want to add now or in the future
}

This way we can also add more parameters in the future without making breaking changes.

We can invoke the "repeated" keys with the KeyDown event.

The other option would be to replace KeyDown and KeyUp with a single key event which reports all three up down and repeat, in which case instead of a bool IsRepeat the struct would have a KeyAction Action { get; }, but I like the previous approach more.

ThomasMiz avatar Jan 04 '21 23:01 ThomasMiz

Sounds like a good idea to me - but not something we can do right now, this would have to be 3.0 work, which is faaar off. For now, we could simply expose a new event Repeat that triggers when a repeat is triggered. This isn't ideal from the user code side, but at least works.

HurricanKai avatar Jan 05 '21 09:01 HurricanKai

We could just have a catch-all Key event.

event Action<KeyEvent> Key;

This would be non-breaking and could be accepted into 2.X.

Perksey avatar Jan 05 '21 12:01 Perksey

Just adding the Key event is an easy solution, but not a good solution.

What I suggest is a breaking change but previous code will be easy to adapt- All you have to do is change the event handler's parameters to a single one and then get the parameters from there. And it solves all these problems.

I think we should make these changes, if not for Silk 2.X then for Silk 3.0 and optionally, until then, we can add the Key event Perksey suggested.

ThomasMiz avatar Jan 05 '21 13:01 ThomasMiz

We can't do breaking changes for 2.X so it'll have to be 3.0.

Silk.NET 3.0 has an official release date of December 31st 9999 but realistically won't be any time before 2022 (I'm not dedicating any time to new massive features for 3.0, only minor improvements, bug fixes, and the monthly updates).

Perksey avatar Jan 05 '21 14:01 Perksey

We can't do breaking changes for 2.X so it'll have to be 3.0.

Silk.NET 3.0 has an official release date of December 31st 9999 but realistically won't be any time before 2022 (I'm not dedicating any time to new massive features for 3.0, only minor improvements, bug fixes, and the monthly updates).

So 3.0 will be more like a big maintenance release?

FrostByteGER avatar Jan 05 '21 16:01 FrostByteGER

I created a proposal for these changes. You can find it here.

ThomasMiz avatar Jan 05 '21 20:01 ThomasMiz

So 3.0 will be more like a big maintenance release?

@FrostByteGER 3.0 has a tracker here: #209. It'll be added to as we further realise 3.0 but we haven't even started thinking about 3.0 yet. We're not in as much of a rush to get 3.0 out as we were 2.0.

Perksey avatar Jan 06 '21 20:01 Perksey

@ThomasMiz if you can pull request this in like #397 we'll review it next working group meeting.

Perksey avatar Jan 12 '21 14:01 Perksey

There currently doesn't appear to be a way to properly detect some keys for keyboard typing input.

The Keyboard.KeyChar provides the characters typed, and keys such as Enter, Backspace, Tab, Delete can be detected via KeyDown. However, if the user is pressing down on the backspace key, the only thing we can register with this system is a single backspace press, and no repeats.

Looking at the GLFW input guide, there aren't just "key down" and "key up" actions, but there's also a "key repeat" action which we're probably ignoring.

We should try to present all these parameters in our KeyChar, KeyDown and KeyUp events.

If you want to do text input, you should use the char callback not the keydown event, according to GLFW. This also automatically handles key modifiers like AltGr+Q=@ and so on. Doesn't fix the backspace problem though.

MatijaBrown avatar Jan 12 '21 15:01 MatijaBrown

This has been resolved in the 3.0 proposals #539

Perksey avatar Jan 10 '23 16:01 Perksey