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

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

もずはっく日記(2012年6月)

2012年6月7日

Firefox 12の日本語入力中にハングアップする件の続報 初回投稿日時: 2012年06月07日10時21分28秒
カテゴリ: Firefox Mozilla Core Mozilla14 Windows バグ修正 バグ検証中
固定リンク: id=2012060700
リンク元: 1件
SNS: (list)

Firefox 12にアップグレードに日本語入力中にハングアップすることがある件ですが、予想通り、件のパッチが投入されたFirefox 14では再現しなくなったという情報を頂いています。

当該バグの方ではやはり根本的な原因は全く想像すらついていません。もし、確実に再現する手段を誰かが発見できたなら、この根本的な解決が出来ますが、残念ながら検証できるエンジニアには誰一人再現できていません。content内のかなりヤバイところにバグが混入してると思われますので、もし、確実に再現する方法・環境を絞り込めたら非常に有益ですのでフィードバックをさらに頂けると助かります。

またこの件で困っている方で、betaチャンネルの利用に抵抗がない方はbetaチャンネルの利用をお勧めします。

2012年6月8日

Bug-org 757049 GTK immodule receives invalid cursor position when the surrounding text contains any non-BMP Unicode character 初回投稿日時: 2012年06月08日15時08分19秒
カテゴリ: GTK Mozilla Core Mozilla15 バグ修正
固定リンク: id=2012060800
リンク元: 0件
SNS: (list)

Linux版のFirefoxが、retreave-surroundingと、delete-surroundingをハンドリングする際にnon-BMP文字を、UTF-16のまま2文字とカウントしているというバグです。

ギリギリでFirefox 15での修正に間に合っています。

2012年6月11日

Windows版Firefoxのwindowed modeとwindowless modeそれぞれのプラグインの構造 初回投稿日時: 2012年06月11日20時47分22秒
最終更新日時: 2012年06月12日12時17分21秒
カテゴリ: Flash Mozilla Core plugin Windows 雑談
固定リンク: id=2012061100
リンク元: 5件
SNS: (list)

知ってる人がどうも少ないっぽいのでちょっと解説を。まずは、『ウインドウ』という用語が分かっていないと話がさっぱり分からないと思うのでその説明から。以下のスクリーンショットはメモ帳の検索ダイアログです。

メモ帳の検索ダイアログのスクリーンショット

一般的にはこのダイアログ全体をひとつのウインドウと呼んだりしますが、Windowsの開発用語では、これはさらに多数のウインドウから構成されていることになります。そのウインドウごとにバラバラにすると以下のようになります。

メモ帳の検索ダイアログの各ウインドウをバラバラにした図

各UI部品それぞれがウインドウで、ウインドウにウインドウが貼り付いてるという形になります。フォーカスはこのウインドウごとに持てる、持てない、という違いがありますが、フォーカスというのはウインドウレベルでの話になります。

さて、Windows版Firefox用のプラグインにはwindowed modeと、windowless modeの二つの動作モードがあります。

Windowed modeの場合、プラグインの表示位置にplugin-container.exeがウインドウを作成し、親のFirefoxのウインドウにそのウインドウを貼り付けます。そして、plugin-container.exe内で動いているプラグインはこのウインドウの上に直接描画したり、さらにウインドウを貼り付けたりします。また、これらのウインドウはフォーカスを持つこともでき、これらの上で発生したイベントを直接処理できます。

Windowless modeの場合、plugin-container.exeはウインドウを作成しません。親のFirefoxのウインドウ自身がイベントを受け取り、その内容を必要があればplugin-container.exe内で動いているプラグインに対してDOMイベント経由で通知を行います。

しかし、ここにややこしい問題が発生します。Windowsではウインドウに描画するにしても、IMEと通信して未確定文字列を取得したり、候補ウインドウの表示位置を指定するにしてもそれぞれのコンテキストを取得してAPIを呼び出さないといけませんが、当然、各コンテキストはプロセスごとに生成されており、他のプロセスが所有するウインドウに関連づけられたコンテキストに対してアクセスすることはできません。

Firefox上でwindowless modeのFlashのエディタでIMEを利用する場合に、キャレット位置に未確定文字列が表示されないのはこれがその理由です。Windowsはアプリが未確定文字列を自分で描画できない場合、Windowsが用意した、独立したウインドウ内に未確定文字列を表示して作業することができるようになっています。そして、最後に確定した文字列のイベントだけをアプリが処理することによって、IMEに対応していないアプリであっても入力だけはかろうじてできるようになっています。

逆に、windowed modeのFlashのエディタでは同じプロセスのウインドウに関連づけられたIMEのコンテキストにフルアクセスできるので、未確定文字列の表示も、候補ウインドウの表示も普通のアプリと同じレベルで処理することができているのです。

それぞれのモードを利用している代表的な例では、Youtubeやニコニコ動画はwindowed modeを利用していて、Ustreamは動画部分はwindowed mode、チャット部分は何故かwindowless modeとなっています。

2012年6月14日

Windows版Flash Player 11.3と各IMEの動作確認表 (もちろん非公式) 初回投稿日時: 2012年06月14日18時55分06秒
最終更新日時: 2012年06月15日11時13分27秒
カテゴリ: Firefox Flash Google Chrome IE Opera Safari Windows
固定リンク: id=2012061400
リンク元: 9件
SNS: (list)

Windows 7 (x64)上での検証結果 (windowed mode)
IE9 Fx13 Chrome Opera Safari
MS-IME (TSF)ローマ字打ち OKOKOKOKOK
かな打ち OKカナロックかからず(言語バーからは可能)カナロックかからず(言語バーからは可能)OKOK
MS-Office IME 2010 (TSF)ローマ字打ち OKOKOKOKOK
かな打ち OKカナロックかからず(言語バーからは可能)カナロックかからず(言語バーからは可能)OKOK
ATOK 2012 (TSF)ローマ字打ち OKOKOKOKOK
かな打ち OKカナロックかからず(言語バーからは可能)カナロックかからず(言語バーからは可能)OKOK
ATOK 2010 (IMM)ローマ字打ち OKOKOKOKOK
かな打ち OKカナロックかからず(言語バーからは可能)カナロックかからず(言語バーからは可能)OKOK
Goolge 日本語入力 (IMM)ローマ字打ち OK未確定文字列にならず、直接入力OKOKOK
かな打ち OK未確定文字列にならず、直接入力OKOKOK
Japanist 2003 (IMM)ローマ字打ち OKOKOKOKOK
かな打ち OKカナロックがかからないので、言語バーからカナロックをかけ、ツールバーの「英数」を「かな」に変更すると入力可能カナロックがかからないので、言語バーからカナロックをかけ、ツールバーの「英数」を「かな」に変更すると入力可能OKOK
Baidu IME (TSF)ローマ字打ち OK未確定文字列にならず、直接入力OKOKOK
かな打ち N/A

この結果からすると、IMEからのカナロックがうまくうごかないというのがFx、Chromeで共通しているので、GUIスレッドと、IMEが実際に動いてるスレッドは別物と推測されます。また、OperaやSafariではそもそも保護モードが有効ではないと思われます。

2012年6月18日

Bug-org 757688 Refactor KeyboardLayout 初回投稿日時: 2012年06月18日11時20分39秒
最終更新日時: 2012年06月18日11時20分57秒
カテゴリ: Mozilla Core Mozilla16 Windows バグ修正
固定リンク: id=2012061800
リンク元: 0件
SNS: (list)

Windowsのキーイベントから、入力された文字を算出してデッドキーの入力処理や、ショートカットキーの入力処理に利用しているmozilla::widget::KeyboardLayoutのリファクタリングを行いました。

KeyboardLayoutnsWindowWM_KEYDOWNを受け取ったときに、KeyboardLayout::OnKeyDown()が呼び出されることを前提に動作しています。このメソッド内で押されたキー、生成される文字列、デッドキーの状態を保存し、いくつかのメソッドがこの情報を外部(nsWindow)に返すようになっています。

しかし、こんなstatefulなクラスは使いにくくて仕方がないので、DOM KeyboardEventの作業前に修正してしまいました。

まず、OnKeyDown()はデッドキーの状態以外を保存しません。この状態のみ、statefulでしか効率的に管理できないので諦めました。その代わり、このデッドキーの状態は、OnKeyDown()内でしか参照されず、他のメソッドは全てstatelessになりました。

現在のキーで入力される文字列は、OnKeyDown()が戻り値として返すようになっています。これにより、最後のOnKeyDown()が呼ばれた際の入力される文字列を返していたGetUniChars()は廃止され、任意のモディファイアの状態を指定できていたGetUniCharsWithShiftState()が、GetUniCharsAndModifiers()に置き換えられ、より使いやすくなっています。

またさらに、このリファクタリングの副作用で、デッドキーも自動テストでテストできるようになっています。ただ、今までの自動テストはショートカットキー以外はあまり有用ではありませんでしたので、文字が入力される場合にはnsWindow::OnKeyDown()内でKeyboardLayout::OnKeyDown()の戻り値とAPIで指定された文字(疑似WM_CHARの内容)とを比較し、異なる場合にはデバッグビルドではそのままクラッシュするようにし、テストの信頼性を向上させています。キーボード周りをハックされる方は注意してください。

Bug-org 765166 IDEOGRAPHIC SPACE (U+3000) should cause line break after a white space 初回投稿日時: 2012年06月18日11時39分53秒
カテゴリ: Mozilla Core Mozilla16 バグ修正
固定リンク: id=2012061801
リンク元: 0件
SNS: (list)

珍しく、Firefox Inputに検証可能(再現可能)で、なおかつ、Firefoxに原因のあるフィードバックがありました。

問題のページは、昔懐かしいテーブルレイアウトで、そのテーブルの幅を指定しています。しかし、全角スペースのみの行がなぜか折り返されず、その幅を押し広げてしまい、レイアウトが崩れていました。

調査してみたところ、折り返し可能な空白文字が連続している場合に、Geckoは折り返さないように処理していました。理由を色々と考えてみましたが、おそらく、大量のまとめられない空白が無駄に行数を増やしてしまうことを阻止したかったんじゃないかと思います。

簡単なテストケースを書いてみたところ、WebKitやOperaでも全角スペース以外の折り返し可能な空白では改行しないようになっていたので、全角スペースについてのみ修正することにしました。

この修正により、全角スペースは空白ではなく通常の文字として処理され、基本的にはJIS X 4051の仕様に近いルールで処理されるようになっています。

ちなみに、IE9では何故かテストケースで全角スペースは折り返しませんでした。それで、問題のページのレイアウトが崩れないというのは謎でしかありませんが、互換モードの動作を考えても不毛なので、深く追求はしていません。