if (hardware_keycode < 0 || hardware_keycode >= NUM_KEYCODES)
return FALSE;
-
- /* Check if shift or capslock modify the keyval */
- for (bit = GDK_SHIFT_MASK; bit < GDK_CONTROL_MASK; bit <<= 1)
+
+ /* Check if modifiers modify the keyval */
+ for (bit = GDK_SHIFT_MASK; bit < GDK_BUTTON1_MASK; bit <<= 1)
{
- if (translate_keysym (hardware_keycode, group, state & ~bit, NULL, NULL) !=
- translate_keysym (hardware_keycode, group, state | bit, NULL, NULL))
+ if (translate_keysym (hardware_keycode,
+ (bit == GDK_MOD1_MASK) ? 0 : group,
+ state & ~bit,
+ NULL, NULL) !=
+ translate_keysym (hardware_keycode,
+ (bit == GDK_MOD1_MASK) ? 1 : group,
+ state | bit,
+ NULL, NULL))
tmp_modifiers |= bit;
}
GtkCellRendererAccelPrivate *priv = accel->priv;
GdkModifierType accel_mods = 0;
guint accel_key;
+ guint keyval;
gchar *path;
gboolean edited;
gboolean cleared;
edited = FALSE;
cleared = FALSE;
- gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (display),
+ accel_mods = event->state;
+
+ _gtk_translate_keyboard_accel_state (gdk_keymap_get_for_display (display),
event->hardware_keycode,
event->state,
+ gtk_accelerator_get_default_mod_mask (),
event->group,
- NULL, NULL, NULL, &consumed_modifiers);
+ &keyval, NULL, NULL, &consumed_modifiers);
- accel_mods = event->state;
gdk_keymap_add_virtual_modifiers (gdk_keymap_get_for_display (display), &accel_mods);
- accel_key = gdk_keyval_to_lower (event->keyval);
+ accel_key = gdk_keyval_to_lower (keyval);
if (accel_key == GDK_KEY_ISO_Left_Tab)
accel_key = GDK_KEY_Tab;
/* Put shift back if it changed the case of the key, not otherwise.
*/
- if (accel_key != event->keyval)
+ if (accel_key != keyval)
accel_mods |= GDK_SHIFT_MASK;
if (accel_mods == 0)
{
- switch (event->keyval)
- {
- case GDK_KEY_Escape:
- goto out; /* cancel */
- case GDK_KEY_BackSpace:
- /* clear the accelerator on Backspace */
- cleared = TRUE;
- goto out;
- default:
- break;
- }
+ switch (keyval)
+ {
+ case GDK_KEY_Escape:
+ goto out; /* cancel */
+ case GDK_KEY_BackSpace:
+ /* clear the accelerator on Backspace */
+ cleared = TRUE;
+ goto out;
+ default:
+ break;
+ }
}
if (priv->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK)
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+
#include "config.h"
+
#include "gtkdebug.h"
#include "gtkkeyhash.h"
+#include "gtkprivate.h"
typedef struct _GtkKeyHashEntry GtkKeyHashEntry;
gint level;
GdkModifierType modifiers;
GdkModifierType consumed_modifiers;
+ gboolean group_mod_is_accel_mod = FALSE;
const GdkModifierType xmods = GDK_MOD2_MASK|GDK_MOD3_MASK|GDK_MOD4_MASK|GDK_MOD5_MASK;
const GdkModifierType vmods = GDK_SUPER_MASK|GDK_HYPER_MASK|GDK_META_MASK;
*/
state &= ~GDK_LOCK_MASK;
- gdk_keymap_map_virtual_modifiers (key_hash->keymap, &mask);
+ _gtk_translate_keyboard_accel_state (key_hash->keymap,
+ hardware_keycode, state, mask, group,
+ &keyval,
+ &effective_group, &level, &consumed_modifiers);
- gdk_keymap_translate_keyboard_state (key_hash->keymap,
- hardware_keycode, state, group,
- &keyval, &effective_group, &level, &consumed_modifiers);
+ /* if the group-toggling modifier is part of the default accel mod
+ * mask, and it is active, disable it for matching
+ */
+ if (mask & GTK_TOGGLE_GROUP_MOD_MASK)
+ group_mod_is_accel_mod = TRUE;
+
+ gdk_keymap_map_virtual_modifiers (key_hash->keymap, &mask);
gdk_keymap_add_virtual_modifiers (key_hash->keymap, &state);
GTK_NOTE (KEYBINDINGS,
{
gint i;
- if (keyval == entry->keyval) /* Exact match */
+ if (keyval == entry->keyval && /* Exact match */
+ /* but also match for group if it is an accel mod, because
+ * otherwise we can get multiple exact matches, some being
+ * bogus */
+ (!group_mod_is_accel_mod ||
+ (state & GTK_TOGGLE_GROUP_MOD_MASK) ==
+ (entry->modifiers & GTK_TOGGLE_GROUP_MOD_MASK)))
+
{
GTK_NOTE (KEYBINDINGS,
g_message (" found exact match, keyval = %u, modifiers = 0x%04x",
{
for (i = 0; i < entry->n_keys; i++)
{
- if (entry->keys[i].keycode == hardware_keycode &&
- entry->keys[i].level == level) /* Match for all but group */
+ if (entry->keys[i].keycode == hardware_keycode &&
+ entry->keys[i].level == level &&
+ /* Only match for group if it's an accel mod */
+ (!group_mod_is_accel_mod ||
+ entry->keys[i].group == effective_group))
{
GTK_NOTE (KEYBINDINGS,
g_message (" found group = %d, level = %d",
}
/* Figure out what modifiers went into determining the key symbol */
- gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (display),
+ _gtk_translate_keyboard_accel_state (gdk_keymap_get_for_display (display),
event->hardware_keycode,
- event->state, event->group,
- NULL, NULL, NULL, &consumed_modifiers);
+ event->state,
+ gtk_accelerator_get_default_mod_mask (),
+ event->group,
+ &accel_key, NULL, NULL, &consumed_modifiers);
- accel_key = gdk_keyval_to_lower (event->keyval);
+ accel_key = gdk_keyval_to_lower (accel_key);
accel_mods = event->state & gtk_accelerator_get_default_mod_mask () & ~consumed_modifiers;
/* If lowercasing affects the keysym, then we need to include SHIFT
- * in the modifiers, we re-uppercase when we match against the keyval,
- * but display and save in caseless form.
+ * in the modifiers, We re-upper case when we match against the
+ * keyval, but display and save in caseless form.
*/
if (accel_key != event->keyval)
accel_mods |= GDK_SHIFT_MASK;
return primary;
}
+
+gboolean
+_gtk_translate_keyboard_accel_state (GdkKeymap *keymap,
+ guint hardware_keycode,
+ GdkModifierType state,
+ GdkModifierType accel_mask,
+ gint group,
+ guint *keyval,
+ gint *effective_group,
+ gint *level,
+ GdkModifierType *consumed_modifiers)
+{
+ gboolean group_mask_disabled = FALSE;
+ gboolean retval;
+
+ /* if the group-toggling modifier is part of the accel mod mask, and
+ * it is active, disable it for matching
+ */
+ if (accel_mask & state & GTK_TOGGLE_GROUP_MOD_MASK)
+ {
+ state &= ~GTK_TOGGLE_GROUP_MOD_MASK;
+ group = 0;
+ group_mask_disabled = TRUE;
+ }
+
+ retval = gdk_keymap_translate_keyboard_state (keymap,
+ hardware_keycode, state, group,
+ keyval,
+ effective_group, level,
+ consumed_modifiers);
+
+ /* add back the group mask, we want to match against the modifier,
+ * but not against the keyval from its group
+ */
+ if (group_mask_disabled)
+ {
+ if (effective_group)
+ *effective_group = 1;
+
+ if (consumed_modifiers)
+ *consumed_modifiers &= ~GTK_TOGGLE_GROUP_MOD_MASK;
+ }
+
+ return retval;
+}
GdkModifierType modifiers);
GdkModifierType _gtk_get_primary_accel_mod (void);
+/* temp hack, will go away soon --mitch */
+#ifndef GDK_WINDOWING_QUARTZ
+#define GTK_TOGGLE_GROUP_MOD_MASK 0
+#else
+#define GTK_TOGGLE_GROUP_MOD_MASK GDK_MOD1_MASK
+#endif
+
+gboolean _gtk_translate_keyboard_accel_state (GdkKeymap *keymap,
+ guint hardware_keycode,
+ GdkModifierType state,
+ GdkModifierType accel_mask,
+ gint group,
+ guint *keyval,
+ gint *effective_group,
+ gint *level,
+ GdkModifierType *consumed_modifiers);
+
G_END_DECLS
#endif /* __GTK_PRIVATE_H__ */