From 244d41b94a045633281e47d720311e907d83aedb Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 6 Sep 2005 18:13:56 +0000 Subject: Add tests for extra virtual modifiers. 2005-09-06 Matthias Clasen * tests/testgtk.c (create_key_lookup): Add tests for extra virtual modifiers. * gtk/gtkkeyhash.c (_gtk_key_hash_lookup): Try to match both against Mod2 - Mod5 and against Super, Hyper, Meta. * gtk/gtkaccellabel.c (_gtk_accel_label_class_get_accelerator_label): * gtk/gtkaccelgroup.c (gtk_accelerator_parse) (gtk_accelerator_name): Support Super, Hyper Meta and Mod2 - Mod5. --- gtk/gtkaccelgroup.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++- gtk/gtkaccellabel.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++- gtk/gtkkeyhash.c | 13 +++++++-- 3 files changed, 164 insertions(+), 4 deletions(-) (limited to 'gtk') diff --git a/gtk/gtkaccelgroup.c b/gtk/gtkaccelgroup.c index d7324d4e5a..e76dc0de1e 100644 --- a/gtk/gtkaccelgroup.c +++ b/gtk/gtkaccelgroup.c @@ -963,6 +963,41 @@ is_release (const gchar *string) (string[8] == '>')); } +static inline gboolean +is_meta (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'm' || string[1] == 'M') && + (string[2] == 'e' || string[2] == 'E') && + (string[3] == 't' || string[3] == 'T') && + (string[4] == 'a' || string[4] == 'A') && + (string[5] == '>')); +} + +static inline gboolean +is_super (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'u' || string[2] == 'U') && + (string[3] == 'p' || string[3] == 'P') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == '>')); +} + +static inline gboolean +is_hyper (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'h' || string[1] == 'H') && + (string[2] == 'y' || string[2] == 'Y') && + (string[3] == 'p' || string[3] == 'P') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == '>')); +} + /** * gtk_accelerator_parse: * @accelerator: string representing an accelerator @@ -1052,7 +1087,25 @@ gtk_accelerator_parse (const gchar *accelerator, { accelerator += 5; len -= 5; - mods |= GDK_MOD1_MASK; + mods |= GDK_ALT_MASK; + } + else if (len >= 6 && is_meta (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= GDK_META_MASK; + } + else if (len >= 7 && is_hyper (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= GDK_HYPER_MASK; + } + else if (len >= 7 && is_super (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= GDK_SUPER_MASK; } else { @@ -1108,6 +1161,9 @@ gtk_accelerator_name (guint accelerator_key, static const gchar text_mod3[] = ""; static const gchar text_mod4[] = ""; static const gchar text_mod5[] = ""; + static const gchar text_meta[] = ""; + static const gchar text_super[] = ""; + static const gchar text_hyper[] = ""; guint l; gchar *keyval_name; gchar *accelerator; @@ -1136,6 +1192,12 @@ gtk_accelerator_name (guint accelerator_key, if (accelerator_mods & GDK_MOD5_MASK) l += sizeof (text_mod5) - 1; l += strlen (keyval_name); + if (accelerator_mods & GDK_META_MASK) + l += sizeof (text_meta) - 1; + if (accelerator_mods & GDK_HYPER_MASK) + l += sizeof (text_hyper) - 1; + if (accelerator_mods & GDK_SUPER_MASK) + l += sizeof (text_super) - 1; accelerator = g_new (gchar, l + 1); @@ -1181,6 +1243,21 @@ gtk_accelerator_name (guint accelerator_key, strcpy (accelerator + l, text_mod5); l += sizeof (text_mod5) - 1; } + if (accelerator_mods & GDK_META_MASK) + { + strcpy (accelerator + l, text_meta); + l += sizeof (text_meta) - 1; + } + if (accelerator_mods & GDK_HYPER_MASK) + { + strcpy (accelerator + l, text_hyper); + l += sizeof (text_hyper) - 1; + } + if (accelerator_mods & GDK_SUPER_MASK) + { + strcpy (accelerator + l, text_super); + l += sizeof (text_super) - 1; + } strcpy (accelerator + l, keyval_name); return accelerator; diff --git a/gtk/gtkaccellabel.c b/gtk/gtkaccellabel.c index fd159c34ba..fcfb80c975 100644 --- a/gtk/gtkaccellabel.c +++ b/gtk/gtkaccellabel.c @@ -556,13 +556,87 @@ _gtk_accel_label_class_get_accelerator_label (GtkAccelLabelClass *klass, g_string_append (gstring, klass->mod_name_control); seen_mod = TRUE; } - if (accelerator_mods & GDK_MOD1_MASK) + if (accelerator_mods & GDK_ALT_MASK) { if (seen_mod) g_string_append (gstring, klass->mod_separator); g_string_append (gstring, klass->mod_name_alt); seen_mod = TRUE; } + if (accelerator_mods & GDK_MOD2_MASK) + { + if (seen_mod) + g_string_append (gstring, klass->mod_separator); + + g_string_append (gstring, "Mod2"); + seen_mod = TRUE; + } + if (accelerator_mods & GDK_MOD3_MASK) + { + if (seen_mod) + g_string_append (gstring, klass->mod_separator); + + g_string_append (gstring, "Mod3"); + seen_mod = TRUE; + } + if (accelerator_mods & GDK_MOD4_MASK) + { + if (seen_mod) + g_string_append (gstring, klass->mod_separator); + + g_string_append (gstring, "Mod4"); + seen_mod = TRUE; + } + if (accelerator_mods & GDK_MOD5_MASK) + { + if (seen_mod) + g_string_append (gstring, klass->mod_separator); + + g_string_append (gstring, "Mod5"); + seen_mod = TRUE; + } + if (accelerator_mods & GDK_SUPER_MASK) + { + if (seen_mod) + g_string_append (gstring, klass->mod_separator); + + /* This is the text that should appear next to menu accelerators + * that use the super key. If the text on this key isn't typically + * translated on keyboards used for your language, don't translate + * this. + * And do not translate the part before the |. + */ + g_string_append (gstring, Q_("keyboard label|Super")); + seen_mod = TRUE; + } + if (accelerator_mods & GDK_HYPER_MASK) + { + if (seen_mod) + g_string_append (gstring, klass->mod_separator); + + /* This is the text that should appear next to menu accelerators + * that use the hyper key. If the text on this key isn't typically + * translated on keyboards used for your language, don't translate + * this. + * And do not translate the part before the |. + */ + g_string_append (gstring, Q_("keyboard label|Hyper")); + seen_mod = TRUE; + } + if (accelerator_mods & GDK_META_MASK) + { + if (seen_mod) + g_string_append (gstring, klass->mod_separator); + + /* This is the text that should appear next to menu accelerators + * that use the meta key. If the text on this key isn't typically + * translated on keyboards used for your language, don't translate + * this. + * And do not translate the part before the |. + */ + g_string_append (gstring, Q_("keyboard label|Meta")); + seen_mod = TRUE; + } if (seen_mod) g_string_append (gstring, klass->mod_separator); diff --git a/gtk/gtkkeyhash.c b/gtk/gtkkeyhash.c index 2741545081..12648e050d 100644 --- a/gtk/gtkkeyhash.c +++ b/gtk/gtkkeyhash.c @@ -358,8 +358,17 @@ _gtk_key_hash_lookup (GtkKeyHash *key_hash, while (tmp_list) { GtkKeyHashEntry *entry = tmp_list->data; - - if ((entry->modifiers & ~consumed_modifiers & mask) == (state & ~consumed_modifiers & mask)) + GdkModifierType xmods, vmods; + + /* If the virtual super, hyper or meta modifiers are present, + * they will also be mapped to some of the mod2 - mod5 modifiers, + * so we compare them twice, ignoring either set. + */ + xmods = GDK_MOD2_MASK|GDK_MOD3_MASK|GDK_MOD4_MASK|GDK_MOD5_MASK; + vmods = GDK_SUPER_MASK|GDK_HYPER_MASK|GDK_META_MASK; + + if ((entry->modifiers & ~consumed_modifiers & mask & ~vmods) == (state & ~consumed_modifiers & mask & ~vmods) || + (entry->modifiers & ~consumed_modifiers & mask & ~xmods) == (state & ~consumed_modifiers & mask & ~xmods)) { gint i; -- cgit v1.2.1