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

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

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

2015年7月1日

Bug-org 1138384 enable CSS writing-mode support in release channels 初回投稿日時: 2015年07月01日10時02分56秒
カテゴリ: CSS Mozilla Core Mozilla41 writing-mode バグ修正
固定リンク: id=2015070100
SNS: (list)

まだいくつか重要な問題が残っているらしいですが、ついに、リリースビルドでもwriting-modeが有効化されました。contenteditableを利用すれば、縦書きのエディタも利用可能です。

もっとも、私個人は縦書きのページで横にスクロールを強いられるとホイールの操作が面倒になるので大量のコンテンツを縦書きしてもらいたくはないですが(読みにくいWebデザインの典型としてリストアップされそうな気も)。

2015年7月7日

Bug-org 1053053 [e10s][TSF] Typed text appears in unfocused textarea when using IME 初回投稿日時: 2015年07月07日01時05分38秒
カテゴリ: e10s Mozilla Core Mozilla42 TSF バグ修正
固定リンク: id=2015070700
SNS: (list)

e10sを有効にしていると、contentプロセス内のエディタにフォーカスを移し、その後、chromeプロセス内のエディタにフォーカスを移動させてもcontentプロセス内のエディタに未確定文字列が表示されるというバグです。

このバグは目には見えないだけで、Windows固有のもので、TSFモードだけではなく、IMMモードでも問題がありました。

問題の根本的な原因は、IMEStateManagerがマルチプロセスに全く対応させられておらず、TabParentで疑似的にWidgetCompositionEvent等、IMEのハンドリングに必要なイベントをアクティブなタブへ送信していたことにあります。そこで、このバグではIMEStateManagerのマルチプロセス対応を行いました。

実際に何が起きてWindowsでのみ、この問題が出ているのかという理由ですが、それは、Windowsでのみ全てのウインドウがアクティブではなくなっても、未確定文字列を強制確定せず、次にウインドウがアクティブになった場合に未確定文字列の編集を続行できるようにしているためです。

何故、Windowsだけこのような挙動になっているかというと、Windowsではプロセスがビジー状態に陥った場合、Windows自身がウインドウを白っぽく描画し、タイトルバーに「応答無し」と表示を行います。この時、アプリはウインドウが一時的にディアクティブになったかのようにイベントをOSから受け取ります。ですので、この時に強制確定してしまうと、システム全体でCPUやディスクアクセスがビジー状態の場合に、まともにIMEが利用できなくなってしまいます。これを避けるため、意図的にこのような動作になっているのです。

では、IMEStateManagerがこの仕様が原因できちんと動かないのかというと、フォーカスが子プロセスから親プロセスに移動した時、子プロセス側のIMEStateManagerはウインドウがディアクティブになった場合と同じ通知を受けとっているためです。このため、実際にはフォーカスが親プロセスの別のエディタに移動した場合にも、子プロセスのIMEContentObserverが破棄されないため、IMEにフォーカスを失ったという通知が送信されません。しかし一方では、親プロセスのIMEStateManagerは、IMEContentObserverを生成し、IMEにフォーカスを得たという通知を出しますので、IMEからすると、複数のエディタが同時にフォーカスを持っているという異常な事態が発生していました。

また、それ以外にも、プロセスをまたいだフォーカス移動では様々な問題が起きていて、例えば、子プロセスのエディタがフォーカスを持っているときに、親プロセスのメニューを開いてもIMEが有効なままというバグもありました。

今回の修正ではまず、IMEStateManagerがアクティブなTabParentを自身で管理するようにしました。nsIContentTabParentを持っているのかどうなのかは、TabParent::GetFrom()で取得できますので、これまでのコードに少し変更を入れるだけで簡単に変更できました。

次に、TabParentのプロセスがフォーカスを失う時(親プロセスがフォーカスを得るときと、他の子プロセスがフォーカスを得る時)に、フォーカスを持っていた子プロセスに、フォーカスを失ったという通知を出すようにしました。これにより、ウインドウ全体がディアクティブになったと思い込んでいる子プロセス側のIMEStateManagerIMEContentObserverを適切に破棄することができます。また、フォーカスを持っていたnsPresContextnsIContentを忘れることで、今までの処理と整合性がとれます。

最後に、メニューが開かれたときと閉じられたときに発生する疑似フォーカス移動を、フォーカスを実際に持っている子プロセスに通知するようにしました。これで、メニューを開き、一時的に全てのキーイベントを処理する親プロセス側のIMEStateManagerと、IMEを一時的に無効化する必要がある子プロセス側のIMEStateManagerで状態を同期できるため、従来のコードそのままでメニューの開閉にも対応することができました。

これまでのIMEStateManagerのコードを読んだことがある人には特に違和感が無いような修正になっていますので、我ながらなかなかうまく修正できたなと思ってます。

ちなみにこの一連のデバッグとパッチ作成は、カナダからの帰国時に太平洋上で行ったものです。いや、どうでもいいことですが。

2015年7月19日

Bug-org 1179093 ContentEventHandler::mSelection should be nsRefPtr<Selection> 初回投稿日時: 2015年07月19日12時07分05秒
カテゴリ: Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015071900
SNS: (list)

現在、nsISelectionmozilla::dom::Selectionでしか実装されていません。そのため、多くの内部処理はSelectionクラスを直接利用するようになっていますが、ContentEventHandlerは未だにnsCOMPtr<nsISelection>を利用していたため、コードが無用に複雑なままでした(XPCOMのメソッドで値を取得する場合、値は引数で受け取らないといけないため)。そこで、nsRefPtr<Selection>として保存するようにし、コードをシンプルにしようというバグです。

しかし、nsISelectionとして取得したものを現在の設計を理由にSelectionにキャストしているので、安全とは言い切れない修正にもなっています。nsISelection::AsSelection()のようなメソッドを今後追加すべきかもしれません。

Bug-org 1179081 ContentEventHandler should use root content's primary frame to retrieve focused widget when there is no caret 初回投稿日時: 2015年07月19日12時27分44秒
カテゴリ: Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015071901
SNS: (list)

ContentEventHandlerは、キャレットのフレームからフォーカスを持った要素が存在しているnsIWidgetを算出します。しかし、エディタ以外がフォーカスを持つ場合にはキャレットが無いことの方が多いので、デバッグビルドではよく警告を吐いていました(Macではテキスト入力以外に使うべきではないとApple自身が定義しているNSTextInputClientプロトコルを当のApple自身が作った辞書での検索サービスが、コンテンツ取得にこのプロトコルを使っているため)。

今回のバグ修正では、キャレットフレームが存在しない場合、検索対象のルートとなるnsIContentのプライマリフレームを利用するように修正しました。

Bug-org 1179082 ContentEventHandler::OnQueryCaretRect() should guess caret rect when the selection is collapsed but there is no caret frame 初回投稿日時: 2015年07月19日12時39分24秒
カテゴリ: Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015071902
SNS: (list)

ContentEventHandlerはキャレットの矩形を取得する際に、検索されたオフセットが、現在のキャレット位置と一致している場合にはキャレットフレームのものを直接利用しようとします。そうしないと、例えば<img>が存在していると、実際のキャレット位置とオフセット位置の文字の矩形から算出したキャレットの矩形が異なることがあるからです。しかし、Mac OS Xの辞書検索サービスのNSTextInputClientプロトコルの「悪用」によりキャレットフレームが存在していないことがあり、その場合には矩形の取得に失敗していました。

今回の修正でキャレットフレームが存在していない場合には、そもそも実際のキャレットを利用しようとせず、オフセット位置の文字の矩形から推測するようにしています。

Bug-org 1179086 ContentEventHandler should use \n for native linebreaker rather than \r 初回投稿日時: 2015年07月19日12時45分29秒
カテゴリ: Mac Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015071903
SNS: (list)

ConentEventHandlerを最初に実装したときから、OS XではNSTextInputプロトコル(現NSTextInputClientプロトコル)で改行入りの文字列を返す場合に、改行文字を\rに置換していました。しかし、今日ではOS XはすっかりUNIX由来のOSらしく\nの方が一般的になっていますので、置換を行わないようにしようというバグです。

一応、今までも特に問題は起きていなかったので、MacのIME等々は\rも未だに改行として認識しているか、単に意味不明なコントロール文字なので単語の区切りとしては機能していたかのどちらかだと思いますが。

Bug-org 1179090 ContentEventHandler should assume that the selection range is [0-0] when there is not selection range 初回投稿日時: 2015年07月19日12時53分11秒
カテゴリ: Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015071904
SNS: (list)

ContentEventHandlerはコンテンツの検索が行われた際には必ず選択範囲が(目には見えなくても)存在していると仮定して実装されています。例えば、フォーカスを持てない要素でもクリックした位置にキャレットがあるかのように選択範囲が存在しています。コンテンツをクリック後にTabキーでフォーカスを移動すると、この見えない選択範囲から付近のフォーカスを持てる要素を検索しているためだったりします。

話を戻すと、この選択範囲は選択可能な要素をクリックするまで生成されませんが、ContentEventHandlerは常に選択範囲が存在しているテキストエディタでの利用を想定していたため、このような状況は想定外でした。そこで、選択範囲が存在しない場合、検索対象のルート要素の先頭部分に選択範囲があると仮定するようにして修正を行いました。

ようするに、これも、Apple自身のNSTextInputClientプロトコルの「悪用」のために発生していたバグです。

Bug-org 1179122 [e10s] TextComposition should manage target in parent process even when its child process has focus 初回投稿日時: 2015年07月19日13時05分29秒
カテゴリ: e10s Events IME Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015071905
SNS: (list)

e10sモードでは、ネイティブのフォーカスは、常にchromeプロセスが持っています。つまり、IMEからのネイティブイベントをハンドリングするのはchromeプロセスになります。そして、各OS向けのwidgetが生成したWidgetCompositionEventは、子プロセス内にフォーカスがある場合に、EventStateManager::PreHandleEvent()で子プロセスにイベントを送信し、chromeプロセス内では何もしないという形をとっていました。つまり、WidgetCompositionEventの送信ターゲットを管理するTextCompositionのインスタンスは子プロセスでのみ生成されていました。

しかし、これでは未確定文字列が存在している状態で親プロセス内でフォーカス移動が発生し、子プロセスがフォーカスを持たなくなってしまうと、強制確定のために発生したWidgetCompositionEventが新たにフォーカスを得た要素へ送信されてしまい、おかしなことになります。

そこで、今回の修正では、EventStateManager::PreHandleEvent()では何も行わないようにし、chromeプロセス内でも常にTextCompositionを生成し、これにWidgetCompositionEventの送信を任せるようにしました。TextCompositionは送信ターゲットが子プロセスを持っていた場合には、DOMツリーにはイベントを送信せず、その子プロセスに送信します。これにより、親プロセス内でフォーカス移動があっても、確定されるまでの一連のWidgetCompsoitionEventは確実に未確定文字列を持っている子プロセスへ送信されることが保証されました。

Bug-org 1180240 ContentEventHandler::OnQuerySelectedText() should use mFirstSelectedRange if mSelection doesn't have selection range 初回投稿日時: 2015年07月19日13時19分11秒
カテゴリ: Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015071906
SNS: (list)

Bug-org 1179090の修正に対するフォーローアップです。ContentEventHandlerの初期化処理では選択範囲が存在していない場合には選択範囲が先頭に存在していると仮定するようにしましたが、ContentEventHandler::OnQuerySelectedText()mSelectionから直接選択範囲を取得していたため、この修正結果の恩恵を受けられていませんでした。

今回の修正で、mSelectionが選択範囲を持たない場合は、初期化時に仮定した選択範囲を保存してあるmFirstSelectedRangeを利用するようにしています。またこの場合の処理はより単純に行えるため、高速に処理するようにしています。

Bug-org 1181714 [TSF] crash in _invalid_parameter_noinfo with Microsoft Office Korean IME 初回投稿日時: 2015年07月19日13時27分54秒
カテゴリ: IME Mozilla Core Mozilla40 Mozilla41 TSF バグ修正 バグ却下
固定リンク: id=2015071907
SNS: (list)

TSFモードを有効にしたFirefox 40 Betaでは、韓国のユーザから大量のクラッシュレポートが送信されてきていました。そのスタックトレースを見ると、フォーカスを失う際にTIP内部でクラッシュしています。ロードされているDLLからすると、MicrosoftのOffice IMEのハングル版のようでした。また、バグにコメントしてくれた中国語版のユーザもやはりOffice IMEでクラッシュするということでした。

スタックの内容からすると、TIPが適切にオブジェクトを参照していないため、フォーカスを失う際にGeckoが手放したなんらかのオブジェクトの参照カウントがゼロになり、先に解放されたところへアクセスしているようでした。何故かOffice IMEをWindows 7にインストールしようとしてもうまくインストールされないので、手探りで書いたパッチを投入してみたものの効果はありませんでした。

しかし、先のコメントしてくれた中国語版のユーザの方が検証してくれたところ、Aurora 41では再現しないとのこと。ということで、Mozilla 41で行われた修正のうちのどれかが、フォーカス喪失時の処理タイミングのまずさを改善したんだと思われます。もともとTSFのデフォルトでの有効化は41に先送り予定だったので、このバグ自体を40で修正するのは断念しました。

Bug-org 1176954 [e10s][TSF][GTK?] TabParent shouldn't notify IME until all sending events are handled 初回投稿日時: 2015年07月19日13時40分55秒
カテゴリ: e10s GTK IME Mozilla Core Mozilla42 TSF バグ修正
固定リンク: id=2015071908
SNS: (list)

e10sモードでは、子プロセスがフォーカスを持つ場合、chromeイベントでハンドリングしたネイティブのIMEイベントが、非同期で子プロセスに処理されることになります。ここで困るのがTSFやGTKでIMEに選択範囲の変化等を通知するタイミングです。これまでは、子プロセスから通知が来た場合に即、TSFやGTKに通知を行っていましたが、子プロセスの処理が遅れている場合、TSFやGTKからするといくつか前の状態が通知されるというおかしなことになります。

今回の修正では、chromeプロセスが送信したWidgetCompositionEventと、WidgetSelectionEventが子プロセスに受信された時に親プロセスに通知を返すようにし、送信中のイベントが無くなった状況でため込んでいた通知を行う様に修正しました(ただ、今、これを書いていて気付きましたが、子プロセス内でイベントを処理し終えてから通知しないとひとつ古い情報を通知することになりそうな……)。

Bug-org 1176950 [e10s][TSF] nsTextStore shouldn't abandon locked content cache before dispatching events because they may be handled asynchronously in e10s mode 初回投稿日時: 2015年07月19日13時57分07秒
カテゴリ: e10s IME Mozilla Core Mozilla42 TSF バグ修正
固定リンク: id=2015071909
SNS: (list)

nsTextStoreは、ドキュメントがロックされている間はコンテンツがJavascriptによって更新されることを防ぐため、コンテンツを予めキャッシュした上で、ドキュメントがアンロックされるまで、イベントを送信しないようにしています。

しかし、e10sモードでは、イベントを発火した後も非同期で処理されるため、次のドキュメントロックが発生した時に、前に送信したイベントが全て処理されているとは限りません。そこで、全てのイベントが処理されたという通知が来るまで、最初にキャッシュしたコンテンツを保持しつづけ、TSFからの応答に期待通りに答える必要が出てきました。

今回の修正では、Bug-org 1176954の修正を利用し、全てのイベントが処理された後に来るNOTIFY_IME_OF_COMPOSITION_UPDATEが通知されるまではキャッシュしたコンテンツを破棄しないようにしました。

Bug-org 1184004 [e10s] Methods to notify IME should use IMENotification at IPC 初回投稿日時: 2015年07月19日14時03分31秒
カテゴリ: e10s IME Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015071910
SNS: (list)

e10sモードでは、コンテンツからIMEへの通知はIPC通信を通して行われるわけてすが、この時に、何故かIMENotificationを直接送受信せず、必要な内容を個別の引数にして渡していました。このため、受信した側ではまたIMENotificationを再度作らないといけないため、IMENotificationの内容が変更される度に変更のコストがけっこう大きかったわけです。

今回の修正ではIMENotification内で定義されていた匿名の構造体全てに名前を与え、IMENotificationをそのまま通信時に利用するようにしました。

Bug-org 1176955 [e10s][TSF] Kakutei-Undo of Japanese IME doesn't work 初回投稿日時: 2015年07月19日14時11分20秒
カテゴリ: e10s IME Mozilla Core Mozilla42 TSF バグ修正
固定リンク: id=2015071911
SNS: (list)

e10sモードでは、TSFモード時にATOK等の実装している確定アンドゥが動かないというバグです。

確定アンドゥは直前に確定した文字列を選択し、そこに未確定文字列を挿入(置換)することで実現されています。しかし、e10sモードでは、非同期でこの選択範囲の変更通知がやってきます。そのため、nsTextStoreはやってきた選択範囲の変更通知を無視して良いかどうか判断がつかず、未確定文字列を強制確定してからTSFに新しい選択範囲を通知していました。

今回の修正ではひとまず、WidgetSelectionEventを子プロセスでハンドリング中に選択範囲が変更された場合、それはそのイベントが原因で発生した通知であるという旨を示すフラグをIMENotificationに追加しました。これにより、nsTextStoreはこれを無視することでひとまず確定アンドゥが機能するようになっています。

ただし、nsISelectionListenerを利用したアドオンが選択範囲をさらに変更するような場合、このフラグは適切に設定されません。しかし、そのようなアドオンの機能というのが今のところ思いつかないので簡単な修正に留めています。

Bug-org 1176959 [e10s][GTK] Kakutei-Undo of Mozc doesn't work 初回投稿日時: 2015年07月19日14時15分21秒
カテゴリ: e10s GTK IME Mozilla Core Mozilla42 バグ修正
固定リンク: id=2015071912
SNS: (list)

e10sモードでは、GTK版Mozcの確定アンドゥが機能していませんでした。

Bug-org 1176955の修正で追加した、選択範囲の変更通知をGTKでも確認するようにし、WidgetSelectionEventが原因だった場合に無視するようにしたら、確定アンドゥが機能しましたので、ひとまずこれをもって修正としています。

2015年7月25日

Bug-org 1184986 [e10s][TSF] ContentCache shouldn't notify IME of layout change until all sending events are handled 初回投稿日時: 2015年07月25日16時50分21秒
最終更新日時: 2015年07月26日14時31分26秒
カテゴリ: e10s GTK IME Mozilla Core Mozilla42 TSF Windows バグ修正
固定リンク: id=2015072500
SNS: (list)

Bug-org 1176954の修正で、IMEへの通知を一部、子プロセスへの送信中のイベントが残っている場合には延期するようにしましたが、NOTIFY_IME_OF_POSITION_CHANGEに関してもそれが必要というバグです。

TSFの動作を見ていると、NOTIFY_IME_OF_POSITION_CHANGEをきっかけに、ITextStoreACPSink::OnLayoutChange()が呼び出されると、即座にITextStore::GetTextExt()を呼び出し、文字位置を取得しようとします。しかし、この際にまだ全てのイベントが処理されていないため、期待したオフセットの文字がまだ存在していない可能性が高く、処理に失敗してしまっていました。

今回の修正で、NOTIFY_IME_OF_POSITION_CHANGEも全てのイベントの送信が完了するまで延期するようにすることで、IMEから見て、コンテンツの更新具合に矛盾がないようになりました。

Bug-org 1185316 [e10s][TSF][GTK?] TabChild should notify TabParent of receiving WidgetCompositionEvent or WidgetSelectionEvent after dispatching it 初回投稿日時: 2015年07月25日16時55分58秒
最終更新日時: 2015年07月26日14時32分22秒
カテゴリ: e10s GTK IME Mozilla Core Mozilla42 TSF Windows バグ修正
固定リンク: id=2015072501
SNS: (list)

Bug-org 1176954の修正では、子プロセスがイベントを受信したら、親プロセスにそれを通知することで親プロセスがIMEに各種通知を発行するタイミングを調整するようにしましたが、この状態で通知すると、それにIMEが反応してコンテンツを取得しに来た場合、一番最後に送信したイベントの結果がまだ、TabParent内のキャッシュに反映されていない可能性があることに気付きました。

今回の修正では、子プロセスがイベントをDOMツリーに投げた後、つまり、エディタがハンドリングした後に親プロセスに通知するように修正しています。これで高速入力時の見た目のレスポンスは若干下がる可能性はありますが、特にTSFモードでのおかしな動作を抑制することができました。

Bug-org 1184449 [IMM] nsIMM32Handler should cache selection notified by NOTIFY_IME_OF_SELECTION_CHANGE 初回投稿日時: 2015年07月25日17時00分06秒
カテゴリ: IME Mozilla Core Mozilla42 Windows バグ修正
固定リンク: id=2015072502
SNS: (list)

IMMモードをハンドリングしている、nsIMM32Handlerは必要なときに逐一、選択範囲を取得していましたが、非常に無駄な演算コストが発生しているので、NOTIFY_IME_OF_SELCTION_CHANGEで通知される新しい選択範囲をキャッシュしておいて、これを利用するように修正しました。

なお、この修正では、NOTIFY_IME_OF_SELECTION_CHANGEが選択されている文字列も通知するように機能追加してあるので、他のプラットフォームのパフォーマンス改善にもつながるかもしれません。

Bug-org 1186015 [IMM] nsIMM32Handler should be renamed to mozilla::widget::IMMHandler 初回投稿日時: 2015年07月25日17時03分57秒
カテゴリ: IME Mozilla Core Mozilla42 Windows バグ修正
固定リンク: id=2015072503
SNS: (list)

nsIMM32Handlermozilla::widget::IMMHandlerに改名し、ヘッダファイル内の名前空間の直接記述を削除してしまおうというバグです。

nsIMM32Handler.hnsIMM32Handler.cppはそれぞれ、IMMHandler.hIMMHandler.cppにリネームしています。

また、HIMCのラッパークラスであるnsIMEContextmozilla::widget::IMEContextにリネームしています。

Bug-org 1186014 [TSF] Rename nsTextStore to mozilla::widget::TSFTextStore 初回投稿日時: 2015年07月25日17時07分22秒
カテゴリ: IME Mozilla Core Mozilla42 TSF Windows バグ修正
固定リンク: id=2015072504
SNS: (list)

nsTextStoremozilla::widget::TSFTextStoreに改名し、ヘッダファイル内の名前空間の直接指定を削除してしまおうというバグです。

ファイル名もそれぞれ、TSFTextStore.hTSFTextStore.cppになり、各TSF関連クラスの名前は全てTSFをプリフィックスとして持つことで、よりその役割を分かりやすくしました。

Bug-org 1172239 High CPU usage when open amazon.co.jp in several tabs #2 初回投稿日時: 2015年07月25日20時13分34秒
カテゴリ: Firefox Mozilla42 バグ修正
固定リンク: id=2015072505
SNS: (list)

日本ではこのバグが原因で乗り替えようかなって言ってる人を見かけるんで、誰か検証できる人居ない? とrocにもちかけて見たところ、御大自ら修正してくれました。なんでも、日本以外のamazonでも発生することはするんだとか。

問題の原因は、Quirksモード用の本来不要なreflowがStandardsモードでも走ってしまうことが原因のようで、その辺を修正してくれたようです。パッチからすると。

2015年7月26日

Bug-org 1187367 [e10s][TSF] TSFTextStore shouldn't destroy native caret until notifying TSF of layout change 初回投稿日時: 2015年07月26日14時53分59秒
最終更新日時: 2015年07月26日15時03分11秒
カテゴリ: e10s IME Mozilla Core Mozilla42 TSF Windows バグ修正
固定リンク: id=2015072600
SNS: (list)

TSF-awareなアプリで動作しているATOKは、何故かネイティブキャレットの位置を参考にサジェストウインドウ位置を決めています。これに対応するため、ITextStoreACP::GetTextExt()が呼び出された時に、その位置にネイティブキャレットを作成し、ドキュメントのロックが解除された時にキャレットを破棄していました。

しかし、e10sモードではこの破棄タイミングが早すぎたために、ATOKのサジェストウインドウが時折、変な位置に一瞬だけ表示されるという現象が起きていました。そこで、レイアウトの変更が発生するまで、キャレットを破棄しないように修正しました。

Windowsのキャレットはプロセスだったか、スレッドだったか全体での共有財産なので、ハックのために長時間作成しておくのは危険なのですが、今のところは仕方ありません。ちなみにATOK以外がアクティブな場合、このハックは動作しません。

Bug-org 1187351 [e10s][TSF] TSFTextStore::GetTextExt() shouldn't return TS_E_NOLAYOUT after notifying TSF of layout change 初回投稿日時: 2015年07月26日15時02分30秒
カテゴリ: e10s IME Mozilla Core Mozilla42 TSF Windows バグ修正
固定リンク: id=2015072601
SNS: (list)

TSFTextStoreNOTIFY_IME_OF_POSITION_CHANGEを受け取った際に、ITextStoreACPSink::OnLayoutChange()を呼び出すことがありますが、この際に、キャッシュしているコンテンツのレイアウトが不確定な最初の文字のオフセットをリセットしていませんでした。そのため、TSFTIPからすると、レイアウトの計算が終わったと通知が来たのに、ITextStoreACP::GetTextExt()を呼び出してみたら、まだだって言われる、という状況に陥っていました。

今回の修正で、ITextStoreACPSink::OnLayoutChange()を呼び出す前に、mLockedContentmMinTextModifiedOffsetNOT_MODIFIEDにリセットすることでこの現象が発生しないようにしています。

Bug-org 1184533 [IMM] ASSERTION: offset is less than cursorPosition!: 'offset >= cursorPosition' 初回投稿日時: 2015年07月26日15時07分39秒
カテゴリ: IME Mozilla Core Mozilla42 Windows バグ修正
固定リンク: id=2015072602
SNS: (list)

IMMHandler::GetCharacterRectOfSelectedTextAt()に昔からあったバグのようです。このメソッドは、選択開始位置、もしくは未確定文字列がある時はその最初の文字からaOffset文字目の文字の矩形を取得するためのものですが、未確定文字列があり、未確定文字列内にキャレットが存在している場合の計算に失敗して、このassertionにヒットしていました。

結局、何が悪かったのかよく分からないので、コード自体をより分かりやすい形で書き直したら再現しなくなりました。下手に最低限のコードで同じ結果を得ようとしてはいけませんね。