Dynamically Setting the Window as Undecorated

Just as the title says:
I want to be able to set the window as ‘undecorated’, while the sketch is running. It causes some errors inside “handleDraw()”, however.

I felt that it may be possible if I call noLoop(), wait for draw() to finish (by using a delay() or Thread.sleep()), and THEN make changes to the JFrame / GLWindow.

Apparently that doesn’t work either!

There doesn’t seem to be a way to know when EXACTLY draw() / handleDraw() finishes, either.

I tried to registerMethod("post", this);, but the post() method doesn’t seem to help either.

Is it just not possible…? Should I return to simply setting the surface object’s size and location…?

(Please be aware that my knowledge of the Processing source code happens to be quite limited!)

YAYY! I found a solution , ":D!
(Another problem though :upside_down_face:, How to type an ASCII emoji on Discourse? :grin:)

void post() {
  if (fs) {
    if (!window.isUndecorated()) {
      try {
        window.setVisible(false);
        window.setUndecorated(true);
        window.setVisible(true);
      }
      catch(Exception e) {
      }
      while (!window.isUndecorated()) {
      }
    } else {
      surface.setLocation(0, 0);
    }
  } else { 
    if (window.isUndecorated()) {
      try {
        window.setUndecorated(false);
      }
      catch(Exception e) {
      }
    }
  }
}

What is fs? It’s a boolean, for which you also need to do this:

  • Make two ints called xbf and ybf, and:
void keyPressed() { 
  try {
    if (keyCode == 107) {
      fs = !fs;
      if (fs) {
        xbf = window.getWidth();
        ybf = window.getHeight();
        surface.setSize(displayWidth, displayHeight);
        surface.setLocation(-8, 0);
      } else {
        surface.setSize(xbf, ybf);
        surface.setLocation(displayWidth/2 - xbf/2, displayHeight/2 - ybf/2 );
      }
    }
  }
  catch(Exception e) {
  }
}

Of course you need this inside setup():
registerMethod("post", this);

I will post an explanation as to how this works soon~!
Also, an optimized version - totally not for myself to copy and paste :joy:.

  • What even IS this/?/1!?1?
    So you know how video games (like Minecraft!!1!) resize the window to ‘fullscreen’ when you press F11? This does that. Setting the window to “undecorated” means to remove the title bar, the window maximize, window minimize, and window close buttons.

  • How did you do it, ("o_O))?
    Right: here is an explanation as to how this works:
    Basically, the window.setUndecorated() method runs a new thread. If you continue to use draw(), you are rendering graphics to the screen, which disrupts, or interrupts that thread.
    To avoid that, I simply put a while loop to wait till the thread is done.
    The if exists to check if the window was already set to undecorated, and if it needs to be done again, since it takes a bit of time to set the window as undecorated!

  • Why do I set the window to invisible and then visible?
    Because for some reason, it resizes it perfectly to fit the screen, and also makes the taskbar disappear. It is needed even though there is a surface.setLocation(0, 0);

  • Why am I using a method called ‘post()’ and what is it?!
    Processing “handles” the draw() function inside a function called handleDraw(), which runs every frame. However, to ensure that the draw() function is ‘safe’ to use (so you didn’t change things and cause random errors all the time), the Processing development team made sure that you couldn’t access them. Problem: libraries need this functionality, and so do we! So they allowed it to be extended and made two more methods, called pre() and post(), which are called before and after draw() is executed, respectively.

  • Why so many ifs?!
    If you’ve ran this code, you know how long it takes to do the task! The ifs ensure that the task isn’t done every single frame - it’s an optimization. But the solution as a whole isn’t as optimized.
    I’ll post the ‘optimized’ version of the code soon!
    Check the solution answer here
    , ":D!

  • What’s this “window” object?!
    This is a way to dig into Processing’s workings and do some of this stuff. I myself came to know about it from here, months ago: Get location of a PApplet window - #10 by micycle
    To know what it contains, check the solution answer here

1 Like

Here it is as promised, ":D!

void post() {
  if (fs)
    if (!window.isUndecorated()) {
      window.setVisible(false);
      try {
        window.setUndecorated(true);
      }
      catch(Exception e) {
      }
      window.setVisible(true);
      while (!window.isUndecorated());
    } else surface.setLocation(0, 0);
  else if (window.isUndecorated())
  try {
    window.setVisible(false);
    window.setUndecorated(false);
    window.setVisible(true);
  } 
  catch(Exception e) {
  }
}

Again, I’m setting the window as invisible and visible again. This is to remove the ‘blur’ that I forgot to notice before-

1 Like

Moment of truth.
Here is the last revision, I hope! :joy:

I’m sad to say this, but this only supports the P2D and P3D renderers!
Pretty sure most people will be using GPU-based rendering anyway, amIrite?

Also, there is bad luck involved…
In short, this could change with newer versions of Processing, …and:

The code, yay!:

import com.jogamp.newt.opengl.GLWindow;
// [https://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/newt/opengl/GLWindow.html];

GLWindow window;

void setup() {
  size(640, 480, P3D);
  registerMethod("post", this); // Never forget the "this dot", and also this!!11!

  sphereDetail(8);
  surface.setResizable(true);
  surface.setTitle("haha press f11");
  window = (GLWindow) surface.getNative();
}


void draw() {
  background(0);

  stroke(255);
  strokeWeight(8);
  line(
    map(window.getX(), 0, displayWidth, 0, width*1.75), 0, 
    map(window.getX(), 0, displayWidth, 0, width*1.75), 
    map(window.getY(), 0, displayHeight, 0, height*2.5)
    );


  if (mousePressed) stroke(255f, 0, 0);
  strokeWeight(1f);
  noFill();
  lights();
  translate(mouseX, mouseY);
  rotateX(millis()*.001f);
  rotateZ(millis()*.001f);
  sphere(50f);
}





boolean fs;
void keyPressed() {
  if (keyCode == 107) {
    fs = !fs;
    surface.setSize(displayWidth, displayHeight);
    if (!fs) surface.setSize(640, 480);
  }
}

void post() {
  if (fs)
    if (!window.isUndecorated()) {
      window.setVisible(false);
      try {
        window.setUndecorated(true);
      }
      catch(Exception e) {
      }
      window.setVisible(true);
      while (!window.isUndecorated());
    } else surface.setLocation(0, 0);
  else if (window.isUndecorated())
  try {
    window.setVisible(false);
    window.setUndecorated(false);
    window.setVisible(true);
  } 
  catch(Exception e) {
  }
}

1 Like