经验分享:笔电 + wayland,接入外置键盘的时候禁用笔记本键盘脚本

之前一直使用的是 xinput 检测外接键盘与禁用内置键盘,但是最近用上了 wayland,xinput用不了,只好另外想办法,下面是我写的脚本,实测可用,希望能够帮到有同样需求的人,同时也请大佬不吝赐教。

#!/usr/bin/env sh
#
# Disable built_in_keyboard when external_keyboard enabled, also enable
# built_in_keyboard when external_keyboard disabled.
#

# Interval
Delay_lag=5

built_in_keyboard="AT Translated Set 2 keyboard" # Name of built_in_keyboard
external_keyboard="AnnePro2 P2 Keyboard"         # Name of external_keyboard
built_in_keyboard_file=$(libinput list-devices | grep -A1 "${built_in_keyboard}" | awk 'NR==2{print $2}')

# Main loop
while true
do
    if $(libinput list-devices | grep "Device:" | grep AnnePro2 > /dev/null); then
        # External keyboard enabled
        external_keyboard_enabled=1
    else
        # External keyboard disabled
        external_keyboard_enabled=0
    fi

    # Process informations
    if [[ "${external_keyboard_enabled}" -eq 1 ]]; then # if external keyboard enabled
        if  [[ ! ${process_pid} ]]; then # if had not disabled keyboard
            evtest --grab "${built_in_keyboard_file}" > /dev/null &
            process_pid=$!
        fi
    else # if external keyboard not enabled
        if [[ ${process_pid} ]]; then # if built in keyboard had been disabled before
            kill $process_pid
            unset process_pid
        fi
    fi

    # Delay
    sleep ${Delay_lag}

done
2 个赞

然后我就可以这样用我的键盘了

用xinput怎么做到这一点?

不搞个udev触发吗?

有想过,但是毕竟不太熟悉,我要准备期末考试没有那么多时间来学习怎么写udev。。。

xinput的话就把检测部分和禁用部分改成xinput | grep…和 xinput disable “${builtin_keyboard}” 就行了。。。

抱歉,手机上面打字有点乱,不知所云。。。

上面的代码用了很久,使用上面有一点问题:suspend 或者 hibernate 之后,或在退出登录之后,有几率出现外置键盘也没有办法使用的情况,这下两个键盘都用不了了只能重启电脑。很神秘,一直找不出原因,所以一直没有怎么用这个脚本了。

因为最近要用,考虑到这个bug,我使用 timeout 改了下程序:每个evtest的进程只进行10秒种,然后每5秒钟检测一次是否需要禁用键盘。具体的看代码吧。这个方法感觉挺笨,不过能用就行,要什么自行车?

#!/usr/bin/env sh
#/Dotfiles/Scripts/keyboard.sh 
#
# Disable built_in_keyboard when external_keyboard enabled, also enable
# built_in_keyboard when external_keyboard disabled.
#

# Interval
built_in_keyboard="AT Translated Set 2 keyboard" # Name of built_in_keyboard
external_keyboard="AnnePro2 P2 Keyboard"         # Name of external_keyboard
built_in_keyboard_file=$(libinput list-devices | grep -A1 "${built_in_keyboard}" | awk 'NR==2{print $2}')


# 

export interval=10

function external_keyboard_connected_p () {
    if $(libinput list-devices | grep "Device:" | grep AnnePro2 > /dev/null); then
        # In BASH script, number 0 stand for "success"
        return 0
    else
        # Non-0 number stand for "error signal"
        return 1
    fi
}

function disable_builtin_keyboard_maybe () {
    if external_keyboard_connected_p; then    
        timeout -s 9 ${interval} evtest --grab "${built_in_keyboard_file}" > /dev/null
    fi
}

function main () {
    while true
    do
        disable_builtin_keyboard_maybe > /dev/null 2>&1 &
        sleep $((${interval} / 2))
    done
}

main

我人麻了,刚刚那个方法还是禁不掉,不知道什么原因,evtest 真的有点搞我的心态。我用xinput算了,就改动一下一个地方就好,完整的代码如下

#!/usr/bin/env sh
#/Dotfiles/Scripts/keyboard.sh 
#
# Disable built_in_keyboard when external_keyboard enabled, also enable
# built_in_keyboard when external_keyboard disabled.
#

built_in_keyboard="AT Translated Set 2 keyboard" # Name of built_in_keyboard
external_keyboard="AnnePro2 P2 Keyboard"         # Name of external_keyboard
built_in_keyboard_file=$(libinput list-devices | grep -A1 "${built_in_keyboard}" | awk 'NR==2{print $2}')

# interval
export interval=10

function external_keyboard_connected_p () {
    if $(libinput list-devices | grep "Device:" | grep AnnePro2 > /dev/null); then
        # In BASH script, number 0 stand for "success"
        return 0
    else
        # Non-0 number stand for "error signal"
        return 1
    fi
}

function disable_builtin_keyboard_maybe () {
    if external_keyboard_connected_p; then
        echo "Disable builtin keyboard"
        # timeout -s 9 ${interval} evtest --grab "${built_in_keyboard_file}" > /dev/null
        xinput disable "${built_in_keyboard}"
    else
        echo "Enable builtin keyboard"
        xinput enable "${built_in_keyboard}"
    fi
}

function main () {
    while true
    do
        echo "testing..."
        disable_builtin_keyboard_maybe 2> /dev/null &
        sleep $((${interval} / 2))
    done
}

main
1 个赞