touchpad.el

EmacsThumbSenseみたいなことをやるためのelispを作ってみました。これを使うとタッチパッドに触れながらキーを押したときに任意のコマンドを実行できます。

必要なもの

synclient
タッチパッドの状態を取得するためにsynclientを必要とします。なお、このコマンドを動かすためには、xorg.confでSHMConfigを有効にする必要があります。
Section "InputDevice"
        Identifier "Synaptics Touchpad"
        Driver "synaptics"
        Option "SendCoreEvents" "true"
        Option "Device" "/dev/psaux"
        Option "Protocol "auto-dev"
        Option "SHMConfig" "on"        # <- この行を追加
EndSection

Ubuntu 8.04 + Emacs 22.1.1で動作を確認していますが、*BSDでも動くかもしれません。

インストール方法

  1. touchpad.elをダウンロードして、load-pathが通ったディレクトリに置く
  2. .emacsに以下の定義を追加する
(require 'touchpad)
(touchpad-start)

使い方

タッチパッドに触れると、カーソルの点滅が停止し、カーソルの色が変わります。この状態でキーを押すと、touchpad-global-set-key, touchpad-define-keyで定義されたコマンドが実行できます。定義していない場合は元のglobal-set-keyやdefine-keyで指定されたコマンドが実行されます。

タッチパッドに触れた領域に応じて実行するコマンドを変えることもできます(最大4つ)。領域は以下のように考えます。

タッチパッドの領域

デフォルトの設定では、タッチパッドのどこの位置に触れても同じ振る舞いをしますが、カスタマイズ変数touchpad-horizontal-separator-position, touchpad-vertical-separator-positionを指定することにより、タッチパッドを以下のような最大4つの領域に分けて振る舞いを変えることもできます。

          horizontal separator
                   |
 (0,0)             v
   +---------------+----------------+
   |               |                |
   |   Region 0    |   Region 1     |
   |               |                |
   +---------------+----------------+ <- vertical separator
   |               |                |
   |   Region 2    |   Region 3     |
   |               |                |
   +---------------+----------------+

horizontal separator, vertical separator はそれぞれタッチパッド上のx, yの座標値を設定します。この座標値は多分タッチパッドの種類ごとに異なると思うので、synclient -m 100 とかして調べてください(このコマンドを実行してタッチパッドに触るとx, yの座標が表示されます)。

horizontal separator, vertical separatorにnilを指定すると、セパレータなしになります。例えば、horizontal separatorに整数値、vertical separatorにnilを指定すると領域は横に2分割されます(左からRegion 0, Region 1)。両方にnilを指定すると領域は1つだけになります(Region 0のみ)。

コマンド&関数
touchpad-start
タッチパッドの監視を実行するためのコマンドです。タッチパッドを触るとカーソルの点滅が止まり、カーソルの色が変化します。タッチパッドの状態はmode-lineにも表示されます("TP:〜"のように表示されます)。
touchpad-stop
タッチパッドの監視を停止するためのコマンドです。
touchpad-global-set-key
タッチパッドが押された状態でのグローバルなキーバインディングを変更するための関数です。(touchpad-global-set-key n key def)のように指定し、nでタッチパッドの領域番号を指定します。key, defはキーとキーが押されたときに実行する定義を指定します。ここは基本的にglobal-set-keyと同じです。
touchpad-define-key
指定されたキーマップで、タッチパッドが押された状態のキーバインディングを変更するための関数です。(touchpad-define-key n keymap key def)のように指定し、nでタッチパッドの領域番号を指定します。keymap, key, defはキーマップ、キー、キーが押されたときに実行する定義をそれぞれ指定します。ここは基本的にdefine-keyと同じです。
touchpad-pressed-region
タッチパッドが押されている領域の番号を返します(0~3の数値)。押されていないときはnilが返ります。
カスタマイズ変数
touchpad-polling-interval
タッチパッドの監視のポーリング間隔を指定します(ミリ秒の単位)。デフォルトは10msです。
touchpad-cursor-color-0 ~ touchpad-cursor-color-3
タッチパッドが押されたときのカーソルの色を指定します(末尾の番号が領域の番号に該当)。デフォルトは "red", "cyan", "green", "brown"となっています。
touchpad-horizontal-separator-position
タッチパッドの左右の区切り線の位置を指定します。nilを指定すると、左右の区切りをなくします。デフォルト値はnilです。
touchpad-vertical-separator-position
タッチパッドの上下の区切り線の位置を指定します。nilを指定すると、上下の区切りをなくします。デフォルト値はnilです。
使用例
;; タッチパッド + w でウィンドウを大きくし、タッチパッド + q でウィンドウを小さくする
(touchpad-global-set-key 0 "w" 'enlarge-window)
(touchpad-global-set-key 0 "q" 'shrink-window)
;;; SKK用の実験的な設定です
;;;
;;; タッチパッドを押している状態が漢字、離すとひらがなの指定になります。
;;; ただし、タッチパッドの押下状態の判定はそれほど鋭敏でないので、
;;; 実際に使うとなると、ちょっといらいらするかもしれません
;;; 
;;; 入力例:「本日は晴天なり」
;;;  ▽ほんじつ
;;;    --------
;;;    タッチパッドを押しながら入力
;;;  本日は
;;;     --
;;;      タッチパッドを離して入力
;;;  本日は▽せいてん
;;;        --------
;;;        タッチパッドを押しながら入力
;;;  本日は晴天なり
;;;          ----
;;;          タッチパッドを離して入力
;;;
 
(defadvice skk-insert (before touchpad-skk-insert-ad (&optional arg parg))
  (when (or (and (not (eq skk-henkan-mode 'on)) (touchpad-pressed-region))
            (and (eq skk-henkan-mode 'on) (not (touchpad-pressed-region))))
    (setq last-command-char (upcase last-command-char))))

(ad-activate 'skk-insert)

注意点

touchpad.elでのタッチパッド状態の監視はそれほど敏感なものではなく、遅延が発生するようです(手持ちの環境だと、感覚的に100msのオーダー)。なので、普通のモディファイアキー(CtrlとかAlt)と同じ感覚で使うとイライラするでしょう。自分で使ってみた感じだと、タッチパッドに触れてからちょっとひと呼吸おいてキーを押すような感じだとよいようです。