2010-09-27 15 views
0

Ola, FolksCGEventCreateKeyboardEvent sur le bureau vs MacBook

Encore une fois, je veux boire de la piscine de connaissances partagées par des personnes utilisant SO.

J'ai écrit une petite application pour OSX qui envoie des événements clés à une application. Je cible OSX 10.5.x et plus récent. Cependant, le problème existe quand je construis pour 10.6.x aussi bien. Tout fonctionne bien sauf quand j'envoie seulement les touches de modification; Alt, Commande, Contrôle et Maj.

Le problème est que sur les deux MacBook, les événements pour les touches de modification semblent être effacés dès que les testeurs bougent le curseur en utilisant la souris ou touchent le pavé tactile.

Sur un bureau avec XCode installé, tout fonctionne correctement. Juste comme il le devrait. Sur deux MacBooks différents, le problème se produit. Le bureau dispose d'un clavier à 101 touches standard et d'une souris à plusieurs boutons.
Lorsqu'une souris est connectée aux MacBooks, une souris à deux boutons avec molette est utilisée. Cependant, le problème existe quand aucun périphérique n'est connecté et que le pavé tactile est utilisé. Ce que je prévois arriver, c'est que l'événement Modifier Key est envoyé à l'application cible, l'utilisateur déplace le curseur en utilisant la souris/pavé tactile, appuyez sur les boutons de la souris/touchpad et/ou appuyez sur les touches du clavier événement de touche de modification bas 'actif'. Puis, quand ils se terminent, l'événement clé vers le haut pour la touche de modification est envoyé.

Voici comment je vous envoie des événements clés vers le bas, la touche Maj enfoncée pour cet exemple:

case ModKeyShiftDown: 
    xEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate); 
    xTheCommand = CGEventCreateKeyboardEvent(xEventSource, kVK_Shift, true); 
    CGEventSetFlags(xTheCommand, kCGEventFlagMaskAlternate); 
    CGEventPost(kCGHIDEventTap, xTheCommand); 
    //CGEventPost(kCGSessionEventTap, xTheCommand); 
    //CGEventPost(kCGAnnotatedSessionEventTap, xTheCommand); 
    CFRelease(xTheCommand); 
    CFRelease(xEventSource); 
break; 

J'ai utilisé les trois drapeaux pour créer la source d'événements (kCGEventSourceStatePrivate, kCGEventSourceStateCombinedSessionState et kCGEventSourceStateHIDSystemState).

J'ai essayé de créer l'événement de clavier avec la source d'événement ainsi que null comme premier paramètre.

J'ai essayé avec et sans les indicateurs appropriés sur l'événement.

J'ai essayé différentes combinaisons d'affichage de l'événement; kCGHIDEventTap, kCGSessionEventTap et kCGAnnotatedSessionEventTap.

Pour être complet, voici comment j'envoie un événement pour la touche Maj:

case ModKeyShiftUp: 
    xEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate); 
    xTheCommand = CGEventCreateKeyboardEvent(xEventSource, kVK_Shift, false); 
    CGEventSetFlags(xTheCommand, 0); 
    CGEventPost(kCGHIDEventTap, xTheCommand); 
    //CGEventPost(kCGSessionEventTap, xTheCommand); 
    //CGEventPost(kCGAnnotatedSessionEventTap, xTheCommand); 
    CFRelease(xTheCommand); 
    CFRelease(xEventSource); 
break; 

Lorsque les testeurs déclenchent une touche de modification vers le bas événement, ils peuvent voir le changement du curseur comme prévu. Cela me permet de savoir que l'événement est en cours de traitement par l'application cible. Cependant, dès qu'ils touchent la souris ou le pavé tactile, le curseur revient à un curseur standard et les événements de la souris sont traités comme si aucun événement de touche de modification n'était actif.

Je voudrais savoir s'il y a un problème avec la façon dont j'envoie les événements. J'aimerais aussi savoir s'il existe un moyen alternatif d'envoyer des événements clés de modification qui vont fonctionner.

Désolé si je l'ai dépassé. Mon excuse est que je n'ai dormi que quelques heures.: P

Thanx

-isdi-

Répondre

0

Ola,

Il est intéressant, en utilisant AXUIElementRef et AXUIElementPostKeyboardEvent semblent fonctionner. Pour quelque raison que ce soit, l'envoi d'événements clés à l'aide de l'objet Accessibilité et de la méthode ci-dessus résout le problème pour les testeurs.