У меня планшет Lenovo ThinkPad X230 с Ubuntu 16.04. Он имеет конвертируемый экран , и когда он находится в режиме планшета, сенсорная панель все еще активна и создает беспорядок.
Я создал следующий скрипт и привязал его к одной из встроенных кнопок (с помощью пользовательского ярлыка ):
#!/bin/bash -e
# Find the TouchPad device ID
ID="$(xinput | grep -ioP 'touchpad.*id=\K[0-9]*')"
if [ "$(LANG=C xinput --list-props "$ID" | awk 'NR==2{print $4}')" == "0" ]; then
# If the device is disabled, then enable it and kill 'onboard' virtual keyboard
xinput enable "$ID"; killall onboard; xrandr -o normal
elif [ "$(LANG=C xinput --list-props "$ID" | awk 'NR==2{print $4}')" == "1" ]; then
# If the device is enabled, then disable it and run 'onboard' virtual keyboard
xinput disable "$ID"; nohup onboard >/dev/null 2>&1 &
fi
Скрипт работает правильно, но это ложное решение, и вчера я потратил несколько часов, чтобы научиться делать это правильно. Поэтому я решил поделиться этим опытом здесь.
Чтобы проверить, находится ли устройство в режиме планшета или нет, мы могли бы прочитать значение (0
или 1
):
/sys/devices/platform/thinkpad_acpi/hotkey_tablet_mode
Это значение переключается конкретными событиями. Мы можем перехватить эти события и связать с ними сценарии, используя acpid
- демон событий расширенной конфигурации и интерфейса питания.
1. Поймай события. Выполните acpi_listen
или netcat -U /var/run/acpid.socket
, поверните крышку в режиме планшета, затем поверните ее обратно. Вот пример выходных данных:
$ acpi_listen
video/tabletmode TBLT 0000008A 00000001
video/tabletmode TBLT 0000008A 00000000
Обратите внимание, что когда крышка закрыта / открыта, результат отличается:
$ acpi_listen
button/lid LID close
button/lid LID open
<час> 2. Сконфигурируйте acpid
для распознавания событий, вызванных изменением режима устройства. Запустите следующие строки в терминал как (одиночные) команды:
cat << EOF | sudo tee /etc/acpi/events/thinkpad-tablet-enabled
# /etc/acpi/events/thinkpad-tablet-enabled
# This is called when the lid is placed in tablet position on
# Lenovo ThinkPad X230 Tablet
event=video/tabletmode TBLT 0000008A 00000001
action=/etc/acpi/thinkpad-touchpad-twist-mode.sh 1
EOF
cat << EOF | sudo tee /etc/acpi/events/thinkpad-tablet-disabled
# /etc/acpi/events/thinkpad-tablet-disabled
# This is called when the lid is placed in normal position on
# Lenovo ThinkPad X230 Tablet
event=video/tabletmode TBLT 0000008A 00000000
action=/etc/acpi/thinkpad-touchpad-twist-mode.sh 0
EOF
Приведенные выше команды создадут файлы:
/etc/acpi/events/thinkpad-tablet-enabled
/etc/acpi/events/thinkpad-tablet-disabled
Примечание. Здесь не представлены сценарии открытия / закрытия крышки. Но они похожи, как указано выше.
3. Перезапустите acpid
, чтобы он мог перечитать фильтры событий, включая те, которые вы только что добавили:
sudo systemctl restart acpid.service
4. Создайте скрипт /etc/acpi/thinkpad-touchpad-in-twist-mode.sh
, который отключит 1
и включит 0
сенсорную панель (&&
сделает ее исполняемой):
cat << EOF | sudo tee /etc/acpi/thinkpad-touchpad-twist-mode.sh && sudo chmod +x /etc/acpi/thinkpad-touchpad-twist-mode.sh
#!/bin/sh
LANG=C # Ensure stable parsing
export DISPLAY="\$(w | awk 'NF > 7 && \$2 ~ /tty[0-9]+/ {print \$3; exit}' 2>/dev/null)" # Get and export the current user's \$DISPAY
export XAUTHORITY="/home/\$(w | awk 'NF > 7 && \$2 ~ /tty[0-9]+/ {print \$1; exit}' 2>/dev/null)/.Xauthority" # Get and export the currentuser's \$XAUTHORITY
ID="\$(xinput | grep -ioP 'touchpad.*id=\K[0-9]*')" # Find the TouchPad device ID
if [ "\${1}" -eq 0 ]; then xinput enable "\$ID" # Laptop mode or Lid is open
elif [ "\${1}" -eq 1 ]; then xinput disable "\$ID" # Tablet mode or Lid is closed
fi
EOF
$DISPAY
и $XAUTHORITY
сеанса текущего пользователя, чтобы позволить root
(который запускает процесс acpid
) получить доступ к сеансу X пользователя соответственно xinput
. $ID
сенсорной панели. И в зависимости от значения входной переменной $1
он включает или отключает сенсорную панель. Примечание. Обратные косые черты перед знаками доллара \$
предназначены для того, чтобы избежать расширения переменной (подстановка команды) в команде cat
. Поэтому, если вы копируете / вставляете скрипт (вместо этого используя подход cat
), вы должны удалить их вручную.
Ссылки:
acpid
- Демон событий расширенной конфигурации и интерфейса питания. w
и awk
и Удалить отдельные слова из строк, используя grep -P '\K'
. используя ответ pa4080,
я должен был сделать это изменение, чтобы оно работало в Ubuntu 18.04: жестко кодируйте моего пользователя в скрипте и запускайте скрипт в контексте моего пользователя.
файл: / etc / acpi / events / thinkpad-lid-event
event=button/lid.*
action=su tim -c '/home/tim/scripts/lid.sh.post'
и lid.sh.post равен
#! /bin/bash
# toggle touchpad enabled status when lid changes (lid closed,touchpad off)
# is run in user context
#
# example rule /etc/acpi/events/thinkpad-lid-close
# event=button/lid.*
# action=su tim -c '/home/tim/scripts/lid.sh.post'
#
# see https://askubuntu.com/questions/91534/disable-touchpad-while-the-lid-is-down
# and https://askubuntu.com/questions/980997/how-do-i-disable-the-touchpad-when-the-lid-is-twisted-or-closed/980999#980999
# this needs an event defined in /etc/acpi/events to call this script when lid status changes
# these variables need to be set to use xinput properly
export XAUTHORITY=`ls -1 /home/$USER/.Xauthority | head -n 1`
export DISPLAY=":`ls -1 /tmp/.X11-unix/ | sed -e s/^X//g | head -n 1`"
export TouchPadID=$(xinput | grep 'TouchPad' | sed -n "s/^.*id=\([[:digit:]]\+\).*$/\1/p")
grep -q closed /proc/acpi/button/lid/*/state
LidClosedResult=$?
xinput set-int-prop $TouchPadID "Device Enabled" 8 $LidClosedResult
if [ $? -eq 0 ]
then
echo "for user: $USER xinput device $TouchPadID enabled status changed to $LidClosedResult because of LID ACPI event" | systemd-cat
else
echo "failed to change xinput device $TouchPadID enabled status after LID ACPI event" | systemd-cat
fi
~