wilix-team / iohook

Node.js global keyboard and mouse listener.
https://wilix-team.github.io/iohook
MIT License
1.2k stars 291 forks source link

XkbGetKeyboard failed to locate a valid keyboard! on Raspberry Pi #207

Closed MatthewCash closed 3 years ago

MatthewCash commented 4 years ago

After successfully building on a Raspberry Pi 1, it fails with a segmentation fault when I try to run a node program.

The only time it works, is when the desktop GUI is running, and the program is run from there using the terminal, SSH does not work at all

Expected Behavior

I expected it not to fail, and to not exit immediately.

Current Behavior

When running the example program example/example.js this is sent to the console

on_library_load [456]: XOpenDisplay failure!
load_input_helper [1907]: XkbGetKeyboard failed to locate a valid keyboard!
Segmentation fault

Steps to Reproduce (for bugs)

  1. Get a Raspberry Pi 1
  2. Build
  3. Run example

Context

I cannot use iohook unless from GUI terminal

Your Environment

dpacmittal commented 4 years ago

Have you tried setting environment variable DISPLAY=:0?

cmidgley commented 4 years ago

I can confirm the some of the same behavior, Raspberry Pi (4) w/Raspbian Buster Lite. In my case, I do not have X installed. However, the messages are the same about no keyboard as well as the segmentation fault.

on_library_load [456]: XOpenDisplay failure!
load_input_helper [1907]: XkbGetKeyboard failed to locate a valid keyboard!
Segmentation fault

I did not realize this library was dependent on X (might be nice to add that to requirements), but since it is, that would explain why it does not work on SSH.

The segmentation fault does seem like a bug, perhaps due to cleaning up resources after the unusual code path of no keyboard?

cmidgley commented 4 years ago

The segmentation fault was pretty easy to locate. In libuiohook/src/x11/input_helper.c, starting at line 1904 is the following:

 else {
                logger(LOG_LEVEL_ERROR,
                                "%s [%u]: XkbGetKeyboard failed to locate a valid keyboard!\n",
                                __FUNCTION__, __LINE__);
        }

        // Get the map.
        keyboard_map = XkbGetMap(disp, XkbAllClientInfoMask, XkbUseCoreKbd);

The failure is that after the error happens, the code still proceeds to try to get the map. If instead you add a "return;" to just after the logger call, the segmentation violation goes away.

 else {
                logger(LOG_LEVEL_ERROR,
                                "%s [%u]: XkbGetKeyboard failed to locate a valid keyboard!\n",
                                __FUNCTION__, __LINE__);
                return;
        }

        // Get the map.
        keyboard_map = XkbGetMap(disp, XkbAllClientInfoMask, XkbUseCoreKbd);

Of course the code doesn't do much as no keyboards were found, but at least the code doesn't crash.

ash0x0 commented 3 years ago

I doubt I will fix this. If this is still an issue and someone is interested, please reopen and express interest and I may allocate some time to it as I do have a few RPis around so I can repro and fix.

FreemanFeng commented 2 weeks ago

如果你在远程服务器上工作,但无法连接到物理显示器,可以考虑使用虚拟显示工具,如Xvfb(X Virtual Framebuffer)。你可以通过以下命令来安装和 启动它:


     sudo apt-get install xvfb
     Xvfb :99 -screen 0 1024x768x24 &
     export DISPLAY=:99