I lost my primary drive on Friday, and I'm having to rebuild a bunch of stuff. I didn't document minor things like this before, so I am this time around. Hopefully someone else finds this useful.

numlockx

There are plenty of different ways to enable NumLock on login, including a decent manual approach. An official X extension, numlockx, can handle it automatically for us. There's an unofficial mirror available to build the package from source, or you can check for it in official channels.

$ dnf search numlockx
Last metadata expiration check: 0:56:24 ago on Sun 20 May 2018 04:02:40 PM CDT.
==================================== Name Exactly Matched: numlockx ====================================
numlockx.x86_64 : Turns on NumLock after starting X

$ sudo dnf install -y numlockx
Last metadata expiration check: 0:47:47 ago on Sun 20 May 2018 04:02:40 PM CDT.
Dependencies resolved.
========================================================================================================
Package Arch Version Repository Size
========================================================================================================
Installing:
numlockx x86_64 1.2-12.fc27 fedora 18 k

Transaction Summary
========================================================================================================
Install 1 Package

Total download size: 18 k
Installed size: 17 k
Downloading Packages:
numlockx-1.2-12.fc27.x86_64.rpm 47 kB/s | 18 kB 00:00
--------------------------------------------------------------------------------------------------------
Total 18 kB/s | 18 kB 00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : numlockx-1.2-12.fc27.x86_64 1/1
Running scriptlet: numlockx-1.2-12.fc27.x86_64 1/1
Verifying : numlockx-1.2-12.fc27.x86_64 1/1

Installed:
numlockx.x86_64 1.2-12.fc27

Complete!

As far as I know, there aren't any problems installing the older version from 27 in 28. numlockx is a fairly simple package that depends on xkb which, as of writing, has not yet been updated drastically enough to worry.

Automating

The previously linked ArchWiki page has good explanations for common configurations. I'm not entirely sure any of them will work with i3, so this solution uses systemd. A unit file will let us connect the action to logging in, and using the user configuration we won't affect any other users.

$ mkdir -p ~/.config/systemd/user
$ $EDITOR ~/.config/systemd/user/numlockx.service
~/.config/systemd/user/numlockx.service
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[Unit]
Description=Turn on NumLock
BindsTo=graphical-session.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/numlockx on
ExecStop=/usr/bin/numlockx off

[Install]
WantedBy=graphical-session.target

This creates a oneshot service whose process is launched from the ExecStart line but exits before other units are fired. By adding the RemainAfterExit option, systemd will report it as active even after the process exits. numlockx tweaks X settings and leaves; it doesn't run perpetually. systemd will automatically stop any user processes when we exit; however, we don't have a process, so the ExecStop line will undo any changes we've made. Because numlockx only touches NumLock in X, we install it to the graphical-session.target via WantedBy. This target is only available to users, not globally. If you want to install it with a different target, e.g. one you've made, double check the available targets and update it as you see fit. Finally, the BindsTo line links the service to the graphical-session.target, meaning the service ends with the target.

Once it's built, all you have to do is enable the service and you're good to go. Below I do a more rigorous start, reloading my user services, starting to ensure it doesn't fail, and only then enabling.

$ systemctl --user daemon-reload

$ systemctl --user status numlockx.service
● numlockx.service - Turn on NumLock
Loaded: loaded (/home/cjharries/.config/systemd/user/numlockx.service; disabled; vendor preset: enab>
Active: inactive (dead)

$ systemctl --user start numlockx.service

$ systemctl --user status numlockx.service
● numlockx.service - Turn on NumLock
Loaded: loaded (/home/cjharries/.config/systemd/user/numlockx.service; disabled; vendor preset: enab>
Active: active (exited) since Sun 2018-05-20 17:48:59 CDT; 1s ago
Process: 9578 ExecStart=/usr/bin/numlockx on (code=exited, status=0/SUCCESS)
Main PID: 9578 (code=exited, status=0/SUCCESS)

May 20 17:48:59 gxc-fedora-28.wotw systemd[2370]: Starting Turn on NumLock...
May 20 17:48:59 gxc-fedora-28.wotw systemd[2370]: Started Turn on NumLock.

$ systemctl --user enable numlockx.service
Created symlink
/home/cjharries/.config/systemd/user/graphical-session.target.wants/numlockx.service
→ /home/cjharries/.config/systemd/user/numlockx.service.

# The next time you log in, it should boot automatically
$ systemctl --user status numlockx.service
● numlockx.service - Turn on NumLock
Loaded: loaded (/home/cjharries/.config/systemd/user/numlockx.service; enabled; vendor preset: enabl>
Active: active (exited) since Sun 2018-05-20 18:09:18 CDT; 49s ago
Process: 4458 ExecStart=/usr/bin/numlockx on (code=exited, status=0/SUCCESS)
Main PID: 4458 (code=exited, status=0/SUCCESS)

May 20 18:09:18 gxc-fedora-28.wotw systemd[4333]: Starting Turn on NumLock...
May 20 18:09:18 gxc-fedora-28.wotw systemd[4333]: Started Turn on NumLock.

Note

I'm not incredibly familiar with user services yet (having just started using them heavily this weekend), so I'm not entirely certain about all the graphical-session.target logic. I've only rebooted twice now to check the flow, and that's two more times than I normally would in at least a week. If you're on an older distro or using an older version of systemd, the target might not exist or work correctly. This command is a good check:

$ systemctl --user list-units --type=target | grep 'graphical-session.target.*loaded.*active' || echo 'whoops'