Nixpkgs: gdm does not follow the xserver keymap attributes

Created on 30 Mar 2016  ·  25Comments  ·  Source: NixOS/nixpkgs

  • System: nixos-unstable
  • Nix version: 1.11.2

After setting up the xserver like the following

services.xserver.enable = true;
services.xserver.layout = "us";
services.xserver.xkbVariant = "colemak";

And running nixos-rebuild switch && reboot, GDM is still using the US Querty layout, while it should be using Colemak instead.

bug GNOME nixos

Most helpful comment

I kinda found a way to fix this.

From what I read, it seems that gdm honors systemd-localed (localectl) for the keyboard layout.

My hacky module, once imported and enabled from a configuration file, creates /etc/X11/xorg.conf.d/00-keyboard.conf based on the services.xserver.layout and services.xserver.xkb{Model, Layout, Options} params. 00-keyboard.conf is the file in which localectl creates and reads the keyboards settings.

{ config, lib, pkgs, ... }:

with lib;
let
  cfg = config.services.xserver;
  fcfg = cfg.localectlFix;
in {
  options.services.xserver.localectlFix = 
    { enable = mkEnableOption "Enables localectl fix.";
    };

  config = mkIf fcfg.enable {
    environment.etc = mkAssert cfg.enable ''
      X11 must be enabled for the fix to work.
    '' { "X11/xorg.conf.d/00-keyboard.conf".text = ''
          Section "InputClass"
            Identifier "Keyboard catchall"
            MatchIsKeyboard "on"
            Option "XkbRules" "base"
            Option "XkbModel" "${cfg.xkbModel}"
            Option "XkbLayout" "${cfg.layout}"
            Option "XkbOptions" "${cfg.xkbOptions}"
            Option "XkbVariant" "${cfg.xkbVariant}"
          EndSection
        '';
       };
  };
}

That seems to do the trick. The layout has changed (for me) in gdm and in localectl.

~ ❯❯❯ localectl
   System Locale: LANG=fr_CA.UTF-8
       VC Keymap: cf
      X11 Layout: ca
       X11 Model: pc104
     X11 Options: terminate:ctrl_alt_bksp

One way to fix this issue would be to implement this in nixos/modules/services/x11/display-managers/gdm.nix. Unfortunately, I did not find yet another (and more graceful) way to change this without relaying on a file created in /etc/X11/xorg.conf.d/.

All 25 comments

/cc @jgeerds @lethalman

I think this is a gnome thing at all. You should change your keyboard settings within gnome settings, because they're overridden.

Actually, about gdm I think we can probably change it in the gdm config generated by nixos, yes.

@lethalman I changed the keyboard settings on GNOME, but that only works _after_ I login.

@lethalman do you have an idea how to write an automated test that checks if the problem is fixed?

I may have found something.

$ systemctl status display-manager.service
● display-manager.service - X11 Server
   [...]
 Main PID: 748 (gdm)
   CGroup: /system.slice/display-manager.service
           ├─748 /nix/store/5wdv9jy03jibradd3bb678qhm0cp4l9a-gdm-3.14.2/bin/gdm

When looking at the path above, there is an etc/gdm/Xsession file with this content:

$ cat /nix/store/5wdv9jy03jibradd3bb678qhm0cp4l9a-gdm-3.14.2/etc/gdm/Xsession
[...]
sysresources=/etc/X11/Xresources 
sysmodmap=/etc/X11/Xmodmap 
sysxkbmap=/etc/X11/Xkbmap

rh6sysresources=/etc/X11/xinit/Xresources 
rh6sysmodmap=/etc/X11/xinit/Xmodmap 
[...]
if [ -z "$XKB_IN_USE" -a ! -L /etc/X11/X ]; then
    if grep '^exec.*/Xsun' /etc/X11/X > /dev/null 2>&1 && [ -f /etc/X11/XF86Config ]; then
       xkbsymbols=`sed -n -e 's/^[     ]*XkbSymbols[   ]*"\(.*\)".*$/\1/p' /etc/X11/XF86Config`
       if [ -n "$xkbsymbols" ]; then
           setxkbmap -symbols "$xkbsymbols"
           XKB_IN_USE=yes
       fi
    fi
fi
[...]

all these references to /etc/X11 are broken. Does it make sense to try to fix those?

Probable, I don't remember if I stopped gdm from using that file or not.

Damien Cassou [email protected] writes:

all these references to /etc/X11 are broken. Does it make sense to
try to fix those?

That's what I found as well, and fixing these links might fix the issue,
at least I think it's worth a try.

@NicolasPetton please pass true to services.xserver.gdm.debug

There is an explicit reference to /etc in gnome3-18/gdm/default.nix:

  configureFlags = [ "--sysconfdir=/etc"  "--localstatedir=/var"

@DamienCassou yes that sysconfdir=/etc needed for tweaking the gdm config.

Maybe it's related to the X11 layout?

$ localectl status
   System Locale: LANG=en_US.UTF-8
       VC Keymap: dvp
      X11 Layout: n/a

I guess this is what broke gdm for me. I tried switching from kdm, but was unable to login due to a bad password. My password contains characters that are impossible to enter on a us keyboard.
Logging into the console worked fine. Since gdm does not offer an obvious way to change the keyboard layout it seems to be badly broken.

$ localectl 
   System Locale: LANG=de_DE.UTF-8
       VC Keymap: de-latin1
      X11 Layout: n/a
$ nixos-option services.xserver.layout
Value:
"de"

Just wondering if there is any updates on this issue; I am experiencing it as well on 16.09.

Setting services.xserver.layout = "us"; services.xserver.xkbVariant = "altgr-intl"; in configuration.nix, it seems that xserver.conf builds correctly:

Section "InputClass"
  Identifier "Keyboard catchall"
  MatchIsKeyboard "on"
  Option "XkbRules" "base"
  Option "XkbModel" "pc104"
  Option "XkbLayout" "us"
  Option "XkbOptions" "eurosign:e"
  Option "XkbVariant" "altgr-intl"
EndSection

And yet setxkbmap -query -verbose 10 yields:

Setting verbose level to 10
locale is C
Trying to load rules file ./rules/evdev...
Trying to load rules file /nix/store/iabz2rjpykza4w57xl1rbq7663xq9gz0-setxkbmap-1.3.1/share/X11/xkb/rules/evdev...
Success.
Applied rules from evdev:
rules:      evdev
model:      pc104
layout:     us,us
variant:    ,
Trying to build keymap using the following components:
keycodes:   evdev+aliases(qwerty)
types:      complete
compat:     complete
symbols:    pc+us+us:2+inet(evdev)
geometry:   pc(pc104)
rules:      evdev
model:      pc104
layout:     us,us
variant:    ,

and localectl yields:

System Locale: LANG=en_US.UTF-8
      VC Keymap: us
      X11 Layout: n/a

I was gonna ask if this should be labeled as an xserver issue but apparently there is no label for that >.<

@DamienCassou @lethalman @NicolasPetton @edolstra ?

Both @NicolasPetton and me are not using NixOS anymore.

I kinda found a way to fix this.

From what I read, it seems that gdm honors systemd-localed (localectl) for the keyboard layout.

My hacky module, once imported and enabled from a configuration file, creates /etc/X11/xorg.conf.d/00-keyboard.conf based on the services.xserver.layout and services.xserver.xkb{Model, Layout, Options} params. 00-keyboard.conf is the file in which localectl creates and reads the keyboards settings.

{ config, lib, pkgs, ... }:

with lib;
let
  cfg = config.services.xserver;
  fcfg = cfg.localectlFix;
in {
  options.services.xserver.localectlFix = 
    { enable = mkEnableOption "Enables localectl fix.";
    };

  config = mkIf fcfg.enable {
    environment.etc = mkAssert cfg.enable ''
      X11 must be enabled for the fix to work.
    '' { "X11/xorg.conf.d/00-keyboard.conf".text = ''
          Section "InputClass"
            Identifier "Keyboard catchall"
            MatchIsKeyboard "on"
            Option "XkbRules" "base"
            Option "XkbModel" "${cfg.xkbModel}"
            Option "XkbLayout" "${cfg.layout}"
            Option "XkbOptions" "${cfg.xkbOptions}"
            Option "XkbVariant" "${cfg.xkbVariant}"
          EndSection
        '';
       };
  };
}

That seems to do the trick. The layout has changed (for me) in gdm and in localectl.

~ ❯❯❯ localectl
   System Locale: LANG=fr_CA.UTF-8
       VC Keymap: cf
      X11 Layout: ca
       X11 Model: pc104
     X11 Options: terminate:ctrl_alt_bksp

One way to fix this issue would be to implement this in nixos/modules/services/x11/display-managers/gdm.nix. Unfortunately, I did not find yet another (and more graceful) way to change this without relaying on a file created in /etc/X11/xorg.conf.d/.

Can't we just unconditionally create the file if X is enabled in nixos/modules/services/x11/xserver.nix?

Yes. It could be.

But, as it is a hack more than anything, I'm hesitant to create it for every user who enables X11. Even if I copy/pasted the configuration section from nixos/modules/services/x11/xserver.nix, I don't know if it could clash or make things more unstable for other users/apps.

And I am new to Nix and NixOS, so I'm still learning best practices. One thing for sure, it would be better to store the created .conf to the nix store before linking it to /etc/X11/xorg.conf.d/.

I can confirm that @adamscott's patch in https://github.com/NixOS/nixpkgs/issues/14318#issuecomment-309250231 fixes the output of localectl status. Unfortunately, it does not fix the output of setxkbmap

$ setxkbmap -query -verbose 10
Setting verbose level to 10
locale is C
Trying to load rules file ./rules/evdev...
Trying to load rules file /nix/store/b4kbwp332jfr8f1169xdn7h9nh7n3px5-setxkbmap-1.3.1/share/X11/xkb/rules/evdev...
Success.
Applied rules from evdev:
rules:      evdev
model:      pc104
layout:     us,us
variant:    ,
Trying to build keymap using the following components:
keycodes:   evdev+aliases(qwerty)
types:      complete
compat:     complete
symbols:    pc+us+us:2+inet(evdev)
geometry:   pc(pc104)
rules:      evdev
model:      pc104
layout:     us,us
variant:    ,

$ localectl status
   System Locale: LANG=en_US.UTF-8
       VC Keymap: emacs2
      X11 Layout: us
       X11 Model: pc104
     X11 Options: ctrl:nocaps

And capslock is not mapped to control in Gnome.

Would this work?

{services.xserver.desktopManager.gnome3.extraGSettingsOverrides = ''
  [org.gnome.desktop.input-sources]
  sources=[('xkb', 'cz+qwerty')]
  xkb-options=['compose:caps']
'';}

Would this work?

{services.xserver.desktopManager.gnome3.extraGSettingsOverrides = ''
  [org.gnome.desktop.input-sources]
  sources=[('xkb', 'cz+qwerty')]
  xkb-options=['compose:caps']
'';}

Doesn't work for me.

Putting the code from https://github.com/NixOS/nixpkgs/issues/14318#issuecomment-309250231 into a .nix file, importing that from /etc/nixos/configuration.nix and setting services.xserver.localectlFix.enable = true there does work for me though.

With the latest nixos-unstable, the GSettings override should be sufficient. The Xorg config, on the other hand will be harmful: https://github.com/NixOS/nixpkgs/issues/32195

Fixed in #32203

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Infinisil picture Infinisil  ·  146Comments

samueldr picture samueldr  ·  88Comments

globin picture globin  ·  65Comments

fdietze picture fdietze  ·  144Comments

tfc picture tfc  ·  68Comments