Bug-org 751749 cannot configure keyboard shortcuts to use Meta modifier instead of Alt
初回投稿日時: 2012年07月26日09時37分18秒
最終更新日時: 2012年07月26日09時56分11秒
カテゴリ: GTK Mozilla Core Mozilla17 バグ修正
SNS:
Tweet (list)
Bug-org 630813によるregressionです。
Bug-org 630813では、Linuxでは現在、Meta一般的ではないので、DOM KeyboardEventからは、Metaキーのイベントを参照できるべきではないとの判断で、押されたキーが、モディファイアキー無しで押された場合に、そのキーがGDK_Meta_(L|R)
を生成する場合であっても、DOM_VK_META
を生成しないようにし、さらに、KeyboardEvent.metaKey
がtrue
を返さないように修正を行いました。
しかし、実際にBug-org 630813が入ったビルド(Fx13)がリリースされると、一部、特殊なキーボードを利用しているユーザを中心にバグ報告がありました。その内容は、Sunや、MacのキーボードをLinuxで利用した場合、従来まではDOMイベントで、Metaキーとして扱われていたもの(つまり、そのキーと一緒に押したキーのイベントで、metaKey
がtrue
となるモディファイアキー)が、モディファイアキーとして機能しなくなったというもので、この現象自体がこのバグの修正対象です。
Bug-org 630813の修正内容を理解しなければ、このバグの理由、修正方法が理解できないので、再度説明しておきます。
Bug-org 630813で問題としたのは、ネイティブのモディファイアフラグと、DOMのモディファイアとの関係が、そのモディファイアフラグをアクティブにするキーとの関係と一致していない事でした。
Linuxのツールキット、GDKでは、モディファイアフラグが以下のように定義されています。
typedef enum { GDK_SHIFT_MASK = 1 << 0, GDK_LOCK_MASK = 1 << 1, GDK_CONTROL_MASK = 1 << 2, GDK_MOD1_MASK = 1 << 3, GDK_MOD2_MASK = 1 << 4, GDK_MOD3_MASK = 1 << 5, GDK_MOD4_MASK = 1 << 6, GDK_MOD5_MASK = 1 << 7, GDK_BUTTON1_MASK = 1 << 8, GDK_BUTTON2_MASK = 1 << 9, GDK_BUTTON3_MASK = 1 << 10, GDK_BUTTON4_MASK = 1 << 11, GDK_BUTTON5_MASK = 1 << 12, /* The next few modifiers are used by XKB, so we skip to the end. * Bits 15 - 25 are currently unused. Bit 29 is used internally. */ GDK_SUPER_MASK = 1 << 26, GDK_HYPER_MASK = 1 << 27, GDK_META_MASK = 1 << 28, GDK_RELEASE_MASK = 1 << 30, GDK_MODIFIER_MASK = 0x5c001fff } GdkModifierType;
最新のGDKでは、Super、Hyper、Metaについても定義があるのですが、新しいものですので、現在のGeckoでは無視しています。
それを踏まえてこのenumを見てみると、Shift、CapsLock、Ctrlキー以外のモディファイアに対するモディファイアフラグは、1から5が用意されているだけです。現に、GDK_Alt_(L|R)
、GDK_Meta_(L|R)
、GDK_Super_(L|R)
、GDK_Hyper_(L|R)
、GDK_Num_Lock
、GDK_Scroll_Lock
を生成するキーと、モディファイアフラグとの関係性は一定ではありません。極端な話、UbuntuやFedoraに付属しているキーボードレイアウトの設定から、設定をいじるだけで関係がずれてしまいます。
そこで、Geckoは、DOM Level3 EventsのKeyboardEvent
に対応するため、XのAPIを利用して、各フラグをアクティブにする物理キーが生成するGDKのkeyval
値(上の例だと、GDK_Alt_L
等)から各フラグがアクティブにする、DOMのモディファイアとの関係を初期化時に決定することにしました。
そのロジックは、基本的には、モディファイアフラグをアクティブにするキーが生成する可能性のある全てのkeyval
値に対応する、DOMのモディファイアを同時にアクティブにするというもので、さらに、GDK_Meta_(L|R)
は、DOMのMetaはアクティブにしないという(今、考えてみると)バグも混入されました。
ちなみに、それ以前は、MOD1
が、Alt、MOD5
が、Metaキーであるという慣例に従って、決め打ちを行っていました。
この事実と、前述の修正内容の結果、MOD5
をアクティブにするキーが単独で押された場合に生成されるkeyval
がGDK_Meta_(L|R)
、GDK_Super_(L|R)
、GDK_Hyper_(L|R)
だった場合に、そのキーがショートカットキーや、アクセスキーのためのモディファイアキーとして機能しなくなってしまっていました(Super、HyperはWinキーとして読み替えられ、os
モディファイアだと扱われますが、os
モディファイア自体が、ショートカットキーや、アクセスキーのモディファイアとして利用ができないため、Metaキー以外の場合にも影響が出ました)。
この問題を修正するために、このバグでは以下のアプローチをとりました。
- DOMのMetaキーを復活
- XULの
<key>
要素は簡単に指定すると、全てのモディファイアの状態がマッチしていないと動作しないので、ひとつのモディファイアフラグが、ひとつのDOMモディファイアしかアクティブにしないように修正 MOD5
をアクティブにしていたキーが、Super、もしくはHyperの場合にも、ショートカットキーや、アクセスキーのモディファイアキーとして利用できるようにXULの<key>
要素のmodifiers
属性で、os
を指定できるように修正
このような修正ですので、このバグで困っていた人は、ui.key.accelKey
の設定を変えなくては依然として、期待通りに利用できない可能性があります。
ui.key.accelKey
の値は新たに、DOM_VK_WIN
を意味する、91
が指定可能になりました。
ui.key.chromeAccess
と、ui.key.contentAccess
は、16
をOR演算で含めることができるようになりました。