>From 68fc18d2816e3997f38d0a3c69566d85b26c8719 Mon Sep 17 00:00:00 2001 From: Florian Pelz Date: Wed, 8 Apr 2020 11:46:16 +0200 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [PATCH] installer: Allow Alt+Shift toggle from non-Latin keyboard layouts. Fixes . * gnu/installer/newt/keymap.scm (%non-latin-layouts): New variable. (toggleable-latin-layout): New procedure to compute combined layouts. (run-keymap-page): Use it. (keyboard-layout->configuration): Apply it in config.scm. * gnu/installer/newt/help.scm (run-help-page): Mention Alt+Shift. * gnu/installer/keymap.scm (kmscon-update-keymap): Pass on XKB options. * gnu/installer/record.scm (): 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. --- gnu/installer.scm | 14 ++++--- gnu/installer/keymap.scm | 8 +++- gnu/installer/newt/help.scm | 5 ++- gnu/installer/newt/keymap.scm | 40 ++++++++++++++++--- gnu/installer/record.scm | 3 +- .../kmscon-runtime-keymap-switch.patch | 27 ++++--------- 6 files changed, 63 insertions(+), 34 deletions(-) diff --git a/gnu/installer.scm b/gnu/installer.scm index 75c5a01570..72b7d195fd 100644 --- a/gnu/installer.scm +++ b/gnu/installer.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2018, 2020 Mathieu Othacehe ;;; Copyright © 2019, 2020 Ludovic Courtès ;;; Copyright © 2019, 2020 Tobias Geerinckx-Rice +;;; Copyright © 2020 Florian Pelz ;;; ;;; This file is part of GNU Guix. ;;; @@ -170,9 +171,9 @@ been performed at build time." (define apply-keymap ;; Apply the specified keymap. Use the default keyboard model. #~(match-lambda - ((layout variant) + ((layout variant options) (kmscon-update-keymap (default-keyboard-model) - layout variant)))) + layout variant options)))) (define* (compute-keymap-step context) "Return a gexp that runs the keymap-page of INSTALLER and install the @@ -235,12 +236,13 @@ selected keymap." ;; The installer runs in a kmscon virtual terminal where loadkeys ;; won't work. kmscon uses libxkbcommon as a backend for keyboard - ;; input. It is possible to update kmscon current keymap by sending it - ;; a keyboard model, layout and variant, in a somehow similar way as - ;; what is done with setxkbmap utility. + ;; input. It is possible to update kmscon current keymap by sending + ;; it a keyboard model, layout, variant and options, in a somehow + ;; similar way as what is done with setxkbmap utility. ;; ;; So ask for a keyboard model, layout and variant to update the - ;; current kmscon keymap. + ;; current kmscon keymap. For non-Latin layouts, we add an + ;; appropriate second layout and toggle via Alt+Shift. (installer-step (id 'keymap) (description (G_ "Keyboard mapping selection")) diff --git a/gnu/installer/keymap.scm b/gnu/installer/keymap.scm index df9fc5e441..d520b782fd 100644 --- a/gnu/installer/keymap.scm +++ b/gnu/installer/keymap.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2018 Mathieu Othacehe +;;; Copyright © 2020 Florian Pelz ;;; ;;; This file is part of GNU Guix. ;;; @@ -154,8 +155,8 @@ Configuration Database, describing possible XKB configurations." ((models layouts) (values models layouts))))) -(define (kmscon-update-keymap model layout variant) - "Update kmscon keymap with the provided MODEL, LAYOUT and VARIANT." +(define (kmscon-update-keymap model layout variant options) + "Update kmscon keymap with the provided MODEL, LAYOUT, VARIANT and OPTIONS." (and=> (getenv "KEYMAP_UPDATE") (lambda (keymap-file) @@ -175,4 +176,7 @@ Configuration Database, describing possible XKB configurations." (put-u8 port 0) (format port variant) + (put-u8 port 0) + + (format port options) (put-u8 port 0)))))) diff --git a/gnu/installer/newt/help.scm b/gnu/installer/newt/help.scm index a488f5fa2a..3ccfaf2e54 100644 --- a/gnu/installer/newt/help.scm +++ b/gnu/installer/newt/help.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2020 Mathieu Othacehe +;;; Copyright © 2020 Florian Pelz ;;; ;;; This file is part of GNU Guix. ;;; @@ -31,7 +32,9 @@ (cons (G_ "Change keyboard layout") keyboard-layout-selection))) (result (run-listbox-selection-page - #:info-text (G_ "This is the help menu, please choose an action.") + #:info-text (G_ "This is the help menu. Here you can change your +keyboard layout. Non-Latin layouts can also be toggled with Alt+Shift. +Please choose an action.") #:title (G_ "Installation help") #:listbox-items items #:listbox-item->text car diff --git a/gnu/installer/newt/keymap.scm b/gnu/installer/newt/keymap.scm index 0147a0b9d5..475ffc2261 100644 --- a/gnu/installer/newt/keymap.scm +++ b/gnu/installer/newt/keymap.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2018, 2020 Mathieu Othacehe ;;; Copyright © 2019 Ludovic Courtès +;;; Copyright © 2020 Florian Pelz ;;; ;;; This file is part of GNU Guix. ;;; @@ -112,10 +113,35 @@ You can switch to different layout at any time from the help menu."))) variants)) (cut append <> <>))) +(define %non-latin-layouts + ;; List of keyboard layouts marked as $nonlatin in xkeyboard-config. + '("am" "ara" "ben" "bd" "bg" "bt" "by" "cs" "deva" "ge" "gh" + "gr" "guj" "guru" "il" "in" "ir" "iku" "jp" "kan" "kh" "kr" + "la" "lao" "lk" "mk" "mm" "mn" "mv" "mal" "olck" "ori" "pk" + "ru" "scc" "sy" "syr" "tel" "th" "tj" "tam" "ua" "uz" + ;; The list from xkeyboard-config is incomplete. Add more layouts when + ;; noticed: + "et")) + +(define (toggleable-latin-layout layout variant) + "If LAYOUT is a non-Latin layout, return a new combined layout, +a variant, and options that allow the user to switch between the +non-Latin and the Latin layout. Otherwise, return LAYOUT, VARIANT, +and the empty string." + (if (member layout %non-latin-layouts) + (let ((latin-layout (if (string=? variant "azerty") "fr" "us"))) + (list + (string-append layout "," latin-layout) + (string-append variant ",") ;comma to use variant only for non-Latin + "grp:alt_shift_toggle")) + (list layout variant ""))) + (define* (run-keymap-page layouts #:key (context #f)) "Run a page asking the user to select a keyboard layout and variant. LAYOUTS -is a list of supported X11-KEYMAP-LAYOUT. Return a list of two elements, the -names of the selected keyboard layout and variant." +is a list of supported X11-KEYMAP-LAYOUT. For non-Latin keyboard layouts, a +second layout and toggle options will be added automatically. Return a list +of three elements, the names of the selected keyboard layout, variant and +options." (define keymap-steps (list (installer-step @@ -151,14 +177,18 @@ names of the selected keyboard layout and variant." (lambda (variant) (gettext (x11-keymap-variant-name variant) "xkeyboard-config"))))) - (list layout (or variant "")))) + (apply toggleable-latin-layout + (list layout (or variant ""))))) (format-result (run-installer-steps #:steps keymap-steps))) (define (keyboard-layout->configuration keymap) "Return the operating system configuration snippet to install KEYMAP." (match keymap - ((name "") + ((name "" "") `((keyboard-layout (keyboard-layout ,name)))) - ((name variant) + ((name variant "grp:alt_shift_toggle") + `((keyboard-layout (keyboard-layout ,name ,variant + #:options '("grp:alt_shift_toggle"))))) + ((name variant _) `((keyboard-layout (keyboard-layout ,name ,variant)))))) diff --git a/gnu/installer/record.scm b/gnu/installer/record.scm index 78acf50c63..13acd33fc6 100644 --- a/gnu/installer/record.scm +++ b/gnu/installer/record.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2018, 2020 Mathieu Othacehe +;;; Copyright © 2020 Florian Pelz ;;; ;;; This file is part of GNU Guix. ;;; @@ -63,7 +64,7 @@ (exit-error installer-exit-error) ;; procedure void -> void (final-page installer-final-page) - ;; procedure (layouts context) -> (list layout variant) + ;; procedure (layouts context) -> (list layout variant options) (keymap-page installer-keymap-page) ;; procedure: (#:key supported-locales iso639-languages iso3166-territories) ;; -> glibc-locale diff --git a/gnu/packages/patches/kmscon-runtime-keymap-switch.patch b/gnu/packages/patches/kmscon-runtime-keymap-switch.patch index 656c76fa40..deb5688daf 100644 --- a/gnu/packages/patches/kmscon-runtime-keymap-switch.patch +++ b/gnu/packages/patches/kmscon-runtime-keymap-switch.patch @@ -1,14 +1,5 @@ -From 360d44d67e7be46108bec982ff2e79b89f04a9a3 Mon Sep 17 00:00:00 2001 -From: Mathieu Othacehe -Date: Thu, 15 Nov 2018 14:34:40 +0900 -Subject: [PATCH] add runtime keymap switch support. - ---- - src/pty.c | 23 ++++++++++- - src/uterm_input.c | 2 + - src/uterm_input_internal.h | 5 +++ - src/uterm_input_uxkb.c | 83 ++++++++++++++++++++++++++++++++++++++ - 4 files changed, 111 insertions(+), 2 deletions(-) +By Mathieu Othacehe . +Modified by Florian Pelz . diff --git a/src/pty.c b/src/pty.c index 1443f4a..f64cb5b 100644 @@ -124,7 +115,7 @@ index 04e6cc9..ec44459 100644 uint16_t key_state, uint16_t code); diff --git a/src/uterm_input_uxkb.c b/src/uterm_input_uxkb.c -index 925c755..4760972 100644 +index 925c755..5d5c22e 100644 --- a/src/uterm_input_uxkb.c +++ b/src/uterm_input_uxkb.c @@ -31,6 +31,9 @@ @@ -137,7 +128,7 @@ index 925c755..4760972 100644 #include #include "shl_hook.h" #include "shl_llog.h" -@@ -178,6 +181,86 @@ static void timer_event(struct ev_timer *timer, uint64_t num, void *data) +@@ -178,6 +181,87 @@ static void timer_event(struct ev_timer *timer, uint64_t num, void *data) shl_hook_call(dev->input->hook, dev->input, &dev->repeat_event); } @@ -145,11 +136,11 @@ index 925c755..4760972 100644 +{ + struct uterm_input_dev *dev = data; + char in; -+ char keymap[3][255]; ++ char keymap[4][255]; + int pos = 0; + int curr_keymap = 0; + int ret; -+ char *model, *layout, *variant; ++ char *model, *layout, *variant, *options; + + if (!(mask & EV_READABLE)) + return; @@ -159,6 +150,7 @@ index 925c755..4760972 100644 + model = keymap[0]; + layout = keymap[1]; + variant = keymap[2]; ++ options = keymap[3]; + + do { + ret = read(dev->rupdate_fd, &in, sizeof(in)); @@ -175,7 +167,7 @@ index 925c755..4760972 100644 + + llog_info(dev->input, "HANDLER CALLED %s|%s|%s\n", + model, layout, variant); -+ uxkb_desc_init(dev->input, model, layout, variant, NULL, NULL); ++ uxkb_desc_init(dev->input, model, layout, variant, options, NULL); + + dev->state = xkb_state_new(dev->input->keymap); + if (!dev->state) { @@ -224,6 +216,3 @@ index 925c755..4760972 100644 int uxkb_dev_init(struct uterm_input_dev *dev) { int ret; --- -2.17.1 - -- 2.26.0