Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIGSEGV when registering hook in JavaFX application #442

Open
Vitaspiros opened this issue May 20, 2023 · 2 comments
Open

SIGSEGV when registering hook in JavaFX application #442

Vitaspiros opened this issue May 20, 2023 · 2 comments
Assignees

Comments

@Vitaspiros
Copy link

Title basically. I have a JavaFX application that throws SIGSEGV in line GlobalScreen.registerNativeHook();. When I remove that line, it doesn't exit but then the application doesn't work. I am running it with Java 17 on Ubuntu 20.04 64-bit. Also I'm using Maven to build it and JNativeHook 2.2.2. Here's the crash log if that helps: https://pastebin.com/hU6ahhaR

@vincemann
Copy link

do it like this

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        // ...all your init stuff

        new Thread(()->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            registerHook();
        }).start();
    }

   private void registerHook(){
        try {
            com.github.kwhat.jnativehook.GlobalScreen.registerNativeHook();
        } catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());

            System.exit(1);
        }
    }
}

Also the problem goes away in old versions:
// https://mvnrepository.com/artifact/com.1stleg/jnativehook
implementation 'com.1stleg:jnativehook:2.1.0'

Also register your Listeners in the same way:

@Inject
    public GlobalHotKeyListener(EventBus eventBus) {
        this.eventBus = eventBus;
        // ugly workaround for bug in jnativehook - keep it like that
        registerListener();
    }

    private void registerListener(){
        new Thread(()->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            GlobalScreen.addNativeKeyListener(this);
        }).start();
    }

Had the same issue, this is my (very pretty) workaround.
Works on:
openjdk 17.0.8 2023-07-18 LTS
Linux debian 5.10.0-28-amd64 #1 SMP Debian 5.10.209-2 (2024-01-31) x86_64 GNU/Linux
javafx version 17.0.1

@vincemann
Copy link

I ended up simplifying like this:
Note that the registration of the listeners should take place in the same thread as hook registration, right after hook registration.

public class Main extends Application{
    @Override
    public void start(Stage primaryStage) throws Exception {
        //  ...
        // only for jnativehook 2.2.2:
        // needs to be run on diff thread, otherwise segfault
        Platform.runLater(this::registerHook);
    }

    private void registerHook() {
        try {
            GlobalScreen.registerNativeHook();
            // must register here bc of thread issues and race conditions in jnativehook
            GlobalScreen.addNativeMouseListener(myMouseListener);
            GlobalScreen.addNativeKeyListener(myHotKeyListener);
        } catch (NativeHookException e) {
            log.error("Failed to register native hook", e);
            System.exit(1);
        }
    }
}

@kwhat kwhat self-assigned this May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants