Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bizarre keyboard shortcut behaviour (UK layout) #97028

Closed
jmaargh opened this issue May 5, 2020 · 15 comments
Closed

Bizarre keyboard shortcut behaviour (UK layout) #97028

jmaargh opened this issue May 5, 2020 · 15 comments
Assignees
Labels
info-needed Issue requires more information from poster linux Issues with VS Code on Linux

Comments

@jmaargh
Copy link

jmaargh commented May 5, 2020

  • VSCode Version: 1.44.2
  • OS Version: Ubuntu 20.04 Desktop, Gnome (near fresh install)

Steps to Reproduce:

  1. Use a UK keyboard
  2. Go to keyboard shortcuts
  3. Try to assign [Ctrl] + [Shift (left shift)] + [` (backtick)] to any command
  4. Command now appears to have two bindings added:
  • [Ctrl] + [Shift] + [`]
  • [Ctrl] + [Shift] + [#] which was neither requested nor desired
  1. Go to the JSON to fix it and observe that apparently it's being stored as "ctrl+shift+[Backslash]"

I assume that this is all to do with some bizarreness related to using JSON (i.e. strings) as the underlying storage medium while what "should" be stored for consistency are scancodes (which can then be interpreted and displayed whichever layout it used. While having the "incorrect" keys stored (and even appear differently in the UI) is livable with (though annoying), it's much less acceptable for one shortcut to take up two distinct physical actions. I would like to use [Ctrl] + [Shift] + [`] and [Ctrl] + [Shift] + [#] for different actions.

Does this issue occur when all extensions are disabled?: Yes

@alexdima alexdima added the linux Issues with VS Code on Linux label May 8, 2020
@alexdima
Copy link
Member

alexdima commented May 8, 2020

@jmaargh This topic is a bit complex. It is documented in great detail here.

Can you please answer the following:

  • What is the exact contents of your keybindings.json ?
  • Have you customized keyboard.dispatch in your settings.json ?
  • Do you have other keyboard layouts installed on the machine?
  • Do you sit physically at the machine on which linux executes on bare metal? (Or do you run linux in a vm, or do you connect to linux via some remote mechanism?)
  • Do you use an ISO or an ANSI physical keyboard?
  • Can you please open up an editor and run F1 > Developer: Inspect key mappings and save the output to a file and attach it here? (you can drag&drop)

@alexdima alexdima added the info-needed Issue requires more information from poster label May 8, 2020
@jmaargh
Copy link
Author

jmaargh commented May 13, 2020

Thanks for the reply. I have things set up the way I want now, so don't need troubleshooting help, but I wanted to raise it as confusing and bizarre behaviour that vsode should avoid. I also appreciate that localisation (esp. where hardware is involved) is annoying and complex. Thanks for working on a great piece of software :)

* Have you customized `keyboard.dispatch` in your `settings.json` ?

no

* Do you have other keyboard layouts installed on the machine?

no

* Do you sit physically at the machine on which linux executes on bare metal? (Or do you run linux in a vm, or do you connect to linux via some remote mechanism?)

yes

* Do you use an ISO or an ANSI physical keyboard?

ISO (I think). It's the standard UK layout

@pfmoore
Copy link

pfmoore commented May 15, 2020

I found this as a result of hitting dbankier/vscode-quick-select#24. The issue there is that Ctrl-K ' and Ctrl-K " aren't mapped properly on a UK keyboard (they seem to map to Ctrl-K # amd Ctrl-K Shift-#, which are basically the physical locations of the ' and " keys on a US keyboard, but not UK).

Using the "Record Keys" feature, I see that Ctrl-K ' appears as Ctrl-K oem_3 and Ctrl-K " appears as Ctrl-K Shift-2.

This seems like it would make it impossible to sanely define key mappings that work as expected across different keyboard layouts.

@jmaargh
Copy link
Author

jmaargh commented May 15, 2020

@pfmoore I don't think it should be impossible. I'm not particularly familiar with js or electron, but good input libraries in general will report keys as scancodes which are layout-independent and OSs provide a way to map those back to what is laid out on the physical keyboard. This is how, for example, most well-made games that allow key remapping "just work" with different layouts.

I suspect one problem here is that vscode is using json strings as the storage backend, which are not layout-independent because they're storing the physical key identity (e.g. ' rather than the scancode).

I say "one problem" because the issue of one key combination adding two different shortcuts that I mentioned initially doesn't seem to be explained by this.

@pfmoore
Copy link

pfmoore commented May 15, 2020

@jmaargh I meant that it's impossible for users to set up layout-independent keybindings, with the current implementation. I'm sure it's possible for VSCode to be changed to fix this issue (although I don't doubt the issue isn't as simple as I'd like it to be 😉).

@alexdima
Copy link
Member

alexdima commented Jun 4, 2020

@pfmoore

I meant that it's impossible for users to set up layout-independent keybindings, with the current implementation.

To create keyboard layout independent keybindings, it is possible to use scan codes in the keybindings definitions with the [] notation, e.g.

{
    "key": "ctrl+[BracketLeft]",
    "command": "actions.find",
    "when": "editorTextFocus"
}

Here is a list of scan codes -- https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values

@pfmoore
Copy link

pfmoore commented Jun 4, 2020

Thanks. It seems odd to me that the "Record Keys" feature doesn't return scan codes. I can't see why I'd ever want layout-dependent results by default....

@alexdima
Copy link
Member

alexdima commented Jun 4, 2020

For portability reasons. In insiders, we already offer settings sync and keybindings will be synchronized across machines, potentially across different OSes. So we default to the most "portable" thing we have...

@pfmoore
Copy link

pfmoore commented Jun 4, 2020

Hmm, OK. Maybe I'm not understanding then. How is Ctrl-K oem_3 more portable than Ctrl-K [Quote]? I originally found this because of an extension that mapped Ctrl-K ', which is not portable to UK keyboards. If they'd mapped Ctrl-K [Quote] I assume it would have worked everywhere?

To be clear, using scan codes will solve my issue, so the only things I'm really discussing now are discoverability (it's hard to find out that scan codes are an option, and "Record Keys" gave no hint) and a bit of background understanding of the reasoning here.

@alexdima
Copy link
Member

alexdima commented Jun 4, 2020

That's why I use quotes when saying "portable" :). Scan codes identify very well the physical key that you have pressed on your current keyboard on your current machine.

But if you move to another keyboard (say from an ISO to an ANSI keyboard), it is possible that you miss a scan code (e.g. IntlBackslash) -- see diagram. This can happen often in Europe, where many laptops ship with an ISO keyboard, but where many developers buy ANSI keyboards. Also, if you then move to an iPad (which is possible with our web client), there will be more trouble to map those scan codes to some keypress combination.

So, as broken as they are, key codes are more "portable".

As for the key code oem_3. oem_3 is an alias for ` so writing Ctrl-K oem_3 is the same as writing Ctrl-K ` in our user settings. OEM3 is the key code which under the US kb layout produces `. Depending on keyboard layouts, key codes can produce other characters or they can be "repositioned" on the keyboard.

So Windows has the concept of scan codes, key codes, and produced characters. So there are two maps, one from scan code to key code (which is irrespective of modifiers), and another one from key code + modifiers to produced characters. That is quite smart because it helps very many developers get correctly things like select all (Ctrl+A) or undo (Ctrl+Z) to work seamlessly under AZERTY/QWERTY, where almost all Windows APIs encourage you to use key codes.

That is why early browsers exposed the concept of key codes to javascript events. Once these concepts were ported to Linux or mac (where there is a single map, from scan code + modifiers to produced characters), things started to quickly fall apart and all browsers try to guess a key code (since that concept does not exist on these platforms)

In the end, browsers now also expose scan codes and that's why on Linux and Mac we dispatch by default based on scan codes. But it would be unusual to dispatch on scan codes on Windows, where all applications dispatch on key codes.

This is quite a mess, so we encourage the following:

  1. extensions should never ship keybindings :)
  2. that people use the UI for editing keybindings and don't go digging too deep because this is really ugly and we try hard to protect you from this crap :).

@pfmoore
Copy link

pfmoore commented Jun 4, 2020

Thanks - nice explanation 🙂 I appreciate you taking the time to clarify all of this for me.

@jmaargh
Copy link
Author

jmaargh commented Jun 4, 2020

Thanks for the explanation, but how did I end up with one shortcut from the recorder affecting two distinct physical key combinations (and apparently two distinct lines in the config file)?

@alexdima
Copy link
Member

@jmaargh Are you OK to close the issue now?

@github-actions github-actions bot locked and limited conversation to collaborators Oct 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
info-needed Issue requires more information from poster linux Issues with VS Code on Linux
Projects
None yet
Development

No branches or pull requests

4 participants
@pfmoore @alexdima @jmaargh and others