2011年1月24日
Panoramaで文字を入力すると自動的にタブの検索フォームが出現し、エディタに一文字が入力されますが、IMEがオンの状態でもフォーカスがエディタ外だったためにIMEが無効になっている時のキーイベントがそのままリダイレクトされるので、次の文字の入力から初めてIMEを経由することになり、意図通りに入力できない、というバグです。昔からFAYTが抱えているのと同じ問題です。
FAYTの時にも悩みましたが、Windowsの入力イベントの仕様上(Geckoの実装上?)、どうしようもないと思い、今回もUIのデザイン自体の見直しを提案していました。しかし、昨年知ったSendInput()
APIが利用可能かもしれないと気づき、実験してみたところうまく動くことが分かりました。
WindowsではメッセージループにWM_KEYDOWN
メッセージのみが送信されてきます。これをTranslateMessage()
APIに渡すと、WM_CHAR
がメッセージキューに挿入されますが、このときにIME (IMM)にも処理が渡っているようです。Geckoでは、GetMessage()
の後、直接TranslateMessage()
を呼んでいて、WM_KEYDOWN
をウインドウが受け取る時には既にIMEで処理が始まっていることになります。つまり、現在の設計ではDOMのkeydown
イベントが発生した時点で、Windowsでは既にIMEが処理を開始している、もしくは、エディタ以外のIMEが無効になっている状態ではIMEを通さずにWM_CHAR
が生成されているという状態になっています。
TranslateMessage()
をDOMのkeydown
イベントの処理結果を見てから呼べという根本的な意見もあるかとは思いますが、開発サイクルのタイミング上、不可能ですし、色々なキーボードレイアウトでテストするにも時間がかかります。そこで、前述のSendInput()
APIによってハックすることにしました。
WM_KEYDOWN
の処理時に、DOMのkeydown
イベントのハンドラがエディタにフォーカスを移動させてIMEが有効になった場合、WM_KEYDOWN
のハンドラがSendInput()
で再度、ネイティブの入力イベントを低レベルで発生させるようにしました。そして、WM_KEYDOWN
のハンドラは次に来たキー入力が期待通りのものだった場合、DOMのkeydown
イベントは再生成しません。そして、エディタ上でkeypress
イベントか、compositionstart
イベントが発生するようになっています。
そして、Panorama側ではkeydown
イベントで検索を開始し、フォーカスを移動させるだけにしました。つまり、今までのkeypress
イベントのリダイレクト処理は行わなくなっています。
この変更が具体的にWebアプリからみて、どのような影響があるのかはイベントの発生順序が見えるデモで確認してみてください。
当然のことながらIMEがオフの状態では以前と変わっていません。IMEがオンの場合、エディタ以外でキーを押すと、エディタには今までは来ていたkeypress
イベントが来なくなっているのが分かるかと思います。その代わりにcompositionstart
イベントやtext
イベントが発生するようになっています。
ちなみに、Macではもともとこの修正後の動作でした。今回の修正ではWindowsとLinuxの動作をMacにあわせた形になります。もし、この変更でなんらかの悪い影響を受けるWebアプリケーションがあったとすれば、それはMacユーザには元々そのユーザ体験を提供してしまっていたことになります。
また、プラットフォーム関わらず、keydown
イベントのpreventDefault()
を呼び出してもIMEの動作を妨げることはできません。DOMのイベントモデル的には良くありませんが、そもそもこれが好ましいことかどうかは分かりません。そのようなロジックに依存したWebアプリを書くと、IMにまっさきにネイティブのKeyPress
イベントを食われてしまうLinux (GTK2)上では動かなくなってしまうからです。
Panoramaのタブの検索は、キー入力とともにフォームが出現して検索が開始されますが、アルファベット以外のキーでは開始できない、というバグです。
Bug-org 610821の修正で同時に修正しています。これによって、ASCII文字を入力しないキーボードレイアウトでも問題なくなっていますし、IMEでかな打ちを利用していても問題なくなっています。
これはFAYT開始時にIMEがオンでもIMEを経由した入力にならない、というバグです。
Bug-org 610821の修正で修正可能にはなりましたが、Firefox 4では修正しません。既存の/や'での検索対象の切り替えをCtrlキーやCmdキーと併用したショートカット形式にしないと、うまく動かないためです。ですが、UIのこのような変更は議論を呼んでしまう可能性があるので次のバージョンに持ち越します。
パッチは既にありますし、内容的に拡張で対応できると思うので、どうしてもという方はその方向でどうぞ(余計な差分が混じっていますが、browser/base/content/tabbrowser.xml
と、toolkit/content/widgets/findbar.xml
の差分だけ適用すれば修正できます)。
DirectWriteだと、MS Pゴシック等で文字がくっつきすぎるというバグです。DirectWriteは最近のバージョンでは東アジアのフォントに対してはビットマップグリフを一定のサイズでは利用するようになっていますが、このビットマップを利用する時にも各文字の幅をアウトラインから計算して返してくるため、フォントサイズ(小数も利用可能)や行頭の位置との関係によっては判読不可能なぐらいにくっついてしまうことがあります。
色々と調べた感じではDirectWriteはどうも内部にビットマップグリフを利用した方が良いフォントのブラックリストを持っているようです。また、このリストでビットマップグリフを利用すべきサイズ指定までやっているのではないかという疑惑すらあります。このへんが全く明文化されていないのでビットマップグリフを持つサイズでは小数は丸めるようにし、GDI互換の幅計算で文字を配置するように修正してもらいました。この結果、以下のようにレンダリング結果が改善しています。
上記のスクリーンショットで赤く囲んだところに注目してください。文脈がなければ判読不可能な組み合わせも出てくることが分かります。
修正後はこのようになっています。まだ一部くっついているところがありますが……
このFirefox 3.6のスクリーンショットを見れば分かるように、もともとGDIのレンダリングでもくっついてることはありますが、これはフォントの問題としか言いようがありません。
もう一ヶ月ぐらいまえの加藤さんのポストですが、かなり興味深い内容です。見たことない人は是非一度チェックを。
ネットブック等で採用されているCPU、Atomでベンチマークをとると、Google ChromeよりもFirefoxの方が高速になってしまう、というものです。
特定のプラットフォームに対して最適化すると陥りがちな結果なのかもしれませんが、本当に速度を求めてブラウザを選択する場合、自分の環境できちんと速度を計測してみることが大切だと言えるかもしれません。
ただ、速度を求めている人の大半というのは実速度よりも思い込みも含めた体感速度を重視している場合が多いように思えるので、そういう基準だとベンチマーク結果にかかわらず、Google ChromeやOperaというのはFirefoxよりは良い選択肢ではあるかもしれません。例えば、システムのマウスホイールのスクロール速度を増やしてみて、それで高速化した、と感じるのであればそれはこのケースに当てはまります。
普段、nightlyでも動く拡張をいくつか利用していますが、その中には(ショートカットキーを除けば)メニューからしかアクセスできない拡張があります。例えばDOM Inspectorが有名です。こういったアドオンは未だにFirefoxボタンのメニューからアクセスできません。これは何故かと、ふと疑問に思ったのですが、その時にこの問題が思いつきました。つまり、開発者がMacを常用している場合、Firefoxボタンのこと自体を知らないかもしくは忘れている、最悪なのがデバッグできない、といった理由で対応が遅れているのではないかということです。
#extdevで確認をとってみても、AMOのレビューではこの問題に関してはノータッチのようで、メニューバー側のメニュー項目しかいじってなくてもAMO的には問題ないようです。ドキュメントで呼びかけてはいるようですが、徹底できるとは正直思えません。
また、UIの変更は他の拡張とのバッティング時にも対策等が必要でしょうから、デバッグ用にMacもFirefoxボタンを付けるべきなのではないか、というのがこのバグです(ちなみに、本体のメニュー構造はMXRで確認できます)。
ひとまず、今のところは、自分の使っている拡張がFirefoxボタンに対応していない場合は、各作者に連絡をとるしかないようです。