Skip to content

#861: Displaying keys based off of scancodes

Frinksy requested to merge Frinksy/veloren:Frinksy/scancodes into master
  • By opening this merge request, you agree to release your code and all other changes under the GPL 3 license and to abide by the terms set by this license.
  • Migrations have been added if applicable
  • Significant changes of this merge request have been added to the changelog.

Context:
I had added support in !1642 (merged) to use scancodes as keybindings (when a VirtualKeyCode is not available) so that international keyboards would be supported to a minimal extent. Those keys were all displayed as "Unknown".

In my branch, you can get the key display name from:

  • Linux:
    • X11 (using xkbcommon and xcb)
    • Wayland: have a proper wayland implementation (using wayland-client)
  • Windows: implementation seems good to me, but will probably need testing from people with different keyboards
  • macOS (I don't own a recent macOS machine, so I probably won't be able to add support)

Explanation, for anyone reviewing this:
New crate source is at: https://gitlab.com/Frinksy/keyboard-keynames/ Below is outdated, but the new crate uses the same code, with changes suggested by Imbris.

I created a new KeyLayout struct.

  • On Windows, it has no members, only a function to convert a scancode to it's String equivalent. It uses the winapi crate to do the transformation (thus needs unsafe code). From what I can tell, it works with pretty much all keys/layouts.

  • On Linux, I use the xkbcommon crate and store a Keymap struct inside KeyLayout. Using this Keymap, the scancodes are translated into their String equivalent. To get the Keymap from the OS, check if using Wayland or X11 and:

    • X11: create an xcb connection, query core keyboard device and get Keymap
    • Wayland: connect to environment, get all available interfaces from the registry, bind to a wl_seat, get keyboard device and get Keymap from there.

    From what I have tested, it works well with all keys, but behaves differently from Windows: dead keys such as ^ are represented as dead_circumflex , I haven't found an easy way around this yet.

As far as I can tell, my implementation is functional.

However, I am not sure how failing to query a Keymap should behave. I could fall back to a US Layout, or I could display all keys as scancodes. I believe the latter is not ideal in the case that we might want to base everything directly off of scancodes in the future.

I also am not the most confident that I have approached this in the right way.

I do not exactly know how much more I can/should do for this MR, and I would greatly appreciate a little bit of guidance 😃

Note: should also address #354

Edited by Frinksy

Merge request reports