_ キーボードショートカット(特殊キーを含んだ場合)
昨日に引き続き、特殊キーを含んだ場合のキーボードショートカットについて。
コンソールアプリケーションと GUI アプリケーションで使用可能なキーを分けるのは、
ncurses (termcap または terminfo) で対応しているキーの組み合わせかどうか、という点。
この対応表には Shift キーによる修飾があるかどうかの情報も含まれているため、
コンソールアプリケーションで特殊キー単体押下と、Shift キーなどの修飾キー + 特殊キー押下が区別できるか、
という境目も ncurses に依存する。
端末エミュレータと ncurses (termcap または terminfo) の呼び方、TERM 環境変数の値などで
動作は異なるが、ここでは GNOME 端末、ncurses-5.7、 TERM=gnome という環境で動作させている。
コンソールアプリケーションで扱える特殊キーを分類すると、以下のようになる。
- 制御コードを出力するキー (修飾なし、Shiftキー修飾、Ctrlキー修飾、Altキー修飾)
- TAB (0x09, BTAB, 0x09, ウインドウ切り替えのため横取り(Alt + Tab))
- Return (0x0d, 0x0d, 0x0d, 0x1b + 0x0d)
- ESC (0x1b, 0x1b, 0x1b, ウインドウ切り替えのため横取り(Alt + ESC))
- Space (0x20, 0x20, InputMethod呼び出しで横取り, GNOME端末のメニュー表示で横取り)
- 特殊キーとして認識するキー(ncurses.h で KEY_〜 の形で宣言されている場合はその名前、
それ以外は識別するための定数)
- キー修飾かどうかが識別できるキー (修飾なし、Shiftキー修飾、Ctrlキー修飾、Altキー修飾)
- カーソルキー右 (RIGHT, SRIGHT, 0x022b, 0x0229)
- カーソルキー左 (LEFT, SLEFT, 0x021c, 0x021a)
- カーソルキー上 (UP, SR, 0x0231, 0x022f)
- カーソルキー下 (DOWN, SF, 0x0208, 0x0206)
- Deleteキー (DC, SDC, 0x0202, 0x0200)
- ファンクションキー(F1〜F12)
- Ctrlキー、Altキー修飾が識別できるキー (修飾なし、Ctrlキー、Altキー修飾。Shiftキー修飾ではキーイベント自体を検出できない)
- Page Upキー (PPAGE, 0x0226, 0x0224)
- Page Downキー (NPAGE, 0x221, 0x021f)
- Altキーのみ修飾が識別できるキー (修飾なし、Altキー修飾。Shiftキー、Ctrlキー修飾ではキーイベント自体を検出できない)
- キー修飾が識別できない組み合わせがある場合
- Homeキー (Shiftキー修飾でキーイベント自体を検出できない他は、すべて KEY_HOME を検出)
- Endキー (Shiftキー修飾でキーイベント自体を検出できない他は、すべて KEY_END を検出)
- BackSpaceキー (Alt+キーで ESC + BACKSPACE を表示する以外は、すべて KEY_BACKSPACE を検出)
コンソールアプリケーションで認識できない(端末エミュレータでブロックされるなどで通知されない)特殊キーは以下。
- Window Manager などが横取りする特殊キー
- F1キー (ヘルプ表示)
- 半角/全角キー (InputMethod 呼び出しに使用)
- PrintScreenキー (画面のスクリーンショット取得)
- コンテキストメニューキー (コンテキストメニュー表示)
- 一部の Shiftキーによる修飾(上記参照)
- 一部の Ctrlキーによる修飾(上記参照)
- Altキーによる修飾 (一部不可。しかし Gnome端末では ESC + 押下したキーという形で無理やり送信している場合もある)
- Windowsキー
- ScrollLockキー
- Pauseキー
- 変換キー
- 無変換キー
- カタカナひらがなキー
- テンキーからの入力(キーボードからの入力と区別できない)
_ そもそもなぜこんなことを考えたか
というと、以下の理由。
- xmonad のショートカットについて考えてみたときに、アプリと Window Manager で使い分けるキーの線引きを
どこですればいいか迷った。
- Emacs のキーバインドで C-; および C-: に機能を割り当てて、端末エミュレータ越しの利用ができないということがあった。