iohook icon indicating copy to clipboard operation
iohook copied to clipboard

Native keymap — returning unicode representation of the key pressed.

Open DCzajkowski opened this issue 6 years ago • 17 comments

Hello everyone! There is this awesome native-keymap package made by Microsoft, that returns characters in the current keyboard layout. It works absolutely amazingly, but I am having hard time using it with this package. From what I understand, we would have to make lookup tables for each OS that map to the constant-y name in the map.

Expected Behavior

Pressing a key gives a unicode value of that key.

Current Behavior

Pressing a key does not provide the unicode representation of the key. Moreover, it does not recognize shift/ctrl/alt click.

Possible Solution

Use the native-keymap package to give awesome feedback.

DCzajkowski avatar May 07 '18 22:05 DCzajkowski

Well, we need someone to test it out with the latest version :) Who's in ?

Djiit avatar May 08 '18 12:05 Djiit

From what I have established, these are the keycode's returned for iohook with their contant-y representation (I don't have some of the keys on my keyboard):

MacOS:

module.exports = {
    '30': 'KeyA',
    '48': 'KeyB',
    '46': 'KeyC',
    '32': 'KeyD',
    '18': 'KeyE',
    '33': 'KeyF',
    '34': 'KeyG',
    '35': 'KeyH',
    '23': 'KeyI',
    '36': 'KeyJ',
    '37': 'KeyK',
    '38': 'KeyL',
    '50': 'KeyM',
    '49': 'KeyN',
    '24': 'KeyO',
    '25': 'KeyP',
    '16': 'KeyQ',
    '19': 'KeyR',
    '31': 'KeyS',
    '20': 'KeyT',
    '22': 'KeyU',
    '47': 'KeyV',
    '17': 'KeyW',
    '45': 'KeyX',
    '21': 'KeyY',
    '44': 'KeyZ',

    '2': 'Digit1',
    '3': 'Digit2',
    '4': 'Digit3',
    '5': 'Digit4',
    '6': 'Digit5',
    '7': 'Digit6',
    '8': 'Digit7',
    '9': 'Digit8',
    '10': 'Digit9',
    '11': 'Digit0',

    '28': 'Enter',
    '1': 'Escape',
    '14': 'Backspace',
    '15': 'Tab',
    '57': 'Space',
    '12': 'Minus',
    '13': 'Equal',
    '26': 'BracketLeft',
    '27': 'BracketRight',
    '0': 'IntlBackslash',
    '39': 'Semicolon',
    '40': 'Quote',
    '51': 'Comma',
    '52': 'Period',
    '53': 'Slash',
    '58': 'CapsLock',
    '43': 'Backslash',
    '41': 'Backquote',

    '29': 'ControlLeft',
    '42': 'ShiftLeft',
    '56': 'AltLeft',
    '3675': 'MetaLeft',

    '': 'ControlRight',

    '54': 'ShiftRight',
    '3640': 'AltRight',
    '3676': 'MetaRight',
}

DCzajkowski avatar May 08 '18 12:05 DCzajkowski

Do you know, does Windows/Linux share these, or do they return different keycodes for each character?

DCzajkowski avatar May 08 '18 13:05 DCzajkowski

@DCzajkowski I can confirm that Windows does not share these codes. Thank you for sharing these though, I was able to construct a map for an app I'm working on 😄

ebramanti avatar Aug 11 '18 09:08 ebramanti

@jadengore Can you share yours?

DCzajkowski avatar Aug 11 '18 09:08 DCzajkowski

@jadengore Do you still have this keymap?

I have MacOS and Linux handy, and may be able to confirm if I grab a Windows VM.

I'm looking for a way to listen for key events using the very popular ccampbell/mousetrap library, and then once the user has picked a combination, using iohook to listen for when that shortcut is pressed.

Mousetrap can return both the key codes pressed ([17, 16, 65]), as well as an ascii representation (e.g. 'ctrl+shift v' and 'ctrl+a s'), but we need a way to translate these to the codes iohook expects. The solution that would probably make most people happy would be able to accept the ascii representation when defining shortcuts.

So, I think the plan would be:

  • Allow registerKeybinding() to accept a string as well as a keycode array.

  • We parse the string into separate modifiers and characters ('ctrl+k v' => ['ctrl', 'k', 'v']), and then depending on the OS we run those characters through a specific keymap.

  • Once we get the right codes, we register them like usual.

I'll try to work on getting keymaps for Linux, and grabbing a Windows VM if nobody with Windows pipes up in the next few hours.

I also have no idea how this will work with keyboards other than US qwerty. Testing on this front with the provided keymaps would be highly appreciated.

Edit: Wait, I actually am seeing a relationship between the rawcode iohook returns in its event, and the charCode value mousetrap returns on keypress events. They are the same.

anoadragon453 avatar Nov 04 '18 15:11 anoadragon453

@anoadragon453 @DCzajkowski Sorry for the delay, you can find the keycodes here: https://github.com/birkholz/soundboard/blob/master/src/keycodes.ts#L5-L69

ebramanti avatar Nov 24 '18 19:11 ebramanti

Thanks @jadengore!

anoadragon453 avatar Nov 27 '18 10:11 anoadragon453

The list below is what we use in win/mac application

const keyNames = {
    0: '§',
    1: 'Esc',
    2: '1',
    3: '2',
    4: '3',
    5: '4',
    6: '5',
    7: '6',
    8: '7',
    9: '8',
    10: '9',
    11: '0',
    12: '-',
    13: '=',
    14: 'Backspace',
    15: 'Tab',
    16: 'q',
    17: 'w',
    18: 'e',
    19: 'r',
    20: 't',
    21: 'y',
    22: 'u',
    23: 'i',
    24: 'o',
    25: 'p',
    26: '[',
    27: ']',
    28: 'Enter',
    29: 'Left Ctrl',
    30: 'a',
    31: 's',
    32: 'd',
    33: 'f',
    34: 'g',
    35: 'h',
    36: 'j',
    37: 'k',
    38: 'l',
    39: ';',
    40: '\'',
    41: '`',
    42: 'Left Shift',
    43: '\\',
    44: 'z',
    45: 'x',
    46: 'c',
    47: 'v',
    48: 'b',
    49: 'n',
    50: 'm',
    51: ',',
    52: '.',
    53: '/',
    54: 'Right Shift',
    56: 'Left Alt', // macos 'Left ⌥'
    57: 'Space',
    58: 'CapsLock',
    59: 'F1',
    60: 'F2',
    61: 'F3',
    62: 'F4',
    63: 'F5',
    64: 'F6',
    65: 'F7',
    66: 'F8',
    67: 'F9',
    68: 'F10',
    87: 'F11',
    88: 'F12',
    61010: 'Insert',
    61011: 'Delete',
    60999: 'Home',
    61007: 'End',
    61001: 'Page Up',
    61009: 'Page Down',
    3639: 'Print Screen',
    3653: 'Pause Break',
    3637: 'Num /',
    55: 'Num *',
    3612: 'Num Enter',
    3655: 'Num Home',
    3657: 'Num Page Up',
    3663: 'Num End',
    3665: 'Num Page Down',
    57420: 'Num Center 5',
    3677: 'Context Menu',
    61008: 'Arrow Down',
    61005: 'Arrow Right',
    61003: 'Arrow Left',
    61000: 'Arrow Up',
    57380: 'Media Stop',
    57360: 'Media Previous',
    57378: 'Media Play',
    57369: 'Media Next',
    57390: 'Volume Down',
    57392: 'Volume Up',
    57376: 'Volume Mute',
    3613: 'Right Ctrl',
    3640: 'Right Alt', // macos 'Right ⌥'
    3675: 'Left Win', // macos 'Left ⌘'
    3676: 'Right Win', // macos 'Right ⌘'
    57419: '←',
    57416: '↑',
    57424: '↓',
    57421: '→',
  }

staticbass avatar Dec 09 '19 17:12 staticbass

Hello fellow coders - Is there any way to know the state of the CapsLock button using iohook, currently it returns the following in either case (on/off) -

keyup { shiftKey: false, altKey: false, ctrlKey: false, metaKey: false, keycode: 58, rawcode: 57, type: 'keyup' }

gauravbharat avatar May 10 '20 06:05 gauravbharat

@gauravbharat I don't think so. iohook detects keyboard events, not the state of the OS. I think you need a different package/your own implementation. I may be wrong though.

DCzajkowski avatar May 11 '20 11:05 DCzajkowski

I made a JSON file for the Darwin keys: https://github.com/yikuansun/desktopspeedruntools/blob/main/window/keycodenames/darwin.json As you may be able to tell based on the awkward formatting, I used a little automation to help. Basically, I made an HTML keydown event listener and used event.key to return key strings. event.code also works but I preferred event.key. For the IOhook event listener and the HTML event listener, I had them write their outputs to separate arrays, creating two outputted arrays: one filled with keycodes and one filled with strings, the array indecies matching. I ran the program and pressed every key, skipping some such as CapsLock, F11, and F12, simply because they could not be read by either IOhook or HTML. Afterwards, I merged the arrays into one object and stringified it. The code is composed of the commented-out areas of https://github.com/yikuansun/desktopspeedruntools/blob/main/window/app.js . If someone could repeat this process for Windows or Linux and share their results, that'd be appreciated!

yikuansun avatar Jan 18 '21 21:01 yikuansun

@gauravbharat I'm also trying to detect the state of Caps Lock. What I noticed is that the matter is more complicated than I originally thought. I connected 2 keyboards at once. It turned out one can have caps enabled and one can have it disabled at the same time. It seems the caps state is internal to the keyboard, not to the system.

Therefore it seems there is no 'global' way to detect it.

pie6k avatar Apr 19 '21 08:04 pie6k

Marked as feature request. Hopefully there's a better way to do this cross-os. Either way, really interested in implementing this.

ash0x0 avatar Jun 11 '21 20:06 ash0x0

@ash0x0 I've found "keypress" event returns a key representation by reading the source code. I believe it's not in the documentation.

DCzajkowski avatar Jun 11 '21 23:06 DCzajkowski

@ash0x0 I've found "keypress" event returns a key representation by reading the source code. I believe it's not in the documentation.

The "keypress"event works for me by combining its keychar value with String.fromCharCode! Thanks @DCzajkowski

raphaelmenges avatar Nov 23 '21 13:11 raphaelmenges

Here's a keymap for Linux: https://github.com/yikuansun/desktopspeedruntools/blob/main/window/keycodenames/linux.json

{"1":"Escape","2":"1","3":"2","4":"3","5":"4","6":"5","7":"6","8":"7","9":"8","10":"9","11":"0","12":"-","13":"=","14":"Backspace","15":"Tab","16":"q","17":"w","18":"e","19":"r","20":"t","21":"y","22":"u","23":"i","24":"o","25":"p","26":"[","27":"]","28":"Enter","29":"Control","30":"a","31":"s","32":"d","33":"f","34":"g","35":"h","36":"j","37":"k","38":"l","39":";","40":"'","41":"`","42":"Shift","43":"\\","44":"z","45":"x","46":"c","47":"v","48":"b","49":"n","50":"m","51":",","52":".","53":"/","54":"Shift","56":"Alt","57":" ","59":"F1","60":"F2","61":"F3","62":"F4","63":"F5","64":"F6","65":"F7","66":"F8","67":"F9","68":"F10","87":"F11","88":"F12","3613":"Control","3640":"Alt","3657":"PageUp","3665":"PageDown","57416":"ArrowUp","57419":"ArrowLeft","57421":"ArrowRight","57424":"ArrowDown"}

yikuansun avatar Oct 10 '22 01:10 yikuansun