-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Non-US keyboard layouts #21
Comments
That's a great idea. Except I have no experience in that area and no easy way to validate it even if I did implement it. Any examples of good implementations? Or even better would be working patches :-) |
A while ago Colin Dean of xvpsource.org sent me a patch that attempted to add Non-US keyboard layout support. Here is the original patch: https://gist.github.com/763752 Here is the patch with some modifications I made to it: https://gist.github.com/2e7f20be852a4527df63 The patch switches from using keydown and keyup events to using the keypress event to get the charCode value which is then mapped through a Unicode table to get the keysym value. Unfortunately, after playing around with it I discovered a couple of issues that prevent it from being a solution for noVNC:
The implication is that in order to do the right thing we will have to determine the right keysym from the keyCode of the keydown event and not rely on the charCode of the keypress event. Most of Colin's patch probably won't be used (although the u2x11 script probably will be), but it was invaluable to me to figure out what really needs to be done. |
Some useful links:
It sounds like the altKey, shiftKey and ctrlKey properties of the key events may be fairly cross-browser (in the browser versions we care about) which is very good if true. |
Also, I added tests/keyboard.html which prints keyboard event data (keyCode, charCode, which, altKey, shiftKey, ctrlKey, translated keysym). |
One thought I've had for how to generate keyboard layout data is that we may be able to create a page that generates fake keyboard events to determine what the keycode+modifiers to charCode data is (i.e. generate keydown event and trap the keypress event), It's possible this is fast enough (and reliable enough) in all browsers we need to support that we might be able to do this on page load in noVNC. But at least we could have a publicly accessible page where people could generate and then submit their layout data. But at the very least we might be able to use the technique with just a few key events to binary search for the keyboard layout that the user is using. Assuming there is no better way to determine that (I haven't searched in detail for how JavaScript can determine keyboard layout). |
i would do both: |
if the keyboard layout could be configurable, it could resolve many problems... |
I tried to integrate the patch from Colin Dean, as noVNC is mostly no usuable for typing text. The git is https://github.com/moobyfr/noVNC |
moobyfr, the change in your fork is not actually functional. You have only added the x11.js file without using it. Perhaps you forget to push the rest of the changes. Also, as I mentioned in the 3rd comment there are two major issues with Colin's approach: the keydown and keyup messages are no longer detected and sent separately, unintended browser events are no longer disabled (e.g. Ctrl-W will close the browser tab rather than sending a Ctrl-W). I am very willing to accept additional keyboard layouts, however the layout must key off off keydown and keyup events and not key off of the keypress event as with Colin's patch. If you would like to develop a French layout that keys off of keydown/keyup then I would gladly pull it into the project. |
I've spent some time to look for the way to go. The keydown/keyup is the way to intercept ~all keys. But there is something bad in the management with javascript for key events. keyCode contain a key reference for a qwerty keyboard, and the real char is in CharCode. Javascript doesn't give us all the power :/ |
noVNC has to use keyCode and not charCode for two reasons: first so that we can send the keydown and keyup separately (for some keys on some layouts we may have to work around this due to keyCode limitations as you describe), but the second and bigger issue is that using charCode requires the key event to propagate/bubble which means that certain key sequences are seen by the browser and cause unintended behavior such as tab, space, enter, Ctrl-W, Ctrl-Tab, etc. If Guacamole is using charCode then they have this problem. Here is a concrete example of the second problem. On most browsers, Ctrl-Minus will shrink the font size and Ctrl-Plus will increase the font size. In order to prevent this from happening in noVNC (and just send the Ctrl-Minus/Plus on to the server), we stop the keyDown event and don't allow it to propagate. However, another effect of stopping the event is that there is no keyPress event generated. I don't know of any way to both generate a keyPress event and prevent bubbling into default browser actions. That is really terrible that on certain keyboard layouts multiple keys generate the same keyCode in Javascript. If anybody has a sudden stroke of brilliance about how to solve the keyboard layout problems without bad side-effects, I'm all ears. In the meantime, we may just have to provide a way (button) for the user to send a '_' character when using an azerty keyboard. Do we know of other keys that have the same overlapping key layout abomination? |
I may ask this question on stackoverflow. |
I've asked the question on stackoverflow here: http://stackoverflow.com/questions/5306132/translate-javascript-keycode-into-charcode-for-non-u-s-keyboard-layout-i-e-aze |
more informations: 3x 2 keys have same keyCode: ";" and ":" are differents keys, and "!" and shift + "&" I have another proposition: add an option to noVNC to use the up/down event only for qwerty users, or the keypress for international users with less functionalities... |
moobyfr, thanks for your work on this. It's a really messy area and I just use a standard U.S. keyboard layout so it's difficult for me to determine exactly where the issues lie. It looks like it's going to have to be something like a fallback for non-US layouts. Although, again, the biggest issue is not getting the mapping correct, the biggest problem is preventing unintended default browser behaviors. So it's likely that keypress will only be used for non-US keys when no modifier key (other than shift) is pressed at the same time. When a modifier (other than shift) is pressed we still can't use keypress on any key layout. |
Okay, it's a huge challenge but I think I've made some forward progress here: In summary:
This isn't a 100% solution since key combinations that cause browser events (tab, enter, backspace, Ctrl-, Alt-, etc) are not translated before being sent, but for normal typing we should be able to get keyboard mapping correct now. I'm going to leave the bug open for a while since I have not been able to test this much on alternate keyboards so I'm sure there are issues, but I think the framework is in place to be able to solve most of the issues. |
Issue #21 - non-US keyboard layouts. Only identify some keys as special during the keyDown event so that when using non-US keyboards the values don't overlap with the values for normal keys. Some keys have to still be identified in both keyDown and keyPress since they generate both: backspace and enter for Firefox and Opera, tab for Opera.
Issue #21 - non-US keyboard layouts. The code section for tab, backspace and enter was commented out for testing but got checked in that way. Fix that.
Also, see this commit and the comments with it: https://github.com/moobyfr/noVNC/commit/c0615b935cc1e0e5cc9be222405185bbf829294a |
I'm closing this issue. I don't have a great way of testing this myself. I can switch keyboard layouts and poke around a bit and things seem to be working fairly well, but I'm not a real user of non-US layouts so I'm relying on community feedback. If anybody listening uses non-US keyboards and is having issues, please re-open. Thanks. |
API change: for intergrators that explicitly include the Javascript files (that do not use include/vnc.js)js, include/input.js is a new file that must also be included. The mouse and keyboard handling could be useful on its own so split it out into a Keyboard and Mouse class in include/input.js. This refactoring is preparation to deal with issue novnc#21 - non-US keyboard layouts.
This is part of addressing issue novnc#21 - non-US keyboard layouts. There are several challenges when dealing with keyboard events: - The meaning and use of keyCode, charCode and which depends on both the browser and the event type (keyDown/Up vs keyPress). - We cannot automatically determine the keyboard layout - The keyDown and keyUp events have a keyCode value that has not been translated by modifier keys. - The keyPress event has a translated (for layout and modifiers) character code but the attribute containing it differs. keyCode contains the translated value in WebKit (Chrome/Safari), Opera 11 and IE9. charCode contains the value in WebKit and Firefox. The which attribute contains the value on WebKit, Firefox and Opera 11. - The keyDown/Up keyCode value indicates (sort of) the physical key was pressed but only for standard US layout. On a US keyboard, the '-' and '_' characters are on the same key and generate a keyCode value of 189. But on an AZERTY keyboard even though they are different physical keys they both still generate a keyCode of 189! - To prevent a key event from propagating to the browser and causing unwanted default actions (such as closing a tab, opening a menu, shifting focus, etc) we must suppress this event in both keyDown and keyPress because not all key strokes generate on a keyPress event. Also, in WebKit and IE9 suppressing the keyDown prevents a keyPress but other browsers still generated a keyPress even if keyDown is suppressed. For safe key events, we wait until the keyPress event before reporting a key down event. For unsafe key events, we report a key down event when the keyDown event fires and we suppress any further actions (including keyPress). In order to report a key up event that matches what we reported for the key down event, we keep a list of keys that are currently down. When the keyDown event happens, we add the key event to the list. If it is a safe key event, then we update the which attribute in the most recent item on the list when we received a keyPress event (keyPress should immediately follow keyDown). When we received a keyUp event we search for the event on the list with a matching keyCode and we report the character code using the value in the 'which' attribute that was stored with that key. For character codes above 255 we use a character code to keysym lookup table. This is generated using the util/u2x11 script contributed by Colin Dean (xvpsource.org).
I'm having problems here with a german keyboard layout and at least the backslash key. Instead of a backslash noVNC sends a left bracket [. The codes send with different Browsers:
Unfortunately i have not the permissions to reopen this issue. |
@tenchman, I've reopened the bug. I can't seem to replicate your problem on Linux (Ubuntu Maverick) with Chrome 12, firefox 4.0.1, or Opera 11.11. I'll have to try with browsers under Windows at some point (I assume that is where you are seeing this?) Just to make sure, is this the keyboard layout you are using? http://en.wikipedia.org/wiki/Keyboard_layout#Germany_and_Austria_.28but_not_Switzerland.29 |
the current version of novnc can't handle correctly AltGr key. In USA, right ctrl + alt can do the same, but these keys don't exist on european keyboards |
@benbracha @DirectXMan12 Have you tested with @danielhb patches referenced above? They might fix your issue. |
@laggarcia - yes, I tried @danielhb version |
@benbracha can you specify which German layout are you using? Because I just tested here with my version, with the layout I believe it's the German default for Gnome and the "@" works fine. However it's AltGr+Q that gives "@", not AltGr+I. |
@benbracha don't know if this is exactly the layout you're using, but just tried it here with German - Austria (Macintosh) and it worked too (with AltGr + L ). What browser are you using? The code will not activate in any browser but latest stable Firefox, Chrome and Opera |
What VNC server are you trying to connect to? Are you trying to connect to xvnc, tigervnc, QEMU vnc ...? Supposing that you're connecting to a QEMU compatible VNC server, using Firefox >= 44 or Chrome >= 48 or Opera >= 36 and mapping the exact same keyboard layout inside the VM, it should work. I've tested it a lot with Linux and Windows 10 but haven't tried Apple. I'll fire it up an old Mac Air here and see if there's something I didn't predict. |
Thanks. Sorry for not being verbose with the details. So: (I'm used to work with guacamole, and at least as I understand - the keyboard layout of the VM is not important, as eventually the actual characters (charCode that are raised from keypressed JS events) are sent to the remote VM. I may miss something here though.. |
Keyboard layout is not important only when you are using the same
Yeah, that's one of the issues you might see when passing charCodes to |
@laggarcia Thanks for the explanation! Just to be clear, when you are saying:
What do you mean by "client and server"? My set up has:
In this setup - should I set the the "client VM" keyboard layout to German as well (like it is set on my Mac)? |
@benbracha I see where you're coming from. I'll explain why as succinct as I can, because this is a long story/topic and @laggarcia already explained a bit. The implementation you're talking about is the regular VNC implementation of key events. You send the key symbol (keysym) to the remote server, the remote server shows it and that's it. This is trivial for VNC clients that have direct access to the keyboard map of the OS and can tell, for example, that AltGr+L does nothing in an English layout but it produces the keysym "@" in yours. QEMU VNC servers, on the other hand, can't be treated as regular VNC servers. QEMU is a hardware emulator which emulates everything, including the keyboard. In this regular VNC implementation, when connecting to the QEMU server, sending a "@" keysym would cause QEMU to transform it back to the actual key strokes that generated it. In en_us layout, it would be Shift+2. But you haven't pressed shift+2, you pressed AltGr+L. But there's no way QEMU knows your layout beforehand. That leads to a lot of problems, as you might have noticed. Then it comes the QEMU extension, the work I've done in noVNC. It does not rely on sending keysyms, but the actual physical key pressed. It's a different code from the regular noVNC keyboard handler. In your case for example, AltGr+L will be sent as 'key of row 6 column 5' + 'key of row 4 column 10'. This is what the QEMU VNC server receives and sends to the VM. So, in order to get the "@" in the VM, the VM must match your own keyboard layout. Supposing that you didn't change the VM keyboard, AltGr+L in a en_us layout gives you no symbol. So, in order to properly make the keyboard work in your case, the VM layout must match the "source" layout. |
"In this setup - should I set the the "client VM" keyboard layout to German as well (like it is set on my Mac)?" Exactly. Not only "German" but the exact same layout you're using. In Ubuntu15 it's called "German-Austria-Macintosh" |
Thanks @danielhb - this really sheds more light on this, and improve my understanding. I you think this is not related to this issue, I would be happy to take this offline with you (email), as it can help me a lot. I did notice this thing: Even if I don't change my "client VM" keyboard and leave it as is (english), when I switch my mac between EN and DE keyboards and send "y" - the "client VM" behaves as expected - types "y" or "z" accordingly. According to your explanation, this shouldn't be possible unless I'll change the "client VM" keyboard to DE.. Maybe I'm missing something more basic with my setup? |
On 04/13/2016 11:20 AM, Ben Bracha wrote:
The reason is that the QEMU VNC extension isn't enabled. Otherwise Another thing that really counts is the browser version. You said that
It's actually the opposite. My changes are on the client side, in the If you want to be sure that you're running the right code, just use the
I am interested to see your case working or at least figured because Feel free to email me at [email protected] if you want to take the |
Thanks, now I see it work (I didn't use your noVNC client side, only the server side, as I thought your changes were on the server side..). It seems like dead-keys are working as well.. at least I tried the AltGr+n that generates a "~" and AltGr+u that generates quotes, although I couldn't get them to add "accent" |
Nice to see it worked! Ubuntu terminal doesn't print all the available characters. Try opening On 04/13/2016 11:57 AM, Ben Bracha wrote:
|
@danielhb so in libvirt, with your patch, there should be no keymap set, correct? For example:
See also: https://www.redhat.com/archives/libvir-list/2009-May/msg00234.html |
@dkelson yes, you're right. No keymap set in libvirt or QEMU, following the recommendation in the link you sent: "Our recommendation is to never set the '-k' /keymap option at all these |
@danielhb : it's work fine for me ! I port your patched version of noVNC in my webvirtcloud fork to try it : https://github.com/brenard/webvirtcloud/tree/html5_console I make my tests with Chromium Version 49.0.2623.108 Built on 8.3, on multiple libvirt/KVM VNC instances without specific keymap configure in libvirt XML configuration, with french keymap configure in VM and french keyboard (azerty). |
I'm glad it worked @brenard ! Thanks for testing it! |
For anyone interested, I've backported the my implementation of the QEMU extension that fixes this bug to the latest noVNC release, 0.5.1. The code can be fetched here: https://github.com/danielhb/noVNC/tree/0.5.1_qemu_extension Same conditions apply (recent Firefox/Chrome/Opera browsers, must connect to a QEMU VNC server). |
Article by Daniel with further defails and background: https://www.ibm.com/developerworks/library/wa-support-multiple-keyboard-layouts-in-web-based-vnc-apps-trs/index.html |
The keyboard option is actually not recommended in the QEMU documentation (https://manpages.debian.org/buster/qemu-system-x86/qemu-system-x86_64.1.en.html). After some tests, it appears that noVNC is already sending raw keyCode to QEMU since 2016 (see novnc/noVNC@f4f4e89). More information can be found in novnc/noVNC#21 and https://www.berrange.com/posts/2010/07/04/more-than-you-or-i-ever-wanted-to-know-about-virtual-keyboard-handling/
The keyboard option is actually not recommended in the QEMU documentation (https://manpages.debian.org/buster/qemu-system-x86/qemu-system-x86_64.1.en.html). After some tests, it appears that noVNC is already sending raw keyCode to QEMU since 2016 (see novnc/noVNC@f4f4e89). More information can be found in novnc/noVNC#21 and https://www.berrange.com/posts/2010/07/04/more-than-you-or-i-ever-wanted-to-know-about-virtual-keyboard-handling/
A nice feature for me and all others with non-US keyboards is to add a keyboard layout option list and/or trying to auto detect locale settings from the browser.
The text was updated successfully, but these errors were encountered: