MSDNでTSFのITextStoreACP
のメソッドのリファレンスを読んでいると、GetSelection()
等のコンテンツ情報取得系のメソッドは、Readロックではなく、Read-Only
ロックをかけた上でアクセスするように書かれていることに気付きました。
呼び出し側からこの違いは非常に小さいことのように思えますが、実装側からすると、Read-Writeロック中に、変更されたコンテンツに、こういったメソッドで情報にアクセスできなくなる、ということになりますので、実装を非常に単純化できます。
このため、試しにRead-Onlyロックでなければアクセス出来ないように修正してみたところ、ATOK 2013も、Windows8のMS-IMEでも、Read-Writeロックで平然とアクセスしてきて、正常に動作しなくなりました。このため、この修正は断念しています。
とりあえず、両社には連絡すべきかなと考えていますが、現実的に考えればMSDNが修正されるべきかなという感じもします。
GTK3では、ISO_Level3_Shiftに加え、ISO_Level5_Shiftという、もうひとつのAltGrキーが追加定義されました。
Geckoでもこれに対応し、どちらのキーが押された場合にも、DOM_VK_ALTGR
(0xE1)のキーコードでキーイベントが発生し、また、押されている間のイベントでは、getModifierState("AltGraph")
がtrue
を返すように修正しました。
Webアプリからこれらのキーの違いを見分けることはできませんが、Linuxでしか見分ける意味の無いものですので、クロスプラットフォームなWebアプリの性質からすれば、この修正で十分でしょう。
フランス語キーボード等では、Caps_Lockではなく、Shift_Lockが一般的だそうです。これをロックすると、アルファベットだけではなく、数字キー等でもShiftキーがロックされた状態となります。
Linuxでは、Shift_Lockをロックしている間の入力イベントは、Shiftキーが押されたのと同様の挙動を示します。このため、Shift_Lockキーそのもののイベントは、Shiftキーのイベントとして発生するように修正しました。これにより、Shiftキーイベントが無いままに、getModifierState("Shift")
がtrue
を返すようになるという状況は、ひとつ減りました(もっとも、そのようなイベントの前後関係を期待したコードは書くべきではありませんが)。
nsEvent::flags
は、uint32_t
として定義され、ビットマスクでその意味が定義されていました。しかし、その種類は多く、また大半はその意味がどこにも書かれておらず、さらに酷いことに、一部のフラグは他でも使い回されているという有様でした。そこで、これを整理しようというのがこのバグです。
当初考えていたのは、各フラグの意味をコメントで明確にし、ビット演算することなく、ヘルパーメソッドを大量にnsEvent
に定義して、イージーミスを回避することだけをひとつめの目標としていました。しかし、えむけいさんの提案で、C++のビットフィールドを用いた本格的なリファクタリングになってしまいました。
まず、mozilla::widget::EventFlags
という構造体を定義し、この中に1ビットのboolメンバを持たせ、各メンバにコメントでその意味を明確に説明するように修正しました。
フラグの参照側はbool変数をテストするだけですので、ビット演算によるイージーミスは無くなります(現に、修正中にイージーミスをひとつ発見しました)。
次に、nsEventDispatcher
が、nsEventListenerManager
に登録されているイベントリスナを呼び出すコード部分では、イベントの処理状況を示すフラグとして、NS_EVENT_FLAG_BUBBLE
、NS_EVENT_FLAG_CAPTURE
、NS_EVENT_FLAG_SYSTEM_EVENT
をメソッドのパラメータにセットし、フェイズやイベントグループをnsEventListenerManager
側で判断できるようにしていました。しかし、これらの状態をそもそもnsEvent::mFlags
に持っていますので、nsEventListenerManager
がこれを参照するようにすることで、nsEventDispatcher
まわりの単純化に成功しています。
さらに、nsEventListenerManager
にイベントリスナを登録する際にリスナの情報を指定する際に、そしてnsEventListenerManager
がこれを保存するのに、NS_EVENT_FLAG_BUBBLE
、NS_EVENT_FLAG_CAPTURE
、NS_EVENT_FLAG_SYSTEM_EVENT
、NS_PRIV_EVENT_UNTRUSTED_PERMITTED
、NS_PRIV_EVENT_FLAG_SCRIPT
が利用されていましたが、mozilla::dom::EventListenerFlags
という、ビットフィールドを利用した構造体を利用することで、nsGUIEvent.h
からも、nsEvent
からも独立した情報として処理するように修正しました。
ただ、GCCではビットマスクによる実装よりも、ビットフィールドによる実装の方が若干遅い様で、極端なベンチマークを行うと、パッチ適用後はパフォーマンスが落ちていました。VCでは逆に若干の高速化が見られたのですが。ただ、どちらにしろ、Tpテストでは検出できない程度の話ですので、そのまま投入されています。