LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Slackware (http://www.linuxquestions.org/questions/slackware-14/)
-   -   How to disable Alps touchpad when USB mouse is present? (http://www.linuxquestions.org/questions/slackware-14/how-to-disable-alps-touchpad-when-usb-mouse-is-present-882195/)

Totoro-kun 05-23-2011 02:37 AM

How to disable Alps touchpad when USB mouse is present?
 
Hello,
I have this little problem on my Dell latitude D620 laptop and Slackware 13.1 system. When I am writig I often hit touchpad or trackpoint buttons making the cursor jump. This is anoying. But I do not want to disable touchpad tap, it would be much more comfortable to configure Slack to disable touchpad completely when i plug in USB mouse, and enable it after I unplug the mouse.

Now, this laptop has option for this in bios, but it only works for the ps/2 mouse, not the usb. And PS/2 ports I supose are present only on docking stations, but I do not own one. It uses Alps touchpad, but is still controled via synaptic hal policies.

So I wonder if there are any easy solutions for this? Maybe a Hal rule? Xorg config files? Or do I need extra software? Maybe someone had a similar problem?

Totoro-kun 05-23-2011 07:40 AM

I have done some searching around and got a general idea on how all this should work. So generally, I need udev .rules file in /etc/udev/rules.d which would run certain commands when i plug/unplug my USB mouse. And I'll probably need couple more scripts to deal with scenarios when system boots with usb mouse connected and when system wakes up from sleep mode, but I'll deal with them later. First I need udev to do it's work.

So here is my progress:
1. I have learned about command
Code:

$ xinput list
which lists my input devices like this:
Code:

# xinput list
⎡ Virtual core pointer                            id=2        [master pointer  (3)]
⎜  ↳ Virtual core XTEST pointer                      id=4        [slave  pointer  (2)]
⎜  ↳ DualPoint Stick                                id=8        [slave  pointer  (2)]
⎜  ↳ Logitech USB Optical Mouse                      id=9        [slave  pointer  (2)]
⎜  ↳ AlpsPS/2 ALPS DualPoint TouchPad                id=7        [slave  pointer  (2)]
⎣ Virtual core keyboard                          id=3        [master keyboard (2)]
    ↳ Virtual core XTEST keyboard                    id=5        [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard                    id=6        [slave  keyboard (3)]
    ↳ Sleep Button                                    id=10        [slave  keyboard (3)]
    ↳ Power Button                                    id=11        [slave  keyboard (3)]
    ↳ Video Bus                                      id=12        [slave  keyboard (3)]

So I want that AlpsPS/2 touchpad and DualPoint Stick would both be disabled when I plug my Logitech USB optical mouse. While googling arround I have found a nice how to for fedora and there is a script for udev rules which I have took for a template and modified to my devices, and now it looks like this:
Code:

# 81-touchpad.rules
#
# this rules file must be named 61* or later because it won't work
# unless it runs after '/lib/udev/rules.d/60-persistent-input.rules'
#
# NOTE: will only affect DISPLAY :0
#
# run:
#  udevadm test --action=add /sys/devices/platform/i8042/serio1/input/input6/mouse1
# or similar to test the following rules
#

# disable PS/2 touchpad on DISPLAY :0 if a mouse is added to the system
ACTION=="add", SUBSYSTEM=="input", ENV{ID_INPUT_MOUSE}=="1", RUN+="/bin/sh -c 'DISPLAY=:0 /usr/bin/xinput --set-prop AlpsPS/2\ ALPS\ DualPoint\ TouchPad Device\ Enabled 0'"

# enable PS/2 touchpad on DISPLAY :0 if a mouse is removed from the system
ACTION=="remove", SUBSYSTEM=="input", ENV{ID_INPUT_MOUSE}=="1", RUN+="/bin/sh -c 'DISPLAY=:0 /usr/bin/xinput --set-prop AlpsPS/2\ ALPS\ DualPoint\ TouchPad Device\ Enabled 1'"

After placing this file in /etc/udev/rules.d and running /etc/rc.d/rc.udev reload I have no effect when I plug/unplug Usb mouse at all. Syslog is silent too, but if i paste /bin/sh -c 'DISPLAY=:0 /usr/bin/xinput --set-prop AlpsPS/2\ ALPS\ DualPoint\ TouchPad Device\ Enabled 0' directly into terminal, then my touchpad gets disabled, and if I change 0 with 1 and paste again, then touchpad gets enabled. So now I believe, that the approach is right, but the script is not compatible with Slackware 13.1 udev? Or I just do not know how to define my Usb mouse maybe? I am not good at scripting, so I'll be very happy if someone could correct this script for me or point to some errors :)

Many thanks in advance

allend 05-23-2011 09:41 AM

Have you tried ENV{ID_INPUT_MOUSE}=="?*" in place of ENV{ID_INPUT_MOUSE}=="1" ? This seems more in line with the match rules in /lib/udev/60-persistent-input.rules.

Totoro-kun 05-23-2011 11:38 AM

Thank you for a suggestion. I have just tried to place
Code:

ENV{ID_INPUT_MOUSE}=="?*"
instead of
Code:

ENV{ID_INPUT_MOUSE}=="1"
But this had no effect for my script. But, if i change
Code:

RUN+="/bin/sh -c 'DISPLAY=:0 /usr/bin/xinput --set-prop AlpsPS/2\ ALPS\ DualPoint\ TouchPad Device\ Enabled 0'"
for line like this:
Code:

RUN+="/usr/bin/synclient TouchpadOff=1"
then script kind of works no mater if =="?*" or =="1" is used. But the problem is, that after reloading udev rules touch pad stays disabled no mater if USB mouse is present or not.

However, I have been googling some more and then I have found article on Arch Linux wiki and then I have tried their script:
Code:

# 81-touchpad.rules
#
# This is udev rules file for configuring touchpad state

# Disable Touchpad while USB mouse is present
ACTION=="add", SUBSYSTEM=="input", KERNEL=="mouse[1-9]", ENV{DISPLAY}=":0.0", ENV{XAUTHORITY}="/home/meisteris/.Xauthority", ENV{ID_CLASS}="mouse", RUN+="/usr/bin/synclient TouchpadOff=1"

# Enable Touchpad when there is no USB mouse connected
ACTION=="remove", SUBSYSTEM=="input", KERNEL=="mouse[1-9]", ENV{DISPLAY}=":0.0", ENV{XAUTHORITY}="/home/meisteris/.Xauthority", ENV{ID_CLASS}="mouse", RUN+="/usr/bin/synclient TouchpadOff=0"

And it works! That means I am halfway to happiness :) Now I need that DualPoint Stick would be disabled too, but it is not controlled by synclient... So I probably have to use xinput command:
Code:

xinput --set-prop DualPoint\ Stick Device\ Enabled 0
Which works if i paste it directly to terminal, but for some reason does not work if I place it in the script like this:
Code:

# 82-touchpad.rules
# Disable DualPoint Stick while USB mouse is present

ACTION=="add", SUBSYSTEM=="input", KERNEL=="mouse[1-9]", ENV{DISPLAY}=":0.0", ENV{XAUTHORITY}="/home/meisteris/.Xauthority", ENV{ID_CLASS}="mouse", RUN+="/usr/bin/xinput --set-prop DualPoint\ Stick Device\ Enabled 0"

ACTION=="remove", SUBSYSTEM=="input", KERNEL=="mouse[1-9]", ENV{DISPLAY}=":0.0", ENV{XAUTHORITY}="/home/meisteris/.Xauthority", ENV{ID_CLASS}="mouse", RUN+="/usr/bin/xinput --set-prop DualPoint\ Stick Device\ Enabled 1"

Any more suggestions? :)

allend 05-23-2011 11:52 AM

You could try quoting the arguments to xinput.
Code:

RUN+="/usr/bin/xinput '--set-prop DualPoint\ Stick Device\ Enabled 1'"

Totoro-kun 05-23-2011 12:26 PM

Weird, if i put arguments into quotes and then reload udev, pointing stick is indeed disabled, but again it stays disabled no mater USB mouse state. But Thank you for a hint. It gave me an idea to try slightly different approach:

I have created two little bash scripts in /usr/bin:
1) /usr/bin/dispoint
Code:

#!/bin/bash
/usr/bin/xinput --set-prop DualPoint\ Stick Device\ Enabled 0

2) /usr/bin/enpoint
Code:

#!/bin/bash
xinput --set-prop DualPoint\ Stick Device\ Enabled 1

And then made them executable.

Now I have two .rules files in
Code:

/etc/udev/rules.d/
1) 81-touchpad.rules
Code:

# 81-touchpad.rules
#
# This is udev rules file for configuring touchpad state

# Disable Touchpad while USB mouse is present
ACTION=="add", SUBSYSTEM=="input", KERNEL=="mouse[1-9]", ENV{DISPLAY}=":0.0", ENV{XAUTHORITY}="/home/meisteris/.Xauthority", ENV{ID_CLASS}="mouse", RUN+="/usr/bin/synclient TouchpadOff=1"

# Enable Touchpad when there is no USB mouse connected
ACTION=="remove", SUBSYSTEM=="input", KERNEL=="mouse[1-9]", ENV{DISPLAY}=":0.0", ENV{XAUTHORITY}="/home/meisteris/.Xauthority", ENV{ID_CLASS}="mouse", RUN+="/usr/bin/synclient TouchpadOff=0"

2) 82-stick.rules
Code:

# 82-stick.rules
#
# This is udev rules file for configuring DualPoint state

# Disable DualPoint Stick while USB mouse is present
ACTION=="add", SUBSYSTEM=="input", KERNEL=="mouse[1-9]", ENV{DISPLAY}=":0.0", ENV{XAUTHORITY}="/home/meisteris/.Xauthority", ENV{ID_CLASS}="mouse", RUN+="/usr/bin/dispoint"

# Enable DualPoint Stick when there is no USB mouse connected
ACTION=="remove", SUBSYSTEM=="input", KERNEL=="mouse[1-9]", ENV{DISPLAY}=":0.0", ENV{XAUTHORITY}="/home/meisteris/.Xauthority", ENV{ID_CLASS}="mouse", RUN+="/usr/bin/enpoint"

After /etc/rc.d/rc.udev reload these scripts work like a charm. Both touch pad and point stick are disabled once USB mouse is connected, and enabled back when USB mouse is disconnected. So the first part is complete and functions as expected.

Now for the part two, I need this behavior to remain when laptop returns from sleep and when laptop boots with USB Mouse connected.

At the moment behavior is like this:

* When USB mouse connected --> both, tp and ps are disabled --> put computer to sleep ---> wake up computer with USB mouse present --> tp remains disabled, but Point Stick is enabled.

* Shut down computer --> connect USB mouse ---> Turn computer on ---> System boots with all of the pointing devices active until USB mouse is plugged out and plugged back in.

I believe I need similar scripts in few other places (so they are executed when computer boots and when computer wakes up from sleep). The question is: What are those places? I am Using Slim and Xfce, system boots directly into runlevel 4, I do not have KDM or any of the K* stuff installed.

Totoro-kun 05-24-2011 04:21 AM

OK, part two is is halfway complete :)

I have been searching a bit more, and found a way to disable touch pad and point stick when booting with USB mouse connected. For this I've added the following script to the end of .xsession file:
Code:

# disable touchpad if more than one mouse is available
if [ `ls -d /sys/class/input/mouse* | wc -l` -gt 2 ]; then
    /usr/bin/dispointers
fi

Note: This will look for mouse devices, and if it finds more than two (my laptop has two internal devices tp and ps) then it executes "/usr/bin/dispointers". So if one would want to use this for a laptop with one internal pointer device, then -gt 2 should be changed to -gt 1

Note #2: /usr/bin/dispointers is actually a bash script that contains two real commands:
Code:

#!/bin/bash
/usr/bin/xinput --set-prop DualPoint\ Stick Device\ Enabled 0 && /usr/bin/xinput --set-prop AlpsPS/2\ ALPS\ DualPoint\ TouchPad Device\ Enabled 0

One to disable Point Stick and other to disable my touch pad.

I've got ideas about this from Arch Forum and Howtoforge article

Now, the only thing remains, is to somehow execute dispointers when laptop wakes up from standby state. In these sites they mention /etc/pm/sleep.d/99touchpad script, but I am not sure that it even gets executed on wake up. Other option seems to be some kind of script in /etc/acpi/, but it's beyond my ability to write such acpi scripts, and I am not able to find any clear enough examples, but I think it should do same thing that script in .xsession does:
1. Check if there are too many pointing devices: [ `ls -d /sys/class/input/mouse* | wc -l` -gt 2 ]
2. run /usr/bin/dispointers

Now any suggestions o do that? :)

Totoro-kun 05-24-2011 06:16 AM

I have tried to put this simple script in /etc/pm/sleep.d/:
Code:

#!/bin/bash
# 100resume
case $1 in
    hibernate)
        echo "Hey guy, we are going to suspend to disk!"
        ;;
    suspend)
        echo "Oh, this time we're doing a suspend to RAM. Cool!"
        ;;
    thaw)
        /bin/sh -c '/usr/bin/chckpointers'
        ;;
    resume)
        /bin/sh -c '/usr/bin/chckpointers'
        ;;
    *)  echo "somebody is calling me totally wrong."
        ;;
esac

and made it executable, but system does not run it at all when going to sleep, so I think I need to place something that executes /usr/bin/chckpointers when computer wakes up from sleep and/or hibernate into /etc/acpi, but i can't figure how scripts work in there...

Any thoughts?

allend 05-24-2011 07:44 AM

Try quoting $1 i.e.
Code:

case "$1" in
For information on pm-utils, look at the READMEs in /usr/doc/pm-utils-1.4.1/

Totoro-kun 05-24-2011 09:15 AM

Thank you very much, after reading docs in /usr/doc/pm-utils and taking 49bluetooth file as example, I have constructed another script and placed in /etc/pm/sleep.d it looks like this:
Code:

#!/bin/sh
#
# 40touchpad file for checking pointers state
#

check_pointers()
{
        if [ `ls -d /sys/class/input/mouse* | wc -l` -gt 2 ]; then
                /usr/bin/dispointers
        else
                /usr/bin/enpointers
        fi
}

case "$1" in
        thaw|resume)
                check_pointers
                ;;
        *) exit $NA
                ;;
esac

And it works! But not like i would expect :/ The problem is, that it only works when I run pm-suspend command as root, but if i press suspend button in Xfce desktop, then this file gets ignored completely. Which is weird.

allend 05-24-2011 09:27 AM

Is your user a member of the power group?

Totoro-kun 05-24-2011 10:01 AM

yes, my user belongs to power, plugdev, games, audio, video gourps. And the suspend is working perfectly, just that script is not executed at all when I suspend from Xfce menu or close the lid of my laptop, it only gets executed when i issue pm-suspend in terminal. So is it possible that Xfce does not use pm-utils for these things?

allend 05-24-2011 10:52 AM

On my netbook I prefer to disable suspend/hibernate in desktop environments and just use pm-utils to handle suspend/hibernate.
I do this by editing /etc/acpi/acpi_handler.sh to add an event for the lid switch.
Code:

#!/bin/sh
# Default acpi script that takes an entry for all actions

IFS=${IFS}/
set $@

case "$1" in
  button)
    case "$2" in
      power) /sbin/init 0
        ;;
      lid) /usr/sbin/pm-suspend # for suspend - Use pm-hibernate for hibernate
        ;;

      *) logger "ACPI action $2 is not defined"
        ;;
    esac
    ;;
  *)
    logger "ACPI group $1 / action $2 is not defined"
    ;;
esac


Totoro-kun 05-25-2011 03:15 AM

This is interesting idea. But I would like to use suspend/hibernate from DE if possible. I would resort to this if no other solution is found however :)

Totoro-kun 05-27-2011 01:21 AM

It seems I have solved it! Finally, after countless hours of searching the internet, I have found nothing :) Not a single issue like this at all, that is weird I thought. So began to improvise and so I have wrote a pm script called 100pointers (which is like exactly the same as script above but differs in numbering and name):
Code:

#!/bin/sh
#        /usr/lib/pm-utils/sleep.d/100pointers
#        When laptop wakes up from sleep/hibernate, lets check
# if there is more than 2 pointing devises present, if so,
# then touchpad and point stick needs to be disabled

check_pointers()
{
        if [ `ls -d /sys/class/input/mouse* | wc -l` -gt 2 ]; then
                /usr/bin/dispointers
        else
                /usr/bin/enpointers
        fi
}

case "$1" in
        thaw|resume)
                check_pointers
                ;;
        *) exit $NA
                ;;
esac

So the problem was, that if i put this script where it belongs (/etc/pm/sleep.d/), then it gets executed only if i run pm-suspend command as root directly in terminal, but if I select suspend action from xfce-power-manager, menu etc, it is not executed. However, if i place this script in /usr/lib/pm-utils/sleep.d/ then all works like a charm. Not sure why though, in the documentation of pm-utils it is mentioned, that stuff made by local system admin should go to /etc/pm/sleep.d and /usr/lib/pm-utils/ is for stuff that comes with the system. So may be a bug?

Well in any case, thank you goes to allend, slackware /usr/doc directory and google. In the end of the day, I am a happy Slacker.

P.S.
In hopes that this may become useful, I am willing to put it all into a complete how-to when I'll have some time to spare.


All times are GMT -5. The time now is 07:34 AM.