2044
udevrules и Xbox gamepad
Прокунсультируйте кто-нибудь по udevrules.
предпосылки: при игре с помощью геймпада, монитор вырубается — уходит в спящий режим. нагуглил решение — маленькая утилита из aur — joystickwake. только ее нужно запускать в фоне перед запуском игры, а потом вырубать (можно не вырубать, но борьба за ресурсы, все дела).
задача — выполнять скрипт при подключении геймпада, а при отключении выполнять еще один.
пытаюсь освоить udevrules, а тут еще и подвернулся повод)
что делаю:
[ 3558.815661] usb 1-4: new full-speed USB device number 20 using xhci_hcd
[ 3558.960747] usb 1-4: New USB device found, idVendor=045e, idProduct=02ea, bcdDevice= 3.01
[ 3558.960753] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 3558.960757] usb 1-4: Product: Controller
[ 3558.960760] usb 1-4: Manufacturer: Microsoft
[ 3558.960763] usb 1-4: SerialNumber: 3033363030303431393237383334
[ 3558.962538] input: Microsoft X-Box One S pad as /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/input/input37
методом «от противного» узнаю, что мой гемпад коннектится как /dev/input/js1
looking at device '/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/input/input28/js1':
KERNEL==«js1»
SUBSYSTEM==«input»
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/input/input28':
KERNELS==«input28»
SUBSYSTEMS==«input»
DRIVERS==""
ATTRS{name}==«Microsoft X-Box One S pad»
ATTRS{uniq}==""
ATTRS{properties}==«0»
ATTRS{phys}==«usb-0000:00:14.0-4/input0»
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0':
KERNELS==«1-4:1.0»
SUBSYSTEMS==«usb»
DRIVERS==«xpad»
ATTRS{authorized}==«1»
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceNumber}==«00»
ATTRS{bNumEndpoints}==«02»
ATTRS{bInterfaceProtocol}==«d0»
ATTRS{bInterfaceSubClass}==«47»
ATTRS{bInterfaceClass}==«ff»
ATTRS{supports_autosuspend}==«0»
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-4':
KERNELS==«1-4»
SUBSYSTEMS==«usb»
DRIVERS==«usb»
ATTRS{maxchild}==«0»
ATTRS{serial}==«3033363030303431393237383334»
ATTRS{urbnum}==«16»
ATTRS{bcdDevice}==«0301»
ATTRS{bNumConfigurations}==«1»
ATTRS{bMaxPower}==«500mA»
ATTRS{bNumInterfaces}==" 3"
ATTRS{bDeviceProtocol}==«d0»
ATTRS{avoid_reset_quirk}==«0»
ATTRS{bmAttributes}==«a0»
ATTRS{version}==" 2.00"
ATTRS{product}==«Controller»
ATTRS{quirks}==«0x0»
ATTRS{bConfigurationValue}==«1»
ATTRS{removable}==«removable»
ATTRS{devpath}==«4»
ATTRS{rx_lanes}==«1»
ATTRS{ltm_capable}==«no»
ATTRS{devnum}==«11»
ATTRS{bMaxPacketSize0}==«64»
ATTRS{idProduct}==«02ea»
ATTRS{manufacturer}==«Microsoft»
ATTRS{bDeviceSubClass}==«47»
ATTRS{configuration}==""
ATTRS{tx_lanes}==«1»
ATTRS{devspec}=="(null)"
ATTRS{bDeviceClass}==«ff»
ATTRS{busnum}==«1»
ATTRS{speed}==«12»
ATTRS{authorized}==«1»
ATTRS{idVendor}==«045e»
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1':
KERNELS==«usb1»
SUBSYSTEMS==«usb»
DRIVERS==«usb»
ATTRS{configuration}==""
ATTRS{idVendor}==«1d6b»
ATTRS{bMaxPacketSize0}==«64»
ATTRS{speed}==«480»
ATTRS{bNumInterfaces}==" 1"
ATTRS{maxchild}==«16»
ATTRS{version}==" 2.00"
ATTRS{bmAttributes}==«e0»
ATTRS{authorized}==«1»
ATTRS{bConfigurationValue}==«1»
ATTRS{devnum}==«1»
ATTRS{authorized_default}==«1»
ATTRS{devspec}=="(null)"
ATTRS{bNumConfigurations}==«1»
ATTRS{bDeviceSubClass}==«00»
ATTRS{bMaxPower}==«0mA»
ATTRS{bDeviceProtocol}==«01»
ATTRS{rx_lanes}==«1»
ATTRS{idProduct}==«0002»
ATTRS{interface_authorized_default}==«1»
ATTRS{vendor}==«0x8086»
ATTRS{local_cpulist}==«0-7»
ATTRS{device}==«0xa12f»
ATTRS{d3cold_allowed}==«1»
ATTRS{broken_parity_status}==«0»
looking at parent device '/devices/pci0000:00':
KERNELS==«pci0000:00»
SUBSYSTEMS==""
DRIVERS==""
создаю:
SUBSYSTEM==«input», ATTRS{idVendor}==«045e», ATTRS{idProduct}==«02ea», ACTION==«add», RUN+="/etc/udev/scripts/joy.sh"
перезапускаю правила:
проверяю — не работает.
скрипт из консоли запускается. если что, вот его пример:
#!/bin/bash
joystickwake && notify-send «Xbox gamepad connected» -t 1000
конечный вариант скриптов:
но, при отключении bluetooth ивент срабатывает дважды. не особо критично, но…
предпосылки: при игре с помощью геймпада, монитор вырубается — уходит в спящий режим. нагуглил решение — маленькая утилита из aur — joystickwake. только ее нужно запускать в фоне перед запуском игры, а потом вырубать (можно не вырубать, но борьба за ресурсы, все дела).
задача — выполнять скрипт при подключении геймпада, а при отключении выполнять еще один.
пытаюсь освоить udevrules, а тут еще и подвернулся повод)
что делаю:
dmesg
[ 3558.960747] usb 1-4: New USB device found, idVendor=045e, idProduct=02ea, bcdDevice= 3.01
[ 3558.960753] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 3558.960757] usb 1-4: Product: Controller
[ 3558.960760] usb 1-4: Manufacturer: Microsoft
[ 3558.960763] usb 1-4: SerialNumber: 3033363030303431393237383334
[ 3558.962538] input: Microsoft X-Box One S pad as /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/input/input37
методом «от противного» узнаю, что мой гемпад коннектится как /dev/input/js1
sudo udevadm info -a -n /dev/input/js1
KERNEL==«js1»
SUBSYSTEM==«input»
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/input/input28':
KERNELS==«input28»
SUBSYSTEMS==«input»
DRIVERS==""
ATTRS{name}==«Microsoft X-Box One S pad»
ATTRS{uniq}==""
ATTRS{properties}==«0»
ATTRS{phys}==«usb-0000:00:14.0-4/input0»
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0':
KERNELS==«1-4:1.0»
SUBSYSTEMS==«usb»
DRIVERS==«xpad»
ATTRS{authorized}==«1»
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceNumber}==«00»
ATTRS{bNumEndpoints}==«02»
ATTRS{bInterfaceProtocol}==«d0»
ATTRS{bInterfaceSubClass}==«47»
ATTRS{bInterfaceClass}==«ff»
ATTRS{supports_autosuspend}==«0»
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-4':
KERNELS==«1-4»
SUBSYSTEMS==«usb»
DRIVERS==«usb»
ATTRS{maxchild}==«0»
ATTRS{serial}==«3033363030303431393237383334»
ATTRS{urbnum}==«16»
ATTRS{bcdDevice}==«0301»
ATTRS{bNumConfigurations}==«1»
ATTRS{bMaxPower}==«500mA»
ATTRS{bNumInterfaces}==" 3"
ATTRS{bDeviceProtocol}==«d0»
ATTRS{avoid_reset_quirk}==«0»
ATTRS{bmAttributes}==«a0»
ATTRS{version}==" 2.00"
ATTRS{product}==«Controller»
ATTRS{quirks}==«0x0»
ATTRS{bConfigurationValue}==«1»
ATTRS{removable}==«removable»
ATTRS{devpath}==«4»
ATTRS{rx_lanes}==«1»
ATTRS{ltm_capable}==«no»
ATTRS{devnum}==«11»
ATTRS{bMaxPacketSize0}==«64»
ATTRS{idProduct}==«02ea»
ATTRS{manufacturer}==«Microsoft»
ATTRS{bDeviceSubClass}==«47»
ATTRS{configuration}==""
ATTRS{tx_lanes}==«1»
ATTRS{devspec}=="(null)"
ATTRS{bDeviceClass}==«ff»
ATTRS{busnum}==«1»
ATTRS{speed}==«12»
ATTRS{authorized}==«1»
ATTRS{idVendor}==«045e»
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1':
KERNELS==«usb1»
SUBSYSTEMS==«usb»
DRIVERS==«usb»
ATTRS{configuration}==""
ATTRS{idVendor}==«1d6b»
ATTRS{bMaxPacketSize0}==«64»
ATTRS{speed}==«480»
ATTRS{bNumInterfaces}==" 1"
ATTRS{maxchild}==«16»
ATTRS{version}==" 2.00"
ATTRS{bmAttributes}==«e0»
ATTRS{authorized}==«1»
ATTRS{bConfigurationValue}==«1»
ATTRS{devnum}==«1»
ATTRS{authorized_default}==«1»
ATTRS{devspec}=="(null)"
ATTRS{bNumConfigurations}==«1»
ATTRS{bDeviceSubClass}==«00»
ATTRS{bMaxPower}==«0mA»
ATTRS{bDeviceProtocol}==«01»
ATTRS{rx_lanes}==«1»
ATTRS{idProduct}==«0002»
ATTRS{interface_authorized_default}==«1»
ATTRS{vendor}==«0x8086»
ATTRS{local_cpulist}==«0-7»
ATTRS{device}==«0xa12f»
ATTRS{d3cold_allowed}==«1»
ATTRS{broken_parity_status}==«0»
looking at parent device '/devices/pci0000:00':
KERNELS==«pci0000:00»
SUBSYSTEMS==""
DRIVERS==""
создаю:
/etc/udev/rules/50-xbox.rules
перезапускаю правила:
sudo udevadm control --reload-rules
проверяю — не работает.
скрипт из консоли запускается. если что, вот его пример:
/etc/udev/scripts/joy.sh
joystickwake && notify-send «Xbox gamepad connected» -t 1000
короче, победа.
решил отказаться от всяких joystickwake и использовать топорный метод xset. конечный вариант правила:/etc/udev/rules.d/98-xbox.rules
ACTION=="add" \
, KERNEL=="js1" \
, ATTRS{name}=="Microsoft X-Box One S pad" \
, RUN+="/bin/bash /etc/udev/scripts/joyadd.sh"
ACTION=="remove" \
, KERNEL=="js1" \
, ATTRS{name}=="Microsoft X-Box One S pad" \
, RUN+="/bin/bash /etc/udev/scripts/joyrem.sh"
# Wireless gamepad
ACTION=="add" \
, KERNEL=="input[0-9]*" \
, ATTRS{name}=="Xbox Wireless Controller" \
, RUN+="/bin/bash /etc/udev/scripts/joyadd.sh (BT)"
ACTION=="remove" \
, ATTRS{name}=="Xbox Wireless Controller" \
, RUN+="/bin/bash /etc/udev/scripts/joyrem.sh (BT)"
конечный вариант скриптов:
/etc/udev/scripts/joyadd.sh
#!/bin/bash
TIME='-t 1000'
STAT=$1
DISPLAY=":0"
XAUTHORITY=/run/user/1000/Xauthority
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
export DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS
xset -dpms
xset s off
su led -c "notify-send 'System Message' 'Xbox Gamepad $STAT connected' $TIME"
/etc/udev/scripts/joyrem.sh
#!/bin/env bash
TIME='-t 1000'
STAT=$1
DISPLAY=":0"
XAUTHORITY=/run/user/1000/Xauthority
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
export DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS
xset +dpms
xset s on
su led -c "notify-send 'Sytem Message' 'Xbox Gamepad $STAT disconnected' $TIME"
но, при отключении bluetooth ивент срабатывает дважды. не особо критично, но…
11 комментариев
Альтернативные решения.
- Смотреть в сторону WM и менеджера питания — умеет ли что-то из них отслеживать полноэкранные окна.
- Также проблему можно решить
- LightsOn, LightsOnPlus и disable_dpms. Отключают DPMS при обнаружении приложений из списка и полноэкранных окон. Для отключения скринлокера может потребоваться минимальный допил.
- Caffeine(-ng).
- Слать геймпадом фейковые клавиатурные нажатия. Но в данном случае это костыль.
К плюсам этих вариантов стоит отнести то, что подключенный геймпад не останавливает скринсейвер полностью, что выглядит весьма логичным.с изяществом таранав рамках принципа KISS средствами xautolock либо xset. Просто и надежно.само правило с name
скрипт:
не работает(
Удав работает от рута. И скрипт запускает от рута. Но su пока никто не отменял.
Получается коряво если юзверей больше одного, но работать с указанным должно. Вопрос с пользователями, в принципе, решаем путем парсинга вывода w(ho).
Для вывода уведомления может понадобиться указать значение DISPLAY.
и добавил в sudoers для joy.sh запуск без запроса пароля пользователя. из терминала запускается, из правила udev не хочет.
пробовал в скрипт вставить
не работает, хотя само правило отрабатывает. проверил с помощью отключения тачпада при подключении геймпада)
походу проблема только с кастомными скриптами, но как ее решить — ума не приложу(
ну и отслеживать окна. открытые на весь экран особо нечем. i3wm из архитекта с минимальным набором пакетов.
UPD: походу какая-то трабла с notify-send… без него все работает. ну и ладно.
Если прямо указать имя пользователя — то же самое?
Но xprop в минимальную поставку вроде как не входит.
ну xprop в принципе тоже можно использовать. спс за идею)
но мои костыли без notify-send проработали до перезагрузки и сломались)
теперь при подключении геймпада udev запускает аж 3 скрипта с joystickwake и потом исчезает из процессов)))
магия)
у меня Xauthority на хомяке не лежит. я его перенес)
в выхлопе пусто… странно…
Есть функция для поиска UID, DISPLAY и USER
С этим от можно перенести все пляски с пользователем в сам скрипт, а удав пусть себе пускает как ему нравится.
теперь notify-send отрабатывает один раз, но не запускается joystickwake. вернее, он пытается запуститься, его попытки даже видно в htop, но потом сразу падает(