Java – Global (low level) Keyboard / Mouse Hook
by Kristian Kraljic, February 9, 2016
About five years ago I started this blog by picking up an idea of Johannes Schüth (Jotschi) about a global keyboard and mouse listener for Java. Today I am very happy to announce the next major version of the library now available on GitHub!
Keyboard and mouse events in Java only work, if the registered component is in focus. For example, in case a window looses its focus (e.g. when minimized), it stops receiving any more events. Through a low-level system-wide hook it’s possible to deliver those events regardless. You’ll find all sources of the latest release, as well as binary bundles / prepackaged Java archives (JAR) on the GitHub project page.
The old post describes all changes I did to the initial version by Johannes (Jotschi). For the new major release I again reworked nearly every part of the library, to make it more stable and versatile. Here is what I did:
- Optimized the native library C code, fixed bugs and removed all parts requireing a C++ compiler in the first place.
- Renamed the event classes and listener interfaces and prepended
Global
to avoid conflicts with existing (Swing) event listeners. - Added support for
mouseWheel
events to theGlobalMouseListener
. - Again allowed negative "out of bounds" values for
GlobalMouseEvents
, to also track the mouse pointer off screen (e.g. on multi-monitor setups). - Improved the threading concept and implemented a native error handling. The
GlobalKeyboardHook
andGlobalMouseHook
constructors will now throw aUnsatisfiedLinkError
if the native libraries can not be loaded or aRuntimeException
in case hooking fails. - All the code has been moved to GitHub and binaries are now beeing continuously built by AppVeyor. Feel free to contribute on GitHub!
(Again) Last but not least, please share your ideas and problems in the comments. I will try to enhance the Global Keyboard / Mouse Hook based on your feedback. For the next release let’s see if we can get Linux and / or Mac OSX support going.
Hi,
I was looking for a long time for something already implemented, works like a charm, thank you for sharing! :)
Remark: you might consider including the MouhseHook .h/.cpp files into the source bundle download as it seems you forgot it.
Nice job!
Adam
Hey Adam,
thanks for your comment.
You are absolutely right. I will add them to the bundle of the next release.
Thanks again & regards,
Kristian
Hi,
i’m not very good at programming in java yet and i have a problem. I always get an error in “Thread-0”, it says something about an “UnsatisfiedLinkError” as u can see here: http://nopaste.info/0d87f74746_nl.html
Thanks for help…
Hi,
Very nice project. However I have the problem described by Timo with the new version (0.2.1).
Exception in thread “Thread-2” java.lang.UnsatisfiedLinkError: de.ksquared.system.mouse.MouseHook.registerHook(Lde/ksquared/system/mouse/GlobalMouseListener;)V
at de.ksquared.system.mouse.MouseHook.registerHook(Native Method)
at de.ksquared.system.mouse.PoolHook.run(MouseHook.java:50)
I use the jar with the lib in it.
Thanks for any help…
Hi! I researched my previous post a little bit and I came up with the following – if I do:
System.loadLibrary(“mousehook”);
the error message is:
Can’t find dependent libraries
If I then see what’s missing in dependency walker – it signals that the following libraries are missing:
GPSVC.DLL and
IESHIMS.DLL
Maybe this can help?
Hi, I’m trying to use these .dll files with my x64 JVM and they won’t load. Is it possible for you to post an x64 build? I have been trying for hours to get the Microsoft SDK to compile it, but there are some linker problems I don’t understand (LNK2019 errors). Until then, I will try running in a 32-bit JRE.
Thanks for the great utility, hopefully I will be able to use it!
Byron
Hey, I am having the same UnsatisfiedLinkError as mentioned above (using the newest version 0.2.1). Please let me know if you come up with a fix for this… the code would be very useful if fixed.
Thanks,
Lucas
If anyone is interested, I did figure out those LNK2019 errors I mentioned last week. When compiling for x64, it is for some reason necessary to specify User32.lib to the linker. Even if this lib is in the search path, the linker won’t discover that the dependencies are defined there. So for the cl.exe command line, the “/LINK” directive must be followed by option “/DEFAULTLIB:User32.lib”. It seems bizarre to me, but anyway, it works.
That is what i needed and it works!
Thanks
I had the same UnsatisfiedLinkError error as the people above. To solve my problem I changed from a 64-bit java version to a 32-bit version.
I compiled the DLLs with VisualStudio 2010, and am running the example code in Java. Everything works for a few seconds, I get output messages on my console, but then it dies with the following error. Has anyone else experienced this?
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (safepoint.cpp:572), pid=11308, tid=11872
# Error: Deadlock in safepoint code. Should have called back to the VM before blocking.
#
# JRE version: 6.0_22-b04
# Java VM: Java HotSpot(TM) 64-Bit Server VM (17.1-b03 mixed mode windows-amd64 )
# An error report file with more information is saved as:
# E:\Workspaces\…\hs_err_pid11308.log
[Too many errors, abort]
NATIVE: DllMain – DLL_PROCESS_ATTACH.
NATIVE: Java_de_ksquared_system_mouse_MouseHook_registerHook – Hooking started!
NATIVE: Java_de_ksquared_system_mouse_MouseHook_registerHook – Hook successful
Example unique snippets from hs_err_pid11308.log file (the first is repeated many times, the second just once, at the end)
————— T H R E A D —————
Current thread (0x0000000006931000): JavaThread “Thread-1” daemon [_thread_in_native_trans, id=11872, stack(0x0000000007cf0000,0x0000000007df0000)]
Stack: [0x0000000007cf0000,0x0000000007df0000]
[error occurred during error reporting (null), id 0xe0000000]
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (safepoint.cpp:572), pid=11308, tid=11872
# Error: Deadlock in safepoint code. Should have called back to the VM before blocking.
#
# JRE version: 6.0_22-b04
# Java VM: Java HotSpot(TM) 64-Bit Server VM (17.1-b03 mixed mode windows-amd64 )
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
————— T H R E A D —————
Current thread (0x0000000006931000): JavaThread “Thread-1” daemon [_thread_in_native_trans, id=11872, stack(0x0000000007cf0000,0x0000000007df0000)]
Stack: [0x0000000007cf0000,0x0000000007df0000]
Thank you so so very much, I spent 10 hours trying to do this and could not even run the basic JNI netbeans demo. I’m running on a vista 32 and it works great :D