Keep NumLock always on

I have already physically removed the Num Lock key cap, so I don't accidentally press it (I use a very compact keyboard). But I understand there is a bug in xorg that toggles Num Lock to off when I switch keyboard layout.

So I need something that either prevents Num Lock "off" at all, or alternatively (perhaps easier?) monitors the Num Lock state and turns it "on" as soon as it notices that it's "off".

Here is a Unix answer that seems to address this, but for LXDE. What would I need to do in order to make this idea work in Ubuntu 15.04 and Unity?

I don't know how to monitor or query the Num Lock state, or how to programmatically change the Num Lock state, but here is a solution that uses a simple script that runs all the time. It sounds like it would work but I am not sure it's smart to have that running all the time?


The cleanest would be of course to fix the bug, but as a workaround, the background script below will do the job:

#!/usr/bin/env python3
import subprocess
import time

key = "org.gnome.settings-daemon.peripherals.keyboard numlock-state"
while True:
    time.sleep(1)
    state = subprocess.check_output([
        "/bin/bash", "-c", "gsettings get "+key]).decode("utf-8").strip()
    if state != "'on'":
        subprocess.Popen([
            "/bin/bash", "-c", "gsettings set "+key+" 'on'"])

How to use

  • Copy the script above into an empty file, save it as NM_on.py
  • Test-run it in the background with the command:

    python3 /path/to/NM_on.py
    
  • If all works fine, add it to Startup Applications: Dash > Startup Applications > Add, add the command:

    /bin/bash -c "sleep 10 && python3 /path/to/NM_on.py"
    

Explanation

We can get the current Num Lockstate in more than one way:

  • running the command:

    xset q
    

    which will give an output like:

    Keyboard Control:
      auto repeat:  on    key click percent:  0    LED mask:  00000000
      XKB indicators:
        00: Caps Lock:   off    01: Num Lock:    off    02: Scroll Lock: off
        03: Compose:     off    04: Kana:        off    05: Sleep:       off
        06: Suspend:     off    07: Mute:        off    08: Misc:        off
        09: Mail:        off    10: Charging:    off    11: Shift Lock:  off
        12: Group 2:     off    13: Mouse Keys:  off
      auto repeat delay:  500    repeat rate:  33
    .....
    

    or with the command:

    gsettings get org.gnome.settings-daemon.peripherals.keyboard numlock-state
    

    which simply returns 'on', 'off' or 'unknown'.

    Since the latter is extremely light weight, we can very well use it in a background script to check once per second, and set the value to 'on', if necessary, with the command:

    gsettings set org.gnome.settings-daemon.peripherals.keyboard numlock-state 'on'
    

and so it does...


Edit

For some reason, I missed your last paragraph, in which you referred to another answer with a similar solution.

Purely theoretically, I always have a problem with scripts that blindly (re-) apply settings, without checking the current state. There could be an argument to do so, if the command

gsettings get org.gnome.settings-daemon.peripherals.keyboard numlock-state

to get the current value, would be more demanding that simply run

numlockx on

to (re-)set numlockx on.
Looking at the time both commands need to finish (which is at least an indication) it is however the other way around; the command

gsettings get org.gnome.settings-daemon.peripherals.keyboard numlock-state

seems to be more "light-weight".

Running a background script a bad idea?

Of course, if you have no reason to run a background script, then don't. At the same time, if a background script is well- written, thoroughly tested, procedures are smartly optimized, and if it does not add any noticeable effect on the processor occupation, it would be silly not to use as a workaround if it adds important functionality or saves you time.

I constantly have at least 4-8 background scripts running. Most of them for weeks without a restart. Never noticed any effect, on my elderly system(s). Keep in mind your system is running numerous loops anyway.