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

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

もずはっく日記(2007年4月)

2007年4月10日

Bug 5625 スレッドペインで件名カラムが空白になるメールがある 初回投稿日時: 2007年04月10日23時45分48秒
カテゴリ: Mozilla Core SeaMonkey Thunderbird
固定リンク: id=2007041000
SNS: (list)

Trunkでのみ発生していた謎のバグ。ランダムっぽく発生して、原因が全く想像つかなかったのだが、デバッグビルドを作って走らせてみると簡単に問題を発見できた。

デバッグビルドで表示されない行の上をマウスカーソルが移動するとUTF-8をUTF-16に変換しようとする関数内で元の文字列がUTF-8じゃないというエラーが出まくっていた。しかし、デバッグして中身を見ても、UTF-8っぽいバイト列だったが、そのデータを作っているコードを見て理由が分かった。

問題はsubjectではなく、アラート用にプレビューテキストを生成する際にUTF-8文字列を特定のバイト数でばっさりと切っていたのが原因だった(trunkではsubjectとプレビューテキストが共にリストアップされる)。ようするに最後の一文字が中途半端に切られていると、validではないUTF-8の文字列になってしまって、描画時に処理が中断してしまっていたのだ。

UTF-8の文字単位でバイト数をカウントして、文字列を縮める関数を用意して、それでプレビューテキストを生成するようにし、表示時の処理もプレビューテキストの取得に失敗してもsubjectだけは表示されるように修正した。

ちなみに、Thunderbird2には間に合っていないのでプレビューテキストが壊れて保存されていくことになる。これによるThunderbird2で発生する問題は新着メールのアラートで該当のメールのプレビューが表示されないことだけで、trunkのように深刻な問題は無い。ただ、壊れたデータが蓄積されている可能性のあるものを今後も処理していかないといけないので、似たようなバグが発生する可能性はある。

2007年4月17日

Bug 5353 [Mac][Cocoa] IME APIの実装 初回投稿日時: 2007年04月17日02時53分37秒
カテゴリ: Mozilla Core
固定リンク: id=2007041700
SNS: (list)

IMEの状態制御に関するほぼすべての開発がこれで終了。Macでもエディタ以外ではIMEが無効になるようになった。

ただし、Macの場合、以前存在したAppleのドキュメントに従い、Romanなキーボードレイアウトしかパスワードエディタで選択できないように修正したため、キリル文字やギリシャ文字の入力ができなくなっているので、これらの言語圏からの苦情によって、まだ仕様変更はあるかもしれない。

今までに関連バグに関わってくれた多くの貢献者の方々に改めて感謝。

IME無効化バグリスト 初回投稿日時: 2007年04月17日04時22分52秒
カテゴリ: Mozilla Core
固定リンク: id=2007041701
SNS: (list)

一通り修正が完了したので記念に関連バグをリストアップ。

IME制御のコードを読みたい方へ 初回投稿日時: 2007年04月17日05時27分20秒
カテゴリ: Mozilla Core
固定リンク: id=2007041702
SNS: (list)

IMEの制御に関する簡単な概念を書いておきます。読む前に目を通しておいてもらえれればコード自体は非常にシンプルでプログラム書いたことのある人なら誰でも読めるようなものです。

IMEを制御する上で、具体的にXPレベルで状態を管理しているのはnsIMEStateManager(以下、ISM)です。これはstaticなメンバのみを持つクラスです。(つまり、現在のGeckoは複数のIMEのトランザクションを同時に保持することは原理的にできません。複数のインスタンスを持つことができるようにしたいと考える人も居るかもしれませんが、かなり困難な仕事になると私は思います。また、その労力に見合った改善は得られないでしょう。)

ISMはメソッド名を見れば分かるように、特定のタイミングで呼び出してもらうだけで、自動で適切な処理を行うように設計しています。しかも、これらのメソッドは大半がnsEventStateManager(以下、ESM)から呼び出されるので、ESM内に本来は包含できるものです。しかし、私はあえて現在の形を提案しました、そこには二つの理由があります。

まず、IMEのコードを他の言語圏の開発者に壊されないように、完全に分離したかったのです。Trunkでは幾度となくIMEユーザにはクリティカルなregressionが発生しています。これはテスト環境を持たない、また、テストできない開発者の修正によるもので当然のことです。(誰が悪いと言うわけではなく、仕方がないことです。)

二つ目は、ESMの構造を変化させなくてはいけないバグの修正があったとしても、ESMからは同じタイミングで呼び出してもらうだけでregressionを回避することが可能です。そのために、コマンドのようなメソッド名ではなく、イベントの名前をメソッド名に使っています。

こういった理由から、本来は分離しなくても良い小さく風変わりなクラスが存在しています。しかし、この小さなクラスがIMEの状態を常に、確実にコントロールします。つまり、このクラスを見るだけでGeckoのIME管理が一望できるというシロモノです。

ISMはフォーカスの移動のタイミングにのみ動作します(フォーカスが本当に移動したのかどうかという判断がちょっとややこしいのですが、この辺はGeckoのコードを理解しないといけないので説明は省きます)。フォーカスが移動したタイミングで、新しくフォーカスを受けたcontentでの、あるべきIMEの状態を考えます。

まず、プリントプレビュー時や、実際に走るかどうかは不明ですが、印刷時には無条件に無効とします。

次に、現在のdocumentが編集可能かどうかを調べます。編集可能な場合(HTMLエディタ)は有効にします。

しかし、それ以上は判断できないので、フォーカスを受けたcontentに問い合わせます。問い合わせはnsIContentGetDesiredIMEStateを使います。このメソッドは基本的にはIMEは無効であるべきだと返しますが、もしそのcontentがエディタを持つ場合、エディタに問い合わせが行きます。エディタはエディタの種類(通常、もしくはパスワード)から適切な状態を返します。

これで新しいIMEの状態を取得することができましたので、今度はnsIKBStateControlを使って現在のIMEの状態を取得します。そして、状態に差異がある場合にのみnsIKBStateControlを用いてIMEの状態の変更を要求します。

nsIKBStateControlはnsIWidgetと共に実装されています。これらの実装部分は各プラットフォーム依存の部分で、プラットフォームのAPIを利用してISMの要求を実行します。

nsIKBStateControlの各実装は今の形に落ち着くまでに紆余曲折ありましたが、できあがったコードはシンプルで、そのプラットフォームのことを知っている人なら簡単に読めるものになっています。各プラットフォームでコードを書く際に参考にするなら、この実装部分のみを読めば良いと言えます。

この様に、やっていることは非常にシンプルです。でもシンプルなことが簡単とは限らないということが分かりますね。

2007年4月27日

Bug 5128 [GTK2][topcrash] GTK2のnsWindow.cppのIM_get_input_context()でクラッシュする #2 初回投稿日時: 2007年04月27日15時33分19秒
カテゴリ: Mozilla Core
固定リンク: id=2007042700
SNS: (list)

パッチは前から出来ていたが、検証できる人が誰も名乗りでないので放置されていたバグ。だが、talkbackによるフィードバックが非常に多いのでパッチを入れることになった。

talkbackによるクラッシュリポートの提出は重要。これの統計で多いクラッシュバグは可能な限り優先的に処理される。送信していない人は逆に損をしているかもしれない。