Tonλ's blog May the λ be with you

A story of keyboard mapping 2/2

by @ardumont on

So, Everything is great! I have my keyboard mapping which permits me to concentrate on my goal.

Or so I thought…

Indeed, at each resume time, my keyboard mapping is reverted back to standard QWERTY.

In this blog post, I will propose a solution that permits to ensure the keyboard is remapped at resume time.

pm-utils

pm-utils to the rescue!

From their README:

What is pm-utils?

Pm-utils provides simple shell command line tools to suspend and hibernate computer that can be used to run vendor, distribution, or user supplied scripts on suspend and resume.

So we can use this, for example, to remap a keyboard at each resume event…

Mapping keyboard script

We need a script that will check if the mapping is effective or not. If not effective, we want to trigger the mapping.

#!/bin/bash
# Use: $0
# If no display variable set, log a simple message and exit
# Otherwise, launch the keyboard mapping.
#
# Test before changing the mapping
# For a much better Emacs/Stumpwm/Firefox with keysnail experience.
# ------------------------------------------------------------------------------

## function

log() {
    echo "display '$DISPLAY' - $1"
}

## Checks

[ -z "$DISPLAY" ] && log "No display so no keyboard mapping." && return 1

## Run

WDIR=$(dirname $0)

# will be *Caps_Lock* if no customisation or empty otherwise
CAPS=$(xmodmap -display $DISPLAY | grep lock | awk '{print $2}')

if [ "$CAPS" = "Caps_Lock" ]; then
    log "xmodmap customisation..."
    xmodmap ~/.Xmodmap
else
    log "xmodmap already customized!";
fi

Source

This script will be called from the service script.

Service script

This is a script that will react to the following events:

Event Description Action
suspend Suspend to ram the os Nothing
hibernate Suspend to disk Nothing
resume Resume from suspend to ram Remap
thaw Resume from suspend to disk Remap

In our case, we do not care about suspend and hibernate events. But at resume or thaw time, we want to remap the keyboard.

#!/bin/sh

# Action script to ensure the mapping is reinitialized at resume time
#
# Copyright: Copyright (c) 2014 Antoine R. Dumont
# License:   GPL-2
#

USER=tony
case "${1}" in
        suspend|hibernate)   # `suspend to ram` or `suspend to disk`
                # do nothing
                ;;
        resume|thaw)         # resume from `suspend to ram` or `suspend to disk`
                su -l $USER -c "export DISPLAY=:0.0 ; /home/$USER/bin/kbd/remap-keyboard.sh" &
                ;;
esac

Source

Of course, edit the script to your need.

Where

  • Give the script the executable rights
chmod +x your-script
  • Install the script in the folder: /etc/pm/sleep.d
  • Name the script with XYZ prefix where XYZ is a priority number

For example, /etc/pm/sleep.d/0000keyboard-mapping.

sudo cp ~/bin/pm-utils/keyboard-mapping-on-resume.sh /etc/pm/sleep.d/0000keyboard-mapping

Note the name 0000 here will ensure the script is run at last position.

Automate

As I often forget these things, I keep creating scripts that encapsulate these behaviours. (This way I remember having done so and can report back to this)

  • Deploy:
#!/bin/sh
# Use: $0
# Script to deploy the pm-utils script to remap the keyboard at wake up time
#

sudo cp ~/bin/pm-utils/keyboard-mapping-on-resume.sh /etc/pm/sleep.d/0000keyboard-mapping

Source

  • Undeploy:
#!/bin/sh
# Use: $0
# Script to remove the personal pm-utils scripts
#

sudo rm /etc/pm/sleep.d/0000keyboard-mapping

Source

Latest posts