Seeing the awesome collaboration between the guys here - https://discourse.mozilla-community.org/t/tear-off-tab-with-sdk/7085/35 - I’m hoping I could get some collaboration too
For one of my addons I need a global hotkey. Meaning from wherever they are, if they hit a the key combination, it will trigger my addon. I am trying to do this off the mainthread, so in a ChromeWorker.
I am making this “module” style so others who find this useful can use it as well. My module is here - https://github.com/Noitidart/System-Hotkey - you can make this an XPI and install. On Windows, hitting the “Print Screen” button will trigger a message to be logged in the console.
The way to do this is:
- Windows -
RegisterHotkey
- Linux -
xcb_grab_key
- Mac -
RegisterEventHotKey
- This is a Carbon API but it is the way to register hotkeys, everyone says so, Apple hasn’t deprecated it. ObjC does not have a method yet to do it.
I knocked out Windows, that just worked on first try. However I was stuck on Linux and Mac OS X.
Linux - XCB - status: no events catching
On Linux I was having a tough time. It worked with this X11 code:
Hotkey is Space bar
// var rez_init = ostypes.API('XInitThreads')(); // This function returns a nonzero status if initialization was successful; otherwise, it returns zero. On systems that do not support threads, this function always returns zero.
// console.log('rez_init:', rez_init);
// based on https://jnativehook.googlecode.com/svn/branches/test_code/linux/XGrabKey.c
// i copied it here as it might come in handy - https://gist.github.com/Noitidart/e12ad03d21bbb91cd214
//Try to attach to the default X11 display.
var display = ostypes.HELPER.cachedXOpenDisplay();
//Get the default global window to listen on for the selected X11 display.
var grabWin = ostypes.HELPER.cachedDefaultRootWindow();
// var rez_allow = ostypes.API('XAllowEvents')(display, ostypes.CONST.AsyncKeyboard, ostypes.CONST.CurrentTime);
// console.log('rez_allow:', rez_allow);
// XkbSetDetectableAutoRepeat(display, true, NULL);
//Find the X11 KeyCode we are listening for.
var key = ostypes.API('XKeysymToKeycode')(display, ostypes.CONST.XK_Space);
console.log('key:', key);
OSStuff.key = key;
//No Modifier
var rez_grab = ostypes.API('XGrabKey')(display, key, ostypes.CONST.None, grabWin, true, ostypes.CONST.GrabModeAsync, ostypes.CONST.GrabModeAsync);
console.log('rez_grab:', rez_grab);
// var rez_sel = ostypes.API('XSelectInput')(display, grabWin, ostypes.CONST.KeyPressMask);
// console.log('rez_sel:', rez_sel);
However x11 is not thread safe, even though I called XInitThreads
it would crash. So I switched to XCB. However the xcb_grab_key
call is not grabbing the key. I am using the Space Bar as a hotkey.
Mac OS X - not working - status: invalid params
on RegisterEventHotKey
This line is where I get stuck:
var rez_reg = ostypes.API('RegisterEventHotKey')(49, ctypes_math.UInt64.add(ctypes.UInt64(ostypes.CONST.shiftKey), ctypes.UInt64(ostypes.CONST.cmdKey)), gMyHotKeyID, rez_appTarget2, 0, gMyHotKeyRef.address());
Hotkey is spacebar
It returns a OSStatus
value of 50
which is errSecAllocate
which means “invalid parameters passed to method” - https://developer.apple.com/library/mac/documentation/Security/Reference/keychainservices/index.html#//apple_ref/c/econst/errSecAllocate
There is a possibility that RegisterEventHotKey
will not work from the spawned thread. However we won’t know till we can get passed this “invalid params” error. I tried this same code on main thread and get the same error.
My question
I created this as a module you can drop in. Maybe others can find it useful. But I was wondering if any Carbon experts and XCB experts could help me tackle this situation.
The code we need to edit is in - https://github.com/Noitidart/System-Hotkey/blob/master/modules/hotkey/HotkeyWorker.js
To edit the types module that is in this repository - https://github.com/Noitidart/ostypes - I included this ino the System-Hotkey repository as a git submodule.