如何将 Capslock 永久映射到 ESC 和 Ctrl,以便它在暂停/恢复后仍然有效

如何将 Capslock 永久映射到 ESC 和 Ctrl,以便它在暂停/恢复后仍然有效

~/.xprofile我在Ubuntu 20.04中使用以下几行来映射CapslockESCCtrl

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

对我来说非常好用。

我的问题是它无法可靠地挂起/恢复。为此,我尝试了两种不同的解决方案:

1. 通过脚本capsmap输入/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                                                                 

我已经使脚本可执行,sudo chmod +x capsmap并且可以从日志中看到它在适当的时间被调用:

$ 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.
...

然而,映射只是有时适用。很多时候,Capslock它只是表现正常。

2. 通过 systemd 服务

我添加了一个服务文件capsmap.service,其etc/systemd/system/内容如下:

[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

文件/usr/local/bin/capsmap

#!/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

然后使用 启用该服务sudo systemctl enable capsmap.service

同样在这种情况下,我可以看到journalctl脚本已成功执行,但正常Capslock行为仍然存在。

$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.   
...

相关内容