On my Dell Vostro 1520, pressing the brightness up/down keys results in GNOME adjusting the brightness by two steps instead of one.

This is demonstrated by running libinput-debug-events and pressing the brightness control keys:

# libinput-debug-events
WARNING: This compatibility wrapper will be removed in the future. Please run 'libinput debug-events' instead
-event4   DEVICE_ADDED     Power Button                      seat0 default group1  cap:k
-event5   DEVICE_ADDED     Video Bus                         seat0 default group2  cap:k
-event2   DEVICE_ADDED     Power Button                      seat0 default group3  cap:k
-event1   DEVICE_ADDED     Lid Switch                        seat0 default group4  cap:S
-event3   DEVICE_ADDED     Sleep Button                      seat0 default group5  cap:k
-event9   DEVICE_ADDED     HDA Intel Mic                     seat0 default group6  cap:
-event10  DEVICE_ADDED     HDA Intel Front Headphone         seat0 default group6  cap:
-event0   DEVICE_ADDED     AT Translated Set 2 keyboard      seat0 default group7  cap:k
-event6   DEVICE_ADDED     AlpsPS/2 ALPS GlidePoint          seat0 default group8  cap:p  size 73x51mm tap(dl off) left scroll-nat scroll-edge dwt-on
-event0   KEYBOARD_KEY      +5.62s      KEY_BRIGHTNESSDOWN (224) pressed
 event0   KEYBOARD_KEY      +5.62s      KEY_BRIGHTNESSDOWN (224) released
-event5   KEYBOARD_KEY      +5.63s      KEY_BRIGHTNESSDOWN (224) pressed
 event5   KEYBOARD_KEY      +5.63s      KEY_BRIGHTNESSDOWN (224) released
 event5   KEYBOARD_KEY      +6.43s      KEY_BRIGHTNESSDOWN (224) pressed
 event5   KEYBOARD_KEY      +6.43s      KEY_BRIGHTNESSDOWN (224) released
-event0   KEYBOARD_KEY      +6.43s      KEY_BRIGHTNESSDOWN (224) pressed
 event0   KEYBOARD_KEY      +6.43s      KEY_BRIGHTNESSDOWN (224) released
-event5   KEYBOARD_KEY      +7.11s      KEY_BRIGHTNESSDOWN (224) pressed
 event5   KEYBOARD_KEY      +7.11s      KEY_BRIGHTNESSDOWN (224) released
-event0   KEYBOARD_KEY      +7.11s      KEY_BRIGHTNESSDOWN (224) pressed
 event0   KEYBOARD_KEY      +7.11s      KEY_BRIGHTNESSDOWN (224) released
 event0   KEYBOARD_KEY      +8.38s      KEY_BRIGHTNESSUP (225) pressed
 event0   KEYBOARD_KEY      +8.38s      KEY_BRIGHTNESSUP (225) released
-event5   KEYBOARD_KEY      +8.38s      KEY_BRIGHTNESSUP (225) pressed
 event5   KEYBOARD_KEY      +8.38s      KEY_BRIGHTNESSUP (225) released
-event0   KEYBOARD_KEY      +9.01s      KEY_BRIGHTNESSUP (225) pressed
 event0   KEYBOARD_KEY      +9.01s      KEY_BRIGHTNESSUP (225) released
-event5   KEYBOARD_KEY      +9.01s      KEY_BRIGHTNESSUP (225) pressed
 event5   KEYBOARD_KEY      +9.01s      KEY_BRIGHTNESSUP (225) released
-event0   KEYBOARD_KEY      +9.61s      KEY_BRIGHTNESSUP (225) pressed
 event0   KEYBOARD_KEY      +9.61s      KEY_BRIGHTNESSUP (225) released
-event5   KEYBOARD_KEY      +9.61s      KEY_BRIGHTNESSUP (225) pressed
 event5   KEYBOARD_KEY      +9.61s      KEY_BRIGHTNESSUP (225) released

It appears that pressing a brightness key once results in two sets of events from different input devices: event0, the regular keyboard, and event5 which is a keyboard named Video Bus.

We want to ignore events from one of these devices. We could do this by running xinput disable 'Video Bus', but this is not a permanent solution. It would be better to use udev rules to tell libinput to ignore events from the device instead.

From the libinput documentation we can see we want to apply the LIBINPUT_IGNORE_DEVICE property to the device. In order to do this, we need to identify it with udevadm info:

$ udevadm info -a -p  /sys/class/input/event5

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:01/input/input7/event5':
    KERNEL=="event5"
    SUBSYSTEM=="input"
    DRIVER==""

  looking at parent device '/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:01/input/input7':
    KERNELS=="input7"
    SUBSYSTEMS=="input"
    DRIVERS==""
    ATTRS{name}=="Video Bus"
    ATTRS{phys}=="LNXVIDEO/video/input0"
    ATTRS{properties}=="0"
    ATTRS{uniq}==""

  looking at parent device '/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:01':
    KERNELS=="LNXVIDEO:01"
    SUBSYSTEMS=="acpi"
    DRIVERS=="video"
    ATTRS{adr}=="0x00020000"
    ATTRS{hid}=="LNXVIDEO"
    ATTRS{path}=="\_SB_.PCI0.GFX0"

  looking at parent device '/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00':
    KERNELS=="PNP0A08:00"
    SUBSYSTEMS=="acpi"
    DRIVERS==""
    ATTRS{adr}=="0x00000000"
    ATTRS{hid}=="PNP0A08"
    ATTRS{path}=="\_SB_.PCI0"
    ATTRS{uid}=="0"

  looking at parent device '/devices/LNXSYSTM:00/LNXSYBUS:00':
    KERNELS=="LNXSYBUS:00"
    SUBSYSTEMS=="acpi"
    DRIVERS==""
    ATTRS{hid}=="LNXSYBUS"
    ATTRS{path}=="\_SB_"

  looking at parent device '/devices/LNXSYSTM:00':
    KERNELS=="LNXSYSTM:00"
    SUBSYSTEMS=="acpi"
    DRIVERS==""
    ATTRS{hid}=="LNXSYSTM"
    ATTRS{path}=="\"

Using the ACPI bus path of an ancestor device looks like a reasonable way to identify the device. This leaves us with the following rule:

$ cat /etc/udev/rules.d/90-libinput-ignore-video-brightness.rules
KERNEL=="event*", ATTRS{path}=="\_SB_.PCI0.GFX0", ENV{LIBINPUT_IGNORE_DEVICE}="1"

With that in place, we can test the rule to see if the match works;

udevadm test /sys/class/input/event5
calling: test
version 238
Load module index
Parsed configuration file /lib/systemd/network/99-default.link
Created link configuration context.
Reading rules file: /lib/udev/rules.d/39-usbmuxd.rules
Reading rules file: /lib/udev/rules.d/40-usb-media-players.rules
Reading rules file: /lib/udev/rules.d/40-usb_modeswitch.rules
Reading rules file: /lib/udev/rules.d/50-firmware.rules
Reading rules file: /lib/udev/rules.d/50-udev-default.rules
Reading rules file: /lib/udev/rules.d/55-Argyll.rules
/lib/udev/rules.d/55-Argyll.rules:132: IMPORT found builtin 'usb_id --export %p', replacing
Reading rules file: /lib/udev/rules.d/55-dm.rules
Reading rules file: /lib/udev/rules.d/56-hpmud.rules
Reading rules file: /lib/udev/rules.d/56-lvm.rules
Reading rules file: /lib/udev/rules.d/60-block.rules
Reading rules file: /lib/udev/rules.d/60-cdrom_id.rules
Reading rules file: /lib/udev/rules.d/60-crda.rules
Reading rules file: /lib/udev/rules.d/60-drm.rules
Reading rules file: /lib/udev/rules.d/60-evdev.rules
Reading rules file: /lib/udev/rules.d/60-fuse.rules
Reading rules file: /lib/udev/rules.d/60-input-id.rules
Reading rules file: /lib/udev/rules.d/60-libgphoto2-6.rules
Reading rules file: /lib/udev/rules.d/60-libsane.rules
Reading rules file: /lib/udev/rules.d/60-pcmcia.rules
Reading rules file: /lib/udev/rules.d/60-persistent-alsa.rules
Reading rules file: /lib/udev/rules.d/60-persistent-input.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage-dm.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage-tape.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage.rules
Reading rules file: /lib/udev/rules.d/60-persistent-v4l.rules
Reading rules file: /lib/udev/rules.d/60-sensor.rules
Reading rules file: /lib/udev/rules.d/60-serial.rules
Reading rules file: /lib/udev/rules.d/61-gnome-settings-daemon-rfkill.rules
Reading rules file: /lib/udev/rules.d/64-btrfs.rules
Reading rules file: /lib/udev/rules.d/64-xorg-xkb.rules
Reading rules file: /lib/udev/rules.d/65-libwacom.rules
Reading rules file: /lib/udev/rules.d/69-cd-sensors.rules
Reading rules file: /lib/udev/rules.d/69-libmtp.rules
Reading rules file: /lib/udev/rules.d/69-lvm-metad.rules
Reading rules file: /lib/udev/rules.d/69-wacom.rules
Reading rules file: /lib/udev/rules.d/69-yubikey.rules
Reading rules file: /lib/udev/rules.d/70-joystick.rules
Reading rules file: /lib/udev/rules.d/70-mouse.rules
Reading rules file: /lib/udev/rules.d/70-power-switch.rules
Reading rules file: /lib/udev/rules.d/70-printers.rules
Reading rules file: /lib/udev/rules.d/70-touchpad.rules
Reading rules file: /lib/udev/rules.d/70-u2f.rules
Reading rules file: /lib/udev/rules.d/70-uaccess.rules
Reading rules file: /lib/udev/rules.d/71-seat.rules
Reading rules file: /lib/udev/rules.d/73-seat-late.rules
Reading rules file: /lib/udev/rules.d/73-special-net-names.rules
Reading rules file: /lib/udev/rules.d/73-usb-net-by-mac.rules
Reading rules file: /lib/udev/rules.d/75-net-description.rules
Reading rules file: /lib/udev/rules.d/75-probe_mtd.rules
Reading rules file: /lib/udev/rules.d/77-mm-cinterion-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-dell-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-ericsson-mbm.rules
Reading rules file: /lib/udev/rules.d/77-mm-haier-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-huawei-net-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-longcheer-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-mtk-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-nokia-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-pcmcia-device-blacklist.rules
Reading rules file: /lib/udev/rules.d/77-mm-qdl-device-blacklist.rules
Reading rules file: /lib/udev/rules.d/77-mm-sierra.rules
Reading rules file: /lib/udev/rules.d/77-mm-simtech-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-telit-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-ublox-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-usb-device-blacklist.rules
Reading rules file: /lib/udev/rules.d/77-mm-usb-serial-adapters-greylist.rules
Reading rules file: /lib/udev/rules.d/77-mm-x22x-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-zte-port-types.rules
Reading rules file: /lib/udev/rules.d/78-sound-card.rules
Reading rules file: /lib/udev/rules.d/80-debian-compat.rules
Reading rules file: /lib/udev/rules.d/80-drivers.rules
Reading rules file: /lib/udev/rules.d/80-iio-sensor-proxy.rules
Reading rules file: /lib/udev/rules.d/80-libinput-device-groups.rules
Reading rules file: /lib/udev/rules.d/80-mm-candidate.rules
Reading rules file: /lib/udev/rules.d/80-net-setup-link.rules
Reading rules file: /lib/udev/rules.d/80-udisks2.rules
Reading rules file: /lib/udev/rules.d/84-nm-drivers.rules
Reading rules file: /lib/udev/rules.d/85-hdparm.rules
Reading rules file: /lib/udev/rules.d/85-hplj10xx.rules
Reading rules file: /lib/udev/rules.d/85-hwclock.rules
Reading rules file: /lib/udev/rules.d/85-nm-unmanaged.rules
Reading rules file: /lib/udev/rules.d/85-regulatory.rules
Reading rules file: /lib/udev/rules.d/90-alsa-restore.rules
Reading rules file: /lib/udev/rules.d/90-console-setup.rules
Reading rules file: /lib/udev/rules.d/90-libgpod.rules
Reading rules file: /etc/udev/rules.d/90-libinput-ignore-video-brightness.rules
Reading rules file: /lib/udev/rules.d/90-libinput-model-quirks.rules
Reading rules file: /lib/udev/rules.d/90-pulseaudio.rules
Reading rules file: /lib/udev/rules.d/95-cd-devices.rules
Reading rules file: /lib/udev/rules.d/95-dm-notify.rules
Reading rules file: /lib/udev/rules.d/95-upower-csr.rules
Reading rules file: /lib/udev/rules.d/95-upower-hid.rules
Reading rules file: /lib/udev/rules.d/95-upower-wup.rules
Reading rules file: /lib/udev/rules.d/97-hid2hci.rules
Reading rules file: /lib/udev/rules.d/99-systemd.rules
rules contain 393216 bytes tokens (32768 * 12 bytes), 38660 bytes strings
29504 strings (242601 bytes), 25643 de-duplicated (207803 bytes), 3862 trie nodes used
GROUP 106 /lib/udev/rules.d/50-udev-default.rules:29
IMPORT builtin 'hwdb' /lib/udev/rules.d/60-evdev.rules:8
IMPORT builtin 'hwdb' returned non-zero
IMPORT builtin 'hwdb' /lib/udev/rules.d/60-evdev.rules:17
IMPORT builtin 'hwdb' returned non-zero
IMPORT builtin 'hwdb' /lib/udev/rules.d/60-evdev.rules:21
IMPORT builtin 'hwdb' returned non-zero
IMPORT builtin 'input_id' /lib/udev/rules.d/60-input-id.rules:5
capabilities/ev raw kernel attribute: 3
capabilities/abs raw kernel attribute: 0
capabilities/rel raw kernel attribute: 0
capabilities/key raw kernel attribute: 3e000b00000000 0 0 0
properties raw kernel attribute: 0
test_key: checking bit block 0 for any keys; found=0
test_key: checking bit block 64 for any keys; found=0
test_key: checking bit block 128 for any keys; found=0
test_key: checking bit block 192 for any keys; found=1
IMPORT builtin 'hwdb' /lib/udev/rules.d/60-input-id.rules:6
IMPORT builtin 'hwdb' returned non-zero
IMPORT builtin 'path_id' /lib/udev/rules.d/60-persistent-input.rules:35
PROGRAM 'libinput-device-group /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:01/input/input7/event5' /lib/udev/rules.d/80-libinput-device-groups.rules:7
starting 'libinput-device-group /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:01/input/input7/event5'
'libinput-device-group /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:01/input/input7/event5'(out) '19/0/6:LNXVIDEO/video'
Process 'libinput-device-group /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:01/input/input7/event5' succeeded.
IMPORT builtin 'hwdb' /lib/udev/rules.d/90-libinput-model-quirks.rules:46
IMPORT builtin 'hwdb' returned non-zero
IMPORT builtin 'hwdb' /lib/udev/rules.d/90-libinput-model-quirks.rules:50
IMPORT builtin 'hwdb' returned non-zero
handling device node '/dev/input/event5', devnum=c13:69, mode=0660, uid=0, gid=106
preserve permissions /dev/input/event5, 020660, uid=0, gid=106
preserve already existing symlink '/dev/char/13:69' to '../input/event5'
Unload module index
Unloaded link configuration context.
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.

ACTION=add
BACKSPACE=guess
DEVNAME=/dev/input/event5
DEVPATH=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:01/input/input7/event5
ID_INPUT=1
ID_INPUT_KEY=1
ID_PATH=acpi-LNXVIDEO:01
ID_PATH_TAG=acpi-LNXVIDEO_01
LIBINPUT_DEVICE_GROUP=19/0/6:LNXVIDEO/video
LIBINPUT_IGNORE_DEVICE=1
MAJOR=13
MINOR=69
SUBSYSTEM=input
TAGS=:power-switch:
USEC_INITIALIZED=13461510
XKBLAYOUT=gb
XKBMODEL=pc105
XKBOPTIONS=
XKBVARIANT=

Looks like it worked. Let's apply the rule for real:

# udevadm trigger /sys/class/input/event5
$ udevadm info /sys/class/input/event5
P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:01/input/input7/event5
N: input/event5
E: BACKSPACE=guess
E: DEVNAME=/dev/input/event5
E: DEVPATH=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:01/input/input7/event5
E: ID_INPUT=1
E: ID_INPUT_KEY=1
E: ID_PATH=acpi-LNXVIDEO:01
E: ID_PATH_TAG=acpi-LNXVIDEO_01
E: LIBINPUT_DEVICE_GROUP=19/0/6:LNXVIDEO/video
E: LIBINPUT_IGNORE_DEVICE=1
E: MAJOR=13
E: MINOR=69
E: SUBSYSTEM=input
E: TAGS=:power-switch:
E: USEC_INITIALIZED=13461510
E: XKBLAYOUT=gb
E: XKBMODEL=pc105

Surely enough, running libinput-list-devices no longer lists event5, so from now on Xorg will ignore the unwanted device!


Having re-read the libinput page, it appears that an entry in the libinput quirks hwdb file can be used instead of a udev rule. This was submitted upstream as https://bugs.freedesktop.org/show_bug.cgi?id=106057.


CategoryTechnote

robots.org.uk: IgnoringLaptopBrightnessDuplicatedEvents (last edited 2018-04-15 18:53:19 by sam)

© Sam Morris <sam@robots.org.uk>.
Content may be distributed and modified providing this notice is preserved.