static int forwardClicks_windowSize = 11; // odd should look nice. Set to 1 for an invisible window static int forwardClicks_clickDelay = 0; // Delay in ms between closing window and forwarding click. 0 seems to work fine. static int forwardClicks_dragDelay = 100; // Delay in ms when dragging static int forwardClicks_trackingSpeed = 10; // How often to move the window (ms) static int forwardClicks_restartDelay = 1000; // How quickly to restart after click (e.g. to allow untraced drags [forwarding dragging doesn't always work]) sbool forwardClicks_verbose; // onClick: voidfunc(Point, Point, int) - press location, release location, button (1 to 3) static void forwardClicks(final O onClickAndRelease) { awtIfNecessary { final new JWindow window; final int windowSize = forwardClicks_windowSize; window.setSize(windowSize, windowSize); window.setVisible(true); window.setAlwaysOnTop(true); JPanel panel = singleColorPanel(Color.red); window.setContentPane(panel); revalidate(window); final new Robot robot; panel.addMouseListener(new MouseAdapter { Point pressed; public void mousePressed(final MouseEvent e) { pressed = getMouseLocation(); } public void mouseReleased(final MouseEvent e) { window.setVisible(false); final Point released = getMouseLocation(); final Point _pressed = or(pressed, released); final int b = e.getButton(); final int mod = b == 1 ? InputEvent.BUTTON1_DOWN_MASK : b == 2 ? InputEvent.BUTTON2_DOWN_MASK : InputEvent.BUTTON3_DOWN_MASK; swingLater(forwardClicks_clickDelay, r { pcallF(onClickAndRelease, _pressed, released, b); robot.mouseMove(_pressed.x, _pressed.y); robot.mousePress(mod); swingLater(neq(_pressed, released) ? forwardClicks_dragDelay : 0, r { robot.mouseMove(released.x, released.y); robot.mouseRelease(mod); // Start tracking again - make new JWindow otherwise we get a crazy item on task bar in Linux swingLater(forwardClicks_restartDelay, r { forwardClicks(onClickAndRelease); }); }); }); } }); swingEvery(window, forwardClicks_trackingSpeed, r { final Point p = getMouseLocation(); // Expand height if in task bar (crude fix for Peppermint Linux) int bottom = getScreenHeight()-(768-743); final Point loc = new Point(p.x-windowSize/2, min(bottom, p.y-windowSize/2)); int h = max(windowSize, p.y-loc.y+windowSize/2); window.setBounds(loc.x, loc.y, windowSize, h); if (forwardClicks_verbose) { Point onScreen = window.getLocationOnScreen(); print(loc + " " + onScreen); } /*if (neq(onScreen, loc)) print("Location not honored");*/ }); } }