diff --git a/ChangeLog b/ChangeLog index 5004a8550..1d2f19157 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2006-08-21 Elijah Newren + + Patch from Ed Catmur to fix keybindings with hex-values (coming + from special extended keyboard keys). #140448. + + * src/keybindings.c (struct _MetaKeyBinding): change keycode from + KeyCode to unsigned int (comment from Elijah: why???), + (reload_keycodes): only grab keysyms for keybindings that have + them, (count_bindings, rebuild_binding_table): bindings can be + valid either due to a valid keysym or a valid keycode, + (display_get_keybinding_action, meta_change_keygrab, + process_tab_grab, process_workspace_switch_grab): handle keycode + as well as keysym + + * src/prefs.[ch] (struct MetaKeyCombo, update_binding, + update_list_binding): handle keycode as well as keysym + + * src/ui.[ch] (meta_ui_accelerator_parse): new function special + cases strings of the form "0x[0-9a-fA-F]+" and otherwise calling + gtk_accelerator_parse(), (meta_ui_parse_accelerator, + meta_ui_parse_modifier): call meta_ui_accelerator_parse instead of + gtk_accelerator_parse. + 2006-08-21 Elijah Newren Allow drags & resizes to be reverted by hitting escape. Based on diff --git a/src/keybindings.c b/src/keybindings.c index 7a36cd4e9..d749c420e 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -238,8 +238,8 @@ struct _MetaKeyBinding { const char *name; KeySym keysym; + KeyCode keycode; unsigned int mask; - unsigned int keycode; MetaVirtualModifier modifiers; const MetaKeyHandler *handler; }; @@ -563,8 +563,9 @@ reload_keycodes (MetaDisplay *display) i = 0; while (i < display->n_screen_bindings) { - display->screen_bindings[i].keycode = XKeysymToKeycode (display->xdisplay, - display->screen_bindings[i].keysym); + if (display->screen_bindings[i].keycode == 0) + display->screen_bindings[i].keycode = XKeysymToKeycode ( + display->xdisplay, display->screen_bindings[i].keysym); ++i; } @@ -577,8 +578,9 @@ reload_keycodes (MetaDisplay *display) i = 0; while (i < display->n_window_bindings) { - display->window_bindings[i].keycode = XKeysymToKeycode (display->xdisplay, - display->window_bindings[i].keysym); + if (display->window_bindings[i].keycode == 0) + display->window_bindings[i].keycode = XKeysymToKeycode ( + display->xdisplay, display->window_bindings[i].keysym); ++i; } @@ -651,7 +653,7 @@ count_bindings (const MetaKeyPref *prefs, { MetaKeyCombo *combo = tmp->data; - if (combo && combo->keysym != None) + if (combo && (combo->keysym != None || combo->keycode != 0)) { count += 1; @@ -693,13 +695,13 @@ rebuild_binding_table (MetaDisplay *display, { MetaKeyCombo *combo = tmp->data; - if (combo && combo->keysym != None) + if (combo && (combo->keysym != None || combo->keycode != 0)) { (*bindings_p)[dest].name = prefs[src].name; (*bindings_p)[dest].keysym = combo->keysym; + (*bindings_p)[dest].keycode = combo->keycode; (*bindings_p)[dest].modifiers = combo->modifiers; (*bindings_p)[dest].mask = 0; - (*bindings_p)[dest].keycode = 0; ++dest; @@ -712,10 +714,10 @@ rebuild_binding_table (MetaDisplay *display, (*bindings_p)[dest].name = prefs[src].name; (*bindings_p)[dest].keysym = combo->keysym; + (*bindings_p)[dest].keycode = combo->keycode; (*bindings_p)[dest].modifiers = combo->modifiers | META_VIRTUAL_SHIFT_MASK; (*bindings_p)[dest].mask = 0; - (*bindings_p)[dest].keycode = 0; ++dest; } @@ -816,6 +818,7 @@ regrab_window_bindings (MetaDisplay *display) static MetaKeyBindingAction display_get_keybinding_action (MetaDisplay *display, unsigned int keysym, + unsigned int keycode, unsigned long mask) { int i; @@ -824,6 +827,7 @@ display_get_keybinding_action (MetaDisplay *display, while (i >= 0) { if (display->screen_bindings[i].keysym == keysym && + display->screen_bindings[i].keycode == keycode && display->screen_bindings[i].mask == mask) { return meta_prefs_get_keybinding_action (display->screen_bindings[i].name); @@ -982,9 +986,9 @@ meta_change_keygrab (MetaDisplay *display, */ meta_topic (META_DEBUG_KEYBINDINGS, - "%s keybinding %s mask 0x%x on 0x%lx\n", + "%s keybinding %s keycode %d mask 0x%x on 0x%lx\n", grab ? "Grabbing" : "Ungrabbing", - keysym_name (keysym), + keysym_name (keysym), keycode, modmask, xwindow); /* efficiency, avoid so many XSync() */ @@ -2421,6 +2425,7 @@ process_tab_grab (MetaDisplay *display, prev_window = meta_display_lookup_x_window (display, prev_xwindow); action = display_get_keybinding_action (display, keysym, + event->xkey.keycode, display->grab_mask); /* Cancel when alt-Escape is pressed during using alt-Tab, and vice @@ -2881,6 +2886,7 @@ process_workspace_switch_grab (MetaDisplay *display, action = display_get_keybinding_action (display, keysym, + event->xkey.keycode, display->grab_mask); switch (action) diff --git a/src/prefs.c b/src/prefs.c index d2be470db..86fc9a6c6 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -2151,6 +2151,7 @@ update_binding (MetaKeyPref *binding, const char *value) { unsigned int keysym; + unsigned int keycode; MetaVirtualModifier mods; MetaKeyCombo *combo; gboolean changed; @@ -2160,10 +2161,11 @@ update_binding (MetaKeyPref *binding, binding->name, value ? value : "none"); keysym = 0; + keycode = 0; mods = 0; if (value) { - if (!meta_ui_parse_accelerator (value, &keysym, &mods)) + if (!meta_ui_parse_accelerator (value, &keysym, &keycode, &mods)) { meta_topic (META_DEBUG_KEYBINDINGS, "Failed to parse new gconf value\n"); @@ -2246,16 +2248,19 @@ update_binding (MetaKeyPref *binding, changed = FALSE; if (keysym != combo->keysym || + keycode != combo->keycode || mods != combo->modifiers) { changed = TRUE; combo->keysym = keysym; + combo->keycode = keycode; combo->modifiers = mods; meta_topic (META_DEBUG_KEYBINDINGS, - "New keybinding for \"%s\" is keysym = 0x%x mods = 0x%x\n", - binding->name, combo->keysym, combo->modifiers); + "New keybinding for \"%s\" is keysym = 0x%x keycode = 0x%x mods = 0x%x\n", + binding->name, combo->keysym, combo->keycode, + combo->modifiers); } else { @@ -2272,6 +2277,7 @@ update_list_binding (MetaKeyPref *binding, MetaStringListType type_of_value) { unsigned int keysym; + unsigned int keycode; MetaVirtualModifier mods; gboolean changed = FALSE; const gchar *pref_string; @@ -2308,6 +2314,7 @@ update_list_binding (MetaKeyPref *binding, while (pref_iterator) { keysym = 0; + keycode = 0; mods = 0; if (!pref_iterator->data) @@ -2328,7 +2335,7 @@ update_list_binding (MetaKeyPref *binding, g_assert_not_reached (); } - if (!meta_ui_parse_accelerator (pref_string, &keysym, &mods)) + if (!meta_ui_parse_accelerator (pref_string, &keysym, &keycode, &mods)) { meta_topic (META_DEBUG_KEYBINDINGS, "Failed to parse new gconf value\n"); @@ -2363,12 +2370,13 @@ update_list_binding (MetaKeyPref *binding, combo = g_malloc0 (sizeof (MetaKeyCombo)); combo->keysym = keysym; + combo->keycode = keycode; combo->modifiers = mods; binding->bindings->next = g_slist_prepend (binding->bindings->next, combo); meta_topic (META_DEBUG_KEYBINDINGS, - "New keybinding for \"%s\" is keysym = 0x%x mods = 0x%x\n", - binding->name, keysym, mods); + "New keybinding for \"%s\" is keysym = 0x%x keycode = 0x%x mods = 0x%x\n", + binding->name, keysym, keycode, mods); pref_iterator = pref_iterator->next; } diff --git a/src/prefs.h b/src/prefs.h index 7f53a7828..a568ed780 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -257,6 +257,7 @@ typedef enum _MetaKeyBindingAction typedef struct { unsigned int keysym; + unsigned int keycode; MetaVirtualModifier modifiers; } MetaKeyCombo; diff --git a/src/ui.c b/src/ui.c index d204cc10f..9134946d6 100644 --- a/src/ui.c +++ b/src/ui.c @@ -34,8 +34,13 @@ #include #include +#include static void meta_stock_icons_init (void); +static void meta_ui_accelerator_parse (const char *accel, + guint *keysym, + guint *keycode, + GdkModifierType *keymask); struct _MetaUI { @@ -737,31 +742,51 @@ meta_ui_have_a_theme (void) return meta_theme_get_current () != NULL; } +static void +meta_ui_accelerator_parse (const char *accel, + guint *keysym, + guint *keycode, + GdkModifierType *keymask) +{ + if (accel[0] == '0' && accel[1] == 'x') + { + *keysym = 0; + *keycode = (guint) strtoul (accel, NULL, 16); + *keymask = 0; + } + else + gtk_accelerator_parse (accel, keysym, keymask); +} + gboolean meta_ui_parse_accelerator (const char *accel, unsigned int *keysym, + unsigned int *keycode, MetaVirtualModifier *mask) { GdkModifierType gdk_mask = 0; guint gdk_sym = 0; + guint gdk_code = 0; *keysym = 0; + *keycode = 0; *mask = 0; if (strcmp (accel, "disabled") == 0) return TRUE; - gtk_accelerator_parse (accel, &gdk_sym, &gdk_mask); - if (gdk_mask == 0 && gdk_sym == 0) + meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); + if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) return FALSE; - if (gdk_sym == None) + if (gdk_sym == None && gdk_code == 0) return FALSE; if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */ return FALSE; *keysym = gdk_sym; + *keycode = gdk_code; if (gdk_mask & GDK_SHIFT_MASK) *mask |= META_VIRTUAL_SHIFT_MASK; @@ -830,17 +855,18 @@ meta_ui_parse_modifier (const char *accel, { GdkModifierType gdk_mask = 0; guint gdk_sym = 0; + guint gdk_code = 0; *mask = 0; if (strcmp (accel, "disabled") == 0) return TRUE; - gtk_accelerator_parse (accel, &gdk_sym, &gdk_mask); - if (gdk_mask == 0 && gdk_sym == 0) + meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); + if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) return FALSE; - if (gdk_sym != None) + if (gdk_sym != None || gdk_code != 0) return FALSE; if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */ diff --git a/src/ui.h b/src/ui.h index ae0bceb67..52b4bdb9c 100644 --- a/src/ui.h +++ b/src/ui.h @@ -179,6 +179,7 @@ gboolean meta_ui_have_a_theme (void); gboolean meta_ui_parse_accelerator (const char *accel, unsigned int *keysym, + unsigned int *keycode, MetaVirtualModifier *mask); gboolean meta_ui_parse_modifier (const char *accel, MetaVirtualModifier *mask);