我正在尝试使用MonoMac公开的API来改进运行在Mac OS上的GTK#应用程序,并使用 NSMenuItem 和 NSMenu 构建本机Mac菜单类。
到目前为止,一切看起来都不错,我能够将一些键盘加速器(KeyEquivalent)设置到菜单,但问题是他们不会对键盘做出反应。键组合在菜单中正确显示,但按键不执行任何操作。使用鼠标选择菜单项可以正常工作。
以下是我用来初始化环境的一些代码:
NSApplication.InitDrawingBridge ();
NSApplication.Init ();
NSMenuItem super = new NSMenuItem (DataHelper.ProductName);
super.Submenu = new NSMenu (DataHelper.ProductName);
NSMenu mainMenu = new NSMenu ();
mainMenu.AddItem (super);
NSApplication.SharedApplication.MainMenu = mainMenu;
< menu initialization comes here >
NSApplication.SharedApplication.Delegate = new AppDelegate ();
NSApplication.SharedApplication.ActivateIgnoringOtherApps (true);
为了让键盘事件传递到菜单,我还有什么需要做的吗?
我查看了MonoDevelop的代码参考,找不到任何可以产生差异的东西。我使用了一些代码来设置KeyEquivalent值。
答案 0 :(得分:0)
事实证明,如果未经处理,GTK不会自动将KeyPress事件发送到菜单。我所做的是在GTK中最外面的容器上捕获事件并手动将其发送到Mac菜单:
注意:下面的大部分代码都是从Monodevelop借来的,并且是MIT / X11许可的
private void frmMain_KeyPressEvent (object o, KeyPressEventArgs args)
{
Gdk.ModifierType state;
state = GtkWorkarounds.FixMacModifiers (args.Event.State, args.Event.Group);
string keyEquivalent;
NSEventModifierMask mask;
GetKeyEquivalentForGdkKey (args.Event.Key, state, out keyEquivalent, out mask);
if (keyEquivalent.Length == 0)
return false;
var nsEvent = NSEvent.KeyEvent (
NSEventType.KeyDown, PointF.Empty, mask, 0, 0,
NSGraphicsContext.CurrentContext, keyEquivalent, keyEquivalent, false, 0);
if (NSApplication.SharedApplication.MainMenu.PerformKeyEquivalent (nsEvent)) {
args.RetVal = true;
return true;
}
return false;
}
public static void GetKeyEquivalentForGdkKey (Gdk.Key key, ModifierType modifierType, out string keyEquivalent, out NSEventModifierMask mask)
{
keyEquivalent = GetKeyEquivalent (key);
mask = 0;
if (keyEquivalent.Length == 0)
return;
if ((modifierType & Gdk.ModifierType.Mod1Mask) != 0) {
mask |= NSEventModifierMask.AlternateKeyMask;
modifierType ^= Gdk.ModifierType.Mod1Mask;
}
if ((modifierType & Gdk.ModifierType.ShiftMask) != 0) {
mask |= NSEventModifierMask.ShiftKeyMask;
modifierType ^= Gdk.ModifierType.ShiftMask;
}
if ((modifierType & Gdk.ModifierType.ControlMask) != 0) {
mask |= NSEventModifierMask.ControlKeyMask;
modifierType ^= Gdk.ModifierType.ControlMask;
}
if ((modifierType & Gdk.ModifierType.MetaMask) != 0) {
mask |= NSEventModifierMask.CommandKeyMask;
modifierType ^= Gdk.ModifierType.MetaMask;
}
}
static string GetKeyEquivalent (Gdk.Key key)
{
char c = (char) Gdk.Keyval.ToUnicode ((uint) key);
if (c != 0)
return c.ToString ();
var fk = GetFunctionKey (key);
if (fk != 0)
return ((char) fk).ToString ();
return "";
}
static FunctionKey GetFunctionKey (Gdk.Key key)
{
switch (key) {
case Gdk.Key.Return:
return (FunctionKey) (uint) '\n';
case Gdk.Key.BackSpace:
return (FunctionKey) 0x08;
// NSBackspaceCharacter
case Gdk.Key.KP_Delete:
case Gdk.Key.Delete:
return (FunctionKey) 0x7F;
// NSDeleteCharacter
case Gdk.Key.KP_Up:
case Gdk.Key.Up:
return FunctionKey.UpArrow;
case Gdk.Key.KP_Down:
case Gdk.Key.Down:
return FunctionKey.DownArrow;
case Gdk.Key.KP_Left:
case Gdk.Key.Left:
return FunctionKey.LeftArrow;
case Gdk.Key.KP_Right:
case Gdk.Key.Right:
return FunctionKey.RightArrow;
case Gdk.Key.F1:
return FunctionKey.F1;
case Gdk.Key.F2:
return FunctionKey.F2;
case Gdk.Key.F3:
return FunctionKey.F3;
case Gdk.Key.F4:
return FunctionKey.F4;
case Gdk.Key.F5:
return FunctionKey.F5;
case Gdk.Key.F6:
return FunctionKey.F6;
case Gdk.Key.F7:
return FunctionKey.F7;
case Gdk.Key.F8:
return FunctionKey.F8;
case Gdk.Key.F9:
return FunctionKey.F9;
case Gdk.Key.F10:
return FunctionKey.F10;
case Gdk.Key.F11:
return FunctionKey.F11;
case Gdk.Key.F12:
return FunctionKey.F12;
case Gdk.Key.F13:
return FunctionKey.F13;
case Gdk.Key.F14:
return FunctionKey.F14;
case Gdk.Key.F15:
return FunctionKey.F15;
case Gdk.Key.F16:
return FunctionKey.F16;
case Gdk.Key.F17:
return FunctionKey.F17;
case Gdk.Key.F18:
return FunctionKey.F18;
case Gdk.Key.F19:
return FunctionKey.F19;
case Gdk.Key.F20:
return FunctionKey.F20;
case Gdk.Key.F21:
return FunctionKey.F21;
case Gdk.Key.F22:
return FunctionKey.F22;
case Gdk.Key.F23:
return FunctionKey.F23;
case Gdk.Key.F24:
return FunctionKey.F24;
case Gdk.Key.F25:
return FunctionKey.F25;
case Gdk.Key.F26:
return FunctionKey.F26;
case Gdk.Key.F27:
return FunctionKey.F27;
case Gdk.Key.F28:
return FunctionKey.F28;
case Gdk.Key.F29:
return FunctionKey.F29;
case Gdk.Key.F30:
return FunctionKey.F30;
case Gdk.Key.F31:
return FunctionKey.F31;
case Gdk.Key.F32:
return FunctionKey.F32;
case Gdk.Key.F33:
return FunctionKey.F33;
case Gdk.Key.F34:
return FunctionKey.F34;
case Gdk.Key.F35:
return FunctionKey.F35;
case Gdk.Key.KP_Insert:
case Gdk.Key.Insert:
return FunctionKey.Insert;
case Gdk.Key.KP_Home:
case Gdk.Key.Home:
return FunctionKey.Home;
case Gdk.Key.Begin:
return FunctionKey.Begin;
case Gdk.Key.KP_End:
case Gdk.Key.End:
return FunctionKey.End;
case Gdk.Key.KP_Page_Up:
case Gdk.Key.Page_Up:
return FunctionKey.PageUp;
case Gdk.Key.KP_Page_Down:
case Gdk.Key.Page_Down:
return FunctionKey.PageDown;
case Gdk.Key.Key_3270_PrintScreen:
return FunctionKey.PrintScreen;
case Gdk.Key.Scroll_Lock:
return FunctionKey.ScrollLock;
case Gdk.Key.Pause:
return FunctionKey.Pause;
case Gdk.Key.Sys_Req:
return FunctionKey.SysReq;
case Gdk.Key.Break:
return FunctionKey.Break;
case Gdk.Key.Key_3270_Reset:
return FunctionKey.Reset;
case Gdk.Key.Menu:
return FunctionKey.Menu;
case Gdk.Key.Print:
return FunctionKey.Print;
case Gdk.Key.Help:
return FunctionKey.Help;
case Gdk.Key.Find:
return FunctionKey.Find;
case Gdk.Key.Undo:
return FunctionKey.Undo;
case Gdk.Key.Redo:
return FunctionKey.Redo;
case Gdk.Key.Execute:
return FunctionKey.Execute;
/*
return FunctionKey.Stop;
return FunctionKey.User;
return FunctionKey.System;
return FunctionKey.ClearLine;
return FunctionKey.ClearDisplay;
return FunctionKey.InsertLine;
return FunctionKey.DeleteLine;
return FunctionKey.InsertChar;
return FunctionKey.DeleteChar;
return FunctionKey.Next;
return FunctionKey.Prev;
return FunctionKey.Select;
return FunctionKey.ModeSwitch;
*/
}
return 0;
}
// "Function-Key Unicodes" from NSEvent reference
enum FunctionKey : ushort
{
UpArrow = 0xF700,
DownArrow = 0xF701,
LeftArrow = 0xF702,
RightArrow = 0xF703,
F1 = 0xF704,
F2 = 0xF705,
F3 = 0xF706,
F4 = 0xF707,
F5 = 0xF708,
F6 = 0xF709,
F7 = 0xF70A,
F8 = 0xF70B,
F9 = 0xF70C,
F10 = 0xF70D,
F11 = 0xF70E,
F12 = 0xF70F,
F13 = 0xF710,
F14 = 0xF711,
F15 = 0xF712,
F16 = 0xF713,
F17 = 0xF714,
F18 = 0xF715,
F19 = 0xF716,
F20 = 0xF717,
F21 = 0xF718,
F22 = 0xF719,
F23 = 0xF71A,
F24 = 0xF71B,
F25 = 0xF71C,
F26 = 0xF71D,
F27 = 0xF71E,
F28 = 0xF71F,
F29 = 0xF720,
F30 = 0xF721,
F31 = 0xF722,
F32 = 0xF723,
F33 = 0xF724,
F34 = 0xF725,
F35 = 0xF726,
Insert = 0xF727,
Delete = 0xF728,
Home = 0xF729,
Begin = 0xF72A,
End = 0xF72B,
PageUp = 0xF72C,
PageDown = 0xF72D,
PrintScreen = 0xF72E,
ScrollLock = 0xF72F,
Pause = 0xF730,
SysReq = 0xF731,
Break = 0xF732,
Reset = 0xF733,
Stop = 0xF734,
Menu = 0xF735,
User = 0xF736,
System = 0xF737,
Print = 0xF738,
ClearLine = 0xF739,
ClearDisplay = 0xF73A,
InsertLine = 0xF73B,
DeleteLine = 0xF73C,
InsertChar = 0xF73D,
DeleteChar = 0xF73E,
Prev = 0xF73F,
Next = 0xF740,
Select = 0xF741,
Execute = 0xF742,
Undo = 0xF743,
Redo = 0xF744,
Find = 0xF745,
Help = 0xF746,
ModeSwitch = 0xF747
}