Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hutchinson <mhutchinson@novell.com>2010-05-20 03:48:45 +0400
committerMichael Hutchinson <mhutchinson@novell.com>2010-05-20 03:48:45 +0400
commit212f5589e89bfec13946ae67c94f92b306d93d73 (patch)
tree1cbdb1ac0592dc4f537d657ec8cc99c183019c02 /main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands
parentc7d6f2111a03de42afd72bd9a1dbc241a3d352a4 (diff)
* MonoDevelop.Components.Commands/KeyBindingManager.cs: Better
handling of mapping raw keys to commands. We now use the keymap to consume shift keys when possible, except for letters. This means commands should remain sane across different keyboards, and will always be stored and displayed concisely. svn path=/trunk/monodevelop/; revision=157580
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingManager.cs79
1 files changed, 42 insertions, 37 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingManager.cs
index f7d3e84702..24796bf3df 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingManager.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingManager.cs
@@ -67,8 +67,14 @@ namespace MonoDevelop.Components.Commands
SelectionModifierControl = Gdk.ModifierType.ControlMask;
SelectionModifierSuper = Gdk.ModifierType.SuperMask;
}
+
+ keymap.KeysChanged += delegate {
+ groupZeroMappings.Clear ();
+ };
}
+ static Gdk.Keymap keymap = Gdk.Keymap.Default;
+
static bool isMac {
get { return MonoDevelop.Core.PropertyService.IsMac; }
}
@@ -131,7 +137,9 @@ namespace MonoDevelop.Components.Commands
return key.ToString ();
}
- //USED INTERNALLY ONLY
+ /// <summary>
+ /// Used for canonicalizing bindings after parsing them
+ /// </summary>
static string AccelFromKey (Gdk.Key key, Gdk.ModifierType modifier)
{
bool complete;
@@ -284,11 +292,25 @@ namespace MonoDevelop.Components.Commands
return mode + "|" + accel;
}
-
+ // NOTE: changes in this should be mirrored in to Mono.TextEditor/Platform.cs
static void MapRawKeys (Gdk.EventKey evt, out Gdk.Key key, out Gdk.ModifierType mod)
{
- key = evt.Key;
mod = evt.State;
+ key = evt.Key;
+
+ uint keyval;
+ int effectiveGroup, level;
+ Gdk.ModifierType consumedModifiers;
+ keymap.TranslateKeyboardState (evt.HardwareKeycode, evt.State, evt.Group, out keyval, out effectiveGroup,
+ out level, out consumedModifiers);
+
+ key = (Gdk.Key)keyval;
+ mod = evt.State & ~consumedModifiers;
+
+ //we restore the shift modifier if it was a letter, since those always get displayed uppercase
+ //Gdk.Keyval.IsUpper doesn't seem to work properly, so we use Char.IsUpper
+ if (char.IsUpper ((char)Gdk.Keyval.ToUnicode (keyval)) && ((consumedModifiers & Gdk.ModifierType.ShiftMask) != 0))
+ mod |= Gdk.ModifierType.ShiftMask;
if (isX11) {
//this is a workaround for a common X mapping issue
@@ -317,57 +339,39 @@ namespace MonoDevelop.Components.Commands
mod |= Gdk.ModifierType.Mod1Mask;
}
- // When shift or opt modifiers are active, we need to decompose keys down to the
- // "root" physical key to make the command appear correct for Mac.
- if (evt.Group == (byte) 1 || (mod & Gdk.ModifierType.ShiftMask) != 0)
- key = GetRootKey (evt);
-
+ // When opt modifier is active, we need to decompose this to make the command appear correct for Mac.
// In addition, we can only inspect whether the opt/alt key is pressed by examining
// the key's "group", because the Mac GTK+ treats opt as a group modifier and does
// not expose it as an actual GDK modifier.
- if (evt.Group == (byte) 1)
+ if (evt.Group == (byte) 1) {
mod |= Gdk.ModifierType.Mod1Mask;
+ key = GetGroupZeroKey (key, evt);
+ }
}
}
- static Dictionary<Gdk.Key,Gdk.Key> hardwareMappings;
- static Gdk.Keymap keymap;
-
- static void InitKeymaps ()
- {
- if (keymap != null)
- return;
-
- keymap = Gdk.Keymap.Default;
- keymap.KeysChanged += delegate {
- hardwareMappings.Clear ();
- };
- hardwareMappings = new Dictionary<Gdk.Key,Gdk.Key> ();
- }
+ static Dictionary<Gdk.Key,Gdk.Key> groupZeroMappings = new Dictionary<Gdk.Key,Gdk.Key> ();
- static Gdk.Key GetRootKey (Gdk.EventKey evt)
+ static Gdk.Key GetGroupZeroKey (Gdk.Key mappedKey, Gdk.EventKey evt)
{
- InitKeymaps ();
Gdk.Key ret;
- if (hardwareMappings.TryGetValue (evt.Key, out ret))
+ if (groupZeroMappings.TryGetValue (mappedKey, out ret))
return ret;
- //FIXME: LookupKey isn't implemented on Mac, so we have to use this workaround
+ //LookupKey isn't implemented on Mac, so we have to use this workaround
uint[] keyvals;
Gdk.KeymapKey [] keys;
keymap.GetEntriesForKeycode (evt.HardwareKeycode, out keys, out keyvals);
- for (uint i = 0; i < keys.Length; i++) {
- if (keys[i].Group == 0 && keys[i].Level == 0) {
- ret = (Gdk.Key)keyvals[i];
- foreach (Gdk.Key key in keyvals)
- hardwareMappings[key] = ret;
- return ret;
- }
- }
+ //find the key that has the same level (so we preserve shift) but with group 0
+ for (uint i = 0; i < keyvals.Length; i++)
+ if (keyvals[i] == (uint)mappedKey)
+ for (uint j = 0; j < keys.Length; j++)
+ if (keys[j].Group == 0 && keys[j].Level == keys[i].Level)
+ return groupZeroMappings[mappedKey] = ret = (Gdk.Key)keyvals[j];
//failed, but avoid looking it up again
- return hardwareMappings[evt.Key] = evt.Key;
+ return groupZeroMappings[mappedKey] = mappedKey;
}
static string ModifierToPartialAccel (Gdk.ModifierType mod, Gdk.Key key, out bool keyIsModifier)
@@ -557,6 +561,7 @@ namespace MonoDevelop.Components.Commands
return i < shortcut.Length && shortcut[i] == '|' && ModifierMask (shortcut.Substring (0, i)) != Gdk.ModifierType.None;
}
+ //FIXME: run bindings through the keymap and MapRawKeys to consume shift modifier if possible
public static string CanonicalizeBinding (string binding)
{
Gdk.ModifierType modeMod, mod;
@@ -688,7 +693,7 @@ namespace MonoDevelop.Components.Commands
}
SetBinding (command, null, null, BindingMode (command.AccelKey), command.AccelKey);
- command.KeyBindingChanged += new KeyBindingChangedEventHandler (OnKeyBindingChanged);
+ command.KeyBindingChanged += OnKeyBindingChanged;
commands.Add (command);
}