2015-09-21 6 views
0

Я пытаюсь использовать приложение GTK #, которое работает в Mac OS, используя API, который MonoMac предоставляет и создает собственное меню Mac, используя NSMenuItem и NSMenu классов.KeyEquivalents, не работающие для MonoMac NSMenuItem при использовании в приложении GTK #

До сих пор все выглядело хорошо, и я смог установить некоторые клавиатурные ускорители (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

Оказалось, что 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 
}