Caps Lock Delay Fix

Hey everyone,

I’ve been doing some tweaking on how the Caps Lock key works when quickly pressed and used to switch from UpperCase to LowerCase letter. If you try to use it in its current state it will still be turned on for a second after turning it off resulting in you typing the next letter as an uppercase letter: THis is an example.

Some background: Back when typewriters were still a thing if you wanted to switch to the uppercase letter you would use shift. Caps Lock was used for typing out Titles when you needed every letter to be uppercase. With the development of personal computers, this was still the thing. However, some operating systems like Windows, had users using Caps Lock instead of Shift to switch to the uppercase letter. So when they tried switching from lowercase to uppercase letter, and vice versa, there was not any kind of delay. Using CapsLock instead of Shift is more a question of habit especially if you used Windows, OS X before switching to Linux.

To “fix” this, I’ve tried multiple solutions, but I think the one in this post is the most practical and does not require patching X11.

So how does the script work?

The script in itself is made from few scripts that will run on startup, ensuring that everything works without needing to manually run it each time.

Here are the essential parts of the script:

The first part is made by exporting xkb config file. To do it run

xkbcomp -xkb $DISPLAY xkbmap

Open the exported file and fine this line

key <CAPS> { [ Caps_Lock ] };

Replace the whole line with this part

key <CAPS> { repeat=no, type[group1]="ALPHABETIC", symbols[group1]=[ Caps_Lock, Caps_Lock], actions[group1]=[ LockMods(modifiers=Lock), Private(type=3,data[0]=1,data[1]=3,data[2]=3)] };

Save the file with some name like capslockfix.sh
To test out new configuration reload the config file:

 xkbcomp -w 0 xkbmap $DISPLAY 

Try to type anything using Caps Lock to switch from uppercase to lowercase letters. There should be no more delay resulting in: THis is an example.

Since we don’t want to run it each time when we start OS via terminal, we will create additional script and startup service.

First the script to execute the command above

Create new bash script with the following data:

#! /bin/sh 

xkbcomp -w 0 /home/username/xkbmap $DISPLAY 

Save it. You can rename your xkbmap config to any other file name if you want to keep it more simple. After you’ve done this add it as a service.

If using Budgie: Go to ,Startup Applications" then click Add and then point out to the bash script created above.

In case this does not work for some reason or you are not using Ubuntu Budgie, you can always create startup file manually. Go to the /home/username/.config/autostart

Create a new file with the following data:

[Desktop Entry]
Name=Caps Lock Fixer
Comment=Fixes problem with
Exec="/home/username/capslockfix.sh"
Terminal=false
Type=Application
X-GNOME-Autostart-enabled=true]

Now, the whole problem with the typing delay should be solved. Due note that it works with multiple languages too as long as you have added additional keyboards before running the script. If you add new keyboard you will need to export new xkbmap file.

Since this method is tedious and requires meddling around with files, I’ve made script to automatize this.


#!/usr/bin/env bash
xkbcomp -xkb $DISPLAY xkbmap
FILE="/home/$USER/xkbmap"
NEWSCRIPT="/home/$USER/capslock.sh"
DESKTOP_AUTO_FILE="$HOME/.config/autostart/capslockf.desktop"
RUNLOG="/path/to/script.log"
sed -i 's/key <CAPS> {         [       Caps_Lock ] };/key <CAPS> {
    repeat=no,
    type[group1]="ALPHABETIC",
    symbols[group1]=[ Caps_Lock, Caps_Lock],
    actions[group1]=[ LockMods(modifiers=Lock), Private(type=3,data[0]=1,data[1]=3,data[2]=3)]
};/' "$FILE"

cat <<EOF >$NEWSCRIPT
  #!/usr/bin/env bash
 xkbcomp -w 0 /home/$USER/xkbmap $DISPLAY
  cp $HOME /backup
EOF
cat <<EOF2 >$DESKTOP_AUTO_FILE
[Desktop Entry]
Type=Application
Exec=$NEWSCRIPT
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name[en_US]=CapsLockf
Name=CapsLockf
Comment[en_US]=
Comment=
EOF2
date >> $RUNLOG

If someone wants to test how it works I would be grateful :slight_smile:

I would like to thank @bashfulrobot for helping me with writing this script, as well to give credit to awesome Arch Wiki.

1 Like

I tried out the first method and it worked perfectly. No caps lock delay anymore at all.

So I then tried the automated script on a second install but it didn’t work correctly for me (I copy-pasted it).

Please note that shell scripts and sed are definitely NOT strong points for me, so if anyone contradicts me on this, they are probably right…

I think the issue is that the sed command was failing because it didn’t like being on multiple lines, and it was having an issue with the square brackets. (Whether or not this is a side effect of me copy-pasting, I don’t know). If I made it one line, and put a “\” before the first square bracket, it seems to work ok:

sed -i 's/key <CAPS> {         \[       Caps_Lock ] };/key <CAPS> {\n        repeat=no,\n        type[group1]="ALPHABETIC",\n        symbols[group1]=[ Caps_Lock, Caps_Lock],\n        actions[group1]=[ LockMods(modifiers=Lock), Private(type=3,data[0]=1,data[1]=3,data[2]=3)]\n    };/' "$FILE"

The only other issue I had is that it creates a capslock.sh script. I am guessing that resulting script needs to be made executable manually before it works correctly? After I did these two things, the script worked perfectly to get rid of the delay, autostart on reboot and all.

But its a good change. I’m a shift key user myself, but still, it was one of those minor annoyances that you never pay much attention to until it happens.

1 Like

Thanks for the feedback!

Yes it seems that the capslock.sh scipt isn’t made executable and it should be. An oversight on my part. It should have chmod +x capslock.sh.

Interesting catch for sed and \ . Yeah it is kinda weird it doesn’t work on multiple lines.

1 Like