diff options
| author | Florian Pelz <pelzflorian@pelzflorian.de> | 2020-04-09 02:17:22 +0200 |
|---|---|---|
| committer | Florian Pelz <pelzflorian@pelzflorian.de> | 2020-04-09 02:42:54 +0000 |
| commit | 91c231a2223440081426929828a23c7baa0214fd (patch) | |
| tree | db6adbba3f79d4cdaa1db0ee33938ced07763a0f | |
| parent | 543516ed0040df28eb15ea9b15ce905c038671c5 (diff) | |
installer: Allow Alt+Shift toggle from non-Latin keyboard layouts.
Fixes <https://bugs.gnu.org/40493>.
* gnu/installer/newt/keymap.scm (%non-latin-layouts): New variable.
(%non-latin-variants): New variable.
(%latin-layout+variants): New variable.
(toggleable-latin-layout): New procedure to compute combined layouts.
(run-keymap-page): Use it.
(keyboard-layout->configuration): Apply it in config.scm.
(run-layout-page): Mention Alt+Shift.
* gnu/installer/keymap.scm (kmscon-update-keymap): Pass on XKB options.
* gnu/installer/record.scm (<installer>): Adjust code comments.
* gnu/installer.scm (apply-keymap): Pass on XKB options.
(installer-steps): Adjust code comments.
* gnu/packages/patches/kmscon-runtime-keymap-switch.patch: Apply XKB options.
| -rw-r--r-- | gnu/installer.scm | 14 | ||||
| -rw-r--r-- | gnu/installer/keymap.scm | 10 | ||||
| -rw-r--r-- | gnu/installer/newt/keymap.scm | 61 | ||||
| -rw-r--r-- | gnu/installer/record.scm | 3 | ||||
| -rw-r--r-- | gnu/packages/patches/kmscon-runtime-keymap-switch.patch | 27 |
5 files changed, 79 insertions, 36 deletions
diff --git a/gnu/installer.scm b/gnu/installer.scm index 6cd3995e512..d2b7fc327da 100644 --- a/gnu/installer.scm +++ b/gnu/installer.scm | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | ;;; Copyright © 2018, 2020 Mathieu Othacehe <m.othacehe@gmail.com> | 2 | ;;; Copyright © 2018, 2020 Mathieu Othacehe <m.othacehe@gmail.com> |
| 3 | ;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org> | 3 | ;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org> |
| 4 | ;;; Copyright © 2019, 2020 Tobias Geerinckx-Rice <me@tobias.gr> | 4 | ;;; Copyright © 2019, 2020 Tobias Geerinckx-Rice <me@tobias.gr> |
| 5 | ;;; Copyright © 2020 Florian Pelz <pelzflorian@pelzflorian.de> | ||
| 5 | ;;; | 6 | ;;; |
| 6 | ;;; This file is part of GNU Guix. | 7 | ;;; This file is part of GNU Guix. |
| 7 | ;;; | 8 | ;;; |
| @@ -170,9 +171,9 @@ been performed at build time." | |||
| 170 | (define apply-keymap | 171 | (define apply-keymap |
| 171 | ;; Apply the specified keymap. Use the default keyboard model. | 172 | ;; Apply the specified keymap. Use the default keyboard model. |
| 172 | #~(match-lambda | 173 | #~(match-lambda |
| 173 | ((layout variant) | 174 | ((layout variant options) |
| 174 | (kmscon-update-keymap (default-keyboard-model) | 175 | (kmscon-update-keymap (default-keyboard-model) |
| 175 | layout variant)))) | 176 | layout variant options)))) |
| 176 | 177 | ||
| 177 | (define* (compute-keymap-step context) | 178 | (define* (compute-keymap-step context) |
| 178 | "Return a gexp that runs the keymap-page of INSTALLER and install the | 179 | "Return a gexp that runs the keymap-page of INSTALLER and install the |
| @@ -235,12 +236,13 @@ selected keymap." | |||
| 235 | 236 | ||
| 236 | ;; The installer runs in a kmscon virtual terminal where loadkeys | 237 | ;; The installer runs in a kmscon virtual terminal where loadkeys |
| 237 | ;; won't work. kmscon uses libxkbcommon as a backend for keyboard | 238 | ;; won't work. kmscon uses libxkbcommon as a backend for keyboard |
| 238 | ;; input. It is possible to update kmscon current keymap by sending it | 239 | ;; input. It is possible to update kmscon current keymap by sending |
| 239 | ;; a keyboard model, layout and variant, in a somehow similar way as | 240 | ;; it a keyboard model, layout, variant and options, in a somehow |
| 240 | ;; what is done with setxkbmap utility. | 241 | ;; similar way as what is done with setxkbmap utility. |
| 241 | ;; | 242 | ;; |
| 242 | ;; So ask for a keyboard model, layout and variant to update the | 243 | ;; So ask for a keyboard model, layout and variant to update the |
| 243 | ;; current kmscon keymap. | 244 | ;; current kmscon keymap. For non-Latin layouts, we add an |
| 245 | ;; appropriate second layout and toggle via Alt+Shift. | ||
| 244 | (installer-step | 246 | (installer-step |
| 245 | (id 'keymap) | 247 | (id 'keymap) |
| 246 | (description (G_ "Keyboard mapping selection")) | 248 | (description (G_ "Keyboard mapping selection")) |
diff --git a/gnu/installer/keymap.scm b/gnu/installer/keymap.scm index df9fc5e441e..c42b308009d 100644 --- a/gnu/installer/keymap.scm +++ b/gnu/installer/keymap.scm | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | ;;; GNU Guix --- Functional package management for GNU | 1 | ;;; GNU Guix --- Functional package management for GNU |
| 2 | ;;; Copyright © 2018 Mathieu Othacehe <m.othacehe@gmail.com> | 2 | ;;; Copyright © 2018 Mathieu Othacehe <m.othacehe@gmail.com> |
| 3 | ;;; Copyright © 2020 Florian Pelz <pelzflorian@pelzflorian.de> | ||
| 3 | ;;; | 4 | ;;; |
| 4 | ;;; This file is part of GNU Guix. | 5 | ;;; This file is part of GNU Guix. |
| 5 | ;;; | 6 | ;;; |
| @@ -154,8 +155,8 @@ Configuration Database, describing possible XKB configurations." | |||
| 154 | ((models layouts) | 155 | ((models layouts) |
| 155 | (values models layouts))))) | 156 | (values models layouts))))) |
| 156 | 157 | ||
| 157 | (define (kmscon-update-keymap model layout variant) | 158 | (define (kmscon-update-keymap model layout variant options) |
| 158 | "Update kmscon keymap with the provided MODEL, LAYOUT and VARIANT." | 159 | "Update kmscon keymap with the provided MODEL, LAYOUT, VARIANT and OPTIONS." |
| 159 | (and=> | 160 | (and=> |
| 160 | (getenv "KEYMAP_UPDATE") | 161 | (getenv "KEYMAP_UPDATE") |
| 161 | (lambda (keymap-file) | 162 | (lambda (keymap-file) |
| @@ -174,5 +175,8 @@ Configuration Database, describing possible XKB configurations." | |||
| 174 | (format port layout) | 175 | (format port layout) |
| 175 | (put-u8 port 0) | 176 | (put-u8 port 0) |
| 176 | 177 | ||
| 177 | (format port variant) | 178 | (format port (or variant "")) |
| 179 | (put-u8 port 0) | ||
| 180 | |||
| 181 | (format port (or options "")) | ||
| 178 | (put-u8 port 0)))))) | 182 | (put-u8 port 0)))))) |
diff --git a/gnu/installer/newt/keymap.scm b/gnu/installer/newt/keymap.scm index 8625afaa036..a555a1ecc12 100644 --- a/gnu/installer/newt/keymap.scm +++ b/gnu/installer/newt/keymap.scm | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | ;;; GNU Guix --- Functional package management for GNU | 1 | ;;; GNU Guix --- Functional package management for GNU |
| 2 | ;;; Copyright © 2018, 2020 Mathieu Othacehe <m.othacehe@gmail.com> | 2 | ;;; Copyright © 2018, 2020 Mathieu Othacehe <m.othacehe@gmail.com> |
| 3 | ;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org> | 3 | ;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org> |
| 4 | ;;; Copyright © 2020 Florian Pelz <pelzflorian@pelzflorian.de> | ||
| 4 | ;;; | 5 | ;;; |
| 5 | ;;; This file is part of GNU Guix. | 6 | ;;; This file is part of GNU Guix. |
| 6 | ;;; | 7 | ;;; |
| @@ -40,10 +41,12 @@ | |||
| 40 | #:info-text | 41 | #:info-text |
| 41 | (case context | 42 | (case context |
| 42 | ((param) (G_ "Please choose your keyboard layout. \ | 43 | ((param) (G_ "Please choose your keyboard layout. \ |
| 43 | It will only be used during the installation process.")) | 44 | It will only be used during the installation process. \ |
| 45 | Non-Latin layouts can be toggled with Alt+Shift.")) | ||
| 44 | (else (G_ "Please choose your keyboard layout. \ | 46 | (else (G_ "Please choose your keyboard layout. \ |
| 45 | It will be used during the install process, and for the installed system. \ | 47 | It will be used during the install process, and for the installed system. \ |
| 46 | You can switch to different layout at any time from the parameters menu."))) | 48 | Non-Latin layouts can be toggled with Alt+Shift. You can switch to a \ |
| 49 | different layout at any time from the parameters menu."))) | ||
| 47 | #:listbox-items layouts | 50 | #:listbox-items layouts |
| 48 | #:listbox-item->text layout->text | 51 | #:listbox-item->text layout->text |
| 49 | #:sort-listbox-items? #f | 52 | #:sort-listbox-items? #f |
| @@ -112,10 +115,48 @@ You can switch to different layout at any time from the parameters menu."))) | |||
| 112 | variants)) | 115 | variants)) |
| 113 | (cut append <> <>))) | 116 | (cut append <> <>))) |
| 114 | 117 | ||
| 118 | (define %non-latin-layouts | ||
| 119 | ;; List of keyboard layouts marked as $nonlatin in xkeyboard-config. | ||
| 120 | ;; See comments in xkeyboard-config file /share/X11/xkb/rules/base. | ||
| 121 | ;; We ignore layouts that support Latin input: "kr" | ||
| 122 | '("am" "ara" "ben" "bd" "bg" "bt" "by" "cs" "deva" "ge" "gh" | ||
| 123 | "gr" "guj" "guru" "il" "in" "ir" "iku" "jp" "kan" "kh" | ||
| 124 | "la" "lao" "lk" "mk" "mm" "mn" "mv" "mal" "olck" "ori" "pk" | ||
| 125 | "ru" "scc" "sy" "syr" "tel" "th" "tj" "tam" "ua" "uz" | ||
| 126 | ;; The list from xkeyboard-config is incomplete. Add more layouts when | ||
| 127 | ;; noticed: | ||
| 128 | "et" "kz")) | ||
| 129 | |||
| 130 | (define %non-latin-variants | ||
| 131 | '("cyrillic")) | ||
| 132 | |||
| 133 | (define %latin-layout+variants | ||
| 134 | ;; These layout+variant combinations are Latin after all. | ||
| 135 | '(("ir" "ku"))) | ||
| 136 | |||
| 137 | (define (toggleable-latin-layout layout variant) | ||
| 138 | "If LAYOUT is a non-Latin layout, return a new combined layout, | ||
| 139 | a variant, and options that allow the user to switch between the | ||
| 140 | non-Latin and the Latin layout. Otherwise, return LAYOUT, VARIANT, | ||
| 141 | and #f." | ||
| 142 | (if (and (not (equal? variant "latin")) | ||
| 143 | (not (member (list layout variant) %latin-layout+variants)) | ||
| 144 | (or (member layout %non-latin-layouts) | ||
| 145 | (member variant %non-latin-variants))) | ||
| 146 | (let ((latin-layout (if (equal? variant "azerty") "fr" "us"))) | ||
| 147 | (list | ||
| 148 | (string-append layout "," latin-layout) | ||
| 149 | ;; Comma to use variant only for non-Latin: | ||
| 150 | (and variant (string-append variant ",")) | ||
| 151 | "grp:alt_shift_toggle")) | ||
| 152 | (list layout variant #f))) | ||
| 153 | |||
| 115 | (define* (run-keymap-page layouts #:key (context #f)) | 154 | (define* (run-keymap-page layouts #:key (context #f)) |
| 116 | "Run a page asking the user to select a keyboard layout and variant. LAYOUTS | 155 | "Run a page asking the user to select a keyboard layout and variant. LAYOUTS |
| 117 | is a list of supported X11-KEYMAP-LAYOUT. Return a list of two elements, the | 156 | is a list of supported X11-KEYMAP-LAYOUT. For non-Latin keyboard layouts, a |
| 118 | names of the selected keyboard layout and variant." | 157 | second layout and toggle options will be added automatically. Return a list |
| 158 | of three elements, the names of the selected keyboard layout, variant and | ||
| 159 | options." | ||
| 119 | (define keymap-steps | 160 | (define keymap-steps |
| 120 | (list | 161 | (list |
| 121 | (installer-step | 162 | (installer-step |
| @@ -151,14 +192,20 @@ names of the selected keyboard layout and variant." | |||
| 151 | (lambda (variant) | 192 | (lambda (variant) |
| 152 | (gettext (x11-keymap-variant-name variant) | 193 | (gettext (x11-keymap-variant-name variant) |
| 153 | "xkeyboard-config"))))) | 194 | "xkeyboard-config"))))) |
| 154 | (list layout (or variant "")))) | 195 | (toggleable-latin-layout layout variant))) |
| 155 | (format-result | 196 | (format-result |
| 156 | (run-installer-steps #:steps keymap-steps))) | 197 | (run-installer-steps #:steps keymap-steps))) |
| 157 | 198 | ||
| 158 | (define (keyboard-layout->configuration keymap) | 199 | (define (keyboard-layout->configuration keymap) |
| 159 | "Return the operating system configuration snippet to install KEYMAP." | 200 | "Return the operating system configuration snippet to install KEYMAP." |
| 160 | (match keymap | 201 | (match keymap |
| 161 | ((name "") | 202 | ((name #f "grp:alt_shift_toggle") |
| 203 | `((keyboard-layout (keyboard-layout ,name | ||
| 204 | #:options '("grp:alt_shift_toggle"))))) | ||
| 205 | ((name #f _) | ||
| 162 | `((keyboard-layout (keyboard-layout ,name)))) | 206 | `((keyboard-layout (keyboard-layout ,name)))) |
| 163 | ((name variant) | 207 | ((name variant "grp:alt_shift_toggle") |
| 208 | `((keyboard-layout (keyboard-layout ,name ,variant | ||
| 209 | #:options '("grp:alt_shift_toggle"))))) | ||
| 210 | ((name variant _) | ||
| 164 | `((keyboard-layout (keyboard-layout ,name ,variant)))))) | 211 | `((keyboard-layout (keyboard-layout ,name ,variant)))))) |
diff --git a/gnu/installer/record.scm b/gnu/installer/record.scm index 7bc22e90e02..6ebd87f6a65 100644 --- a/gnu/installer/record.scm +++ b/gnu/installer/record.scm | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | ;;; GNU Guix --- Functional package management for GNU | 1 | ;;; GNU Guix --- Functional package management for GNU |
| 2 | ;;; Copyright © 2018, 2020 Mathieu Othacehe <m.othacehe@gmail.com> | 2 | ;;; Copyright © 2018, 2020 Mathieu Othacehe <m.othacehe@gmail.com> |
| 3 | ;;; Copyright © 2020 Florian Pelz <pelzflorian@pelzflorian.de> | ||
| 3 | ;;; | 4 | ;;; |
| 4 | ;;; This file is part of GNU Guix. | 5 | ;;; This file is part of GNU Guix. |
| 5 | ;;; | 6 | ;;; |
| @@ -63,7 +64,7 @@ | |||
| 63 | (exit-error installer-exit-error) | 64 | (exit-error installer-exit-error) |
| 64 | ;; procedure void -> void | 65 | ;; procedure void -> void |
| 65 | (final-page installer-final-page) | 66 | (final-page installer-final-page) |
| 66 | ;; procedure (layouts context) -> (list layout variant) | 67 | ;; procedure (layouts context) -> (list layout variant options) |
| 67 | (keymap-page installer-keymap-page) | 68 | (keymap-page installer-keymap-page) |
| 68 | ;; procedure: (#:key supported-locales iso639-languages iso3166-territories) | 69 | ;; procedure: (#:key supported-locales iso639-languages iso3166-territories) |
| 69 | ;; -> glibc-locale | 70 | ;; -> glibc-locale |
diff --git a/gnu/packages/patches/kmscon-runtime-keymap-switch.patch b/gnu/packages/patches/kmscon-runtime-keymap-switch.patch index 656c76fa407..deb5688daf4 100644 --- a/gnu/packages/patches/kmscon-runtime-keymap-switch.patch +++ b/gnu/packages/patches/kmscon-runtime-keymap-switch.patch | |||
| @@ -1,14 +1,5 @@ | |||
| 1 | From 360d44d67e7be46108bec982ff2e79b89f04a9a3 Mon Sep 17 00:00:00 2001 | 1 | By Mathieu Othacehe <m.othacehe@gmail.com>. |
| 2 | From: Mathieu Othacehe <m.othacehe@gmail.com> | 2 | Modified by Florian Pelz <pelzflorian@pelzflorian.de>. |
| 3 | Date: Thu, 15 Nov 2018 14:34:40 +0900 | ||
| 4 | Subject: [PATCH] add runtime keymap switch support. | ||
| 5 | |||
| 6 | --- | ||
| 7 | src/pty.c | 23 ++++++++++- | ||
| 8 | src/uterm_input.c | 2 + | ||
| 9 | src/uterm_input_internal.h | 5 +++ | ||
| 10 | src/uterm_input_uxkb.c | 83 ++++++++++++++++++++++++++++++++++++++ | ||
| 11 | 4 files changed, 111 insertions(+), 2 deletions(-) | ||
| 12 | 3 | ||
| 13 | diff --git a/src/pty.c b/src/pty.c | 4 | diff --git a/src/pty.c b/src/pty.c |
| 14 | index 1443f4a..f64cb5b 100644 | 5 | index 1443f4a..f64cb5b 100644 |
| @@ -124,7 +115,7 @@ index 04e6cc9..ec44459 100644 | |||
| 124 | uint16_t key_state, | 115 | uint16_t key_state, |
| 125 | uint16_t code); | 116 | uint16_t code); |
| 126 | diff --git a/src/uterm_input_uxkb.c b/src/uterm_input_uxkb.c | 117 | diff --git a/src/uterm_input_uxkb.c b/src/uterm_input_uxkb.c |
| 127 | index 925c755..4760972 100644 | 118 | index 925c755..5d5c22e 100644 |
| 128 | --- a/src/uterm_input_uxkb.c | 119 | --- a/src/uterm_input_uxkb.c |
| 129 | +++ b/src/uterm_input_uxkb.c | 120 | +++ b/src/uterm_input_uxkb.c |
| 130 | @@ -31,6 +31,9 @@ | 121 | @@ -31,6 +31,9 @@ |
| @@ -137,7 +128,7 @@ index 925c755..4760972 100644 | |||
| 137 | #include <xkbcommon/xkbcommon.h> | 128 | #include <xkbcommon/xkbcommon.h> |
| 138 | #include "shl_hook.h" | 129 | #include "shl_hook.h" |
| 139 | #include "shl_llog.h" | 130 | #include "shl_llog.h" |
| 140 | @@ -178,6 +181,86 @@ static void timer_event(struct ev_timer *timer, uint64_t num, void *data) | 131 | @@ -178,6 +181,87 @@ static void timer_event(struct ev_timer *timer, uint64_t num, void *data) |
| 141 | shl_hook_call(dev->input->hook, dev->input, &dev->repeat_event); | 132 | shl_hook_call(dev->input->hook, dev->input, &dev->repeat_event); |
| 142 | } | 133 | } |
| 143 | 134 | ||
| @@ -145,11 +136,11 @@ index 925c755..4760972 100644 | |||
| 145 | +{ | 136 | +{ |
| 146 | + struct uterm_input_dev *dev = data; | 137 | + struct uterm_input_dev *dev = data; |
| 147 | + char in; | 138 | + char in; |
| 148 | + char keymap[3][255]; | 139 | + char keymap[4][255]; |
| 149 | + int pos = 0; | 140 | + int pos = 0; |
| 150 | + int curr_keymap = 0; | 141 | + int curr_keymap = 0; |
| 151 | + int ret; | 142 | + int ret; |
| 152 | + char *model, *layout, *variant; | 143 | + char *model, *layout, *variant, *options; |
| 153 | + | 144 | + |
| 154 | + if (!(mask & EV_READABLE)) | 145 | + if (!(mask & EV_READABLE)) |
| 155 | + return; | 146 | + return; |
| @@ -159,6 +150,7 @@ index 925c755..4760972 100644 | |||
| 159 | + model = keymap[0]; | 150 | + model = keymap[0]; |
| 160 | + layout = keymap[1]; | 151 | + layout = keymap[1]; |
| 161 | + variant = keymap[2]; | 152 | + variant = keymap[2]; |
| 153 | + options = keymap[3]; | ||
| 162 | + | 154 | + |
| 163 | + do { | 155 | + do { |
| 164 | + ret = read(dev->rupdate_fd, &in, sizeof(in)); | 156 | + ret = read(dev->rupdate_fd, &in, sizeof(in)); |
| @@ -175,7 +167,7 @@ index 925c755..4760972 100644 | |||
| 175 | + | 167 | + |
| 176 | + llog_info(dev->input, "HANDLER CALLED %s|%s|%s\n", | 168 | + llog_info(dev->input, "HANDLER CALLED %s|%s|%s\n", |
| 177 | + model, layout, variant); | 169 | + model, layout, variant); |
| 178 | + uxkb_desc_init(dev->input, model, layout, variant, NULL, NULL); | 170 | + uxkb_desc_init(dev->input, model, layout, variant, options, NULL); |
| 179 | + | 171 | + |
| 180 | + dev->state = xkb_state_new(dev->input->keymap); | 172 | + dev->state = xkb_state_new(dev->input->keymap); |
| 181 | + if (!dev->state) { | 173 | + if (!dev->state) { |
| @@ -224,6 +216,3 @@ index 925c755..4760972 100644 | |||
| 224 | int uxkb_dev_init(struct uterm_input_dev *dev) | 216 | int uxkb_dev_init(struct uterm_input_dev *dev) |
| 225 | { | 217 | { |
| 226 | int ret; | 218 | int ret; |
| 227 | -- | ||
| 228 | 2.17.1 | ||
| 229 | |||
