diff --git a/src/locale/localed-util.c b/src/locale/localed-util.c index 02fac9786b..eba13a2ac3 100644 --- a/src/locale/localed-util.c +++ b/src/locale/localed-util.c @@ -803,21 +803,35 @@ int find_legacy_keymap(const X11Context *xc, char **ret) { /* If we got an exact match, this is the best */ matching = 10; else { - /* We have multiple X layouts, look for an - * entry that matches our key with everything - * but the first layout stripped off. */ - if (startswith_comma(xc->layout, a[1])) - matching = 5; + /* see if we get an exact match with the order reversed */ + _cleanup_strv_free_ char **b = NULL; + _cleanup_free_ char *c = NULL; + r = strv_split_full(&b, a[1], ",", 0); + if (r < 0) + return r; + strv_reverse(b); + c = strv_join(b, ","); + if (!c) + return log_oom(); + if (streq(xc->layout, c)) + matching = 9; else { - _cleanup_free_ char *x = NULL; + /* We have multiple X layouts, look for an + * entry that matches our key with everything + * but the first layout stripped off. */ + if (startswith_comma(xc->layout, a[1])) + matching = 5; + else { + _cleanup_free_ char *x = NULL; - /* If that didn't work, strip off the - * other layouts from the entry, too */ - x = strdupcspn(a[1], ","); - if (!x) - return -ENOMEM; - if (startswith_comma(xc->layout, x)) - matching = 1; + /* If that didn't work, strip off the + * other layouts from the entry, too */ + x = strdupcspn(a[1], ","); + if (!x) + return -ENOMEM; + if (startswith_comma(xc->layout, x)) + matching = 1; + } } } @@ -825,7 +839,7 @@ int find_legacy_keymap(const X11Context *xc, char **ret) { if (isempty(xc->model) || streq_ptr(xc->model, a[2])) { matching++; - if (streq_ptr(xc->variant, a[3])) { + if (streq_ptr(xc->variant, a[3]) || (isempty(xc->variant) && streq(a[3], "-"))) { matching++; if (streq_ptr(xc->options, a[4])) @@ -848,7 +862,7 @@ int find_legacy_keymap(const X11Context *xc, char **ret) { } } - if (best_matching < 10 && !isempty(xc->layout)) { + if (best_matching < 9 && !isempty(xc->layout)) { _cleanup_free_ char *l = NULL, *v = NULL, *converted = NULL; /* The best match is only the first part of the X11 diff --git a/src/locale/test-localed-util.c b/src/locale/test-localed-util.c index cb66dffd48..f702ff29b0 100644 --- a/src/locale/test-localed-util.c +++ b/src/locale/test-localed-util.c @@ -173,6 +173,18 @@ TEST(x11_convert_to_vconsole) { assert_se(streq(vc.keymap, "es-dvorak")); vc_context_clear(&vc); + /* es no-variant test is not very good as the desired match + comes first in the list so will win if both candidates score + the same. in this case the desired match comes second so will + not win unless we correctly give the no-variant match a bonus + */ + log_info("/* test without variant, desired match second (bg,us:) */"); + assert_se(free_and_strdup(&xc.layout, "bg,us") >= 0); + assert_se(free_and_strdup(&xc.variant, NULL) >= 0); + assert_se(x11_convert_to_vconsole(&xc, &vc) >= 0); + assert_se(streq(vc.keymap, "bg_bds-utf8")); + vc_context_clear(&vc); + log_info("/* test with old mapping (fr:latin9) */"); assert_se(free_and_strdup(&xc.layout, "fr") >= 0); assert_se(free_and_strdup(&xc.variant, "latin9") >= 0); @@ -180,11 +192,14 @@ TEST(x11_convert_to_vconsole) { assert_se(streq(vc.keymap, "fr-latin9")); vc_context_clear(&vc); + /* https://bugzilla.redhat.com/show_bug.cgi?id=1039185 */ + /* us,ru is the x config users want, but they still want ru + as the console layout in this case */ log_info("/* test with a compound mapping (us,ru:) */"); assert_se(free_and_strdup(&xc.layout, "us,ru") >= 0); assert_se(free_and_strdup(&xc.variant, NULL) >= 0); assert_se(x11_convert_to_vconsole(&xc, &vc) >= 0); - assert_se(streq(vc.keymap, "us")); + assert_se(streq(vc.keymap, "ru")); vc_context_clear(&vc); log_info("/* test with a compound mapping (ru,us:) */");