Update keybindings when XKB keyboard layout changes

* Select for XKB keyboard notification events explicitly; since GTK+
  has selected for XKB events, delivery of old-school MappingNotify
  events is disabled.

* Fix a bug where once a keycode was loaded for a key binding,
  it would never be reassigned; we want to laod new keycodes for
  all bindings that have a key symbol rather than a fixed
  keycode.

[ With fixes from Owen W. Taylor <otaylor@fishsoup.net> ]

https://bugzilla.gnome.org/show_bug.cgi?id=565540
This commit is contained in:
Derek Poon 2010-05-02 11:27:25 -04:00 committed by Owen W. Taylor
parent 54e82daae2
commit cb88e0d052
2 changed files with 31 additions and 1 deletions

View File

@ -2642,6 +2642,10 @@ event_callback (XEvent *event,
meta_bell_notify (display, xkb_ev);
}
break;
case XkbNewKeyboardNotify:
case XkbMapNotify:
meta_display_process_mapping_event (display, event);
break;
}
}
#endif

View File

@ -248,9 +248,11 @@ reload_keycodes (MetaDisplay *display)
i = 0;
while (i < display->n_key_bindings)
{
if (display->key_bindings[i].keycode == 0)
if (display->key_bindings[i].keysym != 0)
{
display->key_bindings[i].keycode = XKeysymToKeycode (
display->xdisplay, display->key_bindings[i].keysym);
}
++i;
}
@ -530,6 +532,22 @@ void
meta_display_process_mapping_event (MetaDisplay *display,
XEvent *event)
{
#ifdef HAVE_XKB
if (event->type == display->xkb_base_event_type)
{
meta_topic (META_DEBUG_KEYBINDINGS,
"XKB mapping changed, will redo keybindings\n");
reload_keymap (display);
reload_modmap (display);
reload_keycodes (display);
reload_modifiers (display);
regrab_key_bindings (display);
}
else
#endif
if (event->xmapping.request == MappingModifier)
{
meta_topic (META_DEBUG_KEYBINDINGS,
@ -617,6 +635,14 @@ meta_display_init_keys (MetaDisplay *display)
/* Keys are actually grabbed in meta_screen_grab_keys() */
meta_prefs_add_listener (bindings_changed_callback, display);
#ifdef HAVE_XKB
/* meta_display_init_keys() should have already called XkbQueryExtension() */
if (display->xkb_base_event_type != -1)
XkbSelectEvents (display->xdisplay, XkbUseCoreKbd,
XkbNewKeyboardNotifyMask | XkbMapNotifyMask,
XkbNewKeyboardNotifyMask | XkbMapNotifyMask);
#endif
}
void