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

We need a cross-platform way to detect key-down state #24314

Open
jkotas opened this issue Dec 2, 2017 · 10 comments
Open

We need a cross-platform way to detect key-down state #24314

jkotas opened this issue Dec 2, 2017 · 10 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Console
Milestone

Comments

@jkotas
Copy link
Member

jkotas commented Dec 2, 2017

From @masonwheeler on July 1, 2015 14:48

Right now, if you want to answer the question "Is on the keyboard currently down?", you do it with a PInvoke call to GetAsyncKeyState. Problem is, that will only work for winapi-based platforms. There should be a cross-platform solution for this, and ISTM it's low-level enough that it belongs in CoreCLR and not CoreFX. Feel free to correct me if this isn't the case, and I'll open the issue on CoreFX instead.

Copied from original issue: dotnet/coreclr#1190

@jkotas
Copy link
Member Author

jkotas commented Dec 2, 2017

From @OtherCrashOverride on July 2, 2015 0:5

There should be a cross-platform solution for this, and ISTM it's low-level enough that it belongs in CoreCLR and not CoreFX.

Actually, it doesn't belong in either.

While on the surface it may seem trivial, you have to take into consideration the design of a console. A console is associated with a character device. A character device, as its name implies, reads and writes characters. These characters may source from keyboard, but they may also source from a file and output to one as well.

The distinction of being a character device has an important implication: it does not maintain state. As an example consider sending a capitol 'A'. To the console, it is simply a character encoding. To know if its up or down, you also need to send state information as to whether it was pressed or released. Instead of sending a the character encoding for 'A', you have to send Key.Shift-Pressed and Key.A-Pressed (or check if Key.CapsLock state is pressed) and also handle keyboard mapping for what Key.A means when combined with a modifier key.

Finding out if a key is pressed is actually a very complicated process when you factor in state and international keyboard characteristics with user preferences and/or mappings. This is entirely outside the scope of CoreCLR and CoreFX.

On Windows and OSX, there is a single API to P/Invoke, On Linux, there is not. It depends on the user interface environment (if one is used). The API used is different if you are using the VT environment, a X11 environment, or a Wayland environment. As CoreCLR adopts support for more platforms, the maintenance burden only increases.

In summary, you are better off finding a 3rd party library that supports the platforms you wish to target. An example of such is SDL.

[Edited for better composition.]

@jkotas
Copy link
Member Author

jkotas commented Dec 2, 2017

From @masonwheeler on July 2, 2015 2:0

@OtherCrashOverride You seem to be misunderstanding what I'm looking for, especially if you're bringing up SDL. I know what SDL has to offer--I'm a contributor to the project, in fact--and it looks like you're talking about text input and events and all sorts of complicated stuff along those lines. You're right; that belongs elsewhere, most likely in a GUI library.

That's not what I'm looking for. I'm trying to answer a much simpler question, specifically, the question that is answered by the Winapi function GetAsyncKeyState: "at this exact moment that I am calling this function, is a given physical key up or down?" That has nothing to do with text input, modifier keys, or UI events, and there's no room for different UI toolkits to interpret it differently. It's something that most likely belongs in the PAL.

@jkotas
Copy link
Member Author

jkotas commented Dec 2, 2017

From @OtherCrashOverride on July 2, 2015 2:21

I don't believe I have misunderstood the request: Provide an API call for 'IsKeyPressed'. The verboseness of my response was intended to add more than just "no, this does not belong". I was attempting to illustrate that character devices do not provide the service requested. The Windowing or other Session environment does. Even on a Linux plain text console, there may not be an actual keyboard to provide key press state, it could be a serial device or network ptty.

My post was meant to be more of a "there is a reason it does not already exist; here's why." response.

@jkotas
Copy link
Member Author

jkotas commented Dec 2, 2017

From @OtherCrashOverride on July 2, 2015 2:36

Trying to find a better way to communicate this...

While this API would always work on Windows. It may or may not work on OSX, Linux and FreeBSD. The reason being is that a 'command prompt' may not be driven by a keyboard. In cases such as SSH, the terminal does not send keyup/keydown events. Things like KeyRepeat rate are set at the client, not on the server because it does not know when a key is up or down.

@jkotas
Copy link
Member Author

jkotas commented Dec 2, 2017

From @davidfowl on July 2, 2015 2:49

Doesn't seem like a coreclr thing.

@jkotas
Copy link
Member Author

jkotas commented Dec 2, 2017

From @masonwheeler on July 2, 2015 10:55

@OtherCrashOverride How is this any different from the current state of things on Windows systems, which could just as easily be a server running over Telnet or RDP? If there's no physical input available, then you return false.

@jkotas
Copy link
Member Author

jkotas commented Dec 2, 2017

From @OtherCrashOverride on July 2, 2015 15:27

I think the expectation here is that since there is a single API call on Windows, there is a single API call on all other platforms. The point I have been trying to make is that with Linux, this is not the case.

http://stackoverflow.com/questions/7645058/linux-analog-to-windows-getasynckeystate

The proposed fgetc_unocked would result in polling until a character is received. Once that character has been received, you would only know that it was pressed not that is has been released. Future arrivals of that character may be key repeat and not actual key press.

If there is an elegant solution to this, then someone should submit a pull request with it. The point being made is that it does not exist because its non-trivial and only known to the GUI or session (console) environment managing the 'command prompt'

@masonwheeler
Copy link
Contributor

@jkotas This really isn't a System.Console request. If you want to do console input, that's already got plenty of APIs for it. What I'm looking for is keyboard state; the intended use case is for gaming.

@jkotas
Copy link
Member Author

jkotas commented Dec 2, 2017

System.Console has stuff related to keyboard, e.g. ConsoleKey enum, Console.NumberLock. If this belongs anywhere in CoreCLR/CoreFX repos, it is area-System.Console.

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 5.0 milestone Jan 31, 2020
@maryamariyan maryamariyan added the untriaged New issue has not been triaged by the area owner label Feb 23, 2020
@carlossanlop carlossanlop removed the untriaged New issue has not been triaged by the area owner label Apr 1, 2020
@eiriktsarpalis eiriktsarpalis modified the milestones: 5.0.0, Future Jun 22, 2020
@gabriel-vanca
Copy link

Any update on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Console
Projects
None yet
Development

No branches or pull requests

7 participants