give the mouse back when the user returns mid-movement
This commit is contained in:
@@ -17,6 +17,9 @@ import java.util.function.BooleanSupplier;
|
|||||||
*
|
*
|
||||||
* The movements only happen when the user is away: while the user is actively
|
* The movements only happen when the user is away: while the user is actively
|
||||||
* using the machine, they are skipped, so the app never fights for the mouse.
|
* using the machine, they are skipped, so the app never fights for the mouse.
|
||||||
|
* The same goes for a movement already in progress: the task checks whether
|
||||||
|
* the user is still away at every step, and gives the mouse back when they
|
||||||
|
* are not.
|
||||||
*
|
*
|
||||||
* The movement itself is executed by a {@link SingleStepMovementTask}, which
|
* The movement itself is executed by a {@link SingleStepMovementTask}, which
|
||||||
* runs on its own virtual thread until it reaches its destination.
|
* runs on its own virtual thread until it reaches its destination.
|
||||||
@@ -72,7 +75,7 @@ public class CursorMover implements Runnable
|
|||||||
LOGGER.info("Destination coordinates: {}, {}", destX, destY);
|
LOGGER.info("Destination coordinates: {}, {}", destX, destY);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SingleStepMovementTask movement = new SingleStepMovementTask(robotTracker, destX, destY, click);
|
SingleStepMovementTask movement = new SingleStepMovementTask(robotTracker, destX, destY, click, isUserAway);
|
||||||
movementExecutor.execute(movement);
|
movementExecutor.execute(movement);
|
||||||
} catch (AWTException ex) {
|
} catch (AWTException ex) {
|
||||||
LOGGER.error("Could not start movement task", ex);
|
LOGGER.error("Could not start movement task", ex);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.apache.logging.log4j.Logger;
|
|||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.InputEvent;
|
import java.awt.event.InputEvent;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the mouse cursor towards a destination one small step at a time.
|
* Moves the mouse cursor towards a destination one small step at a time.
|
||||||
@@ -13,6 +14,10 @@ import java.awt.event.InputEvent;
|
|||||||
* it is free. When it gets to its destination, it can optionally perform a
|
* it is free. When it gets to its destination, it can optionally perform a
|
||||||
* double click, with the pacing the app has always used.
|
* double click, with the pacing the app has always used.
|
||||||
*
|
*
|
||||||
|
* If the user comes back mid-movement, the movement is abandoned at once —
|
||||||
|
* within the latency of the away detection, which polls about once a second —
|
||||||
|
* so the mouse is returned to the user instead of being dragged to a corner.
|
||||||
|
*
|
||||||
* All the movements it performs are reported to the {@link RobotMouseTracker},
|
* All the movements it performs are reported to the {@link RobotMouseTracker},
|
||||||
* so that the away detection can tell them apart from the user's.
|
* so that the away detection can tell them apart from the user's.
|
||||||
*/
|
*/
|
||||||
@@ -28,18 +33,21 @@ public class SingleStepMovementTask implements Runnable {
|
|||||||
private final int destX;
|
private final int destX;
|
||||||
private final int destY;
|
private final int destY;
|
||||||
private final boolean click;
|
private final boolean click;
|
||||||
|
private final BooleanSupplier userIsAway;
|
||||||
|
|
||||||
private float currentX;
|
private float currentX;
|
||||||
private float currentY;
|
private float currentY;
|
||||||
private float stepX;
|
private float stepX;
|
||||||
private float stepY;
|
private float stepY;
|
||||||
|
|
||||||
public SingleStepMovementTask(RobotMouseTracker robotTracker, int destinationX, int destinationY, boolean click) throws AWTException {
|
public SingleStepMovementTask(RobotMouseTracker robotTracker, int destinationX, int destinationY, boolean click,
|
||||||
|
BooleanSupplier userIsAway) throws AWTException {
|
||||||
|
|
||||||
this.robotTracker = robotTracker;
|
this.robotTracker = robotTracker;
|
||||||
this.destX = destinationX;
|
this.destX = destinationX;
|
||||||
this.destY = destinationY;
|
this.destY = destinationY;
|
||||||
this.click = click;
|
this.click = click;
|
||||||
|
this.userIsAway = userIsAway;
|
||||||
|
|
||||||
Point location = MouseInfo.getPointerInfo().getLocation();
|
Point location = MouseInfo.getPointerInfo().getLocation();
|
||||||
this.currentX = location.x;
|
this.currentX = location.x;
|
||||||
@@ -65,6 +73,14 @@ public class SingleStepMovementTask implements Runnable {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
while (!hasReachedDestination()) {
|
while (!hasReachedDestination()) {
|
||||||
|
// a user who came back mid-movement gets the mouse back
|
||||||
|
if (!userIsAway.getAsBoolean()) {
|
||||||
|
LOGGER.info("User is back: abandoning the movement at [{}, {}]",
|
||||||
|
Math.round(currentX), Math.round(currentY));
|
||||||
|
robotTracker.moveEnded(Math.round(currentX), Math.round(currentY));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// when less than a full step is left, move exactly what is
|
// when less than a full step is left, move exactly what is
|
||||||
// left, so that both axes always land on their destination
|
// left, so that both axes always land on their destination
|
||||||
stepX = adjustedStep(currentX, destX, stepX);
|
stepX = adjustedStep(currentX, destX, stepX);
|
||||||
|
|||||||
Reference in New Issue
Block a user