Comment 3 for bug 543285

Revision history for this message
midspeclowload (midspeclowload) wrote :

gnome-keybinding-propertiesで表示されているショートカットは
gconfのエントリによって処理しているプロセスが2つに分かれます。
●gnome-settings-daemonで処理されるもの
下記の2つのエントリに記述されているショートカット
・/apps/gnome_settings_daemon/keybindings
・/desktop/gnome/keybindings/

●metacityで処理されるもの
・/apps/metacity/global_keybindings(ショートカットキー)
  (/apps/metacity/keybinding_commandsはそのコマンド)
・/apps/metacity/window_keybindings(ショートカットキー)
  (実行される内容はソースコードに定義)

デフォルトの[ウィンドウのスクリーンショットを撮る]に割当てられている<Alt>Printは動作します
<Alt>Excuteになっても動きます。これはmetacityで処理されているためです。

カスタムショートカットは"/desktop/gnome/keybindings/"の下に作成されるので
gnome-settings-daemonが処理します。

修正すべき箇所は2箇所ありました。

a) Gconfのエントリを解析する部分
b) キー入力イベントのコールバックでキーの照合をする部分

上記のほかに、きちんと直すのであればMappingNotifyイベントが発生した場合に
内部データに持っているキーコードをGconfのエントリから作り直す必要があります。
(本当にパッチを書くのであれば必須であること思っています。)

まず、a)の方ですが
plugins/common/eggaccelerators.c の egg_accelerator_parse_virtual関数で
Gconfのエントリから取得した"<Alt>Execute"の"Execute"の部分を
gdk_keyval_from_nameに渡し、その戻りをgdk_keymap_get_entries_for_keyvalに渡してkeycodeを得ています。
このときgdk_keymap_get_entries_for_keyvalが返すGdkKeymapのうちメンバlevelの値が0のものだけを使用しています。
"Excute"の場合は帰ってくるGdkKeymapKeyが1つだけで、そのlevelが1であるためegg_accelerator_parse_virtualが
エラーを返します。その結果
「** (gnome-settings-daemon:2375): WARNING **: キー・バインディング (custom0) が無効です」
が出力されます。
metacityでは処理の仕方が違うのですが、"<Alt>Excute"をはじくことはありません。
GdkKeymap.levelの意味するところを理解していないのですが、当該のチェックをはずすしました

次に、b)の方
plugins/common/gsd-keygrab.c の match_key関数を修正しました。
ここではXEvent.xkeyをgdk_keymap_translate_keyboard_state関数でkeysymに変更してから
内部データと比較しています。
ただし、gdk_keymap_translate_keyboard_state関数が失敗するとkeycodeによる比較を行います

下記にあるように"Print"と"Excute"はkeycodeが同一ですが、keysymは異なります。
metacityがkeycodeとstateによる比較を行っているので同じようkeycodeとstateを使用するようにしました。
(ただし本当はキーマップが変更された場合に備えてMappingNotifyで内部データを作り直さなければならない)

・Keycodeとkeysiy(xevの出力)
2つともKeycodeは同じで 十進表記で 107 すが、
Keysymは16進でPrint:ff61 , Exucute:ff62

[Print]を押した場合
state 0x10, keycode 107 (keysym 0xff61, Print), same_screen YES,

[Alt+Print]を押した場合
state 0x18, keycode 107 (keysym 0xff62, Execute), same_screen YES,