diff --git a/README.md b/README.md index 2f546a11..b8c1a8a6 100644 --- a/README.md +++ b/README.md @@ -698,6 +698,18 @@ Run every step as your normal user, not with `sudo`: if `manage.py` ever runs as Open `http://127.0.0.1:8000`. The browser consoles connect to `/novncd/` and `/socket.io/` on the panel's own address, which the dev server does not proxy: try them in the Docker image, or behind nginx with `conf/nginx/webvirtcloud.conf`. +### Keyboard layouts + +The VNC console's "Type it" sends the keys that type each character on the VM's keyboard layout. A layout is one file in `console/layouts/`, written from the XKB layout of the same name (needs `libxkbcommon` and `xkeyboard-config`, present on Linux desktops): + +```bash +python3 dev/console_layout.py de "German" # XKB layout, the name the console shows +python3 dev/console_layout.py tr "Turkish F" --variant f # a variant +python3 dev/console_layout.py us "English (US)" --model pc104 # a keyboard without the key left of Z +``` + +It lists the dead keys it leaves out: a character only a dead key types cannot be typed. Type a sample with every character group of the layout into a VM set to that layout before committing the file. + ### Running tests ```bash diff --git a/console/layouts/tr.json b/console/layouts/tr.json new file mode 100644 index 00000000..cc508dc5 --- /dev/null +++ b/console/layouts/tr.json @@ -0,0 +1,54 @@ +{ + "name": "Turkish Q", + "source": {"xkb_layout": "tr", "xkb_variant": "", "xkb_model": "pc105"}, + "keys": { + "Digit1": ["1", "!", ">", "¡"], + "Digit2": ["2", "'", "£", "²"], + "Digit3": ["3", "^", "#", "³"], + "Digit4": ["4", "+", "$", "¼"], + "Digit5": ["5", "%", "½", "⅜"], + "Digit6": ["6", "&", "¾", null], + "Digit7": ["7", "/", "{", null], + "Digit8": ["8", "(", "[", null], + "Digit9": ["9", ")", "]", "±"], + "Digit0": ["0", "=", "}", "°"], + "Minus": ["*", "?", "\\", "¿"], + "Equal": ["-", "_", "|", null], + "KeyQ": ["q", "Q", "@", "Ω"], + "KeyW": ["w", "W", null, null], + "KeyE": ["e", "E", "€", null], + "KeyR": ["r", "R", "¶", "®"], + "KeyT": ["t", "T", "₺", null], + "KeyY": ["y", "Y", "←", "¥"], + "KeyU": ["u", "U", "û", "Û"], + "KeyI": ["ı", "I", "î", "Î"], + "KeyO": ["o", "O", "ô", "Ô"], + "KeyP": ["p", "P", null, null], + "BracketLeft": ["ğ", "Ğ", null, null], + "BracketRight": ["ü", "Ü", "~", null], + "KeyA": ["a", "A", "â", "Â"], + "KeyS": ["s", "S", "ß", null], + "KeyD": ["d", "D", null, null], + "KeyF": ["f", "F", "ª", null], + "KeyG": ["g", "G", null, null], + "KeyH": ["h", "H", null, null], + "KeyJ": ["j", "J", null, null], + "KeyK": ["k", "K", null, null], + "KeyL": ["l", "L", null, null], + "Semicolon": ["ş", "Ş", "´", null], + "Quote": ["i", "İ", "'", null], + "Backquote": ["\"", "é", "<", "°"], + "Backslash": [",", ";", "`", null], + "KeyZ": ["z", "Z", "«", "<"], + "KeyX": ["x", "X", "»", ">"], + "KeyC": ["c", "C", "¢", "©"], + "KeyV": ["v", "V", "„", "‚"], + "KeyB": ["b", "B", "“", "‘"], + "KeyN": ["n", "N", "”", "’"], + "KeyM": ["m", "M", "µ", "º"], + "Comma": ["ö", "Ö", "×", null], + "Period": ["ç", "Ç", "·", "÷"], + "Slash": [".", ":", null, null], + "IntlBackslash": ["<", ">", "|", "¦"] + } +} diff --git a/console/layouts/us.json b/console/layouts/us.json new file mode 100644 index 00000000..68f8b572 --- /dev/null +++ b/console/layouts/us.json @@ -0,0 +1,53 @@ +{ + "name": "English (US)", + "source": {"xkb_layout": "us", "xkb_variant": "", "xkb_model": "pc104"}, + "keys": { + "Digit1": ["1", "!", null, null], + "Digit2": ["2", "@", null, null], + "Digit3": ["3", "#", null, null], + "Digit4": ["4", "$", null, null], + "Digit5": ["5", "%", null, null], + "Digit6": ["6", "^", null, null], + "Digit7": ["7", "&", null, null], + "Digit8": ["8", "*", null, null], + "Digit9": ["9", "(", null, null], + "Digit0": ["0", ")", null, null], + "Minus": ["-", "_", null, null], + "Equal": ["=", "+", null, null], + "KeyQ": ["q", "Q", null, null], + "KeyW": ["w", "W", null, null], + "KeyE": ["e", "E", null, null], + "KeyR": ["r", "R", null, null], + "KeyT": ["t", "T", null, null], + "KeyY": ["y", "Y", null, null], + "KeyU": ["u", "U", null, null], + "KeyI": ["i", "I", null, null], + "KeyO": ["o", "O", null, null], + "KeyP": ["p", "P", null, null], + "BracketLeft": ["[", "{", null, null], + "BracketRight": ["]", "}", null, null], + "KeyA": ["a", "A", null, null], + "KeyS": ["s", "S", null, null], + "KeyD": ["d", "D", null, null], + "KeyF": ["f", "F", null, null], + "KeyG": ["g", "G", null, null], + "KeyH": ["h", "H", null, null], + "KeyJ": ["j", "J", null, null], + "KeyK": ["k", "K", null, null], + "KeyL": ["l", "L", null, null], + "Semicolon": [";", ":", null, null], + "Quote": ["'", "\"", null, null], + "Backquote": ["`", "~", null, null], + "Backslash": ["\\", "|", null, null], + "KeyZ": ["z", "Z", null, null], + "KeyX": ["x", "X", null, null], + "KeyC": ["c", "C", null, null], + "KeyV": ["v", "V", null, null], + "KeyB": ["b", "B", null, null], + "KeyN": ["n", "N", null, null], + "KeyM": ["m", "M", null, null], + "Comma": [",", "<", null, null], + "Period": [".", ">", null, null], + "Slash": ["/", "?", null, null] + } +} diff --git a/console/templates/console-vnc.html b/console/templates/console-vnc.html index e408b757..a8f98898 100644 --- a/console/templates/console-vnc.html +++ b/console/templates/console-vnc.html @@ -7,6 +7,7 @@ #screen { flex: 1 1 auto; min-height: 0; overflow: hidden; } {{ vnc|json_script:"vnc-config" }} +{{ layouts|json_script:"keyboard-layouts" }} {% endblock %} @@ -103,8 +104,16 @@