Skip to content

Commit

Permalink
Fix window close on macOS; only terminate GLFW if no window open.
Browse files Browse the repository at this point in the history
Trigger sketch shutdown but stop window closing in callback, allowing sketch shutdown to proceed normally.
Add extra call to poll GLFW events after window closing - workaround for GLFW issue 1412 pending updated version in LWJGL.
Maintain static window count and only call glfwTerminate() on last window close.
  • Loading branch information
neilcsmith-net committed Aug 11, 2020
1 parent c8ee29e commit 7c3d6b1
Showing 1 changed file with 54 additions and 38 deletions.
92 changes: 54 additions & 38 deletions processing-lwjgl/src/main/java/processing/lwjgl/PSurfaceLWJGL.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class PSurfaceLWJGL implements PSurface {

private static final boolean DEBUG_GLFW =
Boolean.getBoolean("processing.lwjgl.debug");

private static int initCount;

@SuppressWarnings("FieldCanBeLocal")
private GLDebugMessageCallback debugCallback;
Expand Down Expand Up @@ -230,6 +232,8 @@ public void initFrame(PApplet sketch) {
initWindow();
initInputListeners();

initCount++;

}


Expand Down Expand Up @@ -581,7 +585,10 @@ private void initWindow() {
}));

addWindowCallback(GLFW::glfwSetWindowCloseCallback, GLFWWindowCloseCallback
.create(window1 -> tasks.add(() -> sketch.exit())));
.create(window1 -> {
glfwSetWindowShouldClose(window1, false);
tasks.add(() -> sketch.exit());
}));

addWindowCallback(GLFW::glfwSetWindowFocusCallback, GLFWWindowFocusCallback
.create((window1, focused) -> {
Expand Down Expand Up @@ -1149,53 +1156,62 @@ public void startThread() {
private void handleRun() {
this.threadRunning = true;

var sync = new Sync();
sync.initialise();

glfwMakeContextCurrent(window);

GL.createCapabilities();
pgl.setThread(Thread.currentThread());

if (DEBUG_GLFW) {
setupDebugOpenGLCallback();
}

// https://stackoverflow.com/questions/35126615/is-using-a-vao-essential-in-opengl-3-1-with-forward-compatibility-flag-set
glBindVertexArray(glGenVertexArrays());

while (this.threadRunning) {

// Set the swap interval after the setup() to give the user a chance to
// disable V-Sync. As GLFW docs for glfwSwapInterval(int) mention,
// "(...) some swap interval extensions used by GLFW do not allow the swap
// interval to be reset to zero once it has been set to a non-zero value."
if (sketch.frameCount > 0 && this.swapIntervalChanged) {
glfwSwapInterval(this.swapInterval);
this.swapIntervalChanged = false;
}

// Limit the framerate
sync.sync(frameRate);
try {
var sync = new Sync();
sync.initialise();

glfwMakeContextCurrent(window);

GL.createCapabilities();
pgl.setThread(Thread.currentThread());

for (Runnable t = tasks.poll(); t != null; t = tasks.poll()) {
t.run();
if (DEBUG_GLFW) {
setupDebugOpenGLCallback();
}

handleDraw();
// https://stackoverflow.com/questions/35126615/is-using-a-vao-essential-in-opengl-3-1-with-forward-compatibility-flag-set
glBindVertexArray(glGenVertexArrays());

PApplet.mainThread().runLater(GLFW::glfwPollEvents);
while (this.threadRunning) {

// Set the swap interval after the setup() to give the user a chance to
// disable V-Sync. As GLFW docs for glfwSwapInterval(int) mention,
// "(...) some swap interval extensions used by GLFW do not allow the swap
// interval to be reset to zero once it has been set to a non-zero value."
if (sketch.frameCount > 0 && this.swapIntervalChanged) {
glfwSwapInterval(this.swapInterval);
this.swapIntervalChanged = false;
}

// Limit the framerate
sync.sync(frameRate);

for (Runnable t = tasks.poll(); t != null; t = tasks.poll()) {
t.run();
}

handleDraw();

PApplet.mainThread().runLater(GLFW::glfwPollEvents);

}

glBindVertexArray(0);
} catch (Throwable ex) {
this.threadRunning = false;
System.getLogger(PSurfaceLWJGL.class.getName()).log(System.Logger.Level.ERROR,
"Uncaught exception in rendering thread", ex);
}

glBindVertexArray(0);

PApplet.mainThread().runLater(() -> {
// Need to clean up before exiting
// TODO: Make sure sketch does not System.exits before this could run, e.g. during noLoop()
glfwDestroyWindow(window);
glfwTerminate();

glfwPollEvents();
initCount--;
if (initCount <= 0) {
glfwTerminate();
initCount = 0;
}
sketch.exitActual();
});

Expand Down

0 comments on commit 7c3d6b1

Please sign in to comment.