cocoa accessibility-api

¿Cómo puedo usar la API de accesibilidad de Cocoa para detectar que se traiga una ventana al frente?



accessibility-api (4)

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á al observar 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 darle una ID de proceso, que puede usar para crear un objeto AXApplication.

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 puede detectar mi aplicación cuando otra aplicación trae una ventana al frente, sin hacerlo clave?

Espero encontrar una solución que funcione en OS X 10.4 y 10.5

Más información: estoy usando estas declaraciones en este 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);


No he podido suscribirme a los cambios actuales de la ventana, pero puede consultar la API de accesibilidad para la aplicación actual y la ventana de más aplicaciones en primer plano de las aplicaciones actuales.

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 se ve así:

-(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 se inicializa 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 se tomó del ejemplo de Apple UIElementInspector , que también es un gran recurso para aprender sobre la API de accesibilidad.



Eche un vistazo al ejemplo de iChatStatusFromApplication en la documentación del desarrollador. Es exactamente lo que necesitas :)