2010-11-17 16 views
15

Estoy integrando una aplicación GTK # en Mac OS X. GTK en Mac OS X es un contenedor de algunos fundamentos de Cocoa y Carbono. Tenemos algunas cosas específicas de la plataforma utilizando directamente las API de menú global de Carbon (es más de bajo nivel y flexible que Cocoa, y no necesitamos ser de 64 bits).Abrir programáticamente el menú de Ayuda Mac

Parece que GTK se traga todos los eventos de teclado antes de que Carbon los despache como comandos. Esto tiene sentido, porque no hay un mapeo de los comandos de carbono en el mundo GTK. En general, esto no es un problema, porque tenemos un controlador de eventos clave global y distribuimos todo a través de nuestro propio sistema de comando. Sin embargo, esto parece estar impidiendo Cmd-? desde abrir el menú de búsqueda de Ayuda, y no puedo encontrar una manera de hacerlo programáticamente.

función MenuSelect del Gestor de menús es prometedor, pero no he encontrado una manera de determinar la coordenada de forma automática, y por alguna razón que sólo funciona cuando golpeo la combinación dos veces ...

Como alternativa, una forma para enviar el Cmd-? presionar las teclas para manejar el comando de Carbon o sintetizar directamente el evento de comando sería bueno, pero no he tenido suerte en esa área.

ProcessHICommand de carbono no es ningún uso sin un identificador de comando y no puedo averiguar lo que es (si lo hay)

En cuanto cacao, que puede controlar la NSWindow y llame InterpretKeyEvents, pero No he tenido ningún éxito de suerte al sintetizar el NSEvent, solo emite un pitido. El evento que estoy usando es

var evt = NSEvent.KeyEvent (NSEventType.KeyDown, System.Drawing.PointF.Empty, 
    NSEventModifierMask.CommandKeyMask | NSEventModifierMask.ShiftKeyMask, 
    0, win.WindowNumber, NSGraphicsContext.CurrentContext, "?", "?", 
    false, (ushort) keycode); 

código clave se determina a partir de un mapa de teclado GTK ser 44. Me confirmó que el código clave es correcta usando una aplicación sencilla MonoMac (cacao), pero InterpretKeyEvents no funcionó con el evento en que se aplicación tampoco. Y no puedo encontrar ningún selector asociado con el comando.

+2

Los usuarios han estado preguntando por el Cmd-Shift-? vinculación para abrir el menú de búsqueda de Ayuda. De alguna manera, el ciclo de eventos de GTK evita que funcione el manejo incorporado. –

+0

Con el evento de cacao, ¿ha intentado usar "/" en lugar de "?". –

+4

En una nota lateral, su afirmación de que el carbono es "más de bajo nivel y flexible que Cocoa" es incorrecta. Carbon es una API completamente separada que fue diseñada para ser compatible con Mac OS 8/9. Está obsoleto y mal mantenido y no está "debajo" de cacao de ninguna manera. El cacao en realidad es mucho más antiguo que el carbono, aunque es más moderno a primera vista. Realmente debería interactuar con Cocoa en lugar de carbono. –

Respuesta

0

Puede utilizar las API de accesibilidad para falsificar una pulsación en el elemento del menú.

NSString *helpMenuTitle = [[[[NSApplication sharedApplication] mainMenu] itemWithTag:HELP_MENU_TAG] title]; 
AXUIElementRef appElement = AXUIElementCreateApplication(getpid()); 
AXUIElementRef menuBar; 
AXError error = AXUIElementCopyAttributeValue(appElement, 
               kAXMenuBarAttribute, 
               (CFTypeRef *)&menuBar); 
if (error) { 
    return; 
} 

CFIndex count = -1; 
error = AXUIElementGetAttributeValueCount(menuBar, kAXChildrenAttribute, &count); 
if (error) { 
    CFRelease(menuBar); 
    return; 
} 

NSArray *children = nil; 
error = AXUIElementCopyAttributeValues(menuBar, kAXChildrenAttribute, 0, count, (CFArrayRef *)&children); 
if (error) { 
    CFRelease(menuBar); 
    return; 
} 

for (id child in children) { 
    AXUIElementRef element = (AXUIElementRef)child; 
    id title; 
    AXError error = AXUIElementCopyAttributeValue(element, 
                kAXTitleAttribute, 
                (CFTypeRef *)&title); 
    if ([title isEqualToString:helpMenuTitle]) { 
     AXUIElementPerformAction(element, kAXPressAction); 
     CFRelease(title); 
     break; 
    } 
    CFRelease(title); 
} 
CFRelease(menuBar); 
[children release]; 
+0

De hecho, encontramos otra solución que implicaba arreglar el kit de herramientas GTK para que no interceptara la pulsación de tecla pero dejara que Cocoa lo manejara. Sin embargo, estoy aceptando esta respuesta, ya que es una buena solución para cualquiera que esté dispuesto a depender de Accessibility Frameworks. –

+0

cuidado allí. Esto fallará en cualquier idioma que no sea inglés debido al título de "Ayuda" codificado. Debe asignar un valor de etiqueta al menú de ayuda en el menú principal de la aplicación, luego tomar el título real del menú y usarlo en su lugar. – dgatwood

1

Puede hacerlo llamando desde C/Objective-C a AppleScript (GUI) script, que básicamente haría el señalamiento y el clic de un usuario como lo haría un usuario, para abrir el menú de ayuda programáticamente.

+0

Realmente no puedo hacer que la aplicación dependa de Accessibility Frameworks ... –

Cuestiones relacionadas