恰巧在IBM developer看到了一篇
Ubuntu上gesture的教學,但因為那篇是perl及年久失修(?),所以我稍微在Ubuntu 11.04及用python重寫了這個應用。
這篇文章將會給介紹Ubuntu上怎麼來寫筆電的touchpad gesture應用,主要用python、synclient和xdotool。synclient是用來抓touchpad被按下的座標值及指數。xdotool則用來送出相對應的鍵盤行為。
synclient
首先,在Ubuntu 11.04上,若要啟用synclient必需先修改xorg.conf,加入Option "SHMConfig" "on",如下
//file: /usr/share/X11/xorg.conf.d/50-synaptics.conf
Section "InputClass"
Identifier "touchpad catchall"
Driver "synaptics"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Option "SHMConfig" "on"
EndSection
接著可在terminal上使用synclient,來看一下他的輸出:
doro@doro-UL80Jt ~/src/touchpad $ synclient -m 10
time x y z f w l r u d m multi gl gm gr gdx gdy
0.000 418 413 0 0 0 0 0 0 0 0 00000000
0.617 363 359 31 1 0 0 0 0 0 0 00000000
0.627 362 356 31 1 0 0 0 0 0 0 00000000
0.637 363 352 31 1 0 0 0 0 0 0 00000000
0.657 364 349 31 1 0 0 0 0 0 0 00000000
0.677 368 347 31 1 0 0 0 0 0 0 00000000
0.688 371 344 31 1 0 0 0 0 0 0 00000000
0.708 373 340 31 1 0 0 0 0 0 0 00000000
0.728 375 336 31 1 0 0 0 0 0 0 00000000
0.738 376 333 31 1 0 0 0 0 0 0 00000000
0.849 376 333 0 0 0 0 0 0 0 0 00000000
1.688 232 672 31 2 0 0 0 0 0 0 00000000
1.718 274 679 31 3 0 0 0 0 0 0 00000000
1.799 274 679 0 0 0 0 0 0 0 0 00000000
這個指令會輸出目前touchpad被按下的點(x,y)以及f欄位標示出指數。因此我們便可利用這3個值來判斷手勢。最後再利用xdotool來執行我們要做的行為。
Example
底下這個例子,將會實作
- 若3指按下時,送出super+w,進入expo mode
- 若3指按下後移動上/下/左/右超過100個單位,送出ctrl+alt+Up/Down/Left/Right,來做work space的切換
#!/usr/bin/python
# -*- coding: utf-8 -*-
import logging
logging.basicConfig(filename='/tmp/multitouch.log',
level=logging.DEBUG,
format='[%(asctime)s][%(name)s][%(levelname)s] %(message)s')
logger = logging.getLogger('multitouch')
import subprocess
import re
if __name__ == "__main__":
cmd = 'synclient -m 10'
p = subprocess.Popen(cmd, stdout = subprocess.PIPE,
stderr = subprocess.STDOUT, shell = True)
skip = False
try:
while True:
line = p.stdout.readline()
if not line:
break
try:
tokens = [x for x in re.split('([^0-9\.])+', line.strip()) if x.strip()]
x, y, fingers = int(tokens[1]), int(tokens[2]), int(tokens[4])
logger.debug('Result: ' + str(tokens))
if fingers == 3:
if skip:
continue
skip = True
start_x, start_y = x, y
else:
if skip:
diff_x, diff_y = (x - start_x), (y - start_y)
if diff_x > 100:
logger.info('send...diff_x > 100')
subprocess.Popen("xdotool key ctrl+alt+Right", shell=True)
elif diff_x < -100:
logger.info('send...diff_x < -100')
subprocess.Popen("xdotool key ctrl+alt+Left", shell=True)
elif diff_y > 100:
logger.info('send...diff_y > 100')
subprocess.Popen("xdotool key ctrl+alt+Down", shell=True)
elif diff_y < -100:
logger.info('send...diff_y < -100')
subprocess.Popen("xdotool key ctrl+alt+Up", shell=True)
else:
logger.info('send...super+w')
subprocess.Popen("xdotool key super+w", shell=True)
skip = False
except (IndexError, ValueError):
pass
except KeyboardInterrupt:
pass
(keyboard is better, but just for fun :D)