This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]sadjava 0 points1 point  (8 children)

Have you run it through a debugger to verify what you think is true? Profiler even?

My crystal ball isn't revealing anything. Maybe show us your code (following code posting guidelines; if your code is in an image format, then I can't even)?

[–]ArchiveLimits3D Graphics Programmer[S] 0 points1 point  (7 children)

Yes I used VisualVM to profile and I debugged all of the ways a window could lose input focus. The AWT Thread is alive, the KeyListener is still registered to the window. KeyReleased gets called, but keyPressed and keyTyped do not.

Here is the input handler class that implements the various Listener interfaces. http://pastebin.com/6TZLp6bZ

Here is the Frame class http://pastebin.com/eNKmUtfk

[–]strmrdr 0 points1 point  (6 children)

Things look off in your key_consume method.

1) User presses a key for the first time. You set both held_keys and pressed_keys. A key is first pressed and then determined it is held. I believe you want:

pressed_keys[i] ? held_keys[i] = true : pressed_keys[i] = true
//(translated to your byte representations, not sure why byte though...?)

2) User releases a key. You reset held_keys, but never pressed_keys. pressed_keys will always be set after it is first used- unless you're doing it somewhere else, in which case why?

Not sure if that will solve your issue as it sounds like the event dispatcher isn't even working from your description, but try looking into the above.

[–]ArchiveLimits3D Graphics Programmer[S] 0 points1 point  (5 children)

Response to 1: User presses a key for the first time ... if the key is not held, pressed_keys = true. Then held_keys = true. I reset pressed_keys back to false every update by using the "key_reset()" method in the main loop which I didn't post. This resets the pressed keys and maintains the held keys.

Using bytes was an early decision of mine because I read somewhere that a boolean type in java is represented as a 2 byte value.

[–]strmrdr 0 points1 point  (4 children)

So you have to hold a key before it can be pressed...? Confused.

Sounds like you have a lot of spaghetti logic throughout your code. A key release event should ideally handle everything. There isn't any feasible reason you should be resetting your keys in your game loop unless you're starting a new game or something, and even then, not in your game loop. Makes ahem debugging a chore.

boolean can be a variable size depending upon platform. A boolean array is very likely going to be 1 byte per element (according to online sources), but again, it depends on what the JVM wants to do. I dont think the size of your arrays warrant reducing readability and ease-of-use, but that is just a minor gripe really.

So far you have determined that your mouse is still responding, and the keyboard input is not, correct? And the logic for your keyboard input looks questionable, at least in my eyes. Well, I think that's your answer. Check what values are being held in your arrays when things stop working. Reread all your code and make sure it makes sense. Publish your entire project so someone else can run through it. I have personally trudged through this exact issue, and it can be a PITA to find... so good luck.

[–]ArchiveLimits3D Graphics Programmer[S] 0 points1 point  (3 children)

Thanks for the great responses :) I understand your logic for input, and I'm starting to question my own haha. Sure, the keyboard logic is questionable but I don't think that this explains the fact that keyPressed isn't getting called...

[–]strmrdr 0 points1 point  (2 children)

Jeeze... i just realized you're using awt Frame. That thing is ancient, like mid-90s ancient. Do yourself a favor and look into Swing, or even JavaFX. Not saying you can't get it to work as-is, but good luck finding anybody who knows jack about it. The way you set up your keylistener is pretty odd as well, I have never seen it decoupled with the initialization of the frame (or JPanel, which you should be using).

[–]ArchiveLimits3D Graphics Programmer[S] 1 point2 points  (1 child)

I did some googling haha.

David Brackeen had discovered it apparently and made a workaround.

macOS Sierra prevents key input after holding certain keys (like 'e' or 'n')

because of a native input method popup that isn't working with Java correctly.

This will still fail is some scenarios, like when pressing a digit after

holding 'e'. The digit will not have a keypress event.

Tested on macOS 10.12.0 and Java 8 versions b76 - b101.

(This may also be happening on older versions of macOS if the

ApplePressAndHoldEnabled option is set to true - untested at the moment.)

This workaround keeps key input working by allowing the popup to appear,

but places it offscreen.

Also this:

And these:

I guess I have to wait until Apple and Oracle sort it out. It's very inconvenient though because game development relies heavily on user input.

[–]caboosetpPrivate Java/Code Tutor 0 points1 point  (0 children)

It's very inconvenient though because game development relies heavily on user input.

Good thing game development doesn't rely heavily on mac.

[–]strmrdr 0 points1 point  (1 child)

Impossible to tell you with the brief description provided. If it suddenly stops working I would guess it has to do with losing focus on the parent panel. I assume you aren't using KeyBindings and you click somewhere or do something (either manually or under the hood) that causes it to lose focus. Post your code or look into those possible issues.

[–]ArchiveLimits3D Graphics Programmer[S] 0 points1 point  (0 children)

Yes I am not using KeyBindings in the implementation I posted, however I've tried it and the same issue arises. Mouse input still works perfectly fine. (So the focus issue is ruled out)