Skip to content

Instantly share code, notes, and snippets.

@zhchbin
Created November 30, 2012 02:09
Show Gist options
  • Save zhchbin/4173331 to your computer and use it in GitHub Desktop.
Save zhchbin/4173331 to your computer and use it in GitHub Desktop.
Node-webkit hotkey api proposal
<!DOCTYPE>
<html>
<head>
<title>Hotkey Demo</title>
<script type="text/javascript" src='keymap.js'></script>
<script type="text/javascript">
function log(message) {
document.getElementById('log').textContent += message + '\n';
}
var gui = require('nw.gui');
var index = 0;
var hotkey = new gui.Hotkey({
keyCode: KEY_MAP['VKEY_S'], // 's'
shiftKey: false,
altKey: true,
ctrlKey: true,
metaKey: false,
onActive : function() {
log('hotkey[' + (index++) + ']' + JSON.stringify(this.option));
},
onError : function(msg) {
log('Error: ' + msg);
}
});
var hotkey_2 = new gui.Hotkey({
keyCode: KEY_MAP['VKEY_T'], // 't'
altKey: true,
onActive : function() {
log('hotkey[' + (index++) + ']' + JSON.stringify(this.option));
},
onError : function(msg) {
log('Error: ' + msg);
}
});
</script>
</head>
<body>
<pre id="log"></pre>
</body>
</html>
var KEY_MAP = {
'VKEY_BACK' : 0x08,
'VKEY_TAB' : 0x09,
'VKEY_BACKTAB' : 0x0A,
'VKEY_CLEAR' : 0x0C,
'VKEY_RETURN' : 0x0D,
'VKEY_SHIFT' : 0x10,
'VKEY_CONTROL' : 0x11,
'VKEY_MENU' : 0x12,
'VKEY_PAUSE' : 0x13,
'VKEY_CAPITAL' : 0x14,
'VKEY_KANA' : 0x15,
'VKEY_HANGUL' : 0x15,
'VKEY_JUNJA' : 0x17,
'VKEY_FINAL' : 0x18,
'VKEY_HANJA' : 0x19,
'VKEY_KANJI' : 0x19,
'VKEY_ESCAPE' : 0x1B,
'VKEY_CONVERT' : 0x1C,
'VKEY_NONCONVERT' : 0x1D,
'VKEY_ACCEPT' : 0x1E,
'VKEY_MODECHANGE' : 0x1F,
'VKEY_SPACE' : 0x20,
'VKEY_PRIOR' : 0x21,
'VKEY_NEXT' : 0x22,
'VKEY_END' : 0x23,
'VKEY_HOME' : 0x24,
'VKEY_LEFT' : 0x25,
'VKEY_UP' : 0x26,
'VKEY_RIGHT' : 0x27,
'VKEY_DOWN' : 0x28,
'VKEY_SELECT' : 0x29,
'VKEY_PRINT' : 0x2A,
'VKEY_EXECUTE' : 0x2B,
'VKEY_SNAPSHOT' : 0x2C,
'VKEY_INSERT' : 0x2D,
'VKEY_DELETE' : 0x2E,
'VKEY_HELP' : 0x2F,
'VKEY_0' : 0x30,
'VKEY_1' : 0x31,
'VKEY_2' : 0x32,
'VKEY_3' : 0x33,
'VKEY_4' : 0x34,
'VKEY_5' : 0x35,
'VKEY_6' : 0x36,
'VKEY_7' : 0x37,
'VKEY_8' : 0x38,
'VKEY_9' : 0x39,
'VKEY_A' : 0x41,
'VKEY_B' : 0x42,
'VKEY_C' : 0x43,
'VKEY_D' : 0x44,
'VKEY_E' : 0x45,
'VKEY_F' : 0x46,
'VKEY_G' : 0x47,
'VKEY_H' : 0x48,
'VKEY_I' : 0x49,
'VKEY_J' : 0x4A,
'VKEY_K' : 0x4B,
'VKEY_L' : 0x4C,
'VKEY_M' : 0x4D,
'VKEY_N' : 0x4E,
'VKEY_O' : 0x4F,
'VKEY_P' : 0x50,
'VKEY_Q' : 0x51,
'VKEY_R' : 0x52,
'VKEY_S' : 0x53,
'VKEY_T' : 0x54,
'VKEY_U' : 0x55,
'VKEY_V' : 0x56,
'VKEY_W' : 0x57,
'VKEY_X' : 0x58,
'VKEY_Y' : 0x59,
'VKEY_Z' : 0x5A,
'VKEY_LWIN' : 0x5B,
'VKEY_COMMAND' : 0x5B, // Provide the Mac name for convenience.
'VKEY_RWIN' : 0x5C,
'VKEY_APPS' : 0x5D,
'VKEY_SLEEP' : 0x5F,
'VKEY_NUMPAD0' : 0x60,
'VKEY_NUMPAD1' : 0x61,
'VKEY_NUMPAD2' : 0x62,
'VKEY_NUMPAD3' : 0x63,
'VKEY_NUMPAD4' : 0x64,
'VKEY_NUMPAD5' : 0x65,
'VKEY_NUMPAD6' : 0x66,
'VKEY_NUMPAD7' : 0x67,
'VKEY_NUMPAD8' : 0x68,
'VKEY_NUMPAD9' : 0x69,
'VKEY_MULTIPLY' : 0x6A,
'VKEY_ADD' : 0x6B,
'VKEY_SEPARATOR' : 0x6C,
'VKEY_SUBTRACT' : 0x6D,
'VKEY_DECIMAL' : 0x6E,
'VKEY_DIVIDE' : 0x6F,
'VKEY_F1' : 0x70,
'VKEY_F2' : 0x71,
'VKEY_F3' : 0x72,
'VKEY_F4' : 0x73,
'VKEY_F5' : 0x74,
'VKEY_F6' : 0x75,
'VKEY_F7' : 0x76,
'VKEY_F8' : 0x77,
'VKEY_F9' : 0x78,
'VKEY_F10' : 0x79,
'VKEY_F11' : 0x7A,
'VKEY_F12' : 0x7B,
'VKEY_F13' : 0x7C,
'VKEY_F14' : 0x7D,
'VKEY_F15' : 0x7E,
'VKEY_F16' : 0x7F,
'VKEY_F17' : 0x80,
'VKEY_F18' : 0x81,
'VKEY_F19' : 0x82,
'VKEY_F20' : 0x83,
'VKEY_F21' : 0x84,
'VKEY_F22' : 0x85,
'VKEY_F23' : 0x86,
'VKEY_F24' : 0x87,
'VKEY_NUMLOCK' : 0x90,
'VKEY_SCROLL' : 0x91,
'VKEY_LSHIFT' : 0xA0,
'VKEY_RSHIFT' : 0xA1,
'VKEY_LCONTROL' : 0xA2,
'VKEY_RCONTROL' : 0xA3,
'VKEY_LMENU' : 0xA4,
'VKEY_RMENU' : 0xA5,
'VKEY_BROWSER_BACK' : 0xA6,
'VKEY_BROWSER_FORWARD' : 0xA7,
'VKEY_BROWSER_REFRESH' : 0xA8,
'VKEY_BROWSER_STOP' : 0xA9,
'VKEY_BROWSER_SEARCH' : 0xAA,
'VKEY_BROWSER_FAVORITES' : 0xAB,
'VKEY_BROWSER_HOME' : 0xAC,
'VKEY_VOLUME_MUTE' : 0xAD,
'VKEY_VOLUME_DOWN' : 0xAE,
'VKEY_VOLUME_UP' : 0xAF,
'VKEY_MEDIA_NEXT_TRACK' : 0xB0,
'VKEY_MEDIA_PREV_TRACK' : 0xB1,
'VKEY_MEDIA_STOP' : 0xB2,
'VKEY_MEDIA_PLAY_PAUSE' : 0xB3,
'VKEY_MEDIA_LAUNCH_MAIL' : 0xB4,
'VKEY_MEDIA_LAUNCH_MEDIA_SELECT' : 0xB5,
'VKEY_MEDIA_LAUNCH_APP1' : 0xB6,
'VKEY_MEDIA_LAUNCH_APP2' : 0xB7,
'VKEY_OEM_1' : 0xBA,
'VKEY_OEM_PLUS' : 0xBB,
'VKEY_OEM_COMMA' : 0xBC,
'VKEY_OEM_MINUS' : 0xBD,
'VKEY_OEM_PERIOD' : 0xBE,
'VKEY_OEM_2' : 0xBF,
'VKEY_OEM_3' : 0xC0,
'VKEY_OEM_4' : 0xDB,
'VKEY_OEM_5' : 0xDC,
'VKEY_OEM_6' : 0xDD,
'VKEY_OEM_7' : 0xDE,
'VKEY_OEM_8' : 0xDF,
'VKEY_OEM_102' : 0xE2,
'VKEY_PROCESSKEY' : 0xE5,
'VKEY_PACKET' : 0xE7,
'VKEY_DBE_SBCSCHAR' : 0xF3,
'VKEY_DBE_DBCSCHAR' : 0xF4,
'VKEY_ATTN' : 0xF6,
'VKEY_CRSEL' : 0xF7,
'VKEY_EXSEL' : 0xF8,
'VKEY_EREOF' : 0xF9,
'VKEY_PLAY' : 0xFA,
'VKEY_ZOOM' : 0xFB,
'VKEY_NONAME' : 0xFC,
'VKEY_PA1' : 0xFD,
'VKEY_OEM_CLEAR' : 0xFE,
'VKEY_UNKNOWN' : 0
};
{
"name" : "Hotkey-demo",
"main" : "index.html",
"window" : {
"width": 900
}
}
@zhchbin
Copy link
Author

zhchbin commented Nov 30, 2012

1.Yeah, you are right that hardcode the KEY_MAP is a bad idea.
2. keyModifiers: Hotkey.Ctrl | Hotkey.Shift is a common way I know. However, if implement it as you said, the Hotkey.Shirt should be hardcode in the js side. But as the first problem, different platforms have the different value. For example,the Shirt key on GTK is 0, but on WIN is 0x0004. BTW, the IPC problem, it is only one member, because it is a DictionaryValue, you mean that it contains too many? What's more, the user doesn't need to set them one by one. See the hotkey_2 in the example.
4. Global hot key is not equivalent to Accelerators, at least on windows. What you mean is Accelerators I think.

@zcbenz
Copy link

zcbenz commented Nov 30, 2012

You can name Hotkey.Ctrl to 1, Hotkey.Shift to 1 << 1, etc. They don't need to be real key codes, and real key codes are not xor-able, you should convert them to key codes yourself. And mature GUI libraries such as Cocoa and Qt don't use key codes for modifier keys. The most important reason for this is to follow the custom of other GUI libraries.

And there are other special keys like various media keys, you can predefine them in js and then convert them to real key codes in C++, like:

HotKey.BrowserBack = -1;
...
HotKey.MediaStop = -99;

Use negative numbers here because chars' code are always positive, so you can easily distinguish them and then do the conversion.

Though global hot keys are different with accelerators, they're using the same key codes, so we should share code on this part between them, that's why I think we should separate the representation of a hot key with the actual registering of global hot keys.

@zhchbin
Copy link
Author

zhchbin commented Nov 30, 2012

Thank you for your patient replay. Just get the idea about what you want.

What's your plan about when this api should be implemented?

@Frulko
Copy link

Frulko commented Dec 29, 2012

I tried it on my Mac but it did not work. This new feature is compatible for Windows?

@zhchbin
Copy link
Author

zhchbin commented Jan 5, 2013

@Frulko Sorry for this delayed reply. This new feature is still in developing... You can check the status here:nwjs/nw.js#200

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment