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

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

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

2011年7月29日

Bug-org 665406 Support XF86Copy, XF86Paste, XF86Cut, XF86Undo, XF86Redo keysym 初回投稿日時: 2011年07月29日09時04分56秒
カテゴリ: Javascript Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072900
リンク元: 0件
SNS: (list)

私が修正した訳では無いんですが、レビューでパッチの設計を変更してもらって、Webアプリケーションに影響があるので紹介しておきます。

SolarisではCutキーをF20に、CopyキーをF16に、PasteキーをF18に、UndoキーをF14キーに割り当てて、XBL側でもこれらのキーを元の意味に読み替えて動作していました(写真さがしてみたところ、Sun Microsystem's Type 6 Keyboardというページを発見。二つ目の写真で確認できます)。

これを、GDK_CopyGDK_CutGDK_PasteGDK_Undoも利用できるようにし、さらにGDK_Redoも追加しようとしていました。

さすがにそのままやられてしまうと、非常に分かりにくくなってしまうので、以前、WindowsでWM_COPY等のサポートで作成した内部用のcontent commandイベントを利用するように修正してもらいました。

その結果、どうなったかと言うと、これらのキーを押した場合に、キーイベントは発生しなくなりました。これは何故かと言うと、これらのキーをWebアプリがハンドリングする際にキーコード等を見たりせず、直接、テキストの変化を見て欲しいからです(将来的にはDOM3 Eventsのtextinputイベントを見て下さい)。つまり、Windowsでもマルチメディアキーボードや、他のユーティリティソフトがWM_PASTE等を直接送信してきてもキーイベントは発生しませんので、それと同じ結果になるようにしました。また、もうひとつ言えば、この操作は編集メニューから操作したのと同じ結果になります。

逆にユーザの視点に立つと、Linuxでしか発生しないキーイベントで、本来は可能だったクリップボード関連の操作を、このことを知らずに作成されたWebアプリに邪魔されないようになっています。

そういう訳ですので、シビアなことをやっているWebアプリでは意図せずクリップボード関連の操作ができてしまうかもしれませんが、それは意図せずできないよりはユーザにとって良い、ということでこのような設計になりました。

Bug-org 610829 Japanese IME: The textbox may move to a different window prior to commit 初回投稿日時: 2011年07月29日09時28分39秒
カテゴリ: Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072902
リンク元: 0件
SNS: (list)

IMEの強制確定処理が、Firefoxのウインドウの切替で発生した場合にはうまく動かない、というバグです。

原因は、切替先のウインドウでアクティブなIMEのコンテキストが存在しない場合に、::ImmNotifyIME()による強制確定処理が空振りに終わっていたことです。

このAPIが呼ばれる直前に、一時的にそのウインドウのデフォルトのコンテキストを与えるようにすることで修正しました。

また、今まではコンテキストをウインドウから切り離す際に、切り離したコンテキストを保存しておいて、それを再び関連づける、という形で処理していましたが、Win98/Win2000以降で使える::ImmAssociateContextEx() APIが現在のGeckoのサポート状況だと利用できるので、こちらを使って常にデフォルトのコンテキストを割り当てるようになりました。このため、何らかのバグや、他のユーティリティの影響で保存していたコンテキストを万が一、失ってしまってもフォーカス移動だけで問題が解決するようになっています。このため、時々見かける、Firefoxを再起動するまでIMEが希に利用できなくなる、というバグを修正しているかもしれません。

Bug-org 658155 High resolution scrolling should be enabled even when scrolling speed is customized by prefs 初回投稿日時: 2011年07月29日09時34分41秒
カテゴリ: Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072905
リンク元: 0件
SNS: (list)

ユーザがスクロール速度や、スクロール方向、またはホイールとアクセラレーションキーの組み合わせによるアクションをカスタマイズしていた場合にも、高精度スクロールをWindowsでも使えるように修正するバグです。

本来はFirefox 7に入れる予定でしたが、Preferencesでころっと忘れていて、Firefox 8になってしまいました。

Bug-org 519972 Move NSTextInput implementation to nsCocoaTextInputHandler #2 初回投稿日時: 2011年07月29日09時43分45秒
カテゴリ: Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072907
リンク元: 0件
SNS: (list)

かなり長い間かかりましたが、ようやくnsChildView.mmからキーボード、IME関連のコードをTextInputHandler.mmに分離する作業が完了しました。これにより、MacOS X 10.5の時のように、キーボード周りのAPIがまるごと変更された場合にも今までよりは対応しやすくなります。

この修正ではバグを見つけてもバグを修正せずにそのまま移植していますので、何か挙動に変化があるとバグと言えますので、発見された方は報告をお願いします。

今後の予定では、まず、現在進めているキーコードの整理処理(Linux版のレビューさえ進めばFirefox 9か?)が終わったら、いよいよATOKの確定アンドゥの修正のための下準備に入ります。

Bug-org 524865 DebugPrintAllKeyboardLayouts is 80% of startup time 初回投稿日時: 2011年07月29日09時50分43秒
最終更新日時: 2011年07月29日09時51分25秒
カテゴリ: Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072908
リンク元: 0件
SNS: (list)

Mac版のデバッグビルドのスタートアップ時にデバッグ用のキーボードの一覧を作成、表示する処理でスタートアップの80%の時間を消費していた、というバグです。

Bug-org 519972の修正でCocoaのキーボードやIMEの処理内容も細かくログを吐くように修正し、この処理もログの一部に変更しましたので、ログを有効にしている場合以外では問題の処理が走らなくなりました。

後ほどmodestの方に書きますが、NSPR_LOG_MODULES=TextInputHandlerWidgets:1でログを取れます。

Bug-org 552707 While we're expanding selection by dragging, the selection root element should capture mouse events and all scrollable elements should be scrollable 初回投稿日時: 2011年07月29日10時34分53秒
最終更新日時: 2011年07月29日10時35分31秒
カテゴリ: Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072909
リンク元: 0件
SNS: (list)

マウスでテキストを選択中に、選択を開始した要素に一番近い、スクロール可能な要素がマウスをキャプチャしてしまい、それ以外のスクロール可能な要素をスクロールする手段もないし、キャプチャしてる要素の外側の選択状態も変更できるのはおかしい、というバグです。これの修正が今、闘っているregression祭りの元凶です。

まだ対応中のバグで挙動が変更されますので、詳しい説明は後日に回しますが、ざっくりと説明すると、まず、マウスの左ボタンが押された時、選択範囲のルートとなる要素がマウスイベントをキャプチャします。そして、これより外側の要素の内容は選択できません。つまり、意図的に特定要素内に選択範囲を制限できます

<body>
  <div id="div1">
    <p>aaaaaaaaaaaaa</p>
    <p>bbbbbbbbbbbbb</p>
  </div>
  <div id="div2">
    <p>ccccccccccccc</p>
  </div>
</body>

このケースで、マウスのボタンを#div1内で押した場合、#div1内のみが選択できた方が便利だとします。その場合、以下のように記述します。

<script type="text/javascript">
var div1 = document.getElementById("div1");

function div1MouseDownHandler(event)
{
  if (event.button == 0) {
    div1.setCapture(false); // not event.target!
  }
}

div1.addEventListener("mousedown", div1MouseDownHandler, false);
</script>

ただし、文字列のマウスでの選択は特に標準化されている訳ではありませんので、他のブラウザでこの手法で選択範囲を制限できなくてもそれはバグであるという話ではありません。これはあくまでFirefoxでの挙動を利用した手法であることに注意してください。

話を戻すと、これにより、マウスカーソルを選択範囲のルート要素の外側にまで移動すると、その要素は今まで通りにスクロールすることが可能ですが、問題はその内側にある他のスクロール可能な要素です。

これらは、そのスクロール可能な要素の辺(bugzilla上でedgeと呼んでいる部分)にカーソルを移動した時に自動的にスクロールするようにしました。このため、選択中にあらゆるスクロール可能な要素は(ただし、その時に選択可能な要素であること。例えば、textareaやiframeの様に、外側から選択できない要素は除き)、全てスクロールできるようになりました。

Bug-org 670058 crash nsFrame::ExpandSelectionByMouseMove (click on <textarea> for adding comment in facebook) 初回投稿日時: 2011年07月29日11時09分42秒
最終更新日時: 2011年07月29日11時10分21秒
カテゴリ: Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072910
リンク元: 0件
SNS: (list)

Facebookのコメント欄でクリックすると(正確にはクリック中にマウスを動かして、mousedownmousemoveとイベントが発生した時に)クラッシュしていたバグです。

Facebookはコメント欄にフォーカスが来たら、要素の移動やらなんやらが多々発生し、Gecko内部ではそのエディタ自体の作り直しが発生していました。この際にnsFrameSelectionPresShellをデタッチしているのですが、その時同時に選択自体を中止していなかったため、選択範囲の拡張処理が想定していない状況に陥ってクラッシュしていました。

Bug-org 671319 Crash [@ nsFrame::ExpandSelectionByMouseMove] part 2 初回投稿日時: 2011年07月29日11時19分29秒
カテゴリ: Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072911
リンク元: 0件
SNS: (list)

Bug-org 670058で修正したはずのクラッシュがまだ発生しているよ、ということで、とりあえず再現する最小限のテストケース(人間の脳みそでは発生タイミングのシミュレーション不能)からGecko側の処理を見つめ直していきました。

その結果、マウスのキャプチャが解除される時には、選択を中断すべきであるという結論に至りました。例えば、document.releaseCapture();で強制的にリリースさせられると、もうどうしようもありません。

最終的に、このバグ修正で添付した、まだ多少現実的なテストケースは、マウスを二つ利用した場合にのみ発生するものとなっています(例えばノートPC付属のタッチパッドと外付けのマウスとか)。

Bug-org 673315 clipboard.autocopy does not work properly, selected text is no longer available in clipboard (or rather in PRIMARY) 初回投稿日時: 2011年07月29日11時36分00秒
カテゴリ: Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072912
リンク元: 0件
SNS: (list)

Linuxではデフォルト設定で中クリックで貼り付けができますが、この際に使われるのは通常のクリップボードではなく、Primary selectionと呼ばれるものだそうです。知りませんでした。で、このPrimary selectionは文字を選択してマウスのボタンを離した時に自動的に記録されるのですが、Bug-org 671319の修正で、nsFrame側の修正を怠ったのが原因でした。

nsFrameでは通常のmouseup時に先にマウスキャプチャをリリースしていました。このため、正常終了にも関わらず、nsFrameSelection側で異常終了したと判断されてしまい、nsISelectionListenerの変更通知理由がNO_REASONになってしまい、Primary selectionのauto copy処理が処理をしなくなってしまっていました。

まだ修正は完了していませんが、ひとまず正常終了時のreasonは正しくなるように、処理順序を正しく入れ替えました。srを依頼しているrocが来週戻ってくれば異常終了時にもauto copyが行われるようになります。

Bug-org 670508 Crash [@ nsFrame::HandlePress] when ctrl-clicking on td contenteditable 初回投稿日時: 2011年07月29日11時39分18秒
カテゴリ: Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072913
リンク元: 0件
SNS: (list)

contenteditable="true"がスクロール不可能な要素に設定されていて、これをCtrl+クリックするとクラッシュするというバグです。

単に、nsIScrollableFrameのポインタのNULLチェック不足でした。

Bug-org 644621 Drag selection scrolling does not work properly in fullscreen and maximized mode 初回投稿日時: 2011年07月29日11時43分03秒
カテゴリ: Mozilla Core Mozilla8 バグ修正
固定リンク: id=2011072914
リンク元: 0件
SNS: (list)

フルスクリーンモード等、選択時のルート要素がデスクトップの端まで広がりきっていると選択中にドラッグではスクロールできない、というバグです。Firefox Inputでも以前からちょこちょこと報告されていた問題ですね。

Bug-org 552707の修正ではそれまでの動作とできるだけ似せて混乱を与えないように、ルート要素ではその辺にマウスカーソルがあってもスクロールしないようにしていましたが、このバグの修正でその制限を取り払いました。