就上下文而言,我正在尝试在我的笔记本电脑的软件中复制硬件可编程的 60% 键盘体验。
我在 Arch Linux 上使用 colemak ( setxkbap us -variant colemak
),带有 i3wm,没有桌面环境。
我想让 Caps 充当 LCtrl 的功能最多键盘上的键(例如 Caps+c 是 LCtrl+c),但激活特定其他键的其他组合,特别是 Caps + h/n/e/i 表示左/下/上/右作为系统范围的 vim 键绑定。
测试方法
- 打开终端
- 按 Caps+e,期望出现上一个命令(“向上”操作)
- 按 Caps+c,等待新的终端提示符(‘Ctrl+c’ 操作)
我尝试过
尝试 1
修改 xkb 布局为:
- 将 Caps 键分配给其他修饰符(例如 Mode_switch 或 ISO_Level3_Shift)
- 在该修改器层上分配我想要的键
使用以下 .Xmodmap 文件,我可以实现我想要的一半。
keycode 66 = Mode_switch
keycode 43 = h H Left
keycode 44 = n N Down
keycode 45 = e E Up
keycode 46 = i I Right
这对于映射单个键很有效,但似乎没有办法设置类似
keycode 54 = c C Ctrl+c
这也可以通过修改 /usr/share/X11/xkb/symbols/us 中的 olemak 部分来实现,但会受到同样的限制。
尝试 1
修改/usr/share/X11/xkb/symbols/us
以将 Caps 设置为 Mode_switch,然后重新定义相关键的 AltGr 绑定。
这适用于方向键,但我看不到将 AltGr 层设置为组合键(Ctrl + c)的方法
尝试 2 - AutoKey
-option caps:hyper
在启动 setxkbmap 命令时将 Caps 设置为 Hyper 。使用 AutoKey 将 Hyper+KEY 绑定到脚本/短语。
尝试 2.1 - 脚本 send_keys
将 Hyper+c 绑定到此短语:keyboard.send_keys("<ctrl>+c")
结果:无
尝试 2.2 - 脚本 press_key、release_key
将 Hyper+c 绑定到此脚本:
keyboard.press_key("<ctrl>")
keyboard.send_key("c")
keyboard.release_key("<ctrl>")
结果:大约有 1/20 的几率,Ctrl+c 似乎确实被发送了(终端在新行上显示新提示)。如果我继续使用 Hyper+c,它最终会起作用。大多数时候什么也没发生。
尝试 2.3 - 短语
将 Hyper+c 绑定到短语:<ctrl>+c
结果:AutoKey 崩溃
尝试 3 - Python
尝试 3.1——pynput
已关注本指南关于使用 pynput 在 Python 中创建热键。将 Caps 设置为 Hyper,与上述相同。为 Hyper+c 创建绑定,以调用:
keyboard.press("ctrl")
keyboard.press("c")
keyboard.release("c")
keyboard.release("ctrl")
(我当时尝试了各种其他值等,但我记不清了)。结果:没有
尝试 3.2-使用 pyautogui 进行 pynput 与上面相同,但使用 pyautogui 发送 Ctrl+c 组合。结果:无
尝试 4 - i3 配置中的 xdotool
使用 i3 bindsym 调用exec xdotool key ctrl+c
结果:无
尝试 5-使用 xbindkeys 的 xdotool
将 Caps 设置为 Hyper_L 并尝试以下操作。
"xdotool key --delay 0 ctrl+c"
Hyper_L + c + Release
(也尝试使用 Mode_switch 和 等大写字母Mode_switch + c + Release
)
(也尝试使用c:66 + c + Release
。)
结果:无
有趣的是,我可以通过这种方式将单个键绑定到“Ctrl + c”,但不能将两者的组合绑定。
尝试 6 - sxhkd
使用 sxhkd 复制上述内容(现在手头没有确切的语法)结果:无
我不想将 Caps 直接绑定到 Ctrl
一个想法是将 Caps 绑定到 Ctrl,然后将 Ctrl+h/n/e/i 绑定到箭头。我不想这样做因为我想保留将实际 Ctrl 键与 h/n/e/i 实际组合的能力,以便在真正需要这些 Ctrl 组合时使用。
结论
抱歉,没有提供每个按钮的确切代码。我花了一整天时间尝试让它工作,但没有详细记录每个步骤。可以肯定地说,我尽可能广泛地尝试了每一个按钮,并且确信我无法让 Ctrl 组合起作用,尽管 Left/Right/Up/Down 通常可以
我怎样才能在大多数组合中使用 Caps 作为 Ctrl 键,但对其进行编程以在某些组合中调用其他按键?
答案1
为什么我的大部分尝试都没有成功
我发现大多数这些绑定不起作用的原因是,如果您使用 Hyper(例如)作为修饰键,则在发送 Ctrl 组合键时它仍会被“按下”。因此终端实际上会收到 Hyper+Ctrl+c,这可能会被不同地处理。
对于具有不同输出修饰符的其他映射,情况也是如此。您按下的实际修饰符仍将处于活动状态,并且大多数应用程序将以不同于只有一个修饰符的方式处理这两个修饰符。
一个相当接近的解决方案ISO_Level3_Shift
通过将 Caps 绑定到修饰符,用于xmodmap
更改该层上 HNEI 键(或 QWERTY 上的 HJKL)的 xkb 绑定, 可以实现一种最成功的解决方案。
您将需要xbindkeys
创建宏并xdotool
发送您想要调用的结果组合。
- 检查 Caps 键的键码
xev -event keyboard
(我的是 66) - 使用以下内容创建 .Xmodmap,在必要时替换您的键码/符号(以 ! 开头的行是注释)
! Bind Caps to ISO_Level3_Shift modifier
keycode 66 = ISO_Level3_Shift
!Bind the ISO_Level3_Shift modifier to the arrow keys for each
keysym h = h H NoSymbol NoSymbol Left Left
keysym n = n N NoSymbol NoSymbol Down Down
keysym e = e E NoSymbol NoSymbol Up Up
keysym i = i I NoSymbol NoSymbol Right Right
!Remove whatever X currently considers to be it's 'mod5' modifier
clear mod5
!Set ISO_Level3_Shift to be the 'mod5' modifier
add mod5 = ISO_Level3_Shift
这Arch 维基如果你不确定每列是什么,可以很好地解释每列
执行
xmodmap .Xmodmap
(确保执行后在启动时设置 xkbmap )查找按下此键(现在是 Caps)时的修饰键状态
- 跑步
xbindkeys --multikey
- 聚焦出现的窗口并按 Caps + 某个字母
- 您应该看到类似这样的内容
m:0x80 + c
;m:0x80
这是此键生成的修饰符状态
- 使用 .xbindkeysrc 调用 xdotool 来获取你想要的组合
"xdotool key --delay 0 ctrl+c"
m:0x80 + c + Release
- 根据需要对其他键重复上述操作
- 确保添加
+ Release
到末尾;我不完全理解这一点,但没有它就行不通
- 确保这些键输出其 ISO_Level3_Shift 层的常规键码。这需要再次编辑 .Xmodmap 文件。
keysym c = c C NoSymbol NoSymbol c c
根据需要对每个绑定重复上述步骤
编辑这些文件后,请确保重新启动
xbindkeys
并运行xmodmap .Xmodmap
以使更改生效
此解决方案的局限性
- 按下按键和发送结果映射之间会有短暂的延迟
- 按住时映射不会重复,我还没弄清楚该怎么做
如果有人知道更好的解决方案,或者我如何改进这个解决方案,我很想知道!这很麻烦,也不完美,但这是我目前唯一能做到的事情。