Multiple monitors: primary dragable, secondary fullscreen

edited April 2016 in How To...

I need to run a sketch on two monitors. The main window on the primary monitor needs to be dragable and the secondary window needs to fill the entire second screen. I don't need to be able to interact with the secondary window, It's just needed to display images.

If there is no way this could work fullscreen on both monitors could work for me aswell. I didn't have any luck with following the information from my searches, so I came here to ask.

Answers

  • I went trough these tagged discussions and tryed a couple of things but it didn't realy get me any further.

  • edited June 2015
    • In this forum thread below:
      http://forum.processing.org/two/discussion/10937/multiple-sketches
    • There's an example called "Multiple Nested PApplets (v2.0)".
    • It relies on runSketch() in order to have PApplet sketches running in their own separate window.
    • The interesting part for your particular case is that we can pass a String[] array containing some extra options to the new sketch instance like ARGS_FULL_SCREEN and "--display=1".
    • Just make sure the last option is some name you want the sketch to be called.
  • Alright, thanks so far. I managed to get 2 dragable windows from this example but I cant realy figure out where to put the ARGS_FULL_SCREEN and "--display=1".

    final PApplet projector = new projectorSketch();
    
    void setup() {
      size(300, 300);
      runSketch(new String[] { 
        "projector"
      }
      , projector);
    }
    
    void draw() {
      background(0);
      stroke(255);
      line(0, 0, 300, 300);
    }
    
    public static final class projectorSketch extends PApplet {
      void setup() {
        size(300, 150);
      }
    
      void draw() {
        background(0);
        stroke(255);
        line(0, 0, 300, 150);
      }
    }
    
  • edited June 2015 Answer ✓

    ... but I can't really figure out where to put the ARGS_FULL_SCREEN and "--display=1".

    That template was "hidden" as a commented out line: ;)
    //runSketch(new String[] { ARGS_FULL_SCREEN, "Full Window" }, another);

    As I've mentioned, just place the extra configs before the "title" of the sketch.
    Thus for your own runSketch(), that would be something like:
    runSketch(new String[] { "--full-screen", "--display=1", "My Projector" }, projector);

    Don't forget to use displayWidth & displayHeight for the sub-sketch's size():
    size(displayWidth, displayHeight, JAVA2D);

    Just some extra tips: Java's classes & interfaces use the UpperCamelCase for their names.
    Therefore it's class ProjectorSketch, not class projectorSketch! :P
    And of course, ARGS_FULL_SCREEN is the corresponding constant for "--full-screen". ;;)

  • Thanks. It works as intended now.

  • edited June 2015

    Glad it did! Just forgot to tell that "--full-screen" got a @Deprecated alias too: "--present".
    That's an important detail when we need to use the old Processing 1.5.1 version. :-\"
    Of course, "--present" works for all Processing versions! :ar!

  • I'm having problems getting a variable from the main window into the second one. I get the error "Cannot make a static reference to the non-static field".

  • edited June 2015

    In order for the static "minion" sketches to access any member from their "oversëer", that member needs to be declared as static too. Same for the other way around! O:-)

    https://Processing.org/reference/static.html

  • I can't quite wrap my head around it yet. Got an example that does that?

  • edited June 2015 Answer ✓

    Sorry I've forgotten to add that in order to access some static member, we also need to specify the name of its class/interface! :-\"

    That is, if we needed to access main sketch's projector field from inside ProjectorSketch nested class, besides declaring the former as static, we'd need something like:
    Name_of_Main_PDE_File.projector

    Anyways, forget that for now! B/c since you're using runSketch() instead main() in order to ignite the PApplet classes, we don't need them to be either static nor public! :-bd
    By getting rid of the static declaration, those classes become inner classes of the main sketch top class! And therefore, they're fully able to access any members from the latter! \m/

    From your updated example below, take notice that the now inner class ProjectorSketch can access the field member projector from the top sketch class: :D

    // forum.processing.org/two/discussion/11304/
    // multiple-monitors-primary-dragable-secondary-fullscreen
    
    final PApplet projector = new ProjectorSketch();
    
    void setup() {
      size(300, 300, JAVA2D);
      smooth(4);
      noLoop();
      stroke(-1);
    
      runSketch(new String[] { "--display=1", "--present", "Projector" }, projector);
    }
    
    void draw() {
      background(0);
      line(0, 0, width, height);
    }
    
    class ProjectorSketch extends PApplet {
      void setup() {
        size(displayWidth, displayHeight, JAVA2D);
        smooth(4);
        noLoop();
        stroke(#FFFF00);
      }
    
      void draw() {
        background(0);
        line(width, 0, 0, height);
    
        println(projector);
      }
    }
    
  • Alright, tried It and it works nicely. Thanks again.

  • I seem to be unable to use loadImage("filename.png") in the second window. It works fine in the main window.

  • edited June 2015
    • Processing relies on field sketchPath for all of its related I/O API, like loadImage(), saveFrame().
    • Unfortunately for sketches ignited by ourselves, w/ either main() or runSketch(), got their own sketchPath pointing to Processing's installation folder instead! :-&
    • We can check out sketchPath by calling undocumented sketchPath() function too.
    • Other useful alternatives are: dataPath(), sketchFile() & dataFile(). O:-)

    // forum.processing.org/two/discussion/11304/
    // multiple-monitors-primary-dragable-secondary-fullscreen
    
    final PApplet projector = new ProjectorSketch();
    
    void setup() {
      size(300, 300, JAVA2D);
      smooth(4);
      noLoop();
      stroke(-1);
    
      runSketch(new String[] { "--display=1", "Projector" }, projector);
    
      println("Main's  sketchPath: \"" + sketchPath("") + "\"");
      println("Main's  dataPath: \"" + dataPath("") + "\"");
    }
    
    void draw() {
      background(0);
      line(0, 0, width, height);
    }
    
    class ProjectorSketch extends PApplet {
      void setup() {
        size(displayWidth>>1, displayHeight>>1, JAVA2D);
        smooth(4);
        noLoop();
        stroke(#FFFF00);
    
        println("Inner's sketchPath: \"" + sketchPath("") + "\"");
        println("Inner's dataPath: \"" + dataPath("") + "\"");
      }
    
      void draw() {
        background(0);
        line(width, 0, 0, height);
      }
    }
    
    • Running this new test version above, you're gonna notice that main's sketchPath is right.
    • While inner's sketchPath is wrongly misplaced! :-<
    • I envision 2 approaches: Either use I/O functions within main sketch only or...
    • Well, since we already know that at least main's sketchPath is correct, how about pass that important information to the other nested inner sketches too! *-:)
    • A nice way to do that is adding that as an extra element for runSketch()'s String[] parameter:
      runSketch(new String[] { "--display=1", "Projector", sketchPath }, projector);
    • Any extra element inserted after sketch's title, in this case "Projector", is added to the undocumented String[] called args.
    • So the extra sketchPath element's gonna become args[0] inside projector's inner sketch.
    • From there, we can assign args[0] to inner sketch's own sketchPath: sketchPath = args[0];.
    • And tada, all of its I/O operations are gonna point to the right sketchPath! :-bd
    • Only problem I foresee is that later Processing 3 alpha releases changed sketchPath's access level from protected to private! X(
    • In this future case, we're gonna need to prefix everything path-related w/ args[0] inside the "ignited" sketches. :-@

    // forum.processing.org/two/discussion/11304/
    // multiple-monitors-primary-dragable-secondary-fullscreen
    
    final PApplet projector = new ProjectorSketch();
    
    void setup() {
      size(300, 300, JAVA2D);
      smooth(4);
      noLoop();
      stroke(-1);
    
      runSketch(new String[] { "--display=1", "Projector", sketchPath }, projector);
    
      println("Main's  sketchPath: \"" + sketchPath("") + "\"");
      println("Main's  dataPath: \"" + dataPath("") + "\"\n");
    }
    
    void draw() {
      background(0);
      line(0, 0, width, height);
    }
    
    class ProjectorSketch extends PApplet {
      void setup() {
        size(displayWidth>>1, displayHeight>>1, JAVA2D);
        smooth(4);
        //noLoop();
        frameRate(1);
        stroke(#FFFF00);
        strokeWeight(5);
    
        println("Inner's sketchPath: \"" + sketchPath("") + "\"");
        println("Inner's dataPath: \"" + dataPath("") + "\"\n");
    
        sketchPath = args[0]; // re-assign it w/ correct main sketch's path.
        println("Inner's fixed dataPath: \"" + dataPath("") + "\"\n");
      }
    
      void draw() {
        background((color) random(#000000));
        line(width, 0, 0, height);
    
        saveFrame( dataPath("screen-####.jpg") );
      }
    }
    
  • edited June 2015

    Surprise! I've got a more streamlined fix which probably is gonna keep working even on later Processing versions! <:-P After doing some more research and running this simple test below:

    println(sketchPath);
    println(sketchPath(""));
    printArray(args);
    exit();
    

    I've become aware of a "new" runSketch()'s config parameter called "--sketch-path="! :-$
    And that's exactly the very "trick" used by the PDE to pass for our regular sketches the sketchPath to use for I/O operations! :-B
    We merely need to do the same for our own special instantiated sketches. :D
    runSketch(new String[] { "--display=1", "--sketch-path=" + sketchPath(""), "Projector" }, projector);
    And w/ some tiny modifications, like changing displayWidth to screenWidth, the same sketch works even in Processing 1!

    /**
     * Multi-Monitor Sketch (v1.5)
     * by GoToLoop (2015/Jun/28)
     *
     * forum.Processing.org/two/discussion/11304/
     * multiple-monitors-primary-dragable-secondary-fullscreen
     *
     * forum.Processing.org/two/discussion/10937/multiple-sketches
     */
    
    void setup() {
      size(300, 300, JAVA2D);
      smooth(4);
      noLoop();
      frameRate(60);
      stroke(-1);
      strokeWeight(1.5);
    
      runSketch( new String[] { "--display=1",
                                "--present", 
                                "--sketch-path=" + sketchPath,
                                "Projector" },
                 new ProjectorSketch() );
    
      println("Main's  sketchPath: \t\"" + sketchPath("") + "\"");
      println("Main's  dataPath: \t\"" + dataPath("") + "\"\n");
    }
    
    void draw() {
      background(0);
      line(0, 0, width, height);
    }
    
    class ProjectorSketch extends PApplet {
      void setup() {
        size(displayWidth, displayHeight, JAVA2D);
        smooth(4);
        //noLoop();
        frameRate(1);
        stroke(#FFFF00);
        strokeWeight(5);
    
        println("Inner's sketchPath: \t\"" + sketchPath("") + "\"");
        println("Inner's dataPath: \t\"" + dataPath("") + "\"\n");
      }
    
      void draw() {
        background((color) random(#000000));
        line(width, 0, 0, height);
    
        saveFrame( dataPath("screen-####.jpg") );
      }
    }
    
Sign In or Register to comment.