Detect window closing?

Hello, I’m making a multi window app based on example, but I would like intercept any window close event to ask for confirmation and exit, for any of my 2 windows.

I’ve searched the doc, but I could not find how to catch the window close event, could you help me?

Thanks

If you use GLFW as windowing system (likely if you’re on desktop in any platform). Track the getWindowShouldClose() call. More information in the GLFW documentation.

There’s probably a way to capture the glfw flag before OF actually goes on to exit. Tracking that call you will probably find it.

If you want to do things on exit (without preventing it) just inherit ofBaseApp::exit

the exit event should be called whenever a window is closed, you can access it as ofEvents().exit if called from any function in the corresponding app for each window. if you have access to the window you can also do window->events().exit

@arturo, how would you cancel the exit based on some condition? I think the question is how to prevent the exit from happening within the main loop.

oh, yeah i didn’t understood the original question before. there’s no way at the moment to do this, the ofMainLoop class controls how windows are closed and it closes them immediately as soon as the should close condition is true.

Thanks for the answer, so basically I just need to override the getWindowShouldClose() method in my 2 windows, process the confirmation and manually close both windows using setWindowShouldClose() to properly exit the application, am I correct?

Sorry to bother again, but I can’t figure how to actually do it. From what I’ve dug in the sources, overriding this method to intercept the call and eventually change the result seems the right way to go, but I can’t actually figure how to do it since all windows are created this way:

    shared_ptr<ofAppBaseWindow> mainWindow = ofCreateWindow(settings);

I don’t see how to use a custom extended version of GLFW window class?

no this is not happening in the window but in the mainloop, extending the window wouldn’t help what needs to be modified is the mainloop so it doesn’t close windows right after detecting they should close but instead ask if they should

Track the main loop class, who’s setting bShouldClose and what the best way to control the flow is for your app.

Looks like this is the line you want to look at. From what I can see two things make your loop end, bShouldClose from the main loop itself, and the getWindowShouldClose call implemented by GLFW underneath.

Good luck!

Thanks, I have seen this, my problem is how to override this in my application without modifying open frameworks itself? I do not want to mess with OF internals so I would like to to this “cleanly” from my app code, but can’t see how, or am I missing something obvious?

as i said a couple of posts ago there’s no way to do this in OF at the moment without modifying ofMainLoop. if you do so perhaps send a PR so we can integrate the change.

a relatively straight forward way to do it would be to check the return value of the event notification, if it’s true the event is marked as attended which would mean that the window shouldn’t be closed

@arturo Thanks, for the clarification, I’ll try to propose a PR then, but what is the event are you talking, the exit() event? I did not see a windowShouldClose event and was planning to add one.

Sorry i was mistaken it’s actually the window that receives this notification first, triggers the exit event and can cancel it before the main loop gets the shouldClose flag.

In ofAppGLFWWindow::exit_cb, you can change:

//--------------------------------------------
void ofAppGLFWWindow::exit_cb(GLFWwindow* windowP_){
	ofAppGLFWWindow * instance = setCurrent(windowP_);
	instance->events().notifyExit();
}

with:

//--------------------------------------------
void ofAppGLFWWindow::exit_cb(GLFWwindow* windowP_){
	ofAppGLFWWindow * instance = setCurrent(windowP_);
	if(instance->events().notifyExit()){
		glfwSetWindowShouldClose(windowP_, false);
        }
}

that way if the exit event returns true when notified the window will cancel the closing event. in ofApp or any other class you can then do:

ofAddEventListener(ofEvents().exit, this, &ofApp::exit);

...

bool ofApp::exit(){
     if(blah){
           return false;
     }else{
           return true;
     }
}

returning true will cancel the event making any other class listening not receive it and the notify function return true.

In the case of this event the syntax is kind of strange cause you are returning true on exit which looks like you want to exit and returning false that you don’t want to so perhaps to make it clearer adding a new event could be a good idea

1 Like