Arch linux UDEV is not working: Process '/usr/bin/synclient touchpadoff=1' failed with exit code 1

926 Views Asked by At

I want to turn off the touchpad when a USB mouse is plugged in.

Here are my rules:

SUBSYSTEMS=="usb", DRIVERS=="usb", ATTRS{manufacturer}=="Logitech", ATTRS{product}=="USB Receiver", ACTION=="add", RUN+="/usr/bin/synclient touchpadoff=1"
SUBSYSTEMS=="usb", DRIVERS=="usb", ATTRS{manufacturer}=="Logitech", ATTRS{product}=="USB Receiver", ACTION=="remove", RUN+="/usr/bin/synclient touchpadoff=0"

But it gave me this message:

Process '/usr/bin/synclient touchpadoff=1' failed with exit code 1.

I don't know what the above message means.

Help me.

1

There are 1 best solutions below

0
On

It's not work because command "/usr/bin/synclient touchpadoff=1" in udev rules run by another user than auth in Xorg session.

for example if root run "/usr/bin/synclient touchpadoff=1" we got a error:

X11 connection rejected because of wrong authentication.
Failed to connect to X Server.

You should add "udev monitor" script in the startup/autostart applications in your desktop environment (link) or run by current X-authorized user.

I write udev script for my mouse. My mouse has VID 046d and PID c06d - you should replace them with your own. Also you need install Udev::FFI module (run "cpanm Udev::FFI" or "cpan Udev::FFI")

#!/usr/bin/perl
# ATTENTION place it script to startup/autostart applications in your desktop
# environment or run by current x-session user.

use strict;
use warnings;

use Udev::FFI;


use constant {
    MOUSES => [{
        VID => '046d',
        PID => 'c06d'
    }],

    ON_TOUCHPAD_COMMAND => '/usr/bin/synclient touchpadoff=0',
    OFF_TOUCHPAD_COMMAND => '/usr/bin/synclient touchpadoff=1'
};


my %inserted_mouses;



my $udev = Udev::FFI->new() or
    die "Can't create udev context: $@.\n";


# monitor for new devices
my $monitor = $udev->new_monitor() or
    die "Can't create udev monitor: $@.\n";

$monitor->filter_by_subsystem_devtype('usb', 'usb_device');

# start monitor before enumerate to catch devices inserted between enumerate and
# $monitor->poll()
$monitor->start() or
    die "Can't start udev monitor :(\n";


# check already inserted devices
my $enumerate = $udev->new_enumerate() or
    die "Can't create enumerate context: $@.\n";

$enumerate->add_match_subsystem('usb');
# some versions of libudev work incorrectly with $enumerate->add_match_sysattr('idVendor', $vid);
$enumerate->add_match_sysattr('idVendor');
$enumerate->add_match_sysattr('idProduct');
$enumerate->scan_devices();

my @inserted_devices = $enumerate->get_list_entries();
for(@inserted_devices) {
    my $device = $udev->new_device_from_syspath($_);
    my $device_vid = $device->get_sysattr_value("idVendor");
    my $device_pid = $device->get_sysattr_value("idProduct");

    for(@{+MOUSES}) {
        if($device_vid eq $_->{VID} && $device_pid eq $_->{PID}) {
            $inserted_mouses{ $device->get_devpath() } = 1;
            last;
        }
    }
}

# known mouses > 0
if(%inserted_mouses) {
    system(OFF_TOUCHPAD_COMMAND);
}


for(;;) {
    my $device = $monitor->poll(); # blocking read
    my $action = $device->get_action();
    my $device_vid = $device->get_sysattr_value("idVendor");
    my $device_pid = $device->get_sysattr_value("idProduct");

    if($action eq 'add' && defined($device_vid) && defined($device_pid)) {
        for(@{+MOUSES}) {
            if($device_vid eq $_->{VID} && $device_pid eq $_->{PID}) {
                system(OFF_TOUCHPAD_COMMAND)
                    unless %inserted_mouses;

                $inserted_mouses{ $device->get_devpath() } = 1;
                last;
            }
        }
    }
    elsif($action eq 'remove') {
        delete $inserted_mouses{ $device->get_devpath() };

        # known mouses == 0
        unless(%inserted_mouses) {
            system(ON_TOUCHPAD_COMMAND);
        }
    }
}