2012-10-02 16 views
23

Quando il controllo missione viene eseguito, impedisce alle applicazioni di ricevere eventi da tastiera e mouse. Lascia anche l'ultima applicazione in esecuzione pensando che sia ancora focalizzata. Questo è un problema per me perché non ricevo gli eventi keyUp o mouseUp se avvio Mission Control con un pulsante del mouse o un tasto premuto e la mia applicazione si comporterà come se si tenesse premuto quel pulsante o tasto del mouse.OSX: come rilevare se il controllo missione è in esecuzione?

Vorrei un modo per leggere gli eventi sia della tastiera sia del mouse anche quando il controllo missione è attivo o un modo per rilevare che il controllo missione è attivo. Idealmente, mi piacerebbe essere in grado di fare quest'ultimo perché non posso usare la mia applicazione quando Mission Control è in esecuzione.

Ho provato un paio di cose senza fortuna:

  1. Usa addGlobalMonitorForEventsMatchingMask registrare un monitor globale per gli eventi di tastiera e mouse. Cattura gli eventi del mouse (ma non gli eventi della tastiera, anche se lo documentation dice che gli eventi keyDown devono essere inviati al monitor globale) quando passo a un'altra applicazione, ma il controllo missione non sembra consentire la propagazione degli eventi ai monitor globali.
  2. Controllare [[NSRunningApplication currentApplication] {isActive, ownsMenuBar}]. Apparentemente, la mia applicazione è attiva anche se non riceve eventi!
  3. Controllare [NSApp keyWindow] != nil. Apparentemente, una delle mie finestre dovrebbe ricevere eventi chiave. Nessuno di loro lo sono.
  4. Verificare se Mission Control è una delle applicazioni in esecuzione restituite da [NSWorkspace runningApplications]. Mission Control non compare in questo elenco quando è in esecuzione.

Grazie in anticipo!

Edit:

ho finalmente lavorato intorno a questo problema (anche se non in modo molto soddisfacente). Per il mouse, risulta che è possibile interrogare lo stato dei pulsanti premuti con [NSEvent pressedMouseButtons]. Semplicemente tengo traccia di quello che penso debba essere lo stato del mouse dagli eventi NSLeftMouseDown e NSLeftouseUp e lo confrontiamo allo [NSEvent pressedMouseButtons] ogni tanto per assicurarci che siano coerenti. Se non lo sono, so che qualcosa ha dirottato il mio evento NSLeftouseUp e agire di conseguenza.

Per la tastiera, non sono riuscito a trovare un modo per interrogare lo stato della tastiera, quindi non è stato possibile eseguire una soluzione simile. Ho finito per disabilitare la commutazione delle applicazioni usando presentation options quando i tasti sono premuti.

+2

Dalla documentazione: "Gli eventi relativi alle chiavi possono essere monitorati solo se l'accessibilità è abilitata o se l'applicazione è attendibile per l'accesso all'accessibilità (vedere AXIsProcessTrusted)." - Questo è probabilmente il motivo per cui non ricevi eventi chiave. Abilitare "accesso per dispositivi assistivi" nelle preferenze di accessibilità del sistema e vedere se questo cambia qualcosa. – omz

+0

Hai ragione, abilitare l'accessibilità mi dà eventi chiave globali, ma non quando Controllo missione è attivo. –

+0

Ti consiglio di presentare una segnalazione di bug: developer.apple.com/bugreporter -Also, è meglio consentire ai sostenitori di inventare soluzioni piuttosto che chiedere qualcosa di specifico. Detto questo, il bug report dovrebbe solo identificare il problema in modo chiaro e conciso. – Bobjt

risposta

0

Forse mi manca qualcosa, ma hai provato a utilizzare i tocchi di evento invece del monitoraggio globale?

1

Hai provato a livello bash utilizzando NSTask? Qualcosa come ps -faxU <username> dovrebbe elencare tutti i processi in esecuzione e quindi si potrebbe analizzare l'output, o in effetti si potrebbe usare ps -faxU <username> | grep -i "mission control" (In cima alla mia testa non sono sicuro di come si possa chiamare il processo, ma come "controllo missione" sembra legittimo) . Forse non è la soluzione più elegante, ma se non funziona niente potrebbe valerne la pena.

+0

L'ho provato nel terminale. Sfortunatamente, il Controllo Missione esiste per un brevissimo tempo, perché tutto ciò che fa è inviare un messaggio mach al processo Dock (si veda [link] (http://macosxsecrects.blogspot.com/2012/06/notification-center-notification-system .html)), quindi non lo vedresti mai effettivamente attivo nell'elenco dei processi in esecuzione. L'ascolto delle notifiche di NSWorkspace che segnalano quando le applicazioni vengono visualizzate non ha mostrato alcuna traccia di Controllo Missione. Le altre opzioni su [questa pagina] (http://developer.apple.com/library/mac/#technotes/tn2050/_index.html) non erano praticabili per me per altri motivi. –

0

Sembra che DTrace abbia una certa capacità di vedere il controllo missione attivato.Prova a correre:

sudo fs_usage -filesys | grep Mission

dalla riga di comando e quindi avviare l'app Mission Control dalla cartella/Application.

Si dovrebbe vedere un sacco di output relativi all'avvio di Mission Control. Sfortunatamente, questo stesso output non è stato visualizzato usando la scorciatoia o lo scorrimento della tastiera. Ovviamente, usare DTrace nel codice di produzione non è qualcosa che consiglierei davvero.

2

Almeno in OS X 10.10, è possibile utilizzare questo codice per verificare se Mission Control è attivo o meno:

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 
} 

In poche parole, il codice verifica se una finestra specifica di proprietà del Dock di OS X processo è visibile sullo schermo e se si trova in una posizione specifica. Se entrambe le condizioni sono soddisfatte, Mission Control sarà attivo al momento. Il codice funziona in un'app sandbox e non sono richiesti privilegi per i dispositivi di assistenza.

+0

FWIW, questo non funziona esattamente per me in 10.11 (supponendo che abbia tradotto correttamente da Swift a Obj-C). Tuttavia, invocare il controllo missione comporta ulteriori voci con "Dock" come nome del proprietario, quindi potrebbe esserci un altro modo per analizzarle per capire se MC è sicuramente ciò che sta causando ciò. Devo lasciare il problema per ora, ma aggiornerò se lo capisco ... – Matt

Problemi correlati