google objective-c cocoa accessibility macos-carbon accessibility-api

objective-c - google gmail api ios



Obtener el número de ventana a través de la API de accesibilidad OSX (2)

Hay una función privada para obtener el número de la ventana CG para un objeto AX dado para la ventana: _AXUIElementGetWindow . Más detalles en la discusión SO Identifique de forma única la ventana activa en OS X Parece que no hay una API pública para hacer la tarea con un 100% de probabilidad. La identificación de ventanas por título y marco (como se describe en la respuesta anterior) funcionará en el 99.9% de los casos.

Estoy trabajando en una aplicación que mueve ventanas de aplicaciones de terceros en la pantalla.

Para obtener una visión general de todas las ventanas abiertas actualmente, utilizo

CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);

Esto devuelve una serie de diccionarios que definen cada ventana abierta. Aquí hay un diccionario ejemplar devuelto:

{ kCGWindowAlpha = 1; kCGWindowBounds = { Height = 442; Width = 475; X = 3123; Y = "-118"; }; kCGWindowIsOnscreen = 1; kCGWindowLayer = 0; kCGWindowMemoryUsage = 907184; kCGWindowName = Untitled; kCGWindowNumber = 7328; kCGWindowOwnerName = TextEdit; kCGWindowOwnerPID = 20706; kCGWindowSharingState = 1; kCGWindowStoreType = 2; kCGWindowWorkspace = 3; },

El diccionario está lleno de buena información utilizada en otros lugares, pero carece de un objeto de accesibilidad que pueda usarse para modificar las posiciones de las ventanas. Las ventanas están claramente identificadas por el número de ventana.

Ahora estoy usando el PID (kCGWindowOwnerPID) para crear un objeto de accesibilidad para la aplicación de la ventana:

AXUIElementRef app = AXUIElementCreateApplication(pid);

A continuación, se recupera una lista de todas las ventanas que la aplicación ha abierto usando AXUIElementCopyAttributeValues:

NSArray *result; AXUIElementCopyAttributeValues( (AXUIElementRef) app, kAXWindowsAttribute, 0, 99999, (CFArrayRef *) &result );

Esto funciona y devuelve una matriz de AXUIElements. Aquí es donde estoy atrapado. Parece que no hay una llamada a la API para recuperar el número de ventana de un objeto de accesibilidad. ¿Hay alguna manera de cualquiera

a) Encuentre el número de la ventana del objeto de accesibilidad (para finalmente iterar sobre la matriz y encontrar la ventana correcta)

o

b) De lo contrario, ¿coincide claramente una ventana descrita en la matriz devuelta por CGWindowListCopyWindowInfo con los objetos de accesibilidad devueltos por AXUIElementCopyAttributeValues?


Terminamos contratando un desarrollador de accesibilidad dedicado para esta tarea.

Resulta que no hay manera de hacer esto sin usar APIs no documentadas (un no ir en nuestro caso).

Por suerte, hay una solución práctica:

Recorrer todas las ventanas abiertas de la aplicación. Obtenga su posición, tamaño y título:

AXUIElementCopyAttributeValue(target, kAXPositionAttribute, CFTypeRef*)&posValue); AXUIElementCopyAttributeValue(target, kAXSizeAttribute, (CFTypeRef*)&sizeValue); AXUIElementCopyAttributeValue(target, kAXTitleAttribute, (CFTypeRef*)&titleValue);

A continuación, convierta la posición y el tamaño en CGPoint reales de CGPoint y CGSize :

AXValueGetValue(posValue, kAXValueCGPointType, &point); AXValueGetValue(sizeValue, kAXValueCGSizeType, &size);

Compare el tamaño, la posición y el título con los valores devueltos por el objeto en CGWindowListCopyWindowInfo() . Si coinciden, puede asumir con seguridad que es la ventana que estaba buscando y usar el AXUIElement ( target en nuestro caso) ya abierto para trabajarlo.

La sobrecarga para recorrer todas las ventanas abiertas resulta insignificante en OSX. Hay un límite muy bajo en cuántas ventanas se abren al mismo tiempo.

Además, aunque esto no es 100% exacto (es posible que 2 ventanas tengan la misma posición, tamaño y título), no hemos encontrado ninguna situación en el uso real donde esto ocurra hasta ahora.