Score:1

How to persistently map Capslock to ESC and Ctrl so that it still works after suspend/resume

us flag

I'm using the following lines in my ~/.xprofile on Ubuntu 20.04 to map Capslock to ESC and Ctrl:

# make CapsLock behave like Ctrl:                                
setxkbmap -option ctrl:nocaps
# make short-pressed Ctrl behave like Escape:
xcape -e 'Control_L=Escape'

which works perfectly fine for me.

My issue is that it does not survive suspend/resume reliably. For this, I've tried 2 different solutions:

1. Via a script capsmap put into /usr/lib/systemd/system-sleep/

#!/bin/bash                                                            
                                                                       
case "$1" in                                                           
    pre)                                                               
      #code execution BEFORE sleeping/hibernating/suspending     
    ;;                                                                 
    post)                                                              
      #code execution AFTER resuming                             
      /usr/bin/echo "executing: /usr/bin/setxkbmap -option ctrl:nocaps"
      /usr/bin/setxkbmap -option ctrl:nocaps                           
      /usr/bin/echo "executing: /usr/bin/xcape -e 'Control_L=Escape'"  
      /usr/bin/xcape -e 'Control_L=Escape'                             
                                                                       
    ;;                                                                 
esac                                                                   
                                                                       
exit 0                                                                 

I've made the script executable with sudo chmod +x capsmap and can see from the logs that it is called at the appropriate time:

$ journalctl
...
Okt 09 13:29:12 nb systemd-sleep[401221]: System resumed.
Okt 09 13:29:12 nb kernel: Bluetooth: hci0: Device revision is 5
Okt 09 13:29:12 nb kernel: Bluetooth: hci0: Secure boot is enabled
Okt 09 13:29:12 nb kernel: Bluetooth: hci0: OTP lock is enabled
Okt 09 13:29:12 nb kernel: Bluetooth: hci0: API lock is enabled
Okt 09 13:29:12 nb kernel: Bluetooth: hci0: Debug lock is disabled
Okt 09 13:29:12 nb kernel: Bluetooth: hci0: Minimum firmware build 1 week 10 2014
Okt 09 13:29:12 nb kernel: Bluetooth: hci0: Found device firmware: intel/ibt-11-5.sfi
Okt 09 13:29:12 nb systemd-sleep[401287]: executing: /usr/bin/setxkbmap -option ctrl:nocaps
Okt 09 13:29:12 nb systemd-sleep[401288]: Cannot open display "default display"
Okt 09 13:29:12 nb systemd-sleep[401291]: executing: /usr/bin/xcape -e 'Control_L=Escape'
Okt 09 13:29:12 nb systemd-sleep[401293]: Unable to connect to X11 display. Is $DISPLAY set?
Okt 09 13:29:12 nb systemd[1]: systemd-suspend.service: Succeeded.
Okt 09 13:29:12 nb systemd[1]: Finished Suspend.
Okt 09 13:29:12 nb systemd[1]: Stopped target Sleep.
Okt 09 13:29:12 nb systemd[1]: Reached target Suspend.
Okt 09 13:29:12 nb systemd[1]: Stopped target Suspend.
...

However, the mapping only sometimes applies. Quite often, Capslock just behaves as normal.

2. Via a systemd service

I've added a service file capsmap.service to etc/systemd/system/ with the following content:

[Unit]
Description=Map Capslock to ESC and Ctrl
After=suspend.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/capsmap
TimeoutSec=0
StandardOutput=syslog

[Install]
WantedBy=multi-user.target suspend.target

with the file /usr/local/bin/capsmap as

#!/bin/bash

# make CapsLock behave like Ctrl:
/usr/bin/echo "executing: /usr/bin/setxkbmap -option ctrl:nocaps"
/usr/bin/setxkbmap -option ctrl:nocaps

# make short-pressed Ctrl behave like Escape:
/usr/bin/echo "executing: /usr/bin/xcape -e 'Control_L=Escape'"
/usr/bin/xcape -e 'Control_L=Escape'

exit 0

then enabled the service with sudo systemctl enable capsmap.service.

Also in this case, I can see with journalctl that the script was executed successfully, but the normal Capslock behavior is still present.

$journalctl
...
Okt 09 13:07:56 nb systemd[1]: Stopped target Suspend.                                                                                                                                                                                                                            
Okt 09 13:07:56 nb NetworkManager[1049]: <info>  [1633777676.0331] manager: sleep: wake requested (sleeping: yes  enabled: yes)                                                                                                                                                   
Okt 09 13:07:56 nb ModemManager[1137]: <info>  [sleep-monitor] system is resuming                                                                                                                                                                                                 
Okt 09 13:07:56 nb NetworkManager[1049]: <info>  [1633777676.0332] device (enp0s31f6): state change: activated -> unmanaged (reason 'sleeping', sys-iface-state: 'managed')                                                                                                       
Okt 09 13:07:56 nb systemd[1761]: Stopped target Bluetooth.                                                                                                                                                                                                                       
Okt 09 13:07:56 nb upowerd[1344]: treating change event as add on /sys/devices/pci0000:00/0000:00:14.0/usb1/1-8                          
Okt 09 13:07:56 nb capsmap[378798]: executing: /usr/bin/setxkbmap -option ctrl:nocaps                                                                                                                                                                                             
Okt 09 13:07:56 nb systemd[1761]: Reached target Bluetooth.                                                                                                                                                                                                                       
Okt 09 13:07:56 nb NetworkManager[1049]: <info>  [1633777676.0498] dhcp4 (enp0s31f6): canceled DHCP transaction                                                                                                                                                                   
Okt 09 13:07:56 nb capsmap[378799]: Cannot open display "default display"                                                                                                                                                                                                         
Okt 09 13:07:56 nb NetworkManager[1049]: <info>  [1633777676.0498] dhcp4 (enp0s31f6): state changed bound -> done                                                                                                                                                                 
Okt 09 13:07:56 nb avahi-daemon[1041]: Withdrawing address record for 192.168.178.54 on enp0s31f6.                                       
Okt 09 13:07:56 nb avahi-daemon[1041]: Leaving mDNS multicast group on interface enp0s31f6.IPv4 with address 192.168.178.54.                                                                                                                                                      
Okt 09 13:07:56 nb avahi-daemon[1041]: Interface enp0s31f6.IPv4 no longer relevant for mDNS.                                             
Okt 09 13:07:56 nb avahi-daemon[1041]: Withdrawing address record for fe80::778b:d324:d55d:a503 on enp0s31f6.                                                                                                                                                                     
Okt 09 13:07:56 nb avahi-daemon[1041]: Leaving mDNS multicast group on interface enp0s31f6.IPv6 with address fe80::778b:d324:d55d:a503.  
Okt 09 13:07:56 nb avahi-daemon[1041]: Interface enp0s31f6.IPv6 no longer relevant for mDNS.                                                                                                                                                                                      
Okt 09 13:07:56 nb systemd[1]: Started Load/Save RF Kill Switch Status.                                                                  
Okt 09 13:07:56 nb capsmap[378800]: executing: /usr/bin/xcape -e 'Control_L=Escape'                                                                                                                                                                                               
Okt 09 13:07:56 nb NetworkManager[1049]: <info>  [1633777676.0545] manager: NetworkManager state is now CONNECTED_GLOBAL                 
Okt 09 13:07:56 nb capsmap[378805]: Unable to connect to X11 display. Is $DISPLAY set?                                                                                                                                                                                            
Okt 09 13:07:56 nb kernel: kauditd_printk_skb: 9 callbacks suppressed                                                                                                                                                                                                             
Okt 09 13:07:56 nb kernel: audit: type=1107 audit(1633777676.068:1737): pid=1047 uid=103 auid=4294967295 ses=4294967295 subj=unconfined msg='apparmor="DENIED" operation="dbus_signal"  bus="system" path="/org/freedesktop/NetworkManager/ActiveConnection/30" interface="org.fr>
                            exe="/usr/bin/dbus-daemon" sauid=103 hostname=? addr=? terminal=?'                                                                                                                                                                                    
Okt 09 13:07:56 nb kernel: audit: type=1107 audit(1633777676.068:1738): pid=1047 uid=103 auid=4294967295 ses=4294967295 subj=unconfined msg='apparmor="DENIED" operation="dbus_signal"  bus="system" path="/org/freedesktop/NetworkManager/ActiveConnection/30" interface="org.fr>
                            exe="/usr/bin/dbus-daemon" sauid=103 hostname=? addr=? terminal=?'                                                                                                                                                                                    
Okt 09 13:07:56 nb audit[1047]: USER_AVC pid=1047 uid=103 auid=4294967295 ses=4294967295 subj=unconfined msg='apparmor="DENIED" operation="dbus_signal"  bus="system" path="/org/freedesktop/NetworkManager/ActiveConnection/30" interface="org.freedesktop.NetworkManager.Connec>
                                 exe="/usr/bin/dbus-daemon" sauid=103 hostname=? addr=? terminal=?'                                                                                                                                                                               
Okt 09 13:07:56 nb audit[1047]: USER_AVC pid=1047 uid=103 auid=4294967295 ses=4294967295 subj=unconfined msg='apparmor="DENIED" operation="dbus_signal"  bus="system" path="/org/freedesktop/NetworkManager/ActiveConnection/30" interface="org.freedesktop.NetworkManager.Connec>
                                 exe="/usr/bin/dbus-daemon" sauid=103 hostname=? addr=? terminal=?'                                                                                                                                                                               
Okt 09 13:07:56 nb systemd[1]: capsmap.service: Succeeded.   
...
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.