CMD+Q quits my app... why, and why does process not terminate?

My app is derived from Application. It has no keyboard handlers (of the JME type) installed, yet the app window disappears when I press CMD+Q. Why is this? Based on the log tail of this (at end of this post), I set a breakpoint in lwjglAbstractDisplay and see that Display.isCloseRequested() is being set true by CMD+Q, and so, apparently, this is LWJGL behavior. How do I alter this (should I choose to) and how many other in-built behaviors might I expect to encounter?

Also, I notice that my app process does not stop when I this happens. Why is that, and how do I fix that?

This is what is logged when I press CMD+Q:

Jan 24, 2013 2:06:24 PM com.jme3.input.lwjgl.LwjglMouseInput destroy
INFO: Mouse destroyed.
Jan 24, 2013 2:06:24 PM com.jme3.input.lwjgl.LwjglKeyInput destroy
INFO: Keyboard destroyed.
Jan 24, 2013 2:06:24 PM com.jme3.system.lwjgl.LwjglAbstractDisplay deinitInThread
INFO: Display destroyed.

Does your app launch any other threads or do any networking, etc?

Ahh… this is possible, as I do both. However, I am not sure that I have launched the thread at the time of this test, and my networking use is simply that I MAY have newed up some SpiderMonkey stuff but not used it. Let me see what some exploring tells me.

tone

If you start a network server then you will have to shut it down when the app is terminating or it will keep your process running.

Help me understand how this is an issue.

I have not (in this test) spun off a thread. I have these threads running at the end, after hitting cmd+Q.

thread group “main”:
AWT-AppKit (Running)
AWT-EventQueue-0 (Waiting)
AWT-Shutdown (Waiting)
DestroyJavaVM (Running)
Java Sound Event Dispatcher (Waiting)
Timer-0 (Waiting)

ungrouped:
Finalizer (Waiting)
Java2D Disposer (Waiting)
Reference Handler (Waiting)
Signal Dispatcher (Running)

I do not see that I started any threads. I removed the place where I loaded a native library. This configuration is not running SpiderMonkey code.

Do you see threads there that you do not expect?

tone

Do you still have any swing/AWT windows open? The AWT threads will not shut down if there are still active windows.

1 Like

Also, I wonder who started the timer.

I do not have such windows open, but I use Java2D and AWT to assist in drawing dynamic textures, such as putting name tags on avatars.
I am inclined to think AWT started the Timer given its -0 suffix which is much like the other AWT thread name’s. Searching for "Timer (with that initial double quote) in my project yields no hits.

If this is the extent of my issue, I can live with it for now. Ditching my AWT-based code for another alternative now would be more pain than it is worth.

Can you tell me anything about this apparent LWJGL behavior of typing CMD+Q to closing my window, and where I can find such code?

tone

I am doing this for the time being, I guess. I suppose I could parse the log messages to wait for the various Display and KeyInputs to be destroyed, but…

public void requestClose(boolean esc){
    context.destroy(false);

    // this is ugly... but I have AWT threads that refuse to die
    if (!esc) {
        System.exit(0);
    }
}

Yeah, I system exit also just in case. Generally my app shuts down properly but it’s bad to leave zombie processes… especially when they might still be holding on to server connections and stuff.

Thread naming conventions like “-0” are applied not just by AWT but by the JDK in general.
So the timer could have been started by anything. Set a breakpoint on the Timer constructors and you’ll see what started it :slight_smile:

Note that close() on a window is not enough to unregister it from the event loop, you need to call dispose().
And AWT will continue to run while there are windows in the event loop, so you need to dispose() all top-level windows to shut down AWT.
(E.g. the jme3 Settings dialog might still hang around and prevent closing. Or if you’re using windowed mode, a JFrame might still be around.)

I’m a bit surprised to see JavaDestroyVM running.