# Extending the mouse range past the screen size

**URL:** <https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431>\
**Category:** Coding Questions\
**Created:** [October 13, 2018, 4:53pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431 "2018-10-13T16:53:31Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tsskyx](https://avatars.discourse-cdn.com/v4/letter/t/90ced4/32.png) [@Tsskyx](https://discourse.processing.org/u/Tsskyx)\
**Post date:** [October 13, 2018, 4:53pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/1 "2018-10-13T16:53:31Z")

</div>

You see this in a lot of games, this kind of infinite mouse movement, where you can move your mouse around as much as you want, without ever getting stopped by the edges of your screen.

I’ve made something like this, and also made it so that the mouse movement, although getting reset each time the mouse is moved, can actually be extracted.

```auto
import java.awt.*;
Robot robot;
PVector mouse = new PVector();
boolean autoMove = false;

void setup() {
  fullScreen(P3D);
  mouse.set(width/2, height/2);
  strokeWeight(5);
  noCursor();
  try {
    robot = new Robot();
  } 
  catch (Exception e) {
  }
}

void draw() {
  background(255);
  if (!autoMove && (mouseX-pmouseX != 0 || mouseY-pmouseY != 0)) {
    mouse.add(mouseX-width/2, mouseY-height/2);
    robot.mouseMove(width/2, height/2);
    autoMove = true;
  } else {
    autoMove = false;
  }
  point(mouse.x, mouse.y);
  println(mouse.x, mouse.y);
}

```

As you can see, I’ve done it through the Robot class, which automatically resets the mouse whenever it is moved. However, I am disappointed by a couple of things:

(1) I was unable to make this work in a windowed mode. For that, I would need to somehow get the parameters for the window’s position on the screen in the code, but nothing helped, all the guides online were either for an older version of Processing, or too complicated for me to understand.

(2) I couldn’t use the mouseMoved() function, because the resetting of the mouse also triggers it, and that would instantly undo any saved mouse movement away from the point on screen to which the robot resets the mouse. Instead, I’ve had to create my own function, or rather, a conditional statement, which activates only if it didn’t activate the last time, and vice versa.

(3) The movement is quite laggy.

Is there any way I could improve this sketch? Mainly so that I could resolve these three points above?

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [October 13, 2018, 6:33pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/2 "2018-10-13T18:33:35Z")

</div>

If you’re only doing this with the P2D or P3D renderer you’d be better getting access to the JOGL Window and using confinePointer() and/or warpPointer()

[https://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/newt/Window.html](https://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/newt/Window.html)

---

<div class="post-metadata">

**Author:** ![Architector\_4](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/architector_4/32/813_2.png) [@Architector\_4](https://discourse.processing.org/u/Architector_4)\
**Post date:** [October 13, 2018, 6:46pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/3 "2018-10-13T18:46:47Z")

</div>

Try this sketch! It should do everything perfectly regardless of windowed or fullscreen. I guess you could try integrating its code into your code?

```auto
import com.jogamp.newt.opengl.GLWindow;
GLWindow r;
float posX=100;
float posY=100;
boolean Lock=false;
int offsetX=0;
int offsetY=0; //If we lock the pointer, it will be teleported 
                         //to the center of the screen only as soon as 
                         //the draw() function ends, and until then the
                         //position value will be on a random spot
                         //where the user clicked.
                         //If we take into account that spot for that
                         //one frame, we can correct the position.

float Sensitivity=0.5;

void setup(){
  r=(GLWindow)surface.getNative(); //Ooh, complex OpenGL things I don't know much about myself.
  size(640,480,P2D);
  surface.setResizable(true); //I like resizable surfaces.
}

void draw(){
  
  
  if(Lock){posX+=(mouseX-offsetX-width/2)*Sensitivity; posY+=(mouseY-offsetY-height/2)*Sensitivity;} //If lock, then adjust position...
  //Any random code that depends on those positions...
  
  background(0);
  
  fill(192);
  ellipse(posX,posY,20,20);
  
  fill(255);
  text(Lock?"Locked":"Unlocked",2,15);
  text("posX: "+posX+"\nposY: "+posY,2,35);
  
  
  
  
  if(Lock){
    offsetX=offsetY=0;
  r.setPointerVisible(false); //When locked and trying to move, the pointer jerks all over the place, so best to hide it.
  r.warpPointer(width/2,height/2); //Move it to the exact center of the sketch window.
  r.confinePointer(true); //Locks pointer inside of the sketch's window so it doesn't escape.
                          //The pointer will still hit the window's edges, limiting moves fast enough.
                          //But as soon as the pointer is outside of the window it's visible until it's
                          //teleported back inside the window, which is less preferable.
                          
  }else{r.confinePointer(false); r.setPointerVisible(true);} //Else undo that stuff.
  
  
}

void mousePressed(){
  Lock=!Lock;
  if(Lock){
    offsetX=mouseX-width/2; offsetY=mouseY-height/2;
  }else{
    r.warpPointer(round(posX),round(posY)); //Teleport it to an expected position. Handier that way!
  }
  
}

void keyPressed(){
  if(key=='r'){posX=posY=50;}
}

```

Also, this might be a bad idea that would confuse everyone including you, but I’ve made some random messy code that allows you to navigate around 3D space similar to what’s in games _(like you’re flying around in “noclip” mode, if you know what I mean),_ and here it is: [https://pastebin.com/J4wnp6e2](https://pastebin.com/J4wnp6e2)

And yes, I did break my head a couple of times there and made some stuff overly complicated, so please don’t question it! .\_.

_(also that project of mine ended up having a bunch of unrelated functions in it that I pasted in from my other projects, so, uh, have that for free too, I guess? lol)_

---

<div class="post-metadata">

**Author:** ![Tsskyx](https://avatars.discourse-cdn.com/v4/letter/t/90ced4/32.png) [@Tsskyx](https://discourse.processing.org/u/Tsskyx)\
**Post date:** [October 14, 2018, 1:47am UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/4 "2018-10-14T01:47:54Z")

</div>

I have simplified that code into the following:

```auto
import com.jogamp.newt.opengl.GLWindow;
GLWindow r;

PVector mousePos = new PVector();

void setup() {
  size(640, 480, P3D);
  r = (GLWindow)surface.getNative();
  r.setPointerVisible(false);
  mousePos.set(width/2, height/2).mult(3);
}

void draw() {
  r.warpPointer(width/2, height/2);
  mousePos.add(mouseX - width/2, mouseY - height/2);
  background(0);
  ellipse(mousePos.x, mousePos.y, 20, 20);
  println(mousePos.x, mousePos.y, mouseX, mouseY);
}

```

This did everything I needed. However, I don’t understand two things.  
Firstly, that .mult(3) factor.  
According to the console data, after draw is run once, mouseX and mouseY are yet not initialized at the center of the sketch, which they should have, due to the line `r.warpPointer(width/2, height/2);` already being run once. But it’s even weirder that they’re not initialized even the second time over.

All this results in the ellipse initially appearing at negative coordinates, unless I scale the initial position by a factor of 3. Weird.

Second, how come `r.warpPointer()` can stand before `mousePos.add()`?  
Shouldn’t the resetting of the mouse’s position before saving its offset from the center of the screen into the mousePos vector cause the .add() method to output a vector of (0, 0), ergo, not causing the ellipse to move at all?

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [October 14, 2018, 9:45am UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/5 "2018-10-14T09:45:31Z")

</div>

> [@Tsskyx](#):
>
> Second, how come `r.warpPointer()` can stand before `mousePos.add()` ?

`mouseX` and `mouseY` are Processing variables only set before `draw()` is called so the call to `warpPointer()` happens asynchronously - calling it doesn’t result in the mouse variables being updated until a later run through draw. IIRC the `warpPointer()` call will be passed on to the JOGL event thread, and then the mouse updated back on the animation thread, which might explain more than one frame delay.

I’m also confused just looking at it exactly what the `mult(3)` is required for, although the first few mouse positions will be quite off.

---

<div class="post-metadata">

**Author:** ![Tsskyx](https://avatars.discourse-cdn.com/v4/letter/t/90ced4/32.png) [@Tsskyx](https://discourse.processing.org/u/Tsskyx)\
**Post date:** [October 14, 2018, 1:06pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/6 "2018-10-14T13:06:35Z")

</div>

Yes, that’s why I’ve added it in, due to mouseX and mouseY variables being 0, ergo .add() outputting negative values for the first few frames. Though, `r.confinePointer(true);` seems to change that. Adding that in into setup(), I only need a scaling of 2, not three. And moving the position calculation and mouse reset into mouseMoved() further messes with the initial position.

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [October 14, 2018, 1:31pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/7 "2018-10-14T13:31:50Z")

</div>

Yes, but that doesn’t seem very reliable. It may not behave identically on different systems. You could ignore 0,0 and maybe also clamp the maximum distance from centre in your calculations?

---

<div class="post-metadata">

**Author:** ![Architector\_4](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/architector_4/32/813_2.png) [@Architector\_4](https://discourse.processing.org/u/Architector_4)\
**Post date:** [October 14, 2018, 2:08pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/8 "2018-10-14T14:08:27Z")

</div>

Currently can’t test, but what if you replace the `.add()` string with this?  
`if(frameCount>2) mousePos.add(mouseX - width/2, mouseY - height/2);`

It would be less responsive for those 2 first frames, but that would effectively ignore any messy positions the pointer might have during them.

---

<div class="post-metadata">

**Author:** ![Tsskyx](https://avatars.discourse-cdn.com/v4/letter/t/90ced4/32.png) [@Tsskyx](https://discourse.processing.org/u/Tsskyx)\
**Post date:** [October 14, 2018, 2:23pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/9 "2018-10-14T14:23:18Z")

</div>

My current solution is to start modifying the mousePos vector only if frameCount is higher than 2, as @Architector_4 said. It seems to be the safest bet so far.

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [October 14, 2018, 3:03pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/10 "2018-10-14T15:03:50Z")

</div>

> [@Tsskyx](#):
>
> It seems to be the safest bet so far.

Only if you assume that a couple of frames is always enough for this to take effect on every system you want to run it on!

---

<div class="post-metadata">

**Author:** ![Architector\_4](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/architector_4/32/813_2.png) [@Architector\_4](https://discourse.processing.org/u/Architector_4)\
**Post date:** [October 14, 2018, 3:53pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/11 "2018-10-14T15:53:55Z")

</div>

Well, it’s still the best way out(at least that we are aware of).  
Another way that could work is to keep ignoring the pointer position until it’s equal to the window center position, but it would rely on the user to not flail their mouse around on the startup, else it would keep on ignoring until the user stops. lol

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [October 14, 2018, 4:09pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/12 "2018-10-14T16:09:48Z")

</div>

> [@Architector\_4](#):
>
> Another way that could work is to keep ignoring the pointer position until it’s equal to the window center position

Or within a certain distance, which is what I was suggesting above. You could even slowly raise that allowed distance over time. The idea being to dampen out invalid and noisy values.

---

<div class="post-metadata">

**Author:** ![Tsskyx](https://avatars.discourse-cdn.com/v4/letter/t/90ced4/32.png) [@Tsskyx](https://discourse.processing.org/u/Tsskyx)\
**Post date:** [October 14, 2018, 4:15pm UTC](https://discourse.processing.org/t/extending-the-mouse-range-past-the-screen-size/4431/13 "2018-10-14T16:15:22Z")

</div>

I was also thinking of something like: `if (mouseX + mouseY != 0) {...}`, which would ignore the beginning values, but also ignore a jerky move that places the mouse at (0, 0) before resetting it again. Though, the probability of that happening is low.
