ask for permissions instead of exiting when the hook fails
This commit is contained in:
@@ -19,10 +19,15 @@ public class Main {
|
||||
LOGGER.info("Hello world!");
|
||||
|
||||
useSystemLookAndFeel();
|
||||
registerJNativeHook();
|
||||
boolean hookRegistered = registerJNativeHook();
|
||||
|
||||
// all Swing components must be created and updated on the EDT
|
||||
SwingUtilities.invokeLater(mainWindow::init);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
mainWindow.init();
|
||||
if (!hookRegistered) {
|
||||
mainWindow.showPermissionsHelp();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void useSystemLookAndFeel() {
|
||||
@@ -33,18 +38,22 @@ public class Main {
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerJNativeHook() {
|
||||
private static boolean registerJNativeHook() {
|
||||
LOGGER.info("Registering jnativehook library...");
|
||||
try {
|
||||
GlobalScreen.registerNativeHook();
|
||||
GlobalScreen.addNativeKeyListener(new KeyPressListener());
|
||||
LOGGER.info("Successfully registered jnativehook library!");
|
||||
return true;
|
||||
}
|
||||
catch (NativeHookException ex) {
|
||||
LOGGER.error("There was a problem registering the native hook.");
|
||||
LOGGER.error(ex.getMessage());
|
||||
LOGGER.error("There was a problem registering the native hook.", ex);
|
||||
|
||||
System.exit(1);
|
||||
// without the accessibility permission the hotkey cannot be
|
||||
// registered and the mouse cannot be moved either: the app would
|
||||
// look alive but do nothing. don't exit: keep the window and the
|
||||
// tray icon usable, and tell the user what is missing.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@@ -174,6 +175,46 @@ public class MainWindow
|
||||
Main.unregisterJNativeHook();
|
||||
}
|
||||
|
||||
/**
|
||||
* Explains that the app cannot work without its permissions, and offers
|
||||
* a shortcut to the right system settings pane. Must be called on the
|
||||
* EDT, after the window is visible.
|
||||
*/
|
||||
public void showPermissionsHelp() {
|
||||
Object[] options = {"Open System Settings", "Close"};
|
||||
|
||||
int choice = JOptionPane.showOptionDialog(frame,
|
||||
"autosqueal needs the accessibility permission to move the mouse and to\n"
|
||||
+ "listen for the ctrl+alt hotkey, and the screen recording one to\n"
|
||||
+ "show the screen preview. they cannot be granted while it is running.\n\n"
|
||||
+ "grant them in privacy & security, then restart autosqueal.",
|
||||
"permissions needed",
|
||||
JOptionPane.DEFAULT_OPTION,
|
||||
JOptionPane.WARNING_MESSAGE,
|
||||
null,
|
||||
options,
|
||||
options[0]);
|
||||
|
||||
if (choice == 0) {
|
||||
openPrivacySettings();
|
||||
}
|
||||
}
|
||||
|
||||
/** Opens the privacy & security pane at the accessibility section. */
|
||||
private void openPrivacySettings() {
|
||||
if (SystemUtil.getHostSystem() != SystemUtil.OperatingSystem.MAC_OS) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
new ProcessBuilder("open",
|
||||
"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility")
|
||||
.start();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Could not open the system settings", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the automation on or off. Safe to call from any thread: the actual
|
||||
* work is always marshalled to the EDT, since it touches Swing components.
|
||||
|
||||
Reference in New Issue
Block a user