godot-proposals icon indicating copy to clipboard operation
godot-proposals copied to clipboard

Add a method to check the current keyboard Caps Lock status

Open TempestStorm opened this issue 4 years ago • 14 comments
trafficstars

Describe the project you are working on

I am designing a log in screen with a password field (line edit with secret set to true).

Describe the problem or limitation you are having in your project

I want to warn the user when they have left their caps lock on with a small icon next to the password field. However GD script currently does not have a way of determining the current state of the caps lock key. I can use input events to track the when the user has pressed it while running the app, but not knowing the initial state of the key its of limited use.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

I am currently using a work around where OS.execute runs a small platform exclusive C++ executable at the start of the game, then it is tracked using input events. It is somewhat inelegant and it isn't helped by my limited C++ knowledge. More information of my work around is on the official forum

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

I feel this should be added to the OS singleton class. There doesn't seem to be any way of determining of the *lock keys (caps, num and scroll) so it could maybe return a dictionary or there could be a separate function returning a bool for each.

If this enhancement will not be used often, can it be worked around with a few lines of script?

Not with Godot script. The only way I can see of getting it to work is by calling another program or potentially a different script with OS.execute but that is beyond the scope of gdscript and has the potential to make shipping your app require a large dependency like python.

Is there a reason why this should be core and not an add-on in the asset library?

Being able to detect key presses is already a part of core, the toggle status of the lock keys should really be a part of that.

TempestStorm avatar Feb 08 '21 11:02 TempestStorm

Adding the topic:porting label as the implementation requires OS-specific code.

Calinou avatar Feb 08 '21 12:02 Calinou

If this proposal was implemented, would it be expected to also provide a way to set the state of the lock keys ? I started taking a look at how it could be done, and for the html5 platform it seems there is no way to do so due to browser sandboxing. However this should be doable for the desktop platforms. (for mobile platforms, there even doesn't seem to be an equivalent to what the lock keys do)

Kanabenki avatar Feb 11 '21 13:02 Kanabenki

On mobile the keyboard can be in all caps mode, but I'm not sure if it can be fetched. Setting this value even on desktop shouldn't be possible, though, as your hardware should be the authority.

YuriSizov avatar Feb 11 '21 14:02 YuriSizov

To be more precise I was talking about setting the locks system wide through the platform respective APIs (which would in return drive the keyboard lock leds for example), not just inside Godot. However as Godot doesn't provide as far as I know a way to for example emulate physical keypresses, I guess it wouldn't make sense to allow setting the key locks without also implementing that. Both wouldn't be very useful for games in the end but I could see an use case for people wanting to use Godot to create apps, for some kind of automation software like AutoHotkey or a password manager for example.

For both iOS and Android there doesn't seems to be a way to check caps lock from what I saw, only to force caps on/off on a text field basis.

Kanabenki avatar Feb 11 '21 15:02 Kanabenki

I am utilizing the label node to do some specific interactive text that a TextEdit or LineEdit node cannot handle. One issue I've come across is the Caps Lock not being detected if already enabled or not. I CAN handle inputEvents with modifiers such as " event.shift " , however there are no modifiers for caps, which is a bit odd. Doing a trashy workaround such as a custom bool variable that is true/false depending on the press would only confuse users if their CapsLock button was already accidentally enabled when starting the program. This seems like an feature that should be a part of the core release.

j5E01 avatar Sep 08 '21 07:09 j5E01

Hello, just wanted to give more support for this issue. I'm running into the problem of wanting to setup a chatroom in my game, but using TextEdit, LineEdit even label are all clunky in their own respective ways. Needing to create a bunch of hacky workarounds just to have the game register correct keyboard inputs. Some people needing to rescript for every single keystroke.

Xekkel avatar Oct 15 '21 19:10 Xekkel

I've just made an implementation of this feature for Linux/Windows. Decided to put the is_caps_lock_on() method into the DisplayServer, so it resulted in very small change. If you need this functionality please give it a try.

You can compile the branch yourself or use prebuilt Linux or Windows version. Just remember to log into github so the artifacts will be visible.

Download test project to speed up things and leave result of your testing, please. :)

Someone with mac is needed to implement it or at least test it on this os.

Test project preview

pkowal1982 avatar Oct 29 '22 16:10 pkowal1982

@pkowal1982 Can these be written as GD Extentions? I am have to give that a go for Godot 4.0, would also be nice to detect the state of num lock, or perhaps that is already possible.

FeralBytes avatar Jan 03 '23 03:01 FeralBytes

@FeralBytes Never used GDExtension but I think it should be easy to use this code in the plugin. As for NumLock you'll need to search the web yourself, I assume it should be done similar to CapsLock.

pkowal1982 avatar Jan 07 '23 17:01 pkowal1982

Decided to put the is_caps_lock_on() method into the DisplayServer, so it resulted in very small change.

I'm not sure how it works on Windows and Linux, but on macOS you can have multiple keyboards (e.g., built-in MacBook keyboard and external one) with different Caps Lock status on each keyboard at the same time.

bruvzg avatar Jan 07 '23 18:01 bruvzg

Checked it with external keyboard connected to laptop on Ubuntu 22 and Windows 10. CapsLock indicator is always consistent on both keyboards. Funny thing is that Windows shows CapsLock pressed when at least one of CapsLock keys is down and Ubuntu shows status according to last action. @bruvzg Not sure if you propose to change this method to something like:

func is_caps_lock_on(keyboard_index = -1) -> bool

and return status for the particular keyboard if it's found or else return status for default one?

pkowal1982 avatar Jan 08 '23 16:01 pkowal1982

I had set out to find out whether Godot could tell me the state of the Insert key. Instead I'll just note that it should be considered a "lock" for this purpose.

Logopher avatar Mar 21 '25 06:03 Logopher

I had set out to find out whether Godot could tell me the state of the Insert key.

The Insert key does not have a state at the OS level. Some code editors (including the Godot script editor) support using Insert as a toggle between inserting text and replacing text, but this is not done at the OS level.

Therefore, this can be implemented purely on the application side without needing to integrate with OS-level APIs.

Calinou avatar Mar 21 '25 17:03 Calinou

I've rebased @pkowal1982's branch: https://github.com/Calinou/godot/tree/displayserver-add-is-caps-lock-on

However, the implementation on Linux X11 always returns false on my Fedora 41 KDE system. I'm not sure why, as the keyboard LED for Caps Lock turns on and Caps Lock works on the system. The method in the X11 implementation is being called correctly (I checked by adding a print there).

Testing project: test_caps_lock.zip

Calinou avatar Mar 22 '25 01:03 Calinou