tiendas tienda pccomputer pccomponentes murcia madrid informatica españa componentes objective-c macos cocoa

objective c - tienda - OSX: ¿Cómo detectar si se está ejecutando Mission Control?



tienda informatica españa (4)

Cuando se ejecuta Mission Control, evita que las aplicaciones reciban eventos de teclado y mouse. También deja la última aplicación en ejecución pensando que todavía tiene foco. Este es un problema para mí porque no recibo eventos keyUp o mouseUp si inicio el Control de Misión con un botón del mouse o una tecla presionada y mi aplicación se comportará como si ese botón o tecla del mouse estuviera presionada.

Me gustaría una forma de leer los eventos del teclado y del mouse, incluso cuando el Control de la Misión está activo, o una forma de detectar que el Control de la Misión está activo. Idealmente, me gustaría poder hacer esto último ya que efectivamente no puedo usar mi aplicación cuando se está ejecutando Mission Control.

He intentado un par de cosas sin suerte:

  1. Use addGlobalMonitorForEventsMatchingMask para registrar un monitor global para eventos de teclado y mouse. Esto captura los eventos del mouse (pero no los eventos del teclado, aunque la documentation dice que los eventos keyDown deben enviarse al monitor global) cuando cambio a otra aplicación, pero el Control de la Misión no parece permitir que los eventos se propaguen a los monitores globales.
  2. Marque [[NSRunningApplication currentApplication] {isActive, ownsMenuBar}] . ¡Aparentemente, mi aplicación está activa aunque no esté recibiendo eventos!
  3. Compruebe [NSApp keyWindow] != nil . Aparentemente, una de mis ventanas debería estar recibiendo eventos clave. Ninguno de ellos lo es.
  4. Compruebe si Mission Control es una de las aplicaciones en ejecución devueltas por [NSWorkspace runningApplications] . El control de la misión no aparece en esta lista cuando se está ejecutando.

¡Gracias por adelantado!

Editar:

Finalmente he resuelto este problema (aunque no de una manera muy satisfactoria). Para el mouse, resulta que puede consultar el estado de los botones pulsados ​​con [NSEvent pressedMouseButtons] . Simplemente hago un seguimiento de lo que creo que el estado del mouse debe ser de los eventos NSLeftMouseDown y NSLeftouseUp y lo comparo con [NSEvent pressedMouseButtons] vez en cuando para asegurarme de que sean coherentes. Si no lo son, entonces sé que algo ha secuestrado mi evento NSLeftouseUp y actúa en consecuencia.

Para el teclado, no pude encontrar una manera de consultar el estado del teclado, por lo que no pude hacer una solución similar. Terminé deshabilitando el cambio de aplicación usando las opciones de presentación cuando se presionan las teclas.


¿Probaste a nivel bash usando NSTask? Algo como ps -faxU <username> debería enumerar todos los procesos en ejecución y luego se podría analizar la salida, o incluso se podría usar ps -faxU <username> | grep -i "mission control" ps -faxU <username> | grep -i "mission control" (En la parte superior de mi cabeza no estoy seguro de cómo se puede llamar al proceso, pero algo como "control de misión" parece legítimo). Quizás no sea la solución más elegante, pero si nada más funciona, puede valer la pena.


Al menos en OS X 10.10, puedes usar este código para verificar si Mission Control está activo o no:

func missionControlIsActive() -> Bool { var result: Bool = false let windowInfosRef = CGWindowListCopyWindowInfo(CGWindowListOption(kCGWindowListOptionOnScreenOnly), CGWindowID(0)) // CGWindowID(0) is equal to kCGNullWindowID let windowList: NSArray = windowInfosRef.takeRetainedValue() // We own the returned CFArrayRef for entry in windowList { if (entry.objectForKey("kCGWindowOwnerName") as! String) == "Dock" { var bounds: NSDictionary = entry.objectForKey("kCGWindowBounds") as! NSDictionary if (bounds.objectForKey("Y") as! NSNumber) == -1 { result = true } } } return result }

En pocas palabras, el código verifica si una ventana específica que es propiedad del proceso OS X Dock es visible en la pantalla y si está en una posición específica. Si se cumplen ambas condiciones, el Control de la Misión estará activo en este momento. El código funcionará en una aplicación de espacio aislado y no se requieren privilegios para dispositivos de asistencia.


Parece que DTrace tiene cierta capacidad para ver que se activa el Control de la Misión. Intenta correr:

sudo fs_usage -filesys | grep misión

desde la línea de comandos y luego iniciando la aplicación Mission Control desde la carpeta / Aplicación.

Debería ver una gran cantidad de resultados relacionados con el inicio del Control de la Misión. Desafortunadamente, esta misma salida no apareció al utilizar el método abreviado de teclado o deslizar. Por supuesto, usar DTrace en el código de producción no es algo que realmente recomendaría.


Puede que me esté faltando algo, pero ¿ha intentado usar los toques de eventos en lugar del monitoreo global?