[SOLVED] Problems with mapping keys on a USB remote (HID keyboard/mouse device) and reading correct key codes

Hey everyone.

After hours spent trying to resolve this myself, I’m finally giving up and posting here on the forums, in hope that someone will be able to help me.

Please know — before you point me to a generic resource on that topic — that I’ve read and tried whatever I could find on this already (here on the forums, official Kodi wiki, the internet in general) and I’m including my findings below, but nothing has worked for me so far.

So.

The situation

I have this great little USB remote (not IR), which advertises itself on all systems as your run-of-the-mill HID keyboard/mouse (yes, mouse too, because it can act as a mouse if needed):

It works with OSMC out of the box almost entirely:

  • The power button works like a power button, invoking a menu with stuff like closing the system, restarting, etc.
  • The mute button works like a mute button.
  • The up/down/left/right arrows works like they should, I can go up, down, left, right.
  • The OK button works as it should, depending on the context (selecting, entering a submenu, play/pause, etc). It even works with a longpress, which shows a context menu for an item on the screen.
  • The volume up and down buttons increase and decrease the volume.
  • The home button worked like a Home key on a keyboard by default, which simply throws you to the beginning of a list/view you’re in, but this button can be easily mapped to whatever I like (e.g., going to Home screen on OSMC).

However, the back button (that bent arrow left to the home button) has wasted many hours of my day today.

(Pay no attention to the mouse button - when clicked, it simply switches the remote to a mouse mode, where you can use the arrows to move a cursor on the screen, etc. Click it again and it switches back to being a remote/keyboard.)

The problem

So, the back button does work, as in, it does something, but unfortunately:

  • it doesn’t act like a back button
  • can’t be remapped
  • doesn’t emit any code (at least I wasn’t able to catch any)

Here’s what I tried and my findings.

On OSMC

Keymap Editor to the rescue!

The first thing I did was fire up Keymap Editor. It recognized the following:

  • Power button, key code 61663
  • Mute button, key code 61623
  • Arrow up, key code 61568
  • Arrow down, key code 61569
  • Arrow left, key code 61570
  • Arrow right, key code 61571
  • OK button, key code 61453
  • Home button, key code 61576
  • Volume Up, key code 61625
  • Volume Down, key code 61624
  • Back button - unrecognized
  • Mouse button - unrecognized (it simply switches the remote between modes internally)

When in the mode where you press a button to map it to an action, pressing the back button simply results in exiting out of that mode, and Keymap Editor doesn’t register any key code for that press - so nothing is mapped and you can’t even know what kind of code that button sends.

On its own, it behaves differently depending on the context. In most situations it acts like going to the Home screen, no matter how deep you are in the library. For example, if I’m in TV Shows > Friends > Season 8, pressing the back button takes me back straight to the Home screen on OSMC.

But when inside Settings, some N levels deep, it acts like going back one level.

In some cases, it works like going back one level + pressing the Home key; so it would take me back to the previous screen and move/scroll to the top of the list.

Debugging and logs to the rescue

I turned on debugging and started to watch ~/.kodi/temp/kodi.log while pressing different buttons. And of course, the other buttons register, but nothing shows up in the log when I press the back button. The logs look like this (stripped down):

// UP ARROW
DEBUG: CLibInputKeyboard::ProcessKey - using delay: 500ms repeat: 50ms
2019-10-16 21:22:38.702 T:1915778608   DEBUG: Keyboard: scancode: 0x67, sym: 0x0111, unicode: 0x0000, modifier: 0x0
2019-10-16 21:22:38.702 T:1915778608   DEBUG: HandleKey: up (0xf080) pressed, action is Up
2019-10-16 21:22:38.780 T:1915778608   DEBUG: Keyboard: scancode: 0x67, sym: 0x0111, unicode: 0x0000, modifier: 0x0

// DOWN ARROW
DEBUG: CLibInputKeyboard::ProcessKey - using delay: 500ms repeat: 50ms
2019-10-16 21:23:06.168 T:1915778608   DEBUG: Keyboard: scancode: 0x6c, sym: 0x0112, unicode: 0x0000, modifier: 0x0
2019-10-16 21:23:06.168 T:1915778608   DEBUG: HandleKey: down (0xf081) pressed, action is Down
2019-10-16 21:23:06.282 T:1915778608   DEBUG: Keyboard: scancode: 0x6c, sym: 0x0112, unicode: 0x0000, modifier: 0x0

// LEFT ARROW
DEBUG: CLibInputKeyboard::ProcessKey - using delay: 500ms repeat: 50ms
2019-10-16 21:23:13.030 T:1915778608   DEBUG: Keyboard: scancode: 0x69, sym: 0x0114, unicode: 0x0000, modifier: 0x0
2019-10-16 21:23:13.030 T:1915778608   DEBUG: HandleKey: left (0xf082) pressed, action is Left
2019-10-16 21:23:13.147 T:1915778608   DEBUG: Keyboard: scancode: 0x69, sym: 0x0114, unicode: 0x0000, modifier: 0x0

// RIGHT ARROW
DEBUG: CLibInputKeyboard::ProcessKey - using delay: 500ms repeat: 50ms
2019-10-16 21:23:19.847 T:1915778608   DEBUG: Keyboard: scancode: 0x6a, sym: 0x0113, unicode: 0x0000, modifier: 0x0
2019-10-16 21:23:19.847 T:1915778608   DEBUG: HandleKey: right (0xf083) pressed, action is Right
2019-10-16 21:23:20.030 T:1915778608   DEBUG: Keyboard: scancode: 0x6a, sym: 0x0113, unicode: 0x0000, modifier: 0x0

// OK BUTTON
DEBUG: CLibInputKeyboard::ProcessKey - using delay: 500ms repeat: 50ms
2019-10-16 21:24:20.696 T:1915778608   DEBUG: Keyboard: scancode: 0x1c, sym: 0x000d, unicode: 0x000d, modifier: 0x0
2019-10-16 21:24:20.857 T:1915778608   DEBUG: Keyboard: scancode: 0x1c, sym: 0x000d, unicode: 0x000d, modifier: 0x0
2019-10-16 21:24:20.858 T:1915778608   DEBUG: HandleKey: return (0xf00d) pressed, screen saver/dpms woken up

// POWER BUTTON
DEBUG: CLibInputKeyboard::ProcessKey - using delay: 400ms repeat: 80ms
2019-10-16 21:24:30.913 T:1915778608   DEBUG: Keyboard: scancode: 0x8e, sym: 0x0143, unicode: 0x0000, modifier: 0x0
2019-10-16 21:24:30.914 T:1915778608   DEBUG: HandleKey: sleep (0xf0df) pressed, action is ActivateWindow(ShutdownMenu)
2019-10-16 21:24:31.126 T:1915778608   DEBUG: Keyboard: scancode: 0x8e, sym: 0x0143, unicode: 0x0000, modifier: 0x0

// MUTE BUTTON
DEBUG: CLibInputKeyboard::ProcessKey - using delay: 400ms repeat: 80ms
2019-10-16 21:24:41.580 T:1915778608   DEBUG: Keyboard: scancode: 0x71, sym: 0x00ad, unicode: 0x0000, modifier: 0x0
2019-10-16 21:24:41.580 T:1915778608   DEBUG: HandleKey: volume_mute (0xf0b7) pressed, action is Mute
2019-10-16 21:24:41.746 T:1915778608   DEBUG: Keyboard: scancode: 0x71, sym: 0x00ad, unicode: 0x0000, modifier: 0x0

// HOME BUTTON
DEBUG: CLibInputKeyboard::ProcessKey - using delay: 500ms repeat: 50ms
2019-10-16 21:26:58.179 T:1915778608   DEBUG: Keyboard: scancode: 0x66, sym: 0x0116, unicode: 0x0000, modifier: 0x0
2019-10-16 21:26:58.179 T:1915778608   DEBUG: HandleKey: home (0xf088) pressed, action is FirstPage
2019-10-16 21:26:58.363 T:1915778608   DEBUG: Keyboard: scancode: 0x66, sym: 0x0116, unicode: 0x0000, modifier: 0x0

// VOLUME UP
DEBUG: CLibInputKeyboard::ProcessKey - using delay: 400ms repeat: 80ms
2019-10-16 21:25:15.379 T:1915778608   DEBUG: Keyboard: scancode: 0x73, sym: 0x00af, unicode: 0x0000, modifier: 0x0
2019-10-16 21:25:15.380 T:1915778608   DEBUG: HandleKey: volume_up (0xf0b9) pressed, action is VolumeUp
2019-10-16 21:25:15.529 T:1915778608   DEBUG: Keyboard: scancode: 0x73, sym: 0x00af, unicode: 0x0000, modifier: 0x0

// VOLUME DOWN
DEBUG: CLibInputKeyboard::ProcessKey - using delay: 400ms repeat: 80ms
2019-10-16 21:25:22.346 T:1915778608   DEBUG: Keyboard: scancode: 0x72, sym: 0x00ae, unicode: 0x0000, modifier: 0x0
2019-10-16 21:25:22.346 T:1915778608   DEBUG: HandleKey: volume_down (0xf0b8) pressed, action is VolumeDown
2019-10-16 21:25:22.513 T:1915778608   DEBUG: Keyboard: scancode: 0x72, sym: 0x00ae, unicode: 0x0000, modifier: 0x0

// BACK BUTTON
NOTHING ;/

Listening with showkey

I turned off OSMC with sudo service mediacenter stop and ran sudo showkey and started to press different buttons. Finally, something shows up for the back button!

POWER       keycode 142 press/release
MUTE        keycode 113 press/release
UP          keycode 103 press/release
DOWN        keycode 108 press/release
LEFT        keycode 105 press/release
RIGHT       keycode 106 press/release
OK          keycode 28 press/release
BACK        keycode 273 press/release
HOME        keycode 102 press/release
VOL+        keycode 115 press/release
VOL-        keycode 114 press/release

But unfortunately, trying to map it to the back action like this in ~/.kodi/userdata/keymaps/gen.xml doesn’t work:

<keymap>
    <global>
        <keyboard>
            <key id="273">back</key>
        </keyboard>
    </global>
</keymap>

What actually happens when I press the back button

This is what shows up in the logs when I press the back button. For reference, this is when I’m on my OSMC Home screen (most “outer” view possible):

2019-10-16 22:15:33.675 T:1894773472   DEBUG: CLibInputPointer::ProcessButton - event.type: 4, event.button.button: 3, event.button.x: 1920, event.button.y: 0
2019-10-16 22:15:33.698 T:1894773472   DEBUG: CLibInputPointer::ProcessButton - event.type: 5, event.button.button: 3, event.button.x: 1920, event.button.y: 0
2019-10-16 22:15:33.704 T:1915582000   DEBUG: ProcessMouse: trying mouse action rightclick
2019-10-16 22:15:33.705 T:1915582000   DEBUG: CGUIWindowManager::PreviousWindow: Deactivate
2019-10-16 22:15:33.716 T:1915582000   DEBUG: ------ Window Init (Pointer.xml) ------
2019-10-16 22:15:38.733 T:1915582000   DEBUG: ------ Window Deinit (Pointer.xml) ---—

And this what happens when I press while in the Movies section:

2019-10-16 22:13:40.411 T:1894773472   DEBUG: CLibInputPointer::ProcessButton - event.type: 4, event.button.button: 3, event.button.x: 1920, event.button.y: 0
2019-10-16 22:13:40.547 T:1894773472   DEBUG: CLibInputPointer::ProcessButton - event.type: 5, event.button.button: 3, event.button.x: 1920, event.button.y: 0
2019-10-16 22:13:40.554 T:1915582000   DEBUG: ProcessMouse: trying mouse action rightclick
2019-10-16 22:13:40.555 T:1915582000   DEBUG: CGUIWindowManager::PreviousWindow: Deactivate
2019-10-16 22:13:40.565 T:1915582000   DEBUG: ------ Window Init (Pointer.xml) ------
2019-10-16 22:13:40.782 T:1915582000   DEBUG: ------ Window Deinit (MyVideoNav.xml) ------
2019-10-16 22:13:40.783 T:1915582000   DEBUG: FreeVisualisation() started
2019-10-16 22:13:40.783 T:1915582000   DEBUG: FreeVisualisation() done
2019-10-16 22:13:40.787 T:1915582000   DEBUG: CGUIWindowManager::PreviousWindow: Activate new
2019-10-16 22:13:40.787 T:1915582000   DEBUG: ------ Window Init (Home.xml) ------
2019-10-16 22:13:40.790 T:1915582000   DEBUG: [Warning] CGUITextureManager::GetTexturePath: could not find texture 'noop'
2019-10-16 22:13:40.798 T:1790329568   DEBUG: Thread LanguageInvoker start, auto delete: false
2019-10-16 22:13:40.799 T:1790329568    INFO: initializing python engine.
2019-10-16 22:13:40.799 T:1790329568   DEBUG: CPythonInvoker(83, /home/osmc/.kodi/addons/script.skinshortcuts/default.py): start processing
2019-10-16 22:13:40.799 T:1061114592   DEBUG: Thread Timer start, auto delete: false
2019-10-16 22:13:40.816 T:1915582000   DEBUG: FreeVisualisation() done
2019-10-16 22:13:40.816 T:1915582000   ERROR: CBinaryAddonManager::GetInstalledAddonInfo: Requested addon '' unknown as binary
2019-10-16 22:13:41.133 T:1790329568   DEBUG: -->Python Interpreter Initialized<--
2019-10-16 22:13:41.133 T:1790329568   DEBUG: CPythonInvoker(83, /home/osmc/.kodi/addons/script.skinshortcuts/default.py): the source file to load is "/home/osmc/.kodi/addons/script.skinshortcuts/default.py"
2019-10-16 22:13:41.135 T:1790329568   DEBUG: CPythonInvoker(83, /home/osmc/.kodi/addons/script.skinshortcuts/default.py): setting the Python path to /home/osmc/.kodi/addons/script.skinshortcuts:/home/osmc/.kodi/addons/script.module.simplejson/lib:/home/osmc/.kodi/addons/script.module.unidecode/lib:/usr/lib/python2.7:/usr/lib/python2.7/plat-arm-linux-gnueabihf:/usr/lib/python2.7/lib-tk:/usr/lib/python2.7/lib-old:/usr/lib/python2.7/lib-dynload:/usr/local/lib/python2.7/dist-packages:/usr/lib/python2.7/dist-packages:/usr/lib/python2.7/dist-packages/PILcompat:/usr/lib/python2.7/dist-packages/gtk-2.0
2019-10-16 22:13:41.136 T:1790329568   DEBUG: CPythonInvoker(83, /home/osmc/.kodi/addons/script.skinshortcuts/default.py): entering source directory /home/osmc/.kodi/addons/script.skinshortcuts
2019-10-16 22:13:41.154 T:1790329568   DEBUG: CPythonInvoker(83, /home/osmc/.kodi/addons/script.skinshortcuts/default.py): instantiating addon using automatically obtained id of "script.skinshortcuts" dependent on version 2.20.0 of the xbmc.python api
2019-10-16 22:13:41.308 T:1061114592   DEBUG: Thread Timer 1061114592 terminating
2019-10-16 22:13:42.191 T:1790329568   DEBUG: CAddonSettings[script.skinshortcuts]: loading setting definitions
2019-10-16 22:13:42.191 T:1790329568   DEBUG: CAddonSettings[script.skinshortcuts]: trying to load setting definitions from old format...
2019-10-16 22:13:42.217 T:1790329568   DEBUG: CAddonSettings[script.skinshortcuts]: loading setting definitions
2019-10-16 22:13:42.217 T:1790329568   DEBUG: CAddonSettings[script.skinshortcuts]: trying to load setting definitions from old format...
2019-10-16 22:13:42.241 T:1052721888   DEBUG: Thread Timer start, auto delete: false
2019-10-16 22:13:42.266 T:1790329568    INFO: CPythonInvoker(83, /home/osmc/.kodi/addons/script.skinshortcuts/default.py): script successfully run
2019-10-16 22:13:42.266 T:1790329568   DEBUG: onExecutionDone(83, /home/osmc/.kodi/addons/script.skinshortcuts/default.py)
2019-10-16 22:13:42.277 T:1052721888   DEBUG: Thread Timer 1052721888 terminating
2019-10-16 22:13:42.277 T:1044329184   DEBUG: Thread Timer start, auto delete: false
2019-10-16 22:13:42.292 T:1044329184   DEBUG: Thread Timer 1044329184 terminating
2019-10-16 22:13:42.293 T:1052721888   DEBUG: Thread Timer start, auto delete: false
2019-10-16 22:13:42.605 T:1790329568    INFO: Python interpreter stopped
2019-10-16 22:13:42.605 T:1790329568   DEBUG: Thread LanguageInvoker 1790329568 terminating
2019-10-16 22:13:42.798 T:1052721888   DEBUG: Thread Timer 1052721888 terminating
2019-10-16 22:13:44.228 T:1267663584   DEBUG: plugin.audio.spotify --> FINISH transfer for track 0PHm9MrfZdEUasfd1XC0n2 - range 28835884
2019-10-16 22:13:45.564 T:1915582000   DEBUG: ------ Window Deinit (Pointer.xml) ---—

Crazy :). And yes, that Pointer.xml Init and Deinit do happen; the cursor shows up on the screen, and disappears when you perform any action or on its own after a few seconds. What the heck is going on ?!

On Windows

The remote presents itself as two devices, a HID keyboard and HID mouse. SharpKeys recognizes the buttons as follows:

Power button    - unrecognized
Mute button     - 00_100, mutes system
Up              - Arrow: Up E0_48
Down            - Arrow: Down E0_50
Left            - Arrow: Left E0_4B
Right           - Arrow: Right E0_4D
OK button       - Special: Enter 00_1C
Back button     - unrecognized
Mouse button    - unrecognized, PPM/context
Home button     - Special: Home E0_47
Volume Up       - 00_100, louder
Volume Down     - 00_100, quieter

The power button puts the system to sleep when pressed. The mute button mutes/unmutes the audio, system-wide. Volume up and Volume down increase and drecrease volume, system-wide. The home button acts like hitting the Home key on the keyboard. Arrows work like arrows.

The back button, however, acts like right clicking with a mouse. No matter where I am in the system, the action it performs is equivalent to clicking with the right mouse button.

On macOS

The remote, like on Windows, acts as a keyboard and mouse. Key Codes recognizes the buttons as follows:

Power button    - unrecognized
Mute button     - unrecognized
Up              - Unicode: 63232 / 0xf700, Key Code: 126 / 0x7e
Down            - Unicode: 63233 / 0xf701, Key Code: 125 / 0x7d
Left            - Unicode: 63234 / 0xf702, Key Code: 123 / 0x7b
Right           - Unicode: 63235 / 0xf703, Key Code: 124 / 0x7c
OK              - Unicode: 13 / 0xd, Key Code: 36 / 0x24
Back button     - unrecognized
Mouse button    - unrecognized
Home button     - Unicode: 63273 / 0xf729, Key Code: 115 / 0x73
Volume Up       - unrecognized
Volume Down     - unrecognized

The power button does nothing. The mute button mutes/unmutes the audio, system-wide. Volume up and Volume down increase and drecrease volume, system-wide. The home button acts like hitting the Home key on the keyboard. Arrows work like arrows.

And just like on Windows, pressing the back button perfoms an action equivalent to righ-clicking with a mouse.

Where I’m at

As a temporary solution, I’ve remapped the Home button to perform a “back” action, and left the back button as is.

This however, is not a great solution, because:

  • it drives me crazy, having a remote with a back button that goes to the home screen, and a home button that goes back
  • doesn’t fly with the rest of the family; no one can’t seem to remember that those buttons are reversed (can’t blame them) and it’s a constant source of frustration, which is voiced and directed at me without hesitation

Help!

Please, please, if anyone has any idea how to solve this - help me out before I go crazy or my wife kills me :).

I’m curious what that button actually maps to on OSMC, seeing that it’s equivalent to right-clicking on Windows and macOS. It’s also strange because it looks like the system “blocks” it; it catches it and performs some internal action and doesn’t pass it further, so there’s no way to even read the code, let alone force OSMC to let it go and not do anything, so it can go further up the chain and perform an action it’s remapped to.

Update 2019-10-16 23:26:02

Actually, looking closer at the logs now, it looks like on OSMC it also acts like right-clicking with a mouse:

ProcessMouse: trying mouse action rightclick

But how would to prevent that and instead map it to a different action? Is remapping mouse actions even possible on OSMC?

Update 2019-10-17 00:10:45

Solved! If you’re having a similar problem, please refer to the solution: https://discourse.osmc.tv/t/solved-problems-with-mapping-keys-on-a-usb-remote-hid-keyboard-mouse-device-and-reading-correct-key-codes/82627/3?u=roziek

If you had already saved a keymap with keymap editor then the file you want to modify should be in .kodi/userdata/keymaps/gen.xmland you need something like this.

 <keymap>
      <mouse>
        <global>
          <rightclick>PreviousMenu</rightclick>
        </global>
      </mouse>
    </keymap>

The reason why you couldn’t get it to work in keymap editor is because the default behavior for the right mouse button is to back out of a screen. In order to remap a button that is interacting with the program you would need to override that first. In your case this would be something like adding a <rightclick></rightclick> which should disable the default key map until you program it to do something else. Just remember that when you manually edit the keymap file you will need to restart to reload it with the changes.

@darwindesign You’re right, thank you!

I just figured it out myself, shortly after posting and updating a moment later that I nocited it actually does a right-click :). That pointed me in the right direction, and from there I simply refered to Kodi’s official Wiki, specifically the remapping section regarding mice.

What you said is exactly what It did, the only difference being that I chose the “Back” action instead of “PreviousMenu”.

My ~/.kodi/userdata/keymaps/mouse.xml:

<?xml version="1.0" encoding="UTF-8"?>
<keymap>
  <global>
    <mouse>
      <rightclick>Back</rightclick>
    </mouse>
  </global>
</keymap>

My ~/.kodi/userdata/keymaps/keyboard.xml:

<?xml version="1.0" encoding="UTF-8"?>
<keymap>
  <global>
    <keyboard>
      <key id="61576">ActivateWindow(Home)</key>
    </keyboard>
  </global>
</keymap>

So now I have exactly what I wanted. The back button going back, and the home button going straight to the Home screen :).

Gosh, if only I noticed that it was actually doing a right-click earlier… that would’ve saved me sooooooo much time!

However, as a bonus, now I’m wondering: how does Keymap Editor refresh the mappings without restarting OSMC? Would be nice if we could do that ourselves too :).

If you are in a terminal window you can use kodi-send --action=reloadkeymaps

Just as a FYI on your keymap there is no reason to have separate files (it is easier to keep track of what’s going on in a single file)…

<?xml version="1.0" encoding="UTF-8"?>
<keymap>
  <global>
    <keyboard>
      <key id="61576">ActivateWindow(Home)</key>
    </keyboard>
    <mouse>
      <rightclick>Back</rightclick>
    </mouse>
  </global>
</keymap>

Both good tips, thanks and thanks ;). Will definitely make good use of that command.

P.S. I separated them instinctively ;x. I’m a programmer, so separating things into small, contained, single-responsibility modules is like a second nature.

1 Like