bxrrx
July 11, 2024, 1:08am
1
I have a USB foot pedal that acts as a keyboard and sends the F13 key. On Windows and Mac it works like you’d expect. But Linux seems to remap the F13-F24 keys at a low level to a bunch of random XF86 keys.
This reddit thread has instructions for a fix on plain Linux. But I am having trouble translating the fix to NixOS. The NixOS wiki describes how to define an entirely new layout, and how to set predefined options. But it does not describe how to define a new option.
Does anyone have a working recipe for using F13-F24 as normal keys on NixOS?
It looks like someone has tried to do this before.
The problems seems to be that you can’t edit xkb rules:
Replicating the patterns using in the linked code, I came up with this:
{ pkgs, ... }:
let
my-xkeyboard-config = pkgs.xkeyboard_config.overrideAttrs (_: {
postFixup = ''
cat > $out/share/X11/xkb/symbols/myoptions <<EOF
default partial function_keys
xkb_symbols "restore_fk" {
key<FK13> { [ F13 ] };
key<FK14> { [ F14 ] };
key<FK15> { [ F15 ] };
key<FK16> { [ F16 ] };
key<FK17> { [ F17 ] };
key<FK18> { [ F18 ] };
key<FK19> { [ F19 ] };
key<FK20> { [ F20 ] };
key<FK21> { [ F21 ] };
key<FK22> { [ F22 ] };
key<FK23> { [ F23 ] };
key<FK24> { [ F24 ] };
};
EOF
${pkgs.ed}/bin/ed -v $out/share/X11/xkb/rules/evdev <<EOF
/^!\W\+option\W\+=\W\+symbols$
a
myopts:re_fk = +myoptions(restore_fk)
.
w
EOF
${pkgs.ed}/bin/ed -v $out/share/X11/xkb/rules/evdev.xml <<EOF
/<optionList>
a
<group allowMultipleSelection="true">
<configItem>
<name>myopts</name>
<description>My custom options</description>
</configItem>
<option>
<configItem>
<name>myopts:re_fk</name>
<description>Restore original keysyms of the function keys from 13 to 24</description>
</configItem>
</option>
</group>
.
w
EOF
'';
});
in
{
services.xserver = {
enable = true;
exportConfiguration = true; # I'm not sure if this is necessary
xkb.dir = my-xkeyboard-config + "/etc/X11/xkb";
};
}
I have not tested this, but it should be a good starting point for you.
After building your system the files should be modified and located in /etc/X11/xkb/rules/evdev.xml
… etc
1 Like
I haven’t had exactly this problem, but when I’ve had similar problems I’ve fixed them at the libinput level (i.e. below the xkb/wayland level) using keymapper or kmonad or any of various other programs - see GitHub - jtroo/kanata: Improve keyboard comfort and usability with advanced customization for some other options.
Somewhat less intrusive might be using home-manager. I managed to define some XKB options this way in the past:
committed 07:24PM - 11 Jan 23 UTC
The computer has normal keyboard now.
2 Likes
bxrrx
July 14, 2024, 7:27pm
5
Thanks for your responses, especially @lelgenio for writing out that config. It worked exactly as you intended, but unfortunately X wasn’t applying the option. I never figured out why.
In the end I got it working with a hacky script that runs on login:
#!/bin/sh
dir=$(mktemp -d)
mkdir "${dir}"/symbols
cat > "${dir}"/symbols/myoptions <<EOF
xkb_symbols "restore_fk" {
key<FK13> { [ F13 ] };
key<FK14> { [ F14 ] };
key<FK15> { [ F15 ] };
key<FK16> { [ F16 ] };
key<FK17> { [ F17 ] };
key<FK18> { [ F18 ] };
key<FK19> { [ F19 ] };
key<FK20> { [ F20 ] };
key<FK21> { [ F21 ] };
key<FK22> { [ F22 ] };
key<FK23> { [ F23 ] };
key<FK24> { [ F24 ] };
};
EOF
setxkbmap -print \
| sed 's/\(xkb_symbols.*\)"/\1+myoptions(restore_fk)"/' \
| xkbcomp -I"${dir}" - $DISPLAY
rm -r "${dir}"
I got it working by just modifying the inet file directly.
Setting the XKB_CONFIG_ROOT environment variable makes this also work on wayland.
{ pkgs, ... }:
let
fixed-keyboard-config = pkgs.xkeyboard_config.overrideAttrs (_: {
postFixup = ''
${pkgs.gnused}/bin/sed -i 's/\(key <FK\)\(13\|14\|15\|16\|17\|18\|19\|20\|21\|22\|23\|24\)\(>\)\(.\+\)/\1\2\3 { [ F\2 ] };/g' $out/share/X11/xkb/symbols/inet
${pkgs.gnused}/bin/sed -i '/xkb_symbols "evdev" {/a key <FK24> { [ F24 ] };' $out/share/X11/xkb/symbols/inet
'';
});
in
{
services.xserver = {
enable = true;
xkb.dir = fixed-keyboard-config + "/etc/X11/xkb";
};
environment.sessionVariables = {
XKB_CONFIG_ROOT = fixed-keyboard-config + "/etc/X11/xkb";
};
}