Nixpkgs: Volume control with media keys not working for regular user account.

Created on 24 Mar 2017  路  5Comments  路  Source: NixOS/nixpkgs

Issue description

As per the title, relevant portion of my /etc/nixos/configuration.nix:

  hardware.pulseaudio.enable = true;
  sound.mediaKeys = {
    enable = true;
    volumeStep = "5%";
  };
  services.actkbd = {
      enable = true;
      bindings = [
        # "Mute" media key
        { keys = [ 121 ]; events = [ "key" ]; command = "${pkgs.alsaUtils}/bin/amixer -q set Master toggle"; }

        # "Lower Volume" media key
        { keys = [ 122 ]; events = [ "key" "rep" ]; command = "${pkgs.alsaUtils}/bin/amixer -q set Master ${config.sound.mediaKeys.volumeStep}- unmute"; }

        # "Raise Volume" media key
        { keys = [ 123 ]; events = [ "key" "rep" ]; command = "${pkgs.alsaUtils}/bin/amixer -q set Master ${config.sound.mediaKeys.volumeStep}+ unmute"; }

      ];
  };

I had to remap the bindings as the defaults don't seem to match the keycodes on my laptop.

Stracing actk daemon shows it registering key presses and invoking the commands however it seems that amixer tries to connect to the pulseaudio deamon of root user rather the one spawned for my user's account, abbreviated output below:

...
15669 execve("/bin/sh", ["sh", "-c", "/nix/store/0ypf142hl80ck2hqpdlmzm0hpk6jr004-alsa-utils-1.1.0/bin/amixer -q set Master toggle"], [/* 5 vars */]) = 0
...
15669 open("/root/.pulse/client.conf", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
15669 open("/root/.config/pulse/client.conf", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
15669 open("/etc/pulse/client.conf", O_RDONLY|O_CLOEXEC) = 8
...
15669 open("/root/.config/pulse", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = 9
...
15669 readlink("/root/.config/pulse/408420942f8e44ff92b2caf19dc075b1-runtime", "/tmp/pulse-PKdhtXMmr18n", 99) = 23
15669 lstat("/root", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
15669 lstat("/root/.config", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
15669 lstat("/root/.config/pulse", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
15669 lstat("/root/.config/pulse/408420942f8e44ff92b2caf19dc075b1-runtime", {st_mode=S_IFLNK|0777, st_size=23, ...}) = 0
15669 readlink("/root/.config/pulse/408420942f8e44ff92b2caf19dc075b1-runtime", "/tmp/pulse-PKdhtXMmr18n", 4095) = 23
15669 lstat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=4096, ...}) = 0
15669 lstat("/tmp/pulse-PKdhtXMmr18n", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
15669 getuid()                          = 0
15669 socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 9
15669 fcntl(9, F_GETFD)                 = 0x1 (flags FD_CLOEXEC)
15669 setsockopt(9, SOL_SOCKET, SO_PRIORITY, [6], 4) = 0
15669 fcntl(9, F_GETFL)                 = 0x2 (flags O_RDWR)
15669 fcntl(9, F_SETFL, O_RDWR|O_NONBLOCK) = 0
15669 connect(9, {sa_family=AF_UNIX, sun_path="/tmp/pulse-PKdhtXMmr18n/native"}, 110) = -1 ENOENT (No such file or directory)
15669 close(9)                          = 0
15669 socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 9
15669 fcntl(9, F_GETFD)                 = 0x1 (flags FD_CLOEXEC)
15669 setsockopt(9, SOL_SOCKET, SO_PRIORITY, [6], 4) = 0
15669 fcntl(9, F_GETFL)                 = 0x2 (flags O_RDWR)
15669 fcntl(9, F_SETFL, O_RDWR|O_NONBLOCK) = 0
15669 connect(9, {sa_family=AF_UNIX, sun_path="/var/run/pulse/native"}, 110) = -1 ENOENT (No such file or directory)
15669 close(9)                          = 0
15669 write(5, "x", 1)                  = 1
15669 write(2, "ALSA lib pulse.c:243:(pulse_connect) ", 37) = 37
15669 write(2, "PulseAudio: Unable to connect: Connection refused\n", 50) = 50

I guess this makes sense given actk runs as root user. Are there any known workarounds or perhaps there is something wrong with my configuration?

Technical details

question nixos

Most helpful comment

I hit the same wall as you. This is how I solved it:

  services.actkbd = {
    enable = true;
    bindings = [
      { keys = [ 113 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/runuser -l YOUR_USER -c 'amixer -q set Master toggle'"; }
      { keys = [ 114 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/runuser -l YOUR_USER -c 'amixer -q set Master 5%- unmute'"; }
      { keys = [ 115 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/runuser -l YOUR_USER -c 'amixer -q set Master 5%+ unmute'"; }
    ];
  };

i.e. force those commands to run as the user you specify. Also, remove the sound.mediaKeys.enable = true statement, as it will add more keybindings automatically for you which would be redundant

All 5 comments

I personally prefer to do such things on user level. In my case it's a simple line in XMonad config, but there are many other options, e.g. various desktop "applets" for sound control automatically do this.

Initially I tried xfce4-volumed which is what I normally use on my Debian/XMonad desktop but it's not working for some reason. I guess I will set up some XMonad binding or try debugging xfcce4-volumed to see why it's unhappy. In any case thank you for the suggestions.
Going to close this as this seems to be the expected behaviour.

Pulseaudio might be complicating the situation, but I don't really know. Binding the keys to amixer set Master 8%- works for me well.

PulseAudio does complicate the situation: it requires that you connect as the same user that is running the PulseAudio server. I think kbdat commands run as root.

I hit the same wall as you. This is how I solved it:

  services.actkbd = {
    enable = true;
    bindings = [
      { keys = [ 113 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/runuser -l YOUR_USER -c 'amixer -q set Master toggle'"; }
      { keys = [ 114 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/runuser -l YOUR_USER -c 'amixer -q set Master 5%- unmute'"; }
      { keys = [ 115 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/runuser -l YOUR_USER -c 'amixer -q set Master 5%+ unmute'"; }
    ];
  };

i.e. force those commands to run as the user you specify. Also, remove the sound.mediaKeys.enable = true statement, as it will add more keybindings automatically for you which would be redundant

Was this page helpful?
0 / 5 - 0 ratings