端末や端末エミュレータから、コンソールアプリケーションに対してマウス位置を報告することを、マウストラッキングとよびます。
このエントリでは、このマウストラッキングの形式のひとつであるSGR(1006)形式の概要と、それを普及させる意義について述べたいと思います。
224桁問題と拡張マウストラッキングについて
拡張マウストラッキングは、xtermとそれを模倣するいくつかの端末において、224以上の座標をアプリケーションが取得できない仕様上の問題を回避するために考案されたものです。
現在広く普及しているxtermのノーマルトラッキングモード(vimのttymouse=xterm/xterm2)では、マウスレポーティングは7bit形式で以下のように表現されます。
ESC [ M Cb Cx Cy
マウス位置座標はCx、Cyで表現され、それぞれ1バイト固定となります。
さらに印字文字で表現するため+32のオフセットが加算され、224以上(0オリジンで223以上)の座標が表現できません。
これを回避するために、UTF8(1005)形式(座標値をUTF-8の要領でエンコードする)が考案されました。tmux、Poderosaなどの端末が対応しましたが、のちにこの仕様は端末のエンコーディングによっては認識できなくなるなどいくつかの問題があることが判明し、現在では壊れた仕様とみなされています。
これを解決するためにrxvt-unicodeから整数リテラル表現Db, Dx, Dyを使用して
ESC [ Db ; Dx ; Dy M
とする方法が提案され、多くの端末がこれに追従し、アプリケーション側でもMidnight CommanderやVimがこれに対応しました。
しかし現実には、このマウスレポートが誤ってエコーバックされたときに問題が発生すること、いくつかの既存アプリケーション(emacs等)での対応が困難であることなど、またしても不備があることが判明しました。
そこで現在新しく提案されている方法が、xtermによるSGR(1006)形式
ESC [ < Db ; Dx ; Dy M/m
という経緯になります。
さらに詳しいことは、下記をご覧ください。
https://groups.google.com/forum/#!topic/vim_use/lo6PLRUu2Gg
http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
http://togetter.com/li/290073
なぜ、SGR(1006)形式がよいのか
- UTF-8形式は、端末のエンコーディング設定によって問題が出るのみならず、そのノーマルトラッキング形式との中途半端な互換性から、tmuxなどのターミナルマルチプレクサに対して、複数の端末がアタッチしたときに問題が発生することが判明しています( http://togetter.com/li/290073 )。
- urxvt(1015)形式は、端末側の対応は楽なのですが、アプリケーション側の対応がものによっては非常に困難であることが報告されています( https://groups.google.com/forum/#!topic/vim_use/lo6PLRUu2Gg )。たとえば、xtermのterminfoにおいて、シフト + 左カーソルキーのインプットシーケンスは
ESC [ 1 ; 2 D
となりますが、これを左から1文字づつパースしていくとurxvt(1015)形式と途中まで('D'があらわれるまで)区別がつきません。つくりによっては余計なバックトラックが増えるため、効率上の問題もあります。
- アプリケーションのバグなどで万一、マウスレポーティングが誤ってエコーバックされた場合、ECMA-48に準拠した端末ではSGR(1006)形式のレポートは端末によって読み飛ばされ、無害なはずです。ノーマルトラッキングのようにゴミとして表示されたり、urxvt形式のように既存の制御シーケンスとバッティングして誤動作することはないはずです。
現在のSGR(1006)形式のサポート状況
拡張マウスレポーティングが正しく機能するためには、端末側とアプリケーション側、両方のサポートが必要となります。
うち端末側では、比較的普及がすすんでいます。
- xterm (Patch #277以降)
- RLogin
- TeraTerm
- pangoterm
- tty.js (多少のバグあり)
- tanasinn
- mlterm (3.1.2以降)
- mintty
- iTerm2
- mouseterm
- Poderosa (sourceforgeレポジトリの最新版)
- Konsole
- PuTTY
- tmux
- st
- gnome-terminal
その他、GNU Screen、cygwin ck terminal emuratorにもパッチが書かれています。
一方アプリケーション側では近年になって普及の兆しがあり
- Midnight Commander
- Vim
- Emacs
などで実装されました。w3mへもパッチが投稿されています。
今後ncursesなどのライブラリでも対応が予定されています。
自分のつかっている端末の拡張マウストラッキング実装状況を知りたい
自分のつかっている端末が、SGR 1006をサポートしているか知りたいと思っても、アプリケーション側の対応が少ない現状では、なかなか調べられません。
また、パッチを書いてSGR 1006に対応してみた、という場合にも、それを適切にテストできる環境が必要でしょう。
そういうときは、vttest( http://invisible-island.net/vttest/ )を使用しましょう。Unix/Linuxではパッケージマネージャ経由でもインストールすることができるはずですが、バージョン2.7/20111210より前のものでは、SGR 1006には対応していません。なるべく新しいものをつかいましょう。
vttestを立ち上げたら、11 -> 8 -> 5 とメニューをたどることで、マウスのテストメニューに移行することができます。1でノーマルモード、urxvt、SGR形式を切り替え、4/6/7でマウス座標の報告状況テストをすることができます。