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

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

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

亮度键在 showkey 中通过 keycode 识别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 

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

答案1

使用 udev 的解决方案

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

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

笔记samsung-tools:如果你使用的是三星笔记本电脑,你可以通过安装以下软件包来修复所有(取决于型号)功能键http://www.voria.org/forum/

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


确定你的键盘

/lib/udev/findkeyboards

在我的例子中,应该打印连接到计算机的键盘

USB keyboard: input/event9
USB keyboard: input/event7
AT keyboard: input/event4

现在有两个选择:

  • USB 键盘
    如果你想重新映射 USB 键盘,请通过运行检查它们

    udevadm info --export-db | awk '/event9/' RS="" | grep -P 'ID_(VENDOR|MODEL)(?!_ENC)'
    

    您必须将 awk 语句中的 9 替换为正确的数字。输出应类似于

    E: ID_MODEL=USB_Receiver
    E: ID_MODEL_ID=c52b
    E: ID_VENDOR=Logitech
    E: ID_VENDOR_ID=046d
    

    这正确地表明我的键盘是通过我的 Logitech USB 接收器处理的(输入/事件 7 原来是我的 Logitech G9 鼠标,它有一些可编程按钮)。

  • 笔记本电脑键盘
    如果您想重新映射笔记本电脑键盘,您应该记住的数字,AT keyboard在我的情况下是 4。还要获取笔记本电脑的 dmi 信息:

    cat /sys/class/dmi/id/sys_vendor
    

    就我的情况来说

    SAMSUNG ELECTRONICS CO., LTD.
    

    cat /sys/class/dmi/id/product_name
    

    就我的情况来说

    305U1A
    

确定功能键的当前映射

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

sudo /lib/udev/keymap -i input/event4

您可以使用Esc键盘上的 或另一个键盘上的Ctrl+退出此命令。c

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

sudo /lib/udev/keymap -i input/event4 2> /dev/null

或者,如果你仍然有滚动问题

sudo /lib/udev/keymap -i input/event4 > ~/keymap.log

在最后一种情况下,您仍然可以滚动,但如果您按下功能键,它们应该进入~/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

现在写下您想要改变行为的扫描代码。


更改扫描码的键码

如果你发现密钥代码没有明确说明你期望该密钥执行的操作,你可以查看/usr/include/linux/input.h以下内容按键和按钮看看是否有更符合您实际期望的键码。那里的键码是格式KEY_KEYCODE,您必须用KEY_小写字母写下后面的部分。有时更改它就足以解决问题。

但是亮度键通常具有与之关联的正确键码,这就是不允许重新映射它们的原因。所以我们需要将它们更改为其他键码。我们将在本例中使用prog1和,因为我的电脑上没有使用这些键码,但是,如果您的 Apple 键盘有直通键prog2,您也可以使用f13直通f24f20直通。f24F1F19

  1. 创建自定义键盘映射
    在目录中创建一个/lib/udev/keymaps具有合适名称的键盘映射文件,查看输出以ls /lib/udev/keymaps找到合适的名称。我打算使用这个来custom-brightness回答这个问题。

    sudo vim /lib/udev/keymaps/custom-brightness
    

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

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

    sudo vim /lib/udev/keymaps/force-release/custom-brightness
    

    此文件应包含相同的扫描代码,我的看起来像

    # /lib/udev/keymaps/force-release/custom-brightness
    
    0x89
    0x88
    

确保新映射已加载到规则文件中
现在我们需要确保你的映射已加载。我们可以通过编辑来做到这一点/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
    

    已经与其中一条规则匹配,否则将被覆盖。
    添加以下规则,其中您应该适当地更改ID_VENDOR_IDID_MODEL_ID键盘映射的名称

    ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c52b", RUN+="keymap $name custom-brightness"
    
  • 笔记本电脑键盘
    如果/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"
    

    现在还添加一条规则,/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
    

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

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

确保 udev 加载新规则
要加载新规则,请运行

sudo adevadm trigger

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

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

sudo /lib/udev/keymap -i input/event4

现在应该报告亮度键

scan code: 0x89   key code: prog1
scan code: 0x88   key code: prog2

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

为了亮度,你仍然需要将按键绑定到脚本,现在可以使用系统设置 > 键盘 > 快捷键

享受



笔记

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

  • 非常感谢Vaidas Jablonskis 的这篇文章很有帮助。

答案2

使用 halevt 的解决方案

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

编辑:经过一番大汗淋漓,我终于在 中完成了这件事udev。参见我的其他答案

我将使用vim来编辑文件,但如果您不知道,您可以用或vim替换它。nanogedit

安装 halevt

sudo apt-get update && sudo apt-get install halevt

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

sudo /etc/init.d/halevt stop

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

sudo -u halevt halevt -fig:plugdev

现在按下键盘上要绑定脚本的功能键。我知道楼主想让亮度键工作,所以我们就照做吧。亮度键的输出应该如下所示:

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)

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

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

sudo vim /etc/halevt/halevt.xml

并添加以下几行(我在底部,就在之前添加</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>

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

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

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

sudo EDITOR=vim visudo

并在底部添加以下几行

halevt ALL=(root) NOPASSWD: /home/user/brightness-script.sh 

并保存并退出。

确保您的脚本是可执行的

sudo chmod +x /home/user/brightness-script.sh

重新启动 halevt 守护进程

sudo /etc/init.d/halevt start

而且它应该可以工作!

相关内容