2008-12-07 12 views
9

Estoy usando la API de accesibilidad para detectar cuándo una determinada aplicación abre ventanas, cierra ventanas, cuando las ventanas se mueven o cambian de tamaño, o se vuelven principales y/o enfocadas. Sin embargo, la aplicación del cliente parece mover una ventana al frente sin que se active una notificación de la API de accesibilidad .¿Cómo puedo usar la API de accesibilidad de Cocoa para detectar que se traiga una ventana al frente?

¿Cómo puede detectar mi aplicación cuando otra aplicación trae una ventana al frente, sin hacerlo clave?

estoy esperando encontrar una solución que funciona en OS X 10.4 y 10.5

Más información: estoy usando estas declaraciones en el momento. Funcionan bien cuando el usuario selecciona manualmente una ventana para llevarla al frente. Pero no funciona cuando la aplicación en sí está llevando la ventana al frente.

AXObserverAddNotification(observer, element, kAXMainWindowChangedNotification, 0); 
AXObserverAddNotification(observer, element, kAXFocusedWindowChangedNotification, 0); 

Respuesta

7

no he podido suscribirse a los cambios actuales de la ventana, pero se puede pedir a la API de accesibilidad para la aplicación actual, y la ventana de las aplicaciones actuales más plano.

Imagine que tiene una clase llamada CurrentAppData, con los siguientes datos:

@interface CurrentAppData : NSObject { 
    NSString* _title; 
    AXUIElementRef _systemWide; 
    AXUIElementRef _app; 
    AXUIElementRef _window; 
} 

El código para encontrar la aplicación actual es como la siguiente:

-(void) updateCurrentApplication { 
    // get the currently active application 
    _app = (AXUIElementRef)[CurrentAppData 
          valueOfExistingAttribute:kAXFocusedApplicationAttribute 
             ofUIElement:_systemWide]; 

    // Get the window that has focus for this application 
    _window = (AXUIElementRef)[CurrentAppData 
           valueOfExistingAttribute:kAXFocusedWindowAttribute 
              ofUIElement:_app]; 

    NSString* appName = [CurrentAppData descriptionOfValue:_window 
              beingVerbose:TRUE];  

    [self setTitle:appName]; 
} 

En este ejemplo la variable _systemWide es inicializado en la función de inicio de clases como: _system = AXUIElementCreateSystemWide();

La función de clase valueOfExistingAttribute se ve así:

// ------------------------------------------------------------------------------- 
// valueOfExistingAttribute:attribute:element 
// 
// Given a uiElement and its attribute, return the value of an accessibility 
// object's attribute. 
// ------------------------------------------------------------------------------- 
+ (id)valueOfExistingAttribute:(CFStringRef)attribute ofUIElement:(AXUIElementRef)element 
{ 
    id result = nil; 
    NSArray *attrNames; 

    if (AXUIElementCopyAttributeNames(element, (CFArrayRef *)&attrNames) == kAXErrorSuccess) 
    { 
     if ([attrNames indexOfObject:(NSString *)attribute] != NSNotFound 
       && 
      AXUIElementCopyAttributeValue(element, attribute, (CFTypeRef *)&result) == kAXErrorSuccess 
     ) 
     { 
      [result autorelease]; 
     } 
     [attrNames release]; 
    } 
    return result; 
} 

La función anterior fue tomada del ejemplo de Apple UIElementInspector, que es también un gran recurso para aprender acerca de la API de accesibilidad.

5

En Mac OS X, las aplicaciones y las ventanas son cosas completamente independientes, con aplicaciones que contienen ventanas; no son lo mismo que en Microsoft Windows. Necesita detectar la activación y desactivación de cada aplicación.

Lo harás observando kAXApplicationActivatedNotification y kAXApplicationDeactivatedNotification. El objetivo de estas notificaciones es que la aplicación se active y desactive. También necesitará detectar las aplicaciones que inician y cierran; puede hacerlo utilizando Process Manager o NSWorkspace. Ambas API pueden proporcionarle un ID de proceso, que puede usar para crear un objeto AXApplication.

Cuestiones relacionadas