diff options
author | aszlig <aszlig@redmoonstudios.org> | 2017-07-28 12:36:48 +0200 |
---|---|---|
committer | aszlig <aszlig@redmoonstudios.org> | 2017-07-28 12:39:55 +0200 |
commit | 6e5d2f896365fa6737d0c336b7edbc6b6a15fcb9 (patch) | |
tree | 62521cd04d1462265a166bc1aa9e0c631f76de2d /nixos/modules | |
parent | 805467bb5a03db607145dd7aae2ef08e1c1ee746 (diff) | |
download | nixlib-6e5d2f896365fa6737d0c336b7edbc6b6a15fcb9.tar nixlib-6e5d2f896365fa6737d0c336b7edbc6b6a15fcb9.tar.gz nixlib-6e5d2f896365fa6737d0c336b7edbc6b6a15fcb9.tar.bz2 nixlib-6e5d2f896365fa6737d0c336b7edbc6b6a15fcb9.tar.lz nixlib-6e5d2f896365fa6737d0c336b7edbc6b6a15fcb9.tar.xz nixlib-6e5d2f896365fa6737d0c336b7edbc6b6a15fcb9.tar.zst nixlib-6e5d2f896365fa6737d0c336b7edbc6b6a15fcb9.zip |
nixos/xserver: Properly validate XKB options
Checking the keyboard layout has been a long set of hurdles so far, with several attempts. Originally, the checking was introduced by @lheckemann in #23709. The initial implementation just was trying to check whether the symbols/ directory contained the layout name. Unfortunately, that wasn't enough and keyboard variants weren't recognized, so if you set layout to eg. "dvorak" it will fail with an error (#25526). So my improvement on that was to use sed to filter rules/base.lst and match the layout against that. I fucked up twice with this, first because layout can be a comma-separated list which I didn't account for and second because I ran into a Nix issue (NixOS/nix#1426). After fixing this, it still wasn't enough (and this is btw. what localectl also does), because we were *only* matching rules but not symbols, so using "eu" as a layout won't work either. I decided now it's the time to actually use libxkbcommon to try compiling the keyboard options and see whether it succeeds. This comes in the form of a helper tool called xkbvalidate. IMHO this approach is a lot less error-prone and we can be sure that we don't forget about anything because that's what the X server itself uses to compile the keymap. Another advantage of this is that we now validate the full set of XKB options rather than just the layout. Tested this against a variety of wrong and correct keyboard configurations and against the "keymap" NixOS VM tests. Signed-off-by: aszlig <aszlig@redmoonstudios.org> Cc: @lheckemann, @peti, @7c6f434c, @tohl, @vcunat, @lluchs Fixes: #27597
Diffstat (limited to 'nixos/modules')
-rw-r--r-- | nixos/modules/services/x11/xserver.nix | 48 |
1 files changed, 4 insertions, 44 deletions
diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index 638509e710be..3ce124d3da27 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -648,51 +648,11 @@ in services.xserver.xkbDir = mkDefault "${pkgs.xkeyboard_config}/etc/X11/xkb"; - system.extraDependencies = singleton (pkgs.runCommand "xkb-layouts-exist" { - inherit (cfg) layout xkbDir; + system.extraDependencies = singleton (pkgs.runCommand "xkb-validated" { + inherit (cfg) xkbModel layout xkbVariant xkbOptions; + nativeBuildInputs = [ pkgs.xkbvalidate ]; } '' - # We can use the default IFS here, because the layouts won't contain - # spaces or tabs and are ruled out by the sed expression below. - availableLayouts="$( - sed -n -e ':i /^! \(layout\|variant\) *$/ { - # Loop through all of the layouts/variants until we hit another ! at - # the start of the line or the line is empty ('t' branches only if - # the last substitution was successful, so if the line is empty the - # substition will fail). - :l; n; /^!/bi; s/^ *\([^ ]\+\).*/\1/p; tl - }' "$xkbDir/rules/base.lst" | sort -u - )" - - layoutNotFound() { - echo >&2 - echo "The following layouts and variants are available:" >&2 - echo >&2 - - # While an output width of 80 is more desirable for small terminals, we - # really don't know the amount of columns of the terminal from within - # the builder. The content in $availableLayouts however is pretty - # large, so let's opt for a larger width here, because it will print a - # smaller amount of lines on modern KMS/framebuffer terminals and won't - # lose information even in smaller terminals (it only will look a bit - # ugly). - echo "$availableLayouts" | ${pkgs.utillinux}/bin/column -c 150 >&2 - - echo >&2 - echo "However, the keyboard layout definition in" \ - "\`services.xserver.layout' contains the layout \`$1', which" \ - "isn't a valid layout or variant." >&2 - echo >&2 - exit 1 - } - - # Again, we don't need to take care of IFS, see the comment for - # $availableLayouts. - for l in ''${layout//,/ }; do - if ! echo "$availableLayouts" | grep -qxF "$l"; then - layoutNotFound "$l" - fi - done - + validate "$xkbModel" "$layout" "$xkbVariant" "$xkbOptions" touch "$out" ''); |