この日記はMozillaのプロダクトへの貢献者としての私の成果を中心に、気になったバグやWeb界隈の話題について書いていますが、 断り書きがある場合を除き、いかなる団体のオフィシャルな見解ではありません。あくまでも個人的なものです。 Mozilla Foundation、Mozilla Corporation、及び関連企業の公式情報ではないことに注意してください。

現在、XHTML 1.0 (もどき)から、HTML5なコンテンツに修正中です。古い日記は修正が完了していませんので表示が崩れます。 順次、修正していく予定ですのでしばらくお待ちください。

もずはっく日記(2013年2月)

2013年2月19日

Bug-org 833719 Some function keys are not working since Firefox Version 15
初回投稿日時: 2013年02月19日13時08分55秒
最終更新日時: 2013年02月19日13時09分37秒
カテゴリ: Events GTK Mozilla Core Mozilla21 Windows バグ修正
SNS: (list)

Firefox 14までは、Windows/Linux/Macで、キーボードレイアウトとプラットフォームによってはほとんどのキーがkeyCode値が0になっていたり、同じキーボードレイアウトの同じキーがプラットフォーム毎に違う値を返すことがあったりするバグが長年、問題になっていたので、Firefox 15では、Bug-org 630810 (Windows)の修正Bug-org 677252 (Mac)の修正Bug-org 447757 (Linux)の修正で、ほぼ、これらの問題を一掃しましたが、その際に今まで、Windowsでは、ネイティブのvirtual keycode値でDOM keyCode値が定義されていないものに関してはそのままの値をセットするというのを取りやめ、マッピングできないもの、つまり、一般的なWebアプリで処理されるべきではないキーに関しては、keyCode値が0になるようになりました。

このバグは、特定の顧客に向けたWebアプリを提供する報告者の視点からすると、IEやWindows版のWebKitと同じkeyCode値が来ないのは困るというのものでした。

まず、上記バグで新たに定義したkeyCode値は今更動かすとさらに混乱が増すので、これらと重なる値については断念せざるを得ません。しかし、幸い、報告者が問題にしているkeyCode値はこれらとかぶっているものがありませんでした。

しかし、報告者が必要とするkeyCode値にはいくつか問題がありました。まず、顧客の利用している特殊なキーボードの実際のキーの刻印に反して、適切なvirtual keycode値が利用されておらず、OEM specificキーの値を多用している、さらに、Windows SDKで未定義、もしくは予約されているvirtual keycode値も利用している、複数のキーで同じvirtual keycodeを利用している(scan code値は異なっている)、というものです。

OEM specificキーは特殊なハードウェアにWindowsを組み込む際に内部利用用に予約されているようなものですので、本来はWebアプリから見える必要すらありません。その値から、キーの意味を知ることができないからです(つまり、Windows以外の環境ではマッピングしようがないので、非Windows環境でアクセシビリティ上、問題のあるものしか作れない)。しかし、上述のように、特定の顧客に向けたソリューションでは決め打ちで利用することに価値がありますので、これらの値をWindowsでのみ、Webアプリから利用可能にしました。以下がその一覧(定義)です。

  // OEM specific virtual keyCode of Windows should pass through DOM keyCode
  // for compatibility with the other web browsers on Windows.
  const unsigned long DOM_VK_WIN_OEM_FJ_JISHO   = 0x92;
  const unsigned long DOM_VK_WIN_OEM_FJ_MASSHOU = 0x93;
  const unsigned long DOM_VK_WIN_OEM_FJ_TOUROKU = 0x94;
  const unsigned long DOM_VK_WIN_OEM_FJ_LOYA    = 0x95;
  const unsigned long DOM_VK_WIN_OEM_FJ_ROYA    = 0x96;
  // OEM specific virtual keyCode of Windows should pass through DOM keyCode
  // for compatibility with the other web browsers on Windows.
  const unsigned long DOM_VK_WIN_ICO_HELP    = 0xE3;
  const unsigned long DOM_VK_WIN_ICO_00      = 0xE4;
  const unsigned long DOM_VK_WIN_ICO_CLEAR   = 0xE6;
  const unsigned long DOM_VK_WIN_OEM_RESET   = 0xE9;
  const unsigned long DOM_VK_WIN_OEM_JUMP    = 0xEA;
  const unsigned long DOM_VK_WIN_OEM_PA1     = 0xEB;
  const unsigned long DOM_VK_WIN_OEM_PA2     = 0xEC;
  const unsigned long DOM_VK_WIN_OEM_PA3     = 0xED;
  const unsigned long DOM_VK_WIN_OEM_WSCTRL  = 0xEE;
  const unsigned long DOM_VK_WIN_OEM_CUSEL   = 0xEF;
  const unsigned long DOM_VK_WIN_OEM_ATTN    = 0xF0;
  const unsigned long DOM_VK_WIN_OEM_FINISH  = 0xF1;
  const unsigned long DOM_VK_WIN_OEM_COPY    = 0xF2;
  const unsigned long DOM_VK_WIN_OEM_AUTO    = 0xF3;
  const unsigned long DOM_VK_WIN_OEM_ENLW    = 0xF4;
  const unsigned long DOM_VK_WIN_OEM_BACKTAB = 0xF5;
  // OEM specific virtual keyCode of Windows should pass through DOM keyCode
  // for compatibility with the other web browsers on Windows.
  const unsigned long DOM_VK_WIN_OEM_CLEAR  = 0xFE;

実際に、これらの値がどれほど変なものかというと、身近なJISキーボードにある特殊なキーを押してみると分かります。以下の表を見てみて下さい。

JISキーボードレイアウトの特殊キーと、virtual keycode値、DOM keyCode値の対応表
キーvirtual keycodeDOM keyCode
半角/全角VK_OEM_AUTO (WM_KEYUP)、VK_OEM_ENLW (WM_KEYDOWN) (もう一度押すと、逆になる)KeyboardEvent.DOM_VK_WIN_OEM_AUTO (keyup)、KeyboardEvent.DOM_VK_WIN_OEM_ENLW (Keydownkeypress)
漢字(Alt + 半角/全角)VK_KANJI (WM_SYSKEYDOWNWM_SYSKEYUP)KeyboardEvent.DOM_VK_KANJI (keydownkeypresskeyup)
英数VK_OEM_ATTN (WM_KEYDOWNのみ)KeyboardEvent.DOM_VK_WIN_OEM_ATTN (keydownkeypressのみ)
CapsLock (Shift + 英数)VK_CAPITALKeyboardEvent.DOM_VK_CAPS_LOCK (keydownkeyup)
カタカナ ひらがなVK_OEM_COPY (WM_KEYDOWNのみ。VK_OEM_ATTNWM_KEYUPが先に発生することもあり)KeyboardEvent.DOM_VK_WIN_OEM_COPY (keydownkeypressのみ。VK_OEM_ATTNが先行した場合は、KeyboardEvent.DOM_VK_WIN_OEM_ATTNkeyupが先行する)
ローマ字 (Alt + カタカナ ひらがな)VK_ATTN (WM_SYSKEYUP)、VK_OEM_BACKTAB (WM_SYSKEYDOWN) (もう一度押すと逆になる)KeyboardEvent.DOM_VK_ATTN (keyup)、KeyboardEvent.DOM_VK_WIN_OEM_BACKTAB (keydownkeypress)

と、このような感じです。VK_OEM_AUTOVK_OEM_ENLWが特に複雑で、どちらかが半角を意味し、どちらかが全角を意味していて、どちらかが押されっぱなしの状態を作り出していることがうかがえます。とてもではないですが、Webアプリからすると、JISキーボードのハンドリングとしては使えたものではない挙動です。

これ以外にも、以下のkeyCodeが副作用も考えられないので定義されました。

  // Following keys are not used on most keyboards.  However, for compatibility
  // with other browsers on Windows, we should define them.
  const unsigned long DOM_VK_ATTN           = 0xF6;
  const unsigned long DOM_VK_CRSEL          = 0xF7;
  const unsigned long DOM_VK_EXSEL          = 0xF8;
  const unsigned long DOM_VK_EREOF          = 0xF9;
  const unsigned long DOM_VK_PLAY           = 0xFA;
  const unsigned long DOM_VK_ZOOM           = 0xFB;
  const unsigned long DOM_VK_PA1            = 0xFD;

DOM_VK_ZOOM以外は、昔のIBMのコンピュータのキーボードに存在したキー向けと思われるので、Linuxでも同等のものをマッピングしています。ちなみに、VK_ZOOMを利用するキーボードは私は知りません。

これら以外の未定義や、予約済みのvirtual keycode値はWebアプリに渡す予定はありません。これらの値が将来定義され、他のプラットフォームでマッピングが必要になるかもしれないからです。

関連するかもしれないエントリ

bug-org 833719を含むエントリ