diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index 313f5c38e4923401553d9c7c83ca3849723c0174..6f4ae0ec24dc6e0e29cf201a1906b25462c6b49e 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -53,6 +53,13 @@ enum { LAST_SIGNAL }; +enum { + VIEW_LETTERS_LOWER, + VIEW_LETTERS_UPPER, + VIEW_NUMBERS, + VIEW_SYMBOLS +}; + static guint signals[LAST_SIGNAL] = { 0, }; #define EEK_KEYBOARD_GET_PRIVATE(obj) \ @@ -63,6 +70,7 @@ struct _EekKeyboardPrivate EekLayout *layout; EekModifierBehavior modifier_behavior; EekModifierType modifiers; + EekModifierType old_level; GList *pressed_keys; GList *locked_keys; GArray *outline_array; @@ -206,24 +214,43 @@ static void set_level_from_modifiers (EekKeyboard *self) { EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self); - gint level = 0; - if (priv->modifiers & priv->alt_gr_mask) { - /* Alt-Gr is the 123 and ABC keys */ - priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK; - level |= 2; + /* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */ + gint level = ((priv->modifiers & priv->alt_gr_mask) ? 2 : 0) | + ((priv->modifiers & EEK_SHIFT_MASK) ? 1 : 0); + + switch (priv->old_level) { + case VIEW_LETTERS_UPPER: + { + /* Redirect upper case letters to numbers instead of symbols, clearing + the shift modifier to keep the modifiers in sync with the level */ + if (level == VIEW_SYMBOLS) { + level = VIEW_NUMBERS; + priv->modifiers &= ~EEK_SHIFT_MASK; + } + break; } - - if (priv->modifiers & EEK_SHIFT_MASK) { - /* Left Shift is the Shift and =/+ keys */ - level |= 1; - - if (level == 1) - priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LATCH; - else - priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK; + case VIEW_SYMBOLS: + { + /* Redirect symbols to lower case letters instead of upper case, + clearing the shift modifier to keep the modifiers in sync with the + level */ + if (level == VIEW_LETTERS_UPPER) { + level = VIEW_LETTERS_LOWER; + priv->modifiers &= ~EEK_SHIFT_MASK; + } + break; + } + case VIEW_LETTERS_LOWER: /* Direct transitions between views */ + case VIEW_NUMBERS: + default: + break; } + if (level == VIEW_NUMBERS || level == VIEW_SYMBOLS) + priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK; + + priv->old_level = level; eek_element_set_level (EEK_ELEMENT(self), level); }