[FIXED] Keyboard.isKeyDown() returns false true

Started by Mytrill, April 02, 2012, 14:38:00

Previous topic - Next topic

Matzon

patch hasn't been applied... - and thats a good thing, imo.

The call to WindowsKeyboard.nukeDownKeys(); on all WM_MOVE and WM_WINDOWPOSCHANGING seems extremely excessive?

ra4king

Yeah this patch hasn't been incorporated yet. KappaOne told me this needed more testing, even the only change is in Java and this mostly affects Windows. However, I have tested it on Windows and Linux and it works :)

EDIT: @Matzon, nukeDownKeys only nukes the keys once, all further calls are ignored until the keys are set again.
-Roi

aldacron

The proper solution to this (on Windows) has to be implemented on the native side. When a mouse button is pressed, the Win32 API function SetCapture should be called. This guarantees that the window will continue receiving mouse button events even when the mouse is outside the window and does not block other windows from getting those same events. Then, when a button up event is received, ReleaseCapture should be called. Using this approach will allow LWJGL's internal mouse button state to remain consistent and not interfere with other programs.

There are likely alternatives for the other OSes, if it is an issue there. The GLFW library uses this approach on Windows and AFAIK behaves consistently across its supported platforms.

NateS

Just want to throw in my "me too!". A fix for this would be great. Every once in a while switching to/from my app, the ctrl key gets stuck down. This is a modifier in my app and its very confusing for a moment. The repro is simply: press ctrl, lose window focus, release ctrl, focus window. It then sees ctrl down until pressed again.

NateS

I've been spending a lot of time using my desktop tools. I curse this issue every single day! :-[

spasi

I committed a fix for this on Windows, please test the next nightly build.

kappa

Quote from: spasi on August 23, 2012, 10:53:16
I committed a fix for this on Windows, please test the next nightly build.
Nice job.

Just curious, WindowsKeyboard.fireLostKeyEvents() is called every frame, we might be able to get away with only calling it on focus change (i.e. when WindowsDisplay.appActive(boolean) method is called). Not sure if it'll have any practical effect on performance but if it works it should reduce a number of jni calls each frame.

spasi


kappa

Quote from: spasi on August 23, 2012, 14:00:38
It's only called on appActive(true).
Ah cool, guess I read code wrong, sorry.

ra4king

The new commit isn't showing up on CIA, but it is on SourceForge.
-Roi

NateS

Quote from: spasi on August 23, 2012, 10:53:16
I committed a fix for this on Windows, please test the next nightly build.
Sorry for the delay. With the nightly #1782, I start my app and ctrl is correctly not reported as pressed. After pressing and releasing ctrl, ctrl is incorrectly reported as still being pressed. Subsequent presses of ctrl do not remedy the problem. Ctrl is reported and being pressed until I focus a different application and then return to my app.

TLDR; clearing the button states seems to work, but normal usage is now broken.

spasi


NateS

I've got a bug report from a Linux user where if they use ctrl+alt+arrow to switch desktops, when they switch back the ctrl key is reported as down until it is pressed again.

NateS

Sorry to bring this up again, but it is still an problem on Linux. Eg, if I alt+tab from my app to another, when I come back to my app it still sees the alt key as being down.

spasi

This should be fixed now. I ended up copying GLFW's approach; LWJGL will now create virtual key up events for all keys that were pressed when the window loses focus. If a key is pressed before regaining focus (or it was never released), normally you'd get a stream of repeat events (if enabled) after the window activation. The trick is to handle the first of those repeat events as a normal key down event. So, it'll go like this:

key down -> repeat down -> ... -> repeat down -> focus lost -> key up

then after gaining focus:

focus gained -> key down -> repeat down -> ...

On Windows, it works perfectly and is actually a cleaner solution than the previous workaround.

On Linux, it works just as great, except for modifier keys. Linux apparently does not send repeat events for those. It still works better than before though, if the user never releases the modifier between the focus events, they'll just have to release and press again. The app will only receive the virtual up when focus was lost, not the real one after focus was gained.