Adam Williamson 18e1ed
From cf649cc21bf997b90606db664d74726fcaf002de Mon Sep 17 00:00:00 2001
Adam Williamson 18e1ed
From: Adam Williamson <awilliam@redhat.com>
Adam Williamson 18e1ed
Date: Fri, 15 Sep 2023 16:02:29 -0700
Adam Williamson 18e1ed
Subject: [PATCH 2/2] find_legacy_keymap: try matching with layout order
Adam Williamson 18e1ed
 reversed
Adam Williamson 18e1ed
Adam Williamson 18e1ed
The lines in kbd-model-map date back to ye olde times (RH's old
Adam Williamson 18e1ed
system-config-keyboard), and I think predate this bug:
Adam Williamson 18e1ed
Adam Williamson 18e1ed
https://bugzilla.redhat.com/show_bug.cgi?id=1039185
Adam Williamson 18e1ed
Adam Williamson 18e1ed
where we got strong feedback that, for 'switched' layout setups
Adam Williamson 18e1ed
like Russian, US English should be the *first* layout and the
Adam Williamson 18e1ed
native layout the *second* one. This is how anaconda and, as of
Adam Williamson 18e1ed
recently, gnome-initial-setup configure such cases - but that
Adam Williamson 18e1ed
means, if we try to use localed to convert these configurations
Adam Williamson 18e1ed
using kbd-model-map, we get the wrong result (we get "us" as the
Adam Williamson 18e1ed
console layout). See also:
Adam Williamson 18e1ed
Adam Williamson 18e1ed
https://bugzilla.redhat.com/show_bug.cgi?id=1912609
Adam Williamson 18e1ed
Adam Williamson 18e1ed
where we first noticed this wasn't working right, but sadly, we
Adam Williamson 18e1ed
'fixed' it with a not-really-correct bodge in anaconda instead
Adam Williamson 18e1ed
of doing it properly.
Adam Williamson 18e1ed
Adam Williamson 18e1ed
Signed-off-by: Adam Williamson <awilliam@redhat.com>
Adam Williamson 18e1ed
---
Adam Williamson 18e1ed
 src/locale/localed-util.c      | 44 ++++++++++++++++++++++------------
Adam Williamson 18e1ed
 src/locale/test-localed-util.c |  5 +++-
Adam Williamson 18e1ed
 2 files changed, 33 insertions(+), 16 deletions(-)
Adam Williamson 18e1ed
Adam Williamson 18e1ed
diff --git a/src/locale/localed-util.c b/src/locale/localed-util.c
Adam Williamson 18e1ed
index 6a05b50a31..eba13a2ac3 100644
Adam Williamson 18e1ed
--- a/src/locale/localed-util.c
Adam Williamson 18e1ed
+++ b/src/locale/localed-util.c
Adam Williamson 18e1ed
@@ -803,21 +803,35 @@ int find_legacy_keymap(const X11Context *xc, char **ret) {
Adam Williamson 18e1ed
                         /* If we got an exact match, this is the best */
Adam Williamson 18e1ed
                         matching = 10;
Adam Williamson 18e1ed
                 else {
Adam Williamson 18e1ed
-                        /* We have multiple X layouts, look for an
Adam Williamson 18e1ed
-                         * entry that matches our key with everything
Adam Williamson 18e1ed
-                         * but the first layout stripped off. */
Adam Williamson 18e1ed
-                        if (startswith_comma(xc->layout, a[1]))
Adam Williamson 18e1ed
-                                matching = 5;
Adam Williamson 18e1ed
+                        /* see if we get an exact match with the order reversed */
Adam Williamson 18e1ed
+                        _cleanup_strv_free_ char **b = NULL;
Adam Williamson 18e1ed
+                        _cleanup_free_ char *c = NULL;
Adam Williamson 18e1ed
+                        r = strv_split_full(&b, a[1], ",", 0);
Adam Williamson 18e1ed
+                        if (r < 0)
Adam Williamson 18e1ed
+                                return r;
Adam Williamson 18e1ed
+                        strv_reverse(b);
Adam Williamson 18e1ed
+                        c = strv_join(b, ",");
Adam Williamson 18e1ed
+                        if (!c)
Adam Williamson 18e1ed
+                                return log_oom();
Adam Williamson 18e1ed
+                        if (streq(xc->layout, c))
Adam Williamson 18e1ed
+                                matching = 9;
Adam Williamson 18e1ed
                         else {
Adam Williamson 18e1ed
-                                _cleanup_free_ char *x = NULL;
Adam Williamson 18e1ed
-
Adam Williamson 18e1ed
-                                /* If that didn't work, strip off the
Adam Williamson 18e1ed
-                                 * other layouts from the entry, too */
Adam Williamson 18e1ed
-                                x = strdupcspn(a[1], ",");
Adam Williamson 18e1ed
-                                if (!x)
Adam Williamson 18e1ed
-                                        return -ENOMEM;
Adam Williamson 18e1ed
-                                if (startswith_comma(xc->layout, x))
Adam Williamson 18e1ed
-                                        matching = 1;
Adam Williamson 18e1ed
+                                /* We have multiple X layouts, look for an
Adam Williamson 18e1ed
+                                 * entry that matches our key with everything
Adam Williamson 18e1ed
+                                 * but the first layout stripped off. */
Adam Williamson 18e1ed
+                                if (startswith_comma(xc->layout, a[1]))
Adam Williamson 18e1ed
+                                        matching = 5;
Adam Williamson 18e1ed
+                                else {
Adam Williamson 18e1ed
+                                        _cleanup_free_ char *x = NULL;
Adam Williamson 18e1ed
+
Adam Williamson 18e1ed
+                                        /* If that didn't work, strip off the
Adam Williamson 18e1ed
+                                         * other layouts from the entry, too */
Adam Williamson 18e1ed
+                                        x = strdupcspn(a[1], ",");
Adam Williamson 18e1ed
+                                        if (!x)
Adam Williamson 18e1ed
+                                                return -ENOMEM;
Adam Williamson 18e1ed
+                                        if (startswith_comma(xc->layout, x))
Adam Williamson 18e1ed
+                                                matching = 1;
Adam Williamson 18e1ed
+                                }
Adam Williamson 18e1ed
                         }
Adam Williamson 18e1ed
                 }
Adam Williamson 18e1ed
 
Adam Williamson 18e1ed
@@ -848,7 +862,7 @@ int find_legacy_keymap(const X11Context *xc, char **ret) {
Adam Williamson 18e1ed
                 }
Adam Williamson 18e1ed
         }
Adam Williamson 18e1ed
 
Adam Williamson 18e1ed
-        if (best_matching < 10 && !isempty(xc->layout)) {
Adam Williamson 18e1ed
+        if (best_matching < 9 && !isempty(xc->layout)) {
Adam Williamson 18e1ed
                 _cleanup_free_ char *l = NULL, *v = NULL, *converted = NULL;
Adam Williamson 18e1ed
 
Adam Williamson 18e1ed
                 /* The best match is only the first part of the X11
Adam Williamson 18e1ed
diff --git a/src/locale/test-localed-util.c b/src/locale/test-localed-util.c
Adam Williamson 18e1ed
index a19d80a967..f702ff29b0 100644
Adam Williamson 18e1ed
--- a/src/locale/test-localed-util.c
Adam Williamson 18e1ed
+++ b/src/locale/test-localed-util.c
Adam Williamson 18e1ed
@@ -192,11 +192,14 @@ TEST(x11_convert_to_vconsole) {
Adam Williamson 18e1ed
         assert_se(streq(vc.keymap, "fr-latin9"));
Adam Williamson 18e1ed
         vc_context_clear(&vc);
Adam Williamson 18e1ed
 
Adam Williamson 18e1ed
+        /* https://bugzilla.redhat.com/show_bug.cgi?id=1039185 */
Adam Williamson 18e1ed
+        /* us,ru is the x config users want, but they still want ru
Adam Williamson 18e1ed
+        as the console layout in this case */
Adam Williamson 18e1ed
         log_info("/* test with a compound mapping (us,ru:) */");
Adam Williamson 18e1ed
         assert_se(free_and_strdup(&xc.layout, "us,ru") >= 0);
Adam Williamson 18e1ed
         assert_se(free_and_strdup(&xc.variant, NULL) >= 0);
Adam Williamson 18e1ed
         assert_se(x11_convert_to_vconsole(&xc, &vc) >= 0);
Adam Williamson 18e1ed
-        assert_se(streq(vc.keymap, "us"));
Adam Williamson 18e1ed
+        assert_se(streq(vc.keymap, "ru"));
Adam Williamson 18e1ed
         vc_context_clear(&vc);
Adam Williamson 18e1ed
 
Adam Williamson 18e1ed
         log_info("/* test with a compound mapping (ru,us:) */");
Adam Williamson 18e1ed
-- 
Adam Williamson 18e1ed
2.41.0
Adam Williamson 18e1ed