fix scheduling, threading and movement bugs
scheduling: - cursor mover created a new java.util.timer for every movement and never cancelled it, leaking a live thread roughly every 10 seconds; timers are replaced by a single shared scheduledexecutorservice with daemon threads, shut down when the automation stops. clicks: - the double click sequence used thread.sleep() inside a timer task, blocking the scheduler thread; it is now scheduled as one-shot actions on the shared scheduler, with the same pacing as before. - stopping the automation now also cancels in-flight movements and pending clicks, instead of letting them run to completion. movement math: - when the destination shared one coordinate with the starting position, the step on the other axis was computed as length/0 = infinity, and the stop condition checked one axis with || instead of &&, so a movement could stop (and click) before reaching its destination. steps are now guarded and the movement stops only when both axes have converged. ui and lifecycle: - the app could not be closed: closing the window only hid it, and ESC unregistered the hotkey without exiting. the window now exits cleanly on close, stopping the automation and unregistering the native hook. - toggleRunning() was called from the jnativehook thread and touched swing components off the EDT; UI updates are now marshalled to the EDT. - the hotkey thrashed: key repeats re-fired the toggle while ctrl+alt was held, and any other key pressed with the combo held toggled it too. it now fires exactly once, when the combo is completed. away-detection (CursorMoveListener) stays intentionally unscheduled: it cannot tell the user's movements apart from the app's own, and will be reworked in a future iteration.
This commit is contained in:
@@ -7,6 +7,8 @@ import org.apache.logging.log4j.Logger;
|
||||
import wtf.beatrice.autosqueal.listener.KeyPressListener;
|
||||
import wtf.beatrice.autosqueal.ui.MainWindow;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class Main {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(Main.class);
|
||||
@@ -16,7 +18,9 @@ public class Main {
|
||||
LOGGER.info("Hello world!");
|
||||
|
||||
registerJNativeHook();
|
||||
mainWindow.init();
|
||||
|
||||
// all Swing components must be created and updated on the EDT
|
||||
SwingUtilities.invokeLater(mainWindow::init);
|
||||
}
|
||||
|
||||
private static void registerJNativeHook() {
|
||||
@@ -34,8 +38,19 @@ public class Main {
|
||||
}
|
||||
}
|
||||
|
||||
public static void unregisterJNativeHook() {
|
||||
try {
|
||||
GlobalScreen.unregisterNativeHook();
|
||||
LOGGER.info("Successfully unregistered jnativehook library!");
|
||||
}
|
||||
catch (NativeHookException ex) {
|
||||
LOGGER.error("There was a problem unregistering the native hook.");
|
||||
LOGGER.error(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static MainWindow getMainWindow() {
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user