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

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

もずはっく日記(2015年8月)

2015年8月9日

Bug-org 1186017 [GTK] nsGtkIMModule should be renamed to mozilla::widget::IMContextWrapper 初回投稿日時: 2015年08月09日10時49分22秒
最終更新日時: 2015年08月09日11時01分25秒
カテゴリ: GTK IME Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015080900
リンク元: 0件
SNS: (list)

nsGtkIMModulemozilla::widget::IMContextWrapperにリネームしようというバグです。既に、KeymapWrapperというクラスがキーイベントの処理を行っていますので、それに合わせた名前になっています。

今回の修正により、widget/gtk/nsGtkIMModule.(h|cpp)も、widget/gtk/IMContextWrapper.(h|cpp)にリネームされました。

Bug-org 1187566 [TSF] TSFTextStore::Content should compute mMinTextModifiedOffset only with the latest composition string and original composition string 初回投稿日時: 2015年08月09日11時01分01秒
最終更新日時: 2015年08月09日11時03分38秒
カテゴリ: IME Mozilla Core Mozilla41 Mozilla42 TSF Windows
固定リンク: id=2015080901
リンク元: 0件
SNS: (list)

Google日本語入力の安定版では候補ウインドウ位置を決める時にITextStoreACP::GetTextExt()が失敗すると、ウインドウの左下に表示してしまうことがあるバグがあります。TS_E_NOLAYOUT問題が修正されているWindows 10でも発生しますので、Google日本語入力自体のバグのようです(開発版では修正されているとのことですが、時間がとれなくて、まだ未確認)。

元々、TS_E_NOLAYOUT問題対策でGeckoが入れているコードで、最初の文節でのみこの症状が抑えられていました。ですが、2文節目以降で発生していたので、Gecko側のこのハックに何らかの問題があるのではないかと調査してみたところ、Google日本語入力の独特の挙動により、意図通りに動いていないバグを見つけました。

Google日本語入力は、未確定文字列が変化する際に、最初に未確定文字列全部を空文字列で置き換えてきます。次に、新しい未確定文字列を挿入します。このため、TSFTextStore::Content内で、ドキュメントロック中にどの文字以降に変化があったのかを調べた際に、常に未確定文字列の最初の文字から変化しているという判定になってしまっていました。

そこで、未確定文字列がドキュメントロック中に2回以上変更されても、ロック前の未確定文字列と最新の未確定文字列を常に比較し、それまでの変更が取り消されていないかを確認するようにして対処しました。

このバグはe10sの有効・無効に関わらず発生しますので、TSFモードが最初に有効になるMozilla 41でも修正予定です(既に承認されていますが、パッチはまだ入っていない状態)。

TS_E_NOLAYOUT問題については一度ドキュメントにまとめないといけないかもしれませんね。

Bug-org 1050644 [TSF][e10s] Candidate window of TIPs don't work correctly 初回投稿日時: 2015年08月09日11時22分11秒
カテゴリ: e10s IME Mozilla Core Mozilla42 TSF Windows バグ修正
固定リンク: id=2015080902
リンク元: 0件
SNS: (list)

e10sモードで、TSFモードを有効にしていると、様々なTIPで候補ウインドウ位置やサジェストウインドウ位置がおかしくなるというバグでしたが、これまでの修正により、確認されている問題はWindows 8以降のMicrosoft謹製の中国語(簡体字・繁体字共)のTIPで全くウインドウが表示されないというバグだけになりましたのでその修正をこのバグで行いました。

まず、問題が発生しているTIPのUIや挙動からすると、これらのTIPは全て同じソースコードをベースに作られているように感じました。そのため、一つの修正で全てに対応できると思いましたが、結果、その通りだったようです。

これに対応するには、まず、問題のあるTIPをリストアップし、それぞれのTIP名を調べなくてはいけません。これが毎度毎度、ロケールごとに別の名前になっている可能性があるので面倒です。結果は以下のようになりました。

問題のあったMS製中国語TIPとその名前
中国語ロケール以外での名前 簡体字版での名前 繁体字版での名前
Microsoft Pinyin 微软拼音 微軟拼音
Microsoft Wubi 微软五笔 微軟五筆
Microsoft ChangJie 微软仓颉 微軟倉頡
Microsoft Quick 微软速成 微軟速成

これらがアクティブな場合、ITextStoreACP::GetTextExt()acpEndを、絶対に変更が行われてない未確定文字列の最初の文字のオフセットに読み替え、acpStartをそれ以下のオフセットとすることで対処しました。

このハックは、PinyinとWubiはintl.tsf.hack.ms_simplified_chinese.do_not_return_no_layout_errorを、ChangJieとQuickはintl.tsf.hack.ms_traditional_chinese.do_not_return_no_layout_errorfalseにすることで無効化できるようにしています。

Bug-org 1187579 [e10s][TSF] Enable TSF mode in e10s mode 初回投稿日時: 2015年08月09日11時25分41秒
カテゴリ: e10s IME Mozilla Core Mozilla42 TSF Windows バグ修正
固定リンク: id=2015080903
リンク元: 0件
SNS: (list)

まだ、内部的には問題が残っているものの、日常利用のレベルではe10sモードでも、TSFモードが問題無く利用できるレベルになったので、デフォルトで有効にしようというバグです。

今回、ついにデフォルトで有効になりました。これで、IMEのe10s対応はひとつ、大きな山を越えました。

Bug-org 1191213 nsBaseWidget::NotifyWindowMoved() shouldn't notify IME when native IME handler doesn't have focus 初回投稿日時: 2015年08月09日11時35分01秒
最終更新日時: 2015年08月09日11時38分05秒
カテゴリ: IME Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015080904
リンク元: 0件
SNS: (list)

ウインドウが移動した場合に、候補ウインドウの位置をそれに追従させるために、nsBaseWidget::NotifyWindowMoved()NOTIFY_IME_OF_POSITION_CHANGEを発行していますが、IMEContentObserverが存在していない際にも発行していたため、これを確認しようというバグです。

nsBaseWidgetwidgetのコードですので、dom配下のIMEContentObserverを直接見るべきではありません(簡単にできますが、モジュール間の依存関係上、好ましくない)。そこで、今回の修正では、IMEContentObserverが生成された時に発行されるNOTIFY_IME_OF_FOCUSと、破棄される時に発行されるNOTIFY_IME_OF_BLURの間、nsBaseWidget::mIMEHasFocustrueにするようにし、これがtrueの場合にのみ、nsBaseWidget::NotifyWindowMoved()NOTIFY_IME_OF_POSITION_CHANGEを発行するように修正しました。

Bug-org 1183873 5,000 instances of "'!mContentCache.CacheEditorRect(this, &aIMENotification)'" and associated warnings emitted from widget/PuppetWidget.cpp during linux64 debug testing 初回投稿日時: 2015年08月09日11時42分20秒
最終更新日時: 2015年08月26日12時31分28秒
カテゴリ: e10s GTK IME Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015080905
リンク元: 0件
SNS: (list)

GTK版のFirefoxのみ、デバッグビルドでウインドウを移動すると警告が大量に出るため、自動テストのログが5,000の、!mContentCache.CacheEditorRect(this, &aIMENotification)とそれに付随して出る警告で埋まっているというバグです。

原因は、bug-org 1191213の修正で取り除かれましたので、こちらも修正されました。

Bug-org 1188442 Fix IMMHandler.cpp compilation on mingw. 初回投稿日時: 2015年08月09日11時51分47秒
最終更新日時: 2015年08月09日11時52分18秒
カテゴリ: IME Mozilla Core Mozilla42 Windows バグ修正
固定リンク: id=2015080906
リンク元: 0件
SNS: (list)

Bug-org 1184449の修正によるregressionです。Bug-org 1184449では、IMMHandlerが選択範囲をmSelectionに可能な限りキャッシュし、負荷を減らそうとしました。しかし、実際にはキャッシュすることも出来ていなかった上にmingwでのコンパイルエラーの原因になってしまっていました。

前回の修正で、フォーカスを持っている間は、IMMHandler::GetSelection()で、mSelectionを返し、それ以外の場合は一時的なインスタンスを返すようにしていました。しかし、単純なミスで、この戻り値がSelection&ではなく、Selectionだったため(一時的なインスタンスを返す必要があったため)、実際にはmSelectionが動作していませんでした。また、元々はSelection&としてパッチを書き始めていたため、戻り値の受け取り側は全て、Selection&として受け取っていたため、mingwではコンパイルエラーになっていたのです。

今回の修正で、戻り値の型を元通り、Selection&とし、一時的なインスタンスの代わりに、メソッド内で定義した静的なインスタンスを利用するように修正しています。

Bug-org 1186799 composition string in contenteditable element isn't committed when you click outside of the editor 初回投稿日時: 2015年08月09日12時08分21秒
最終更新日時: 2015年08月09日12時09分11秒
カテゴリ: IME Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015080907
リンク元: 0件
SNS: (list)

contenteditableなエディタ上に未確定文字列が存在している時に、編集不能なその外側をクリックしても未確定文字列は実際には確定されているものの、未確定文字列の見た目がそのまま残ってしまうというバグです。

原因は、nsHTMLEditorEventListener::MouseDown()が、editing hostの外側でクリックされた場合には何もしていないことが原因でした。

editing hostの外側でクリックが行われると、まず、mosuedownイベントが発生します。これにより、フォーカス移動が発生し、このcontenteditableなエディタはフォーカスを失います。この時に内部ではREQUEST_TO_COMMIT_COMPOSITIONが発行され、ネイティブのIMEに未確定文字列の確定を促し、それが実行されると、NS_COMPSOITION_COMMIT_AS_ISイベント等が発火されます。

通常は、このパターンでもうまくいくはずだったのですが、このケースではcontenteditableなエディタというのが問題でした。

nsHTMLEditorは(仕様が同じ形になりましたが)、ドキュメントにひとつだけ存在し、複数のcontenteditableな要素があっても、フォーカスが移動する度に初期化され、使い回すことになります。このような動作を実現するため、フォーカスを持ったcontenteditableな要素の外側にある要素は編集不能と判断されます。つまり、どのcontenteditableな要素もフォーカスを持たない場合、全ての要素が編集不能と判断されます。

このため、フォーカスを失った後にnsHTMLEditorが受け取った確定イベントは全て、処理に失敗していたのです。

これを修正するために、今回は、フォーカスを失う前段階であるmosuedownediting host外で発生した場合にも強制確定を行うようにしました。若干雑な修正の仕方なのですが、現在、エディタは自分が未確定文字列を管理していない場合には、IMEに対して確定のリクエストを出さないようになっていますので、十分に安全に修正されていると思われます。

2015年8月16日

Bug-org 1194055 Size of <input> elements has changed in Firefox 40 初回投稿日時: 2015年08月16日13時25分23秒
最終更新日時: 2015年08月25日13時16分24秒
カテゴリ: CSS HTML Mozilla Core Mozilla40 Windows バグ原因判明 バグ報告 バグ検証中
固定リンク: id=2015081600
リンク元: 15件
SNS: (list)

この問題は、Firefox 40.0.3で修正されていますのでそちらの記事を参照してください。

Firefox 40がリリース後、<input>の幅が広がっている!」レイアウトが崩れてるけど何か変更あった?というツイートがArmy of Awesomeで大量に散見されるようになりました。その原因は、Bug-org 1123654の修正によるものでした。

原因

Bug-org 1123654は、<input type="file">のボタンのキャプションが英語版だとBrowse…と表示されるべきなのですが、WindowsでGetStockObject(DEFAULT_GUI_FONT)を利用してシステムフォントを取得すると、Windows XP以前の古いUI用のデフォルトフォントが返されるため、そのフォントによっては三点リーダー(…)が、アンダーバーに見えるというバグです(Unicodeでは、行中央に表示される日本語の三点リーダーと、欧米のピリオド三つの文字は同じ文字で、フォント側のグリフの違いで使い分けるようになっています)。

このバグ対応で、「本当の」システムフォントを利用するように修正され、システムフォントの取得にGetStockObject(DEFAULT_GUI_FONT)の利用しなくなったのですが、これが日本語版のWindows、特にWindows 7のみで今回の問題を引き起こしていました。

日本語版WindowsのデフォルトのUIフォントは以下のような変遷をたどっています。

日本語版WindowsのデフォルトUIフォント一覧
WindowsデフォルトのUIフォント
Windows XPMS UI Gothic
Windows Vistaメイリオ
Windows 7
Windows 8Meiryo UI
Windows 8.1
Windows 10Yu Gothic UI

これらのフォントのうち、MS UI Gothicの平均文字幅(実測ではなく、フォントが自称している平均文字幅のことです)が一番小さく、Meiryo UIとYu Gothic UIも若干MS UI Gothicより広い程度で、おそらく、0の文字幅に近い数字を採用していると思われます。

そして問題のメイリオはもっとも大きな平均文字幅を持っていました。なんと、メイリオの平均文字幅は、MS UI Gothicのそれの約2倍もあるのです

これらのフォントを直接指定してみると、以下のような違いが出てきます。

例:
MS UI Gothic

メイリオ

Meiryo UI

Yu Gothic UI

スクリーンショット:
上記例のスクリーンショット(Windows 10)

これほどの違いがあれば問題が出るのも当然です。おそらく、Windows 8以降でこのバグを発見することは難しかったでしょう。上記の例をWindowsで表示すれば分かるように、多少は幅が広がるものの、致命的と言えるほどの違いではないからです。

現状

現在もBug-org 1194055ではどのように修正すべきか結論は出ていません。また、Firefox 40のマイナーアップデートでの修正はリスク管理の面から難しいかもしれません。12週間以上見つかっていなかったregressionをリスクを負ってまでリリース版で修正すべきなのかという話は当然出ています。

しかし、ボランティアも含め、テスタはその環境には最新のOSを利用する人が多く、現在となっては古いWindows 7でしか目立たない、しかも日本語環境特有のバグが見逃されてしまったのは、残念ながら必然だったようにも思います。

Webサイト側での回避方法

未だにどのような決着となるかは不透明ですが、これを機に、Webアプリの開発者の方々は<input>要素のサイズもCSSで明示することをお勧めします

CSSでwidthを指定しているとそもそも今回のような問題は発生しません。なぜなら、今回のバグは、仕様が不明確なHTMLによるサイズ指定の実装の互換性が問題になっているからです。<input>size属性や、<textarea>cols属性は、プロポーショナルフォントを意識していない仕様であり、各ブラウザとも自身の過去のバージョンとの互換性の問題もあり、非常に変更が難しいものとなっています(今回のような破綻が発生しかねません)。

また、これらの属性値は各要素にとって主体的なサイズ指定であって、レイアウトで重要な他の要素との大きさの関係を指定できるものではありません。考えてみてください、予想外に大きくなった<input>要素というのは、その親要素や、レイアウト時に横に並んでいる要素に対して大きくなりすぎていることこそが本当に発生している問題なのです。

これを解決するために、私は、<input>要素には、常にwidthプロパティにパーセント値を利用して親要素に対して固定したり、max-widthプロパティを利用して最大幅を制限しておくことをお勧めします。特に、max-widthを指定しておけば、トリッキーなデザインのサイト以外は大抵、解決してしまうでしょう。

もう一つの解決策として、font-familyを明示してしまうという手法も考えられます。しかし、私はこの方法は推奨しません。その理由は、ユーザにとって不便なフォントが指定されてしまうかもしれないからです。自分が好きではないフォントの利用を強制されるのは少なからず、ユーザに不快感を与えると考えられます。また、未知の環境(例えば数年後に登場しているであろう新しいOS上)ではフォントが存在しない可能性もあります。

どちらにしろ、まだしばらくFirefox側での対応に日数はかかりそうですし、Firefox 41での修正となると、9月22日まで修正されないことになります。

もし、実用上問題があるほどにレイアウトが崩れている場合は、上述のように、CSSのwidthプロパティとmax-widthプロパティを利用した修正を強くお勧めします

2015年8月25日

Bug-org 1194055 Size of <input> elements has changed in Firefox 40 #2 初回投稿日時: 2015年08月25日13時13分22秒
カテゴリ: CSS HTML IME Mozilla Core Mozilla40 Mozilla41 Mozilla42 Mozilla43 バグ修正
固定リンク: id=2015082500
リンク元: 0件
SNS: (list)

Firefox 40をWindows 7やWindows Vistaで利用していると、Firefox 39までに比べて、CSSで幅指定を行っていない<input>要素の幅が倍ぐらいになって、レイアウトが崩れてしまうという例のバグの続報です。

既に先週からmozilla-central (43)、Aurora (Developers Edition, 42)、Beta (41)では修正パッチが投入されていましたが、ようやく、今週リリース予定のFirefox 40.0.3向けにもパッチが投入されました。

ここでは、どのように修正されたのかを解説しておきます。

まずおさらいですが、Firefox 39までは、GetStockObject(DEFAULT_GUI_FONT) APIを利用して、システムのUIフォントを取得していました。日本語版のWindowsでは通常、Windows Vista以降でもレガシーなMS UI Gothicになります。

しかし、欧米では一部、レガシーなフォントのままでは表示がうまくいかないケースがあるので、SystemParametersInfoW(SPI_GETNONCLIENTMETRICS)を利用して、本当のUIフォントを取得するようになりました。その結果、日本語版Windowsでは、バージョンごとに以下のフォントを利用されるようになりました。

日本語版WindowsのデフォルトUIフォント一覧
WindowsデフォルトUIフォント
Windows XPMS UI Gothic
Windows Vistaメイリオ
Windows 7
Windows 8Meiryo UI
Windows 8.1
Windows 10Yu Gothic UI

このうち、メイリオのみ、フォント情報がMS UI Gothicのものと大きく違っていたため、互換性が著しく低くなってしまっていたのが今回の問題の修正すべきポイントだったわけです。

今回の修正では、Windows 2000で導入された、MS Shell Dlg 2疑似フォント<input type="text">等と、<select>で利用するように修正されています。この疑似フォントは、国際化されたアプリでダイアログを表示する際等に適切なフォントとして定義されています。また、Windows 2000やXPと互換性を持ったアプリにはこのフォントを利用するように書かれています

MS Shell Dlg 2疑似フォントは、Tahomaにマッピングされており(レジストリのHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes)、TahomaはFontLinkによって、日本語の文字のレンダリングには、MS UI Gothicを最初に参照するようになっています(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink参照)。

これにより、Firefox 40.0.3以降では、<input>要素ではTahomaを基準にsize属性のレンダリング結果が決まるようになります。つまり、従来と同じMS UI Gothicには戻りません。このため、若干のレンダリング結果の差は今後も発生します。

例:
MS UI Gothic (Firefox 39までのレンダリング結果)

Tahoma (Firefox 40.0.3以降のレンダリング結果)

スクリーンショット:
上記例のスクリーンショット(Windows 10)

この結果から分かるように若干、MS UI GothicよりもTahomaは広いです。ただし、その差は約1.05倍です。約2倍になっていたメイリオ等からするとわずかな差異となっています。

余談ですが、日本人にとっては下線位置も気になるところです。Tahoma経由でMS UI Gothicを表示するようになるので、下線の位置は1px、従来よりも文字に近づきます。このため、人によっては若干、IMEで入力中の文字列が見づらいと感じるかもしれません。

2015年8月26日

Bug-org 1192156 IME related structs, classes and enums defined in nsIWidget.h should be separated to different header 初回投稿日時: 2015年08月26日12時43分18秒
カテゴリ: IME Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015082600
リンク元: 0件
SNS: (list)

nsIWidget.hのIME関連のメソッドで利用している様々な構造体やenumの定義や実装のコードが大量にnsIWidgetクラスの定義の上にあるため、それを別のヘッダファイルに移動させようという話です。

今回の修正で、widget/IMEData.hという新しいヘッダファイルを作成し、ここに移動させました。

現在のところ、nsIWidget.hが単純にIMEData.hをincludeしているので依存関係が改善できていませんが、時間があれば前方宣言を利用して改善してみたいですね(もしくはコードレベルで貢献したい方、やってみませんか?)。

Bug-org 1187724 Flash hangs on BBC iPlayer after changing system volume through keyboard 初回投稿日時: 2015年08月26日13時02分59秒
最終更新日時: 2015年08月27日09時38分42秒
カテゴリ: Events Flash KeyboardEvent Mozilla Core Mozilla41 Mozilla42 Mozilla43 plugin Windows バグ修正
固定リンク: id=2015082601
リンク元: 0件
SNS: (list)

イギリスからBBCのサイトにアクセスした際に見ることができるFlashの動画プレーヤー上で、キーボード上のボリュームキーからボリュームを調整しようとするとハングアップするというバグです。

手探りでパッチを作って、テストしてもらったところ、Bug-org 865561の修正によるregressionでした。

MSDNのWM_APPCOMMANDのドキュメントをあらためて読んでみると、このメッセージはフォーカスを持ったウインドウが処理しなかった場合、その親ウインドウへと送信されていくタイプであることが分かりました。wParamが本来のターゲットのウインドウハンドルを持っているため、これが別プロセスのウインドウだった場合はKeyboardEventを発火しないようにしました。

このバグは単純に他のサイトでは再現しないことから、keydownkeyupのイベントリスナがFlash Playerにアクセスしようとして発生していると思われます(plugin-container.exeのプロセスは、WM_APPCOMMANDDefWindowProc()経由でGeckoに送信中なのでハングアップしてしまう)。

Bug-org 555642 [IMM32][TSF] Shouldn't paint caret during composition when the caret is in selected clause 初回投稿日時: 2015年08月26日23時04分49秒
最終更新日時: 2015年08月26日23時06分37秒
カテゴリ: IME Mozilla Core Mozilla43 Windows バグ修正
固定リンク: id=2015082602
リンク元: 0件
SNS: (list)

e10s関係の作業でかなりストレス貯まってきたのと、レビュアが夏期休暇をとってて通常の仕事がしづらいので、気晴らしを兼ねて古いバグの修正を行うことにしました。一つ目はこのバグです。Bug-org 553975の修正によって、未確定文字列の背景色が設定されていても、キャレットが常に表示されるようになりました。しかし、これはWindowsでは不自然な描画で、特に、IMEがキャレットを未確定文字列内に表示するように指示していない時に表示するのは間違っていました。

今回の修正で、未確定文字列の文節情報の中にキャレット位置の情報が含まれていない場合、キャレットを未確定文字列の末尾に表示するのをやめるようにしました。

しかし、キャレットの表示状態はステートフルで、エディタが単純に未確定文字列の文節をセットする際にキャレットを直接非表示にしてしまうと復元することが困難だったり、ウインドウのフォーカス状態の変化により表示されるように上書きされることが予想されました。そのため、nsCaretにはWindowsのAPIと同じ様に、非表示をオーバーライドできるメソッドを用意し、その呼び出し回数をカウントしてゼロの場合だけ従来の表示・非表示状態を用いるようにしました。これにより、エディタ以外のモジュールが非表示にしたい場合も今回の修正とバッティングすることはありません。そして、nsEditor自身はnsCaretの強制非表示カウントを複数回カウントアップしてしまわないように、boolのメンバ変数を使って2回以上呼んでしまわないようにしています。

Windows以外でもキャレットを非表示にすることはもちろん可能ですが、現在、未確定文字列にキャレットを含めない指定を行っているのはWindows版のwidgetだけです(TSFモードではハングルのTIPが利用されている時のみ)。

Bug-org 299603 Use IM specified style for preedit string (It is better to use PANGO_ATTR_BACKGROUND for XIMReverse) 初回投稿日時: 2015年08月26日23時24分59秒
カテゴリ: GTK IME Mozilla Core Mozilla43 バグ修正
固定リンク: id=2015082603
リンク元: 0件
SNS: (list)

放置していたバグ修正第二弾です。LinuxのIMEは未確定文字列のスタイル情報を一般的には指定してきます(一部の変換エンジンは自分でカスタマイズもできます)。しかし、GTK版Geckoはこの指定をそのまま利用せず、そのスタイルから各文節の「意味」を推測して独自の描画を行っていました。

今回の修正では、まず、WindowsのTSFサポートのために実装していた、未確定文字列のスタイル指定をGTKのIMContextWrapperで設定するようにしました。これで表示はひとまず解決です。

続いて、アクセシビリティ上、適切な値を設定しておかなくてはいけない文節のタイプ(意味)はキャレット位置から推測するようにしました。まず、文節がひとつしかなく、未確定文字列全てを覆っているのであれば、NS_TEXTRANGE_RAWINPUT、文節内のいずれかの文字の前にキャレットが存在している場合、その文節をNS_TEXTRANGE_SELECTEDCONVERTEDTEXT、そして、それ以外の文節をNS_TEXTRANGE_CONVERTEDTEXTとしています。この方法なら、選択文節の末尾にキャレットを持ってくるIMEでなければ正しく意味づけもできているはずです。

これまでの未確定文字列の表示方法のせいでIME開発者が未確定文字列に指定するデフォルトのデザインに制約がありましたが、それがこの修正で取っ払われたことになります。

しかし、LinuxのIME開発者は常にシステムデフォルトのwidget上でIMEが利用されることを念頭に、前景色と背景色のどちらかしか設定しない可能性が考えられます。そこで、未確定文字列の文節が前景色か背景色どちらかだけが設定されていた場合、もう一方にはネイティブwidgetの配色を使うことでコントラストを確保するようにしました。

最後に、今回のバグ修正中に発見した、バグもついでに修正しています。それは、未確定文字列内にサロゲートペアが存在していて、それより後ろにキャレットがあると、キャレットの位置がずれてしまうというものです。

GTKはキャレット位置を文字数単位で指定してくるのに対して、GeckoはUTF-16で2バイトを1文字としてカウントしていたためです。単純に、glibの関数を利用して、GTKにとっての文字数分のUTF-16文字列を取得し、その長さからキャレット位置を算出するようになりました。

Bug-org 1196124 crash in dosprintf when you enable logging nsIMM32HandlerWidgets 初回投稿日時: 2015年08月26日23時34分21秒
最終更新日時: 2015年08月26日23時35分05秒
カテゴリ: IME Mozilla Core Mozilla42 Mozilla43 Windows バグ修正
固定リンク: id=2015082604
リンク元: 0件
SNS: (list)

Windows XPでテストしている時に、環境変数でNSPR_LOG_MODULES=nsIMM32HandlerWidgets:5が設定されたままになっていたのですが、テキストフィールドにフォーカスが当たると、即座にクラッシュしてしまっていました。調べてみると、Bug-org 1186015の修正時に二つのMOZ_LOG()を統合した際に、%uを一つ追加せずに、変数を追加していたため、ひとつずつずれて、%sint32_tが当たってしまい、クラッシュしていました。

2015年8月27日

Bug-org 90712 [IMM] Enter key shouldn't commit composing string of ChangJie for WinXP 初回投稿日時: 2015年08月27日11時12分33秒
最終更新日時: 2015年08月27日11時23分30秒
カテゴリ: IME Mozilla Core Mozilla43 Windows バグ修正
固定リンク: id=2015082700
リンク元: 0件
SNS: (list)

放置バグの修正第三弾。Windows XP用のMS製の中国・台湾向けIMEのいくつかは、やはり同じコードベースで作られているようですが、ChangJie等、いくつかのIMEは、Enterキーを押した場合、IMEがそれを処理せずにそのままアプリに送信されてきます。その際にGeckoでは強制確定してしまうのですが、ネイティブアプリだと未確定のまま改行を挿入し、候補ウインドウ位置を移動させます。しかし、これは、未確定文字列を自身で描画するアプリには難しい動作なのでIE6がどのようにしているか調べて見ると、単純に未確定文字列をキャンセルして、改行を行っていました。

Geckoは以前にIMEが未確定の状態で特定のキーイベントがIMEに処理されずに来た場合に未確定文字列をキャンセルするようにしていました。ここにVK_RETURNも追加して対応しています。

Bug-org 1189396 [TSF] Some IME's composition string is committed at starting to input composition string in google.com 初回投稿日時: 2015年08月27日11時21分25秒
カテゴリ: IME Mozilla Core Mozilla43 TSF Windows バグ修正
固定リンク: id=2015082701
リンク元: 0件
SNS: (list)

TSFモードで(google.co.jpではなく) google.comのトップページで未確定文字列を入力しだすと、google.comは検索結果をインクリメンタルサーチし始めると同時にエディタが上部へとそのまま移動します。この際に一文字目の未確定文字列が確定されてしまうというバグです。

原因は、エディタが移動した際にIMEContentObserverが選択範囲の変化通知を受け取って、nsIWidgetNOTIFY_IME_OF_SELECTION_CHANGEを送信し、それを受けてTSFTextStoreが強制確定を行っていたのが原因でした。

今回の修正で、IMEContentObserverNOTIFY_IME_OF_SELECTION_CHANGEを送信する前にフラットテキストのオフセットに変換した状態で、選択範囲が変更されているか確認し、変更されていない場合には送信しないように修正しました。

2015年8月30日

Bug-org 930843 NS_UI_ACTIVATE should be dispatched as trusted event even if it's caused by untrusted event 初回投稿日時: 2015年08月30日09時51分19秒
カテゴリ: Events Mozilla Core Mozilla43 バグ修正
固定リンク: id=2015083000
リンク元: 0件
SNS: (list)

放置していたバグの修正です。NS_UI_ACTIVATEは、DOMActivateイベントの元です。ちなみに、DOMActivateイベントとは、マウスで要素をクリックした時にアクティブ状態になったことを通知するイベントですが、DOM Level 3では不採用が確定して削除できないか模索もされています。

それはさておき、今回のバグは、そのDOMActivateがuntrustedなマウスイベントによって発生した場合(例えばclickイベントを生成して要素上で発火した時や、click()メソッドでクリックを偽装した場合)、そのイベントのisTrustedを引き継いで、falseのままイベントを生成していました。

isTrustedはそのイベントがユーザエージェントから発火されたものかどうかを示します。つまり、このケースではクリックのエミュレーションが原因であっても、実際にアクティブになったからDOMActivateイベントを生成しているので、そのisTrusted属性は常にtrueでなくてはいけないのです。

今回の修正で、NS_UI_ACTIVATEが信頼できるソースから生成されたのかどうかを判断するにはWidgetEvent::mEvent::mIsTrustedが利用できなくなったので、それを検査していた(と思われる)箇所のために、InternalUIEvent::IsTrustable()というメソッドを追加しています。

Bug-org 1198594 crash in libsystem_kernel.dylib@0x16286 初回投稿日時: 2015年08月30日10時06分19秒
カテゴリ: e10s IME Mozilla Core Mozilla42 Mozilla43 バグ修正
固定リンク: id=2015083001
リンク元: 0件
SNS: (list)

Mac OS X 10.10でエディタにフォーカスを合わせると高確率でクラッシュするらしいバグです。スタックが変なことになっていますが、よく見ると、ContentCacheInParent::FlushPendingNotifications()内でdeleteを行っている最中にクラッシュしているようでした。

このメソッド内でdeleteが走る可能性といえば、IMENotification::mMessageNOTIFY_IME_OF_SELECTION_CHANGEから別のものに変更される際にIMENotification::mSelectionChangeData::mStringが削除される場合以外にないです。そこで、IMENotificationを確認してみたところ、コピーコンストラクタでIMENotification::mMessageを初期化するのを忘れていたことに気付きました。これを修正したら発生しなくなったことから、Bug-org 1184449の修正(SelectionChangeDatamStringを追加した)によるregressionであることは明らかなのですが、何故かOS Xでのみ発生し(しかも10.10だけ?)、Bug-org 1189396の修正がトリガーとなって高確率でクラッシュするようになっているという不思議なバグでした。

ちなみに、もちろん、他のOSでもクラッシュする可能性はあります。コピーコンストラクタでIMENotificationが生成された時に、mMessageたまたまNOTIFY_IME_OF_SELECTION_CHANGEになっていればクラッシュします。

セキュリティ上の懸念があるクラッシュバグなので、リポートが皆無のAuroraでも修正を申請しています。

Bug-org 1199224 [TSF] MS Korean IME doesn't replace composition string properly after ASCII character 初回投稿日時: 2015年08月30日10時31分44秒
カテゴリ: IME Mozilla Core Mozilla41 Mozilla42 Mozilla43 TSF Windows バグ修正
固定リンク: id=2015083002
リンク元: 0件
SNS: (list)

TSFモードで、ハングルのTIPを利用している時に、半角記号の後ろでハングル文字を入力しようとすると最初のハングル文字の合成中に、最初に入力した文字が確定され、その後、二文字目以降が合成された未確定文字がその前に挿入されるというバグです。

ハングルのIMEは基本的にはQWERTYキーボードのアルファベットキーを押した時だけ未確定文字列を生成し、ハングル文字を一文字ずつ合成していく(ローマ字入力がかな一文字ずつ完成するたびにコミットされるイメージ)のですが、記号のキーを押した場合にはそのままキーイベント経由で文字が入力されます。そのため、日本人とは比較にならないぐらいに半角記号混じりの文章を入力するようで、これが原因でTSFTextStoreの設計ミスを洗い出してくれていました。

TSFTextStoreはTSFのドキュメントロックをエミュレートするため、ロックが要求された時点でフォーカスを持つエディタの情報を収集・キャッシュし、この情報からTSFの問い合わせに応答するようになります。そして、ドキュメントがアンロックされた時にこれを破棄し、コンテンツのリアルタイムの情報を取得しにいくようになります。

このドキュメントのアンロック時のキャッシュ破棄に問題がありました。なんと、リード・オンリーなロックの場合、破棄していなかったのです。

ハングルのTIPの場合、半角記号がそのままキーイベント経由で入力されるため、TSFTextStoreを経由せずに文字入力が行われます。しかし、その直前にTIPがリード・オンリーなロックをかけた状態でコンテンツを取得しに来ていると半角記号が入力される前のコンテンツをキャッシュしているわけです。この古いキャッシュをハングル文字の入力を開始した時にも利用しているため、実際のキャレット位置がキャッシュしているコンテンツの外側になってしまうことになります(キャレット位置の情報はコンテンツ側から更新通知が来て、リアルタイムに更新されます)。この矛盾によりTIPは混乱し、未確定文字列を一旦確定させてしまうものの、二文字目以降の合成は何故か継続されるという不思議な挙動(これはこれでTIPのバグ)を起こして、このバグのような症状になっていた訳です。

今回の修正では単純にリード・オンリーなロックのアンロック時にもキャッシュを破棄すれば良いだけの話だったので、TSFが最初に有効になるBetaでの修正も申請中です。

Bug-org 895274 Change GUI MESSAGES to enum 初回投稿日時: 2015年08月30日10時49分00秒
カテゴリ: Events Mozilla Core バグ修正
固定リンク: id=2015083003
リンク元: 0件
SNS: (list)

まだ作業半ばですが、しばらく、他の人のパッチを壊す可能性のあるバグなので紹介しておきます。

これまで、WidgetEvent::messageuint32_tとして定義されていて、その値は単純にマクロを使って、整数値に名前を付けていただけでした。

このバグではソースコードをより安全なものにするため、これを名前付きenumに変更しました。その名前はmozilla::EventMessageです。これにより、整数値を単純にWidgetEvent::mMessage(リネームしました)に代入しようとしたり、比較しようとするとコンパイルエラーになるようになり、分かり難いバグの発生を抑えています。

そして現在はコーディングルールに従い、全てのイベントのメッセージをeプレフィックス付きの短い名前に置換していっています。影響範囲の大きいであろうキーイベントとマウスイベントのメッセージは昨日、mozilla-inboundに既に投入しました。明日にあると思われるマージでmozilla-centralに入ると思いますが、その近辺をいじっていたパッチはrebaseが必要になります。

そして、来週も時間をかけて地道な置換作業が続いていく予定です。