Let's say someone wants to create a cross-platform (Mac, Linux, Windows) global hotkey in Go (golang) - you press a hotkey combination anywhere in OS and let's say something is printed in terminal.
Currently, (July 2016) I haven't found any library to do that, so maybe we can find a way together.
It would involve, of course, calls to some native OS bindings for each OS, but there is very sparse information on how to do it.
Mac
Judging from Googling one should use addGlobalMonitorForEventsMatchingMask
EDIT: useless example removed
Linux
Looks like the suspect is XGrabKey
, though, no example code anywhere in near sight https://github.com/search?utf8=%E2%9C%93&q=language%3Ago+XGrabKey&type=Repositories&ref=searchresults
Windows
It seems that we need to use RegisterHotKey
, but trying to find some example code leads nowhere: https://github.com/search?utf8=%E2%9C%93&q=language%3Ago+RegisterHotKey
Some interesting cross-platform project to research (in Java) is https://github.com/tulskiy/jkeymaster
Any help would be greatly appreciated!
It can be done. For example gaming engine Azul3d can do that https://github.com/azul3d/engine/tree/master/keyboard. Your OSX snippet doesn't compile because AppDelegate.h file is missing. You can either write it by hand or first compile project with XCode which do bookkeeping for you and then look at AppDelegate.h and AppDelegate.m. On linux to log keystroke stream you can just read /dev/input/event$ID file which is done here https://github.com/MarinX/keylogger. On windows you will need some syscalls like in this code https://github.com/eiannone/keyboard. Both on nix and win you even need not cgo and can be happy with syscalls and pure Go.
This is possible on most operating systems with simple system calls, in Go you can use package
syscall
to do system calls without any extra C code or cgo compiler.Note that the online official documentation of the
syscall
package shows only the linux interface. Other operating systems have slightly different interface, e.g. on Windows thesyscall
package also contains asyscall.DLL
type,syscall.LoadDLL()
andsyscall.MustLoadDLL()
functions, among others. To view these, run thegodoc
tool locally, e.g.This starts a webserver that hosts a web page similar to
godoc.org
, navigate tohttp://localhost:6060/pkg/syscall/
.Here I present a complete, runnable Windows solution in pure Go. The complete example application is available on the Go Playground. It doesn't run on the playground, download it and run it locally (on Windows).
Let's define the type to describe hotkeys we want to use. This is not Windows-specific, just to make our code nicer. The
Hotkey.String()
method provides a human-friendly display name of the hotkey such as"Hotkey[Id: 1, Alt+Ctrl+O]"
.The windows
user32.dll
contains functions for global hotkey management. Let's load it:It has a
RegisterHotkey()
function for registering global hotkeys:Using this, let's register some hotkeys, namely ALT+CTRL+O, ALT+SHIFT+M, ALT+CTRL+X (which will be used to exit from the app):
We need a way to "listen" to events of pressing those hotkeys. For this,
user32.dll
contains thePeekMessage()
function:PeekMessage()
stores the message into anMSG
struct, let's define it:Now here's our listening loop which listens and acts on global key presses (here just simply print the pressed hotkey to the console, and if CTRL+ALT+X is pressed, exit from the app):
And we're done!
Starting the above application prints:
Now let's press some of the registered hotkeys (with any app being in focus, not necessarily our app), we'll see on the console: