将快捷方式绑定到功能/多媒体键时出现问题

rem*_*emi 8 keyboard shortcut-keys

我想将批处理脚本连接到快捷方式。当我在系统设置 > 键盘 > 快捷方式下绑定它时,它适用于每个键,除了来自外部 Apple 键盘的亮度键。

亮度键在 showkey 中使用键码224225识别。

xev 输出:

FocusOut event, serial 41, synthetic NO, window 0x4000001,
mode NotifyGrab, detail NotifyAncestor

FocusIn event, serial 41, synthetic NO, window 0x4000001,
    mode NotifyUngrab, detail NotifyAncestor

KeymapNotify event, serial 41, synthetic NO, window 0x0,
    keys:  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
           0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0 
Run Code Online (Sandbox Code Playgroud)

有什么建议我可以做什么?

Ger*_*ger 11

使用udev解决

由于 HAL 已被弃用并udev已被使用,因此这种方法优于我的其他答案(尽管我认为使用 HAL 的解决方案更简单)。

但是对于许多功能键,您可以简单地使用系统设置 > 键盘 > 快捷方式来绑定脚本,请先尝试!它可以为您省去很多麻烦。例如,亮度键不起作用(我不知道为什么不行),所以如果您想知道如何更改例如亮度键的行为,请继续阅读。

注意:如果您运行的是三星笔记本电脑,您可以通过samsung-toolshttp://www.voria.org/forum/安装软件包来修复所有(取决于型号)功能键

本指南假定您知道如何使用终端并使用vim编辑器。如果您不知道,vim请在命令中将其替换为geditnano


确定你的键盘

/lib/udev/findkeyboards
Run Code Online (Sandbox Code Playgroud)

应该打印连接到计算机的键盘,在我的情况下

USB keyboard: input/event9
USB keyboard: input/event7
AT keyboard: input/event4
Run Code Online (Sandbox Code Playgroud)

现在有两个选择:


确定您当前的功能键映射

现在我们可以通过听键盘来确定我们当前的键盘映射(插入正确的数字)

sudo /lib/udev/keymap -i input/event4
Run Code Online (Sandbox Code Playgroud)

您可以通过Esc在键盘上使用或在另一个键盘上使用Ctrl+来退出此命令c

如果您的屏幕开始向下滚动非常困难,请按EscCtrl+c几次,然后再试一次

sudo /lib/udev/keymap -i input/event4 2> /dev/null
Run Code Online (Sandbox Code Playgroud)

或者,如果您仍然遇到滚动问题

sudo /lib/udev/keymap -i input/event4 > ~/keymap.log
Run Code Online (Sandbox Code Playgroud)

在最后一种情况下,您仍然可以滚动,但是如果您按下功能键,它们应该会进入~/keymap.log您稍后可以阅读的位置。

现在我们可以通过按下它们来检查您的功能键的当前映射,这应该会给您一个列表(这是我的Fn+F1Fn+ F12):

scan code: 0xCE   key code: kpplusminus
scan code: 0x89   key code: brightnessdown
scan code: 0x88   key code: brightnessup
scan code: 0x82   key code: switchvideomode
scan code: 0xF9   key code: f23
scan code: 0xA0   key code: mute
scan code: 0xAE   key code: volumedown
scan code: 0xB0   key code: volumeup
scan code: 0x43   key code: f9
scan code: 0x44   key code: f10
scan code: 0xB3   key code: prog3
scan code: 0x86   key code: wlan
Run Code Online (Sandbox Code Playgroud)

现在写下您希望更改其行为的扫描代码。


更改扫描码的键码

如果您清楚地看到关键代码没有涵盖您期望的关键功能,您可以在/usr/include/linux/input.h按键和按钮”下查看是否有更符合您实际想要发生的事情的关键代码。那里的关键代码在格式中KEY_KEYCODE,你必须KEY_用小写写下后面的部分。有时改变这个就足以解决问题。

然而,亮度键通常具有与其关联的正确键码,这就是不允许它们被重新映射的原因。所以我们需要将它们更改为其他键码。我们将使用prog1prog2在这个例子中,因为这些都不在我的电脑上使用,但您也可以使用f13通过f24,或者f20通过f24如果有一个有Apple键盘F1通过F19按键。

  1. 创建自定义键盘映射
    在目录中创建一个/lib/udev/keymaps具有合适名称的键盘映射文件,查看输出ls /lib/udev/keymaps以查看合适的名称。我是custom-brightness为了这个问题而去的。

    sudo vim /lib/udev/keymaps/custom-brightness
    
    Run Code Online (Sandbox Code Playgroud)

    并输入您要更改的键的扫描码,然后输入您希望它们拥有的扫描码。我的custom-brightness看起来像这样:

    # /lib/udev/keymaps/custom-brightness
    
    0x89 prog1
    0x88 prog2
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建自定义密钥发布文件。 仅当您更换笔记本电脑键盘时
    有时未正确发送按键释放事件,导致计算机挂起。为了避免这种情况,我们还将编写一个自定义密钥发布文件

    sudo vim /lib/udev/keymaps/force-release/custom-brightness
    
    Run Code Online (Sandbox Code Playgroud)

    这个文件应该包含相同的扫描码,我的看起来像

    # /lib/udev/keymaps/force-release/custom-brightness
    
    0x89
    0x88
    
    Run Code Online (Sandbox Code Playgroud)

确保新映射已加载到规则文件中
现在我们需要确保您的映射已加载。我们可以通过编辑来做到这一点/lib/udev/rules.d/95-keymap.rules,所以做一个备份是明智的

同样,我们有两个选择:

  • USB 键盘
    因为你有一个 USB 键盘,你应该在下面添加你的条目LABEL="keyboard_usbcheck",它应该超过你的键盘制造商的其他条目。这是因为我的键盘带有

    E: ID_MODEL=USB_Receiver
    E: ID_MODEL_ID=c52b
    E: ID_VENDOR=Logitech
    E: ID_VENDOR_ID=046d
    
    Run Code Online (Sandbox Code Playgroud)

    已与其中一项规则匹配,否则将被覆盖。
    添加下面的规则,你应该改变ID_VENDOR_ID,并ID_MODEL_ID和你的键盘布局的appropiately名称

    ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c52b", RUN+="keymap $name custom-brightness"
    
    Run Code Online (Sandbox Code Playgroud)
  • 笔记本电脑键盘
    如果/lib/udev/findkeyboards你的笔记本电脑键盘按AT keyboard你的规律应该LABEL="keyboard_vendorcheck"放在下面,否则放在下面LABEL="keyboard_modulecheck"。再次将其放在笔记本电脑制造商的其他条目下。添加以下规则(SAMSUNG ELECTRONICS CO., LTD.有点长,所以我使用了通配符)

    ENV{DMI_VENDOR}=="SAMSUNG*", ATTR{[dmi/id]product_name}=="305U1A", RUN+="keymap $name custom_brightness"
    
    Run Code Online (Sandbox Code Playgroud)

    现在还可以/lib/udev/rules.d/95-keyboard-force-release.rules在备份后添加规则

    sudo cp /lib/udev/rules.d/95-keyboard-force-release.rules /lib/udev/rules.d/95-keyboard-force-release.rules.bak
    sudo vim /lib/udev/rules.d/95-keyboard-force-release.rules
    
    Run Code Online (Sandbox Code Playgroud)

    再次在制造商的其他条目下添加

    ENV{DMI_VENDOR}=="SAMSUNG*", ATTR{[dmi/id]product_name}=="305U1A", RUN+="keyboard-force-release.sh $devpath custom_test"
    
    Run Code Online (Sandbox Code Playgroud)

确保 udev 加载新规则
加载新规则运行

sudo adevadm trigger
Run Code Online (Sandbox Code Playgroud)

注意:(udevadm control --reload-rules仍在许多网站上的说明中)不起作用。

现在检查规则是否成功应用

sudo /lib/udev/keymap -i input/event4
Run Code Online (Sandbox Code Playgroud)

现在应该报告亮度键

scan code: 0x89   key code: prog1
scan code: 0x88   key code: prog2
Run Code Online (Sandbox Code Playgroud)

在系统设置中重新映射键
如果最后一步报告了正确的键码,则键开始自动工作(以防它们首先有错误的键码)。

对于亮度,您仍然必须将键绑定到一个脚本,现在可以使用System Settings > Keyboard > Shortcuts

享受



注意事项

  • 如果您的密钥有错误的密钥代码并通过这种方法修复,请按照中的说明操作/usr/share/doc/udev/README.keymap.txt.gz(您可以打开它而不使用 解压zless)并将您的结果发送到那里提到的电子邮件地址,然后更改可以包含在下一个版本中。许多用户将受益!

  • 非常感谢Vaidas Jablonskis 的这篇有用的帖子。


Ger*_*ger 6

使用 halevt 的解决方案

根据手册页halevt是 HAL 事件的通用处理程序。它已被弃用并由 代替udev,但由于我对它的了解不够,udev我将给出一个halevt解决方案。

编辑:在大汗淋漓之后,我设法在udev. 请参阅我的另一个答案

我将用于vim编辑文件,但如果您不知道vim可以用nano或替换它gedit

安装 halevt

sudo apt-get update && sudo apt-get install halevt
Run Code Online (Sandbox Code Playgroud)

确定要绑定到脚本的事件
停止halevt已经运行的守护进程:

sudo /etc/init.d/halevt stop
Run Code Online (Sandbox Code Playgroud)

现在看看是否halevt可以识别您要使用的键的事件,启动侦听器:

sudo -u halevt halevt -fig:plugdev
Run Code Online (Sandbox Code Playgroud)

现在按下键盘上要绑定脚本的功能键。我知道 OP 想让他的亮度键正常工作,所以让我们继续吧。亮度键的输出应如下所示:

Condition: /org/freedesktop/Hal/devices/platform_i8042_i8042_KBD_port_logicaldev_input,ButtonPressed (brightness-down)
Condition: /org/freedesktop/Hal/devices/platform_i8042_i8042_KBD_port_logicaldev_input,ButtonPressed (brightness-up)
Run Code Online (Sandbox Code Playgroud)

可以看到传输了brightness-downbrightness-up事件。

将事件绑定到脚本
现在编辑文件/etc/halevt/halevt.xml

sudo vim /etc/halevt/halevt.xml
Run Code Online (Sandbox Code Playgroud)

并添加以下几行(我在底部,就在之前</halevt:Configuration>):

<halevt:Device match="hal.info.category = input">

    <halevt:Condition name="ButtonPressed" value="brightness-up" exec="sudo /home/user/brightness-script.sh up"/>

    <halevt:Condition name="ButtonPressed" value="brightness-down" exec="sudo /home/user/brightness-script.sh down"/>

</halevt:Device>
Run Code Online (Sandbox Code Playgroud)

当然,您应该更改value为从侦听器获得的事件以及exec要执行的命令。

授予 halevt 用户执行命令或脚本的权限
由于halevt守护程序以halevt用户身份运行,因此您必须授予它执行您在exec.

运行(记得vim用你选择的编辑器替换)

sudo EDITOR=vim visudo
Run Code Online (Sandbox Code Playgroud)

并在底部添加以下几行

halevt ALL=(root) NOPASSWD: /home/user/brightness-script.sh 
Run Code Online (Sandbox Code Playgroud)

并保存并退出。

确保你的脚本是可执行的

sudo chmod +x /home/user/brightness-script.sh
Run Code Online (Sandbox Code Playgroud)

再次启动 halevt 守护进程

sudo /etc/init.d/halevt start
Run Code Online (Sandbox Code Playgroud)

它应该工作!