The answer is "you can" and "you can't". Let's start with the "can't".
Can't:
It seems macOS incorrectly detects the attempt to move the mouse as coming from IntelliJ, when in fact, it's coming from java
. You can give IntelliJ all the permissions you want, but java
will never be able to move the cursor when the permissions are given to IntelliJ.
IntelliJ (which is a Java application) is running a child process to start your program. The child process is the java
command line and not the same java
as is bundled with IntelliJ. This child process needs the permissions.
Can:
This is a bit round about.
- Use Gradle to build your project, IntelliJ recognizes Gradle projects and interacts nicely with them
- Remove all occurrences of IntelliJ and Java from Accessibility permissions in macOS system preferences -> Security and Privacy.
- Be sure all Gradle daemons are stopped (or if you haven't run Gradle yet, then be sure the next step is the first time gradle runs since you last rebooted your computer)
- Run you application from the command line using Gradle
- macOS will prompt to give permissions, open system preferences and give
java
permission.
- Run IntelliJ and run your app as a gradle project through IntelliJ, and voila!
What happens: IntelliJ, in step 6, uses the already running gradle daemon process to execute your application. This process is using java
and java
has permission to move the mouse cursor in macOS system preferences.
It's not pretty, but it works. If you're like me, you use gradle anyway for java projects in IntelliJ, and all you have to do is remember to run your project from the command line before running it from IntelliJ. This way, the gradle daemon (a java
process) will be responsible for running the application and proper permissions will be detected by macOS.
I tested this with the following code (note a few modifications, as the OP code had some "bugs"):
import javax.swing.SwingUtilities;
import java.awt.AWTException;
import java.awt.MouseInfo;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class RunRobot {
public static void main(String[] args) {
int x = 12,
y = 300;
final int[] xAct = new int[1],
yAct = new int[1];
try {
Robot robot = new Robot();
robot.mouseMove(x, y);
robot.waitForIdle();
SwingUtilities.invokeAndWait(()->{
xAct[0] = (int) MouseInfo.getPointerInfo().getLocation().getX();
yAct[0] = (int) MouseInfo.getPointerInfo().getLocation().getY();
});
String sPred = String.format("Predicted mouse location : %, d, %, d", x, y),
sAct = String.format("Actual mouse location : %, d, %, d", xAct[0], yAct[0]);
System.out.println(sPred);
System.out.println(sAct);
} catch (InterruptedException | AWTException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
SwingUtilities.invokeAndWait
used to get theMouseInfo
. – Tropine