Showing posts with label ubuntu. Show all posts
Showing posts with label ubuntu. Show all posts

Wednesday, September 29, 2010

Disable touchpad when USB Mouse connected on Ubuntu (Lucid)

Update: 7/11/2010 Fixed a bug that happened with my laptop. The xinput was reset periodically for some reason.

Update: 2/11/2010 Fixed it a bit to make it works better. Now it don't need fix device name.

I wrote a short script to disable touchpad when mouse attached in Jaunty, which never works for me anymore after Jaunty. The reason is that gconftool and synclient could not correctly set touchpad state (it works for a very short while, until Gnome or X enable it back again). I just found the solution for Lucid (and probably for Maverick). It's

#!/usr/bin/python


import dbus # needed to do anything
from dbus.exceptions import DBusException
import dbus.decorators # needed to receive messages
import dbus.glib # needed to receive messages
from dbus.mainloop.glib import DBusGMainLoop
import gobject # needed to loop & monitor
import os, re, time, sys

global add_action, remove_action, bus, hal_manager

_debug = True
device_added = []
touchpad_enabled = True
device_cap = 'input.mouse'

add_action = 'sleep 1s && xinput --list --short | grep -i touchpad | sed "s/^.*[[:space:]]*id=\\([0-9]*\\)[[:space:]]*.*$/\\1/g" | xargs -I id xinput --set-prop id --type=int --format=8 "Device Enabled" 0'
remove_action = 'xinput --list --short | grep -i touchpad | sed "s/^.*[[:space:]]*id=\\([0-9]*\\)[[:space:]]*.*$/\\1/g" | xargs -I id xinput --set-prop id --type=int --format=8 "Device Enabled" 1'
check_action = 'xinput --list --short | grep -i touchpad | sed "s/^.*[[:space:]]*id=\\([0-9]*\\)[[:space:]]*.*$/\\1/g" | xargs -I id xinput --list-props id | grep -qi "device.*enabled.*:[[:space:]]*0$"'

exclude_devices = ['usb_device_a5c_4503_noserial_if0_logicaldev_input']

def dprint(msg) :
    global _debug
    if _debug :
        sys.stderr.write(msg + '\n')
        sys.stderr.flush()

#@dbus.decorators.explicitly_pass_message
def add_device(*args, **keywords):
    check_and_run_add_action(args[0])

def check_and_run_add_action(device_path) :
    global device_added

    retval = False
    Path = device_path.split('/')
    dprint('device added == %s' % Path)

    if Path[-1] in exclude_devices :
        return retval

    device_obj = bus.get_object('org.freedesktop.Hal', device_path)
    device = dbus.Interface(device_obj, dbus_interface = "org.freedesktop.Hal.Device")
    cap = device.QueryCapability(device_cap)

    dprint('Device capability == %s' % cap)
    try :
        prop = device.GetPropertyString('info.subsystem')
    except DBusException :
        prop = None

    dprint('Property String == %s' % prop)

    if cap and prop and (prop == 'input') :
        device_added.append(Path[-1])
        dprint('Executing add_action')
        os.system(add_action)
        retval = True
    return retval
       
#@dbus.decorators.explicitly_pass_message
def remove_device(*args, **keywords):
    global bus, _debug, device_added

    Path = args[0].split('/')
    dprint('device removed == %s' % Path)

    try :
        if device_added :
            if Path[-1] in device_added :
                device_added.remove(Path[-1])
                dprint('Excuting remove_action')
                os.system(remove_action)
            else :
                # other device removed, run add action again to make sure
                # this workaround a bug in Lucid that device was periodically removed will reset enable flag
                os.system(add_action)
    except :
        dprint('Exception while removing device')
        if _debug :
            import traceback
            traceback.print_exc()

DBusGMainLoop(set_as_default = True)
bus = dbus.SystemBus()  # connect to system bus
hal_manager_obj = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
hal_manager = dbus.Interface(hal_manager_obj, 'org.freedesktop.Hal.Manager')

# Add listeners for all devices being added or removed
bus.add_signal_receiver(add_device, 'DeviceAdded', 'org.freedesktop.Hal.Manager',
                        'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
bus.add_signal_receiver(remove_device, 'DeviceRemoved', 'org.freedesktop.Hal.Manager',
                        'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')

# Run remove action once to enable touchpad
dprint('Running removaction once')
os.system(remove_action)

# Find mouse first
dprint('Finding mouse first')
udis = hal_manager.FindDeviceByCapability(device_cap)
for udi in udis :
    dprint('Found device == %s' % udi)
    Path = udi.split('/')
    if check_and_run_add_action(udi) :
        break

# monitor
dprint('Start Mainloop')
loop = gobject.MainLoop()
try :
    loop.run()
except SystemExit, e :
    dprint('Got SystemExit exception %s' % e)
    raise e
except Exception, e :
    dprint('Got Exception from the loop')
    if _debug :
        import traceback
        traceback.print_exc()
    loop.quit()
    sys.exit(255)
The trick is to use xinput instead of gconftool/synclient!

Wednesday, September 02, 2009

Disable touchpad when USB Mouse connected on Ubuntu (Jaunty)

Do you have problem with Synaptics touchpad Palm detection? Do you accidentally touch the touchpad while typing? On Windows Vista, there is an option to disable touchpad when USB Mouse connected, but how to do that on Ubuntu? Here's how I 'properly' did it on my Ubuntu 9.04 (Jaunty).
  • Create a Dbus signal handler script using Python. Here's the script
#!/usr/bin/python

global DeviceName, AddAction, RemoveAction, bus, hal_manager

#DeviceName = 'usb_device_15ca_c3_noserial_if0_logicaldev_input'
DevicePattern = r'usb_device.*_input'
DeviceCap = 'input.mouse'
AddAction = '/usr/bin/gconftool --set --type=bool /desktop/gnome/peripherals/mouse/touchpad_enabled false'
RemoveAction = '/usr/bin/gconftool --set --type=bool /desktop/gnome/peripherals/mouse/touchpad_enabled true'

import dbus # needed to do anything
import dbus.decorators # needed to receive messages
import dbus.glib # needed to receive messages
import gobject # needed to loop & monitor
import os # needed to
import re, time

DeviceRe = re.compile(DevicePattern, re.IGNORECASE | re.DOTALL)

#@dbus.decorators.explicitly_pass_message
def add_device(*args, **keywords):
Path = args[0].split('/')
device_obj = bus.get_object('org.freedesktop.Hal', args[0])
device = dbus.Interface(device_obj, dbus_interface = "org.freedesktop.Hal.Device")

cap = device.QueryCapability(DeviceCap)

if cap and DeviceRe.match(Path[-1]) :
os.system(AddAction)

#@dbus.decorators.explicitly_pass_message
def remove_device(*args, **keywords):
Path = args[0].split('/')
try :
device_obj = bus.get_object('org.freedesktop.Hal', args[0])
device = dbus.Interface(device_obj, dbus_interface = "org.freedesktop.Hal.Device")
cap = device.QueryCapability(DeviceCap)
except :
# assume true, since device might be already removed
cap = True

if cap and DeviceRe.match(Path[-1]) : # Device found
os.system(RemoveAction)

bus = dbus.SystemBus() # connect to system bus
hal_manager_obj = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
hal_manager = dbus.Interface(hal_manager_obj, 'org.freedesktop.Hal.Manager')

# Add listeners for all devices being added or removed
bus.add_signal_receiver(add_device, 'DeviceAdded', 'org.freedesktop.Hal.Manager',
'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
bus.add_signal_receiver(remove_device, 'DeviceRemoved', 'org.freedesktop.Hal.Manager',
'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')

# Run remove action once to enable touchpad
os.system(RemoveAction)
time.sleep(1)

# Find mouse first
udis = hal_manager.FindDeviceByCapability('input.mouse')
for udi in udis :
Path = udi.split('/')
if DeviceRe.match(Path[-1]) : # Check if this is our prefer mouse
os.system(AddAction)
break # no need to keep looking

# monitor
loop = gobject.MainLoop()
loop.run()
  • If you wonder how I got the HAL path of USB mouse, try connecting your mouse and do "lshal", look for "Mouse" and see how your path looks like. Change the path properly if the default one is not match.
  • Add the script to run when log-in by going to System->Start up Applications
  • Log-out and re-Log-in again. That's it.
Another way to do this is to handle it in UDEV. However, I found that GNOME will always try to enable it back that way. Besides, UDEV is run by root, but touchpad setting is per-user. Disabling Touchpad permanently (in Mouse setting) and use synclient to control touchpad is another way to go.

Sunday, September 07, 2008

Sharing Thunderbird between Vista & Ubuntu

ปัญหาอย่างหนึ่งที่ตะก่อนผมเจอระหว่างการใช้ Windows กับ Linux สลับๆกันก็คือเรื่อง Mail คือเพราะใช้ Thunderbird บน Windows มาตลอด เวลาจะส่งเมล์ต้องกลับไปส่งใน Windows ตลอดเลย จำได้ว่าตอนนั้นพยายามลองใช้วิธี share profile ข้าม OS กันแต่ปรากฎว่าไม่ค่อยจะเวิร์ค จำไม่ได้ว่าเพราะอะไร แต่คงเป็นเพราะเวอร์ชันมันต่างกันมาก (บนวินโดวส์เวอร์ชันล่าสุด บน Linux ใช้ของที่มีอยู๋ตอนนั้นไม่ได้เอามาลงเอง) แต่นั่นมันก็นานแล้วตั้งแต่สมัย Fedora Core 2 ได้ ตอนนี้ HDD ที่พอแล้วหันกลับมาลอง เทคนิคเดิมระหว่าง Vista กับ Ubuntu 8.0.4.1 ปรากฎว่าเวิร์คดี แถมใช้ Profile ที่อยู่บน NTFS ซะด้วย

วิธีแก้ง่ายๆก็ใช้วิธีเรียก
thunderbird -profilemanager
แล้วก็ลบ profile เก่า เลือกอันใหม่ แล้วบอก directory เก็บ Profile แค่นี้ก็เรียบร้อย แถม add-on ก็มาหมดด้วย หรือจะใช้วิธีไปแก้ไฟล์ profiles.ini ก็ได้ อย่าลืมเปลี่ยน IsRelative เป็น 0

จริงๆแล้ววิธีนี้ควรจะใช้ได้กับ Firefox ด้วย แต่ลองแล้วปรากฎว่า
  1. FoxyProxy ไม่ค่อยเวิร์ค เพราะเก็บ path ที่ชี้ไปที่ database แบบ absolute เลย เป็น /D:/Doc/xxx อะไรยังงี้
  2. อันนี้น่ากลัวกว่า คือมันมี add-on ของ Ubuntu โผล่เข้าไปผสมด้วย (Ubuntu Firefox add-ons)
ผมเลยตัดสินใจไม่ใช้ firefox profiles ร่วมกันละกัน ไม่เป็นไรเท่าไหร่แค่ browsing history ปกติก็ไม่ได้เก็บ bookmark ไว้ในเครื่องอยู่แล้ว