我有一个小数字键盘,我想用它来启动宏和快捷方式,旁边是我的常规键盘。我可以将宏和快捷键附加到这些键(例如,数字键盘 1 可最小化活动窗口),但我的主键盘数字键盘也会激活该快捷方式。
我想要一种方法让辅助键盘完全独立运行,然后为其附加快捷键。
这是我从 得到的输出xinput
。
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ LVT Recon gaming mouse id=10 [slave pointer (2)]
⎜ ↳ LVT Recon gaming mouse id=11 [slave pointer (2)]
⎜ ↳ Corsair Corsair K30A Gaming Keyboard id=13 [slave pointer (2)]
⎜ ↳ SIGMACHIP USB Keyboard id=18 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Power Button id=8 [slave keyboard (3)]
↳ Sleep Button id=9 [slave keyboard (3)]
↳ Corsair Corsair K30A Gaming Keyboard id=12 [slave keyboard (3)]
↳ Corsair Corsair K30A Gaming Keyboard id=14 [slave keyboard (3)]
↳ LVT Recon gaming mouse id=15 [slave keyboard (3)]
↳ Corsair Corsair K30A Gaming Keyboard id=16 [slave keyboard (3)]
↳ SIGMACHIP USB Keyboard id=17 [slave keyboard (3)]
↳ SIGMACHIP USB Keyboard id=19 [slave keyboard (3)]
答案1
尽管我的另一个答案可能会在大多数 Linux 上运行,即使它们已有很多年历史,SystemD 和 udev 实际上使事情变得更容易:
用于
lsusb
查找附加键盘的供应商和产品代码。 (在我的例子中,它是供应商 145F,产品 0177。确保字母为大写。)创建一个文件
/etc/udev/hwdb.d/90-extra-keyboard.hwdb
,其内容类似于:
evdev:input:b0003v145Fp0177*
KEYBOARD_KEY_7005b=stopcd
第一行标识设备:v 后面的四个字母是供应商代码,p 之后是产品代码,来自上一步。每一行都将扫描码映射到符号名称。要获取扫描码,请运行evtest
:
Event: time 1553711252.888538, -------------- SYN_REPORT ------------
Event: time 1553711257.656558, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70059
Event: time 1553711257.656558, type 1 (EV_KEY), code 79 (KEY_KP1), value 1
要了解符号名称的用途,请查看#define KEY_…
以下行列表/usr/include/linux/input-event-codes.h
:
#define KEY_PLAYPAUSE 164
#define KEY_PREVIOUSSONG 165
#define KEY_STOPCD 166
#define KEY_RECORD 167
通过运行重新构建并加载内部数据库
systemd-hwdb update; udevadm trigger
evtest
通过再次运行或在设置中分配快捷方式来验证新设置是否有效。
在应用程序中尝试此操作时,请记住,如果您的桌面环境已经使用该快捷方式,则应用程序甚至不会看到按键。
答案2
原则上是的。当我最后一次2012年做过这个,要走的方法是尝试告诉 Linux 第二个键盘非常奇怪,真正的意思是XF86VolumeUp当它发送 的按键时Num 1,或者其他什么。幸运的是,有很多标准键盘上不存在的键码可以通过这种方式使用。
让我们针对单个键来运行一下:
- 用于
xev | grep -i key
查找额外键盘上按键的键码。例如,我将keypap 9使用键码 81 进行操作。(注意:我的额外键盘有一个标有“00”的键,但会发送“0”两次,我不知道如何处理。)
KeyPress event, serial 38, synthetic NO, window 0x4400001,
state 0x10, keycode 81 (keysym 0xffb9, KP_9), same_screen YES,
KeyRelease event, serial 39, synthetic NO, window 0x4400001,
state 0x10, keycode 81 (keysym 0xffb9, KP_9), same_screen YES,
request MappingKeyboard, first_keycode 8, count 248
- 检查
setxkbmap -query
您的(主)键盘的规则。我们将尝试将您的额外键盘变成该布局上的十几个媒体键。对我来说,它是
rules: evdev
model: pc105
layout: de
variant: nodeadkeys
- 在 中找到足够的条目
/usr/share/X11/xkb/symbols/inet
。右侧是应用程序将看到的内容,可能带有 Shift 键修饰符等,左侧是扫描码。我会选择这个,因为我的键盘没有“计算器”键:
key <I148> { [ XF86Calculator ] };
- 创建一个文件,
/usr/share/X11/xkb/keycodes/
将扫描码映射到键码(从第一步开始)。是的,这看起来倒退了。我的文件名为 trustkeypad,如下所示:
default xkb_keycodes "trustkeypad" {
minimum= 8;
maximum= 255;
// keypad 9
<I148> = 81;
};
编译这个文件
xkbcomp -xkb trustkeypad
尝试一下
setxkbmap -v -v -device 17 -keycodes (filename)
。 (17 是你的 idxinput
。)我的结果如下所示:
Warning! Multiple definitions of keycodes
Using command line, ignoring rules file
Applied rules from evdev:
rules: evdev
model: pc105
layout: de
variant: nodeadkeys
Trying to build keymap using the following components:
keycodes: trustkeypad
types: complete
compat: complete
symbols: pc+de(nodeadkeys)+inet(evdev)
geometry: pc(pc105)
看起来不错,特别是键码行。如果您xev
现在运行,您应该会看到正在生成的新符号。唉,我现在只取得了一半的胜利:
KeyPress event, serial 39, synthetic NO, window 0x4600001,
root 0x168, subw 0x0, time 24043275, (1666,897), root:(1670,950),
state 0x10, keycode 81 (keysym 0x1008ff1d, XF86Calculator), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 39, synthetic NO, window 0x4600001,
root 0x168, subw 0x0, time 24043403, (1666,897), root:(1670,950),
state 0x10, keycode 81 (keysym 0x1008ff1d, XF86Calculator), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 39, synthetic NO, window 0x4600001,
root 0x168, subw 0x0, time 24043403, (1666,897), root:(1670,950),
state 0x10, keycode 77 (keysym 0x0, NoSymbol), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 39, synthetic NO, window 0x4600001,
root 0x168, subw 0x0, time 24043411, (1666,897), root:(1670,950),
state 0x10, keycode 77 (keysym 0x0, NoSymbol), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
但在我意外地使 X 崩溃了几次之后(不要认为将密钥代码文件中的最小值设置得更高会有帮助),这种情况就消失了。也许此时简单的重新启动会有所帮助。成功后,你应该只会得到类似的东西
KeyPress event, serial 38, synthetic NO, window 0x3e00001,
root 0x168, subw 0x0, time 26443862, (930,972), root:(934,1025),
state 0x10, keycode 81 (keysym 0x1008ff1d, XF86Calculator), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 39, synthetic NO, window 0x3e00001,
root 0x168, subw 0x0, time 26444022, (930,972), root:(934,1025),
state 0x10, keycode 81 (keysym 0x1008ff1d, XF86Calculator), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
您可以在用户设置中验证您现在可以为该键分配快捷方式,并且它会说它已分配给计算器键。
这里仍然缺少:弄清楚如何使其成为标准设置,以及重新启动时的设置。这可能会涉及查看 udev,并且https://help.ubuntu.com/community/Custom%20keyboard%20layout%20definitions可能有用,尽管它有一个 2014 年的“过时”标签。
答案3
我假设我不是Linux专家,只是一个用户。不过,我想根据我的需要分享一下我解决这个问题的方法。这并不是像其他用户提出的解决方案那样真正的解决方案,而更像是解决问题的一种方法。我发现这个软件叫输入重映射器这允许我更改我的 2 个键盘的映射分别地,在设备菜单中选择它们。
该程序提供了触发语法组合键并且似乎有一个可选的自定义宏语言。
但是,由于我无法编写单个代码串,所以我所做的只是将我的宏分配给组合键我的主键盘尚未使用。例如,在 Ubuntu 22.10 中。
然后分配组合键到我的第二个键盘的一个键(在图像 KP_BEGIN 中),使用输入重新映射器软件和 key_combination-sintax:
当然不是一个优雅的解决方案,但对于像我这样不熟悉终端的人来说可能更容易实现。
答案4
所描述的hwdb
修改方法不适用于连接的多个 USB 键盘,因为不同 USB 键盘上同一按钮的扫描码是相同的,您将在所有连接的 USB 键盘上重新映射该按钮。
仅内置笔记本电脑键盘和 USB 键盘的扫描码不同。
我会尝试这个 python 方法(在评论中找到它)https://www.youtube.com/watch?v=Arn8ExQ2Gjg)
安装Python及其
evdev
模块(稍后你会需要它)cd
到 /dev/input/by-id/如果没有插入键盘,
ls
.插入键盘,然后
ls
。将有两个新的符号链接。记下它在文件系统中的绝对位置(例如 /dev/input/by-id/usb-0c45_USB_WIRED_KEYBOARD_event-kbd )退出终端。创建一个 python 文件并将其放入其中:
from evdev import InputDevice, categorize, ecodes dev = InputDevice('/absolute/position/of/device') dev.grab() for event in dev.read_loop(): if event.type == ecodes.EV_KEY: key = categorize(event) if key.keystate == key.key_down: if key.keycode == 'KEY_ESC': print("Hello, world!")
现在,如果您按第二个键盘上的转义键,它将打印“Hello, world!”