一段时间以来,我一直对将键盘上的 Windows 键 (Super_L) 绑定到复制和粘贴功能感兴趣,原因无他,只是为了方便和在桌面和 MacBook 之间保持一致。
在阅读了 xmodmap 并执行以下操作后,我认为我已经接近了:
$ # re-map Super_L to Mode_switch, the 3rd col in keymap table `xmodmap -pke`
$ xmodmap -e "keycode 133 = Mode_switch"
$ # map Mode_switch+c to copy
$ xmodmap -e "keycode 54 = c C XF86_Copy C"
$ # map Mode_switch+v to paste
$ xmodmap -e "keycode 55 = v V XF86_Paste V"
不幸的是,XF86Copy 和 XF86Paste 似乎根本不起作用。它们列在/usr/include/X11/XF86keysym.h
并xev
显示 X 将按键序列解释为 XF86Paste 和 XF86Copy,这些符号真的有效吗?它们必须有应用程序级支持吗?
答案1
将 Super 绑定到 Ctrl
Windows/Logo/Super
将左键绑定为另一个Ctrl
键怎么样?
您可以使用以下 xmodmap 命令实现此目的:
remove mod4 = Super_L
keysym Super_L = Control_L
add Control = Control_L
假设你保存了上面的代码,super_as_ctrl.xmodmap
你可以通过执行以下命令来测试效果
xmodmap super_as_ctrl.xmodmap
为了使更改永久生效(重新登录/重启后仍然生效),请将文件重命名为.Xmodmap
您的主文件夹。
(以上是在Ubuntu 11.10 live系统上测试的,但其他Linux发行版应该也一样)
调整终端程序的复制/粘贴快捷方式
绑定后Super
,Ctrl
您现在Super-C
几乎可以在任何地方使用复制。唯一常见的例外是您的终端程序。但是,您可以在那里重新定义快捷方式。
我发现gnome-terminal
现在甚至还有这个选项(反正我习惯了之后才有Ctrl-Shift-C
)。如果您使用这个,请进入Edit / Keyboard Shortcuts...
菜单并指定Ctrl-C
复制和粘贴。等Ctrl-V
应该类似。konsole
不用担心,您不会失去使用快捷方式终止程序的能力。重新绑定终端的复制快捷方式后,您可以像以前Ctrl-Shift-C
一样使用Ctrl-C
。终端在这里不会区分是否按下了 Shift。并且快捷方式不再被复制捕获。或者,将终止重新绑定到另一个快捷方式,正如 MountainX 在他的回答中所建议的那样。
XF86Copy 等不起作用
关于复制和粘贴的按键符号:显然它们没有效果。我通过将复制操作分配给 Shift-ScrollLock(它未被使用,我想用非修饰键进行测试)进行了快速测试:
xmodmap -e 'keycode 78 = Scroll_Lock XF86Copy Scroll_Lock'
按下它没有效果,XF86AudioMute 也没有效果。但是,当分配字母“a”时,它确实有效。所以我猜这些 XF86 特殊键符号存在特定问题。
答案2
如果您只想将 Super+x、Super+c、Super+v 形式的几个序列绑定到其他序列(例如 Ctrl+x、Ctrl+c、Ctrl+v),以便(如 OP 所希望的)这些特定的 Super 键序列通常会映射到剪切和粘贴,而不会影响系统上 Super 键的任何其他用途,则只需使用 XKB 扩展即可。下面的过程概述了步骤,并给出了两个不同起始键盘设置细节的两个不同示例;希望这能提供足够的信息以适应您的系统。它假设您可以轻松地在系统上创建和编辑文件,包括系统位置中的文件,例如/usr/share/X11/xkb
。
决定 XKB 配置树的存放位置。首先找到系统配置树。它通常位于 /usr/share/X11/xkb 中,如果它不在那里,我不太确定如何找到它;您可以直接在系统中搜索名为“xkb”的目录。无论如何,一旦找到它,您可以就地修改系统配置树,也可以使用您选择的任何目录。使用系统目录的优点是您可以更轻松地调用更改,但缺点是将来的系统更新可能会覆盖您的更改(已警告您)。无论如何,此后提到的所有文件名都与此目录相关,我将在需要时将其称为 $XKBLOCAL$,并且所有命令都假定这是您的当前目录。
确定当前 x、c、v 键的 XKB“类型”键。最简单的方法是通过命令
xkbcomp -a $DISPLAY - | grep -C 6 c,
(请注意,逗号是故意包含在模式中的)。在我的第一个示例设置中,这将产生:key <AB02> { type= "ALPHABETIC", symbols[Group1]= [ x, X ] }; key <AB03> { type= "ALPHABETIC", symbols[Group1]= [ c, C ] }; key <AB04> { type= "ALPHABETIC", symbols[Group1]= [ v, V ] }; key <AB05> {
而在我的其他示例设置中,这会产生
key <AB02> { type= "FOUR_LEVEL", symbols[Group1]= [ x, X, approxeq, dead_ogonek ] }; key <AB03> { type= "FOUR_LEVEL", symbols[Group1]= [ c, C, ccedilla, Ccedilla ] }; key <AB04> { type= "FOUR_LEVEL", symbols[Group1]= [ v, V, squareroot, U25CA ] }; key <AB05> {
结果是,在第一个示例中,相关键的类型为“ALPHABETIC”,而在第二个示例中,它们的类型为“FOUR_LEVEL”。根据您的键盘设置,您可能会发现它们完全是其他类型。在下文中,类型将被称为 $TYPE$,您必须在以下命令中将其替换为实际字符串 ALPHABETIC 或其他任何内容。
找到 $TYPE$ 的定义并将其复制到 $XKBLOCAL$/types 目录中的新文件中。下面是执行此操作的命令:
xkbcomp -a $DISPLAY - | grep -z -o 'type "$TYPE$" {[^}]*};' > types/cutpaste
。我选择的文件“cutpaste”的名称是任意的,您可以使用任何您喜欢的名称,但请注意,您必须在后续步骤中始终引用此文件。在第一个设置中,此文件获取内容type "ALPHABETIC" { modifiers= Shift+Lock; map[Shift]= Level2; map[Lock]= Level2; level_name[Level1]= "Base"; level_name[Level2]= "Caps"; };
在另一个例子中,它获取内容
type "FOUR_LEVEL" { modifiers= Shift+LevelThree; map[Shift]= Level2; map[LevelThree]= Level3; map[Shift+LevelThree]= Level4; level_name[Level1]= "Base"; level_name[Level2]= "Shift"; level_name[Level3]= "Alt Base"; level_name[Level4]= "Shift Alt"; };
编辑文件 types/cutpaste 以执行两项操作:添加前言和后言,使其成为正确的 XKB 子句,并修改类型名称和类型定义以添加与 Super 对应的修饰符产生的另一个级别。您应该检查系统上的修饰符是什么,它很可能是下面使用的 Mod4。从 types/cutpaste 的两个示例最终版本中应该可以看出必要的修改,即:
default partial xkb_types "addsuper" { type "ALPHABETIC_SUPER" { modifiers= Shift+Lock+Mod4; map[Shift]= Level2; map[Lock]= Level2; map[Mod4]= Level3; map[Shift+Mod4]= Level3; map[Lock+Mod4]= Level3; level_name[Level1]= "Base"; level_name[Level2]= "Caps"; level_name[Level3]= "With Super"; }; };
和
default partial xkb_types "addsuper" { type "FOUR_LEVEL_SUPER" { modifiers= Shift+LevelThree+Mod4; map[Shift]= Level2; map[LevelThree]= Level3; map[Shift+LevelThree]= Level4; map[Mod4]= Level5; map[Shift+Mod4] = Level5; map[LevelThree+Mod4] = Level5; map[Shift+LevelThree+Mod4] = Level5; level_name[Level1]= "Base"; level_name[Level2]= "Shift"; level_name[Level3]= "Alt Base"; level_name[Level4]= "Shift Alt"; level_name[Level5]= "With Super"'; }; };
将第二步中 grep 输出的键符号定义复制到第二个新文件 symbol/cutpaste 中,并添加类似的前言和后言,修改定义以使用新类型,并向定义添加操作以处理 Super 版本生成的所需键。在我们的两个示例中,这样做的结果是:
default partial xkb_symbols "superversions" { replace key <AB02> { type[Group1]= "ALPHABETIC_SUPER", symbols[Group1]= [ x, X, NoSymbol ], actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<LatX>,mods=Control,clearmods=Super)] }; replace key <AB03> { type[Group1]= "ALPHABETIC_SUPER", symbols[Group1]= [ c, C, NoSymbol ], actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<LatC>,mods=Control,clearmods=Super)] }; replace key <AB04> { type[Group1]= "ALPHABETIC_SUPER", symbols[Group1]= [ v, V, NoSymbol ], actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<LatV>,mods=Control,clearmods=Super)] }; };
和
default partial xkb_symbols "superversions" { replace key <AB02> { type[Group1]= "FOUR_LEVEL_SUPER", symbols[Group1]= [x,X,approxeq,dead_ogonek,NoSymbol], actions[Group1]= [NoAction(),NoAction(),NoAction(),NoAction(),RedirectKey(key=<LatX>,mods=Control,clearmods=Super)] }; replace key <AB03> { type[Group1]= "FOUR_LEVEL_SUPER", symbols[Group1]= [c,C,ccedilla,Ccedilla,NoSymbol], actions[Group1]= [NoAction(),NoAction(),NoAction(),NoAction(),RedirectKey(key=<LatC>,mods=Control,clearmods=Super)] }; replace key <AB04> { type[Group1]= "FOUR_LEVEL_SUPER", symbols[Group1]= [v,V,squareroot,U25CA,NoSymbol], actions[Group1]= [NoAction(),NoAction(),NoAction(),NoAction(),RedirectKey(key=<LatV>,mods=Control,clearmods=Super)] }; };
请注意,在第二个例子中,我还挤掉了一些(不重要的)空白,以便对行长度进行一点控制。
找到 XKB 当前使用的规则集的名称。这很简单,它显示在 的结果中
setxkbmap -query
。在我的例子中,它是“evdev”。将系统版本的 rules/evdev(或规则集的名称)复制到 $XKBLOCAL$/rules/evdev,并添加指向我们创建的选项的规则。您有两个选择:您可以复制所有 evdev,或者只复制提及您实际使用的键盘型号、布局、变体和选项的部分。当然,如果您正在修改系统文件,则无需进行任何复制,只需进行编辑即可。
在这种情况下,无论初始键盘设置如何,添加的内容都是相同的,因此这只是一个例子。您找到规则文件中以 开头的部分,
! option = symbols
并向该部分添加一行cutpaste:super = +cutpaste
,您还找到规则文件中以 开头的部分,! option = types
并向该部分添加一行cutpaste:super = +cutpaste
。复制系统版本的 evdev.lst 并为您的新选项添加一行。请注意,此文件的名称仅对应于规则文件的名称加上 .lst。与上一步一样,您可以复制整个文件,也可以只复制您正在使用的模型、布局、变体和选项所引用的部分。您只需找到此文件以 开头的部分,
! option
然后在该部分添加如下一行:cutpaste:super Add super equivalents of cut and paste operations
即可。好的,现在所有配置文件都已就位。如果您修改了系统文件,现在可以使用 调用新选项
setxkbmap -option cutpaste:super
。另一方面,如果您没有这样做,您必须让 setxkbmap 知道您的 $XKBLOCAL$ 目录在哪里。更糟糕的是,服务器也不知道该目录在哪里,并且 setxkbmap 不会(或者可能无法,因为最终服务器可能在另一台机器上运行)告诉它。因此,您必须将 setxkbmap 的输出通过管道传输到 xkbcomp,并告诉该命令您的 $XKBLOCAL 目录在哪里。因此,完整的命令行是setxkbmap -I$XKBLOCAL$ -option cutpaste:super -print | xkbcomp -I$XKBLOCAL - $DISPLAY
。
希望这篇文章能对某些人有所帮助或感兴趣,因为好的权威 XKB 文档/参考资料很少。一个非常有用的参考资料是http://madduck.net/docs/extending-xkb/。
答案3
这是我的做法。这不是终极解决方案,但我尝试过实现终极解决方案,但经过大量努力还是无法实现。因此,我选择了一种简单且能满足我 90% 以上需求的方法。我可以在几分钟内在任何一台计算机上(或任何新安装的 Linux 上)实现它。非常简单。
在 X 终端应用程序中,设置快捷方式首选项。我在 Gnome 和 KDE 中都这样做过。例如,在 Konsole 中,转到菜单 > 设置 > 配置快捷方式。Gnome X 终端中有一个类似的菜单。只需选择快捷方式(例如“复制”)并输入所需的按键序列即可。
如果终端复制粘贴快捷键与终端命令冲突,也有一个简单的解决方法。例如,如果有人想使用 CTRL-C 进行复制(以便 X 终端符合 CUA 标准),该怎么办?
在这种情况下,您可以轻松更改 stty 键绑定(在 .bashrc 中)。继续 CTRL-C 复制示例,假设您希望中断键现在为 CTRL-b(表示“break”)。这实现了这一点:
echo "stty intr \^b" >> ~/.bashrc
然后源.bashrc。
整个解决方案非常简单,只需使用 X 终端设置更改快捷方式,然后(可选)使用一行 echo 命令解决与 stty 的冲突即可。非常简单,几乎涵盖了我需要的一切。
答案4
Windows 键可能是修饰键。运行此操作并重试:
xmodmap -e 'remove Mod4 = Super_L'