Close the full screen second window through keyboard or through parent window?

Here is my code


PWindow win;

public void settings() {
  size(320, 240);  

}

void setup() { 
  surface.setLocation(20,20);
  //win = new PWindow();
}

void draw() {
  background(255, 0, 0);
  fill(255);
  rect(10, 10, frameCount, 10);
}

void mousePressed() {
  println("mousePressed in primary window");
  if(win == null) win = new PWindow();
} 

class PWindow extends PApplet {
  PWindow() {
    super();
    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
  }

  void settings() {
  fullScreen();
  }

  void setup() {
    background(150);
  }

  void draw() {
    ellipse(random(width), random(height), random(50), random(50));
    println("mousePressed in secondary window");

  }

  void keyPressed() {
//if it is esc key then close the window 
  }
  
  void exit()
  {
    dispose();
    win = null;
  }
}

And afte rthe second fullscreen sketch closes, the parent sketch still runs.
It would be great if you can spare some time and give me some suggestions. Or code hahahah

1 Like

There are several things to be aware of.

(1) In your code when the fullscreen window is is created it hides all other windows and becomes the active window which means ALL key and mouse events are sent to it. The original sketch window is effectively deaf and dumb and will not respond to key and mouse events these events can’t be used to close the secondary window. It is worse than that because it is not easy to make the sketch window the active one.

(2) You can force the sketch window to remain on top by adding the line surface.setAlwaysOnTop(true); to the setup method. You can see it in the code below. Simply clicking on the sketch window will then make it active.

(3) The method used to close the window depends on whether it uses the JAVA2D renderer (Java AWT, default) or P2D / P3D renderer (OpenGL)

I have modified your code and added some new methods to the PWindow class. If you run the sketch and click on the window your fullscreen window opens. Type the key ‘x’ and the secondary window closes leaving the sketch window open. If the secondary window uses P2D/P3D then a secondary NPE exception is generated but it doesn’t seem to cause any problems.

import java.awt.*;
import java.awt.event.*;
import com.jogamp.newt.opengl.*;

PWindow win;

public void settings() {
  size(320, 240);
}

void setup() { 
  surface.setLocation(20, 20);
  //surface.setAlwaysOnTop(true);
}

void draw() {
  background(255, 0, 0);
  fill(255);
  rect(10, 10, frameCount, 10);
}

void mousePressed() {
  //println("mousePressed in primary window");
  if (win == null) win = new PWindow();
} 

class PWindow extends PApplet {
  PWindow() {
    super();
    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
  }

  void settings() {
    fullScreen();
    //fullScreen(P2D);
  }

  void setup() {
    background(150);
  }

  void draw() {
    ellipse(random(width), random(height), random(50), random(50));
    //println("mousePressed in secondary window");
  }

  void close() {
    PSurface s = getSurface();
    if (s instanceof processing.awt.PSurfaceAWT) {
      // JAVA2D renderer (default)
      println("JAVA2D");
      Frame frame = (Frame) ((processing.awt.PSurfaceAWT.SmoothCanvas) getSurface().getNative()).getFrame();
      frame.getToolkit().getSystemEventQueue().postEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
    } else if (s.getNative() instanceof com.jogamp.newt.opengl.GLWindow) {
      // P2D or P3D renderer
      println("P2D / P3D");
      GLWindow window = (GLWindow) s.getNative();
      window.destroy();
    }
  }

  void keyTyped() {
    if (key == 'x' && win != null) {
      win.close();
    }
  }

  void exit() {
    dispose();
    win = null;
  }
}
3 Likes

Hi quark,

I have tried your example and it works great with the processing renderer.
Unfortunately as you said there is an exception when using the P2D/P3D renderer.
In my case this is thrown:

OpenGL error 1282 at top endDraw(): invalid operation
Caught subsequent NullPointerException: null on thread Animation Thread-FPSAWTAnimator#00-Timer0-FPSAWTAnimator#01-Timer1
    [0]: jogamp.newt.WindowImpl.getGraphicsConfiguration(WindowImpl.java:1122)
    [1]: jogamp.newt.WindowImpl.unlockSurface(WindowImpl.java:1065)
    [2]: jogamp.opengl.GLDrawableImpl.unlockSurface(GLDrawableImpl.java:332)
    [3]: jogamp.opengl.GLContextImpl.release(GLContextImpl.java:425)
    [4]: jogamp.opengl.GLContextImpl.release(GLContextImpl.java:382)
    [5]: jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1308)
    [6]: jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
    [7]: com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:759)
    [8]: com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:81)
    [9]: com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:452)
    [10]: com.jogamp.opengl.util.FPSAnimator$MainTask.run(FPSAnimator.java:178)
    [11]: java.util.TimerThread.mainLoop(Timer.java:555)
    [12]: java.util.TimerThread.run(Timer.java:505)

Sometimes the OpenGL error 1282 is there and sometimes not.
The second window gets inactive but does not close or dispose.

Is my assumption right that a thread is still running which tries to draw in the window?
noLoop() in the second window before closing didnt do the trick.

I try to close the window and restart it in fullscreen or “normal” (changing by F11). The restart works which means i get a lot of windows when the old one is not closed.

EDIT: After playing around a bit and testing i discovered this:

Caught subsequent NullPointerException: null on thread Animation Thread-FPSAWTAnimator#00-Timer0

For each window i try to close there is added a timer:

Caught subsequent NullPointerException: null on thread Animation Thread-FPSAWTAnimator#00-Timer0-FPSAWTAnimator#01-Timer1-FPSAWTAnimator#02-Timer2-FPSAWTAnimator#03-Timer3

I think that my assumption of threads still running is right. But i also know that i dont have a clue on what to do now. :grin: