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

IOHook Breaks after calling getUserMedia() on Windows Only #230

Closed enzious closed 3 years ago

enzious commented 4 years ago

Expected Behavior

Keydown events should be sent when the electron app is in focus and also when the app is not in focus.

Current Behavior

After calling navigator.mediaDevices.getUserMedia(...) in the renderer process, all events stop being sent when the app is in focus. When not in focus, the events are sent currently. Before calling getUserMedia(...) it works like described in "Expected Behavior".

Issue seems to appear only on windows. On Mac OS it workes fine

Steps to Reproduce (for bugs)

Sample app can be found here: https://github.com/dominik-vincenz/iohook-issue-sample (For old version with same issue)

1. Start provided electron app and type sth. while the app is in focus and out of focus

2. In the electron log all keypressed are logged

3. Click Button "GetUserMedia"

4. Type again with app in focus and out of focus.

5. Keypresses are not only logged when the app is not in focus

Your Environment

Windows 10 electron-8.0.0 iohook-0.6.5

Next Steps?

Could a more knowledgeable developer point me in the right direction on this issue? It may be something in Chrom(e/ium)... I don't see anything obvious in the iohook library.

enzious commented 4 years ago

Found the issue: https://bugs.chromium.org/p/chromium/issues/detail?id=935228

This is a bit annoying, but may be fixable.

Perhaps forking the process doing the hook but that's a bit of a refactor.

enzious commented 4 years ago

Forking the iohook script using child-process.fork() may work :thinking:

enzious commented 4 years ago

I can confirm. Using ChildProcess.fork(...) is a workaround for this issue.

@dominik-vincenz @chevonc @adambailey-

ash0x0 commented 3 years ago

I can't repro this currently, using node 14 and electron 11. Hopefully it's gone, if not please reopen.

levycodev commented 2 years ago

For anyone stumbling on this, the error is caused by Windows-only Chromium blocking the message loop when an audio channel is active and your electron app has focus (I would consider this a bug). However, to work around it, you can run a separate process that creates a keyboard hook AND DOES NOTHING ELSE BUT CALL THE NEXTHOOK API! Essentially, you are causing this second process to ensure that the first processes hook gets called! Make sure the "helper" process is started after you have installed in the first hook.

In my case, the hook was being installed by a .node extension and worked perfectly UNTIL an audio/video session was started, and during that time, my keyboard hook function never got called. As soon as the audio/video was stopped, it started working again.

I am installing my hook like this (both in the .node addon and in the "helper" exe);

kbHookProc = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, nullptr, 0);

And my hook calls the next hook like this (at the end);

return CallNextHookEx(kbHookProc, code, wparam, lparam);

I start my "helper" process like this in node, after I have loaded my extension;

const myAddon = require("./my_node_addon"); const guard = "./my_helper.exe"; const child = execFile(guard, [], {cwd:__dirname}, (error, stdout, stderr) => { if (error) { throw error; } });

Now the helper will ensure the hook from my_node_addon gets called! Crazy, but it works!