2017-06-17 4 views
0

Pour un projet multiplate-forme avec beaucoup de code hérité, mon application Cocoa utilise une seule NSWindow avec un NSView personnalisé qui capture tous les événements de la souris et dessine tous les détails graphiques de l'application.CFRunLoopRunInMode gèle récursivement la fenêtre principale

J'ai besoin de mettre en œuvre un comportement modal local et donc j'utiliser à l'intérieur du fil conducteur:

CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0,01, false);

dans une boucle locale. La fonction revient après 0,01 seconde comme prévu avec une valeur de kCFRunLoopRunTimedOut. Toutefois, les événements de la souris ne sont plus reçus par le NSView personnalisé pendant cette période et mon application semble donc figée (avec le curseur de la souris en couleur qui tourne).

Les événements de minuterie arrivent toujours au NSView personnalisé, mais pas les événements de souris.

Apple spécifie que cette fonction peut être appelée récursivement. Y at-il autre chose que je devrais faire pour que le NSView reçoive toujours les entrées de la souris de l'utilisateur?

+0

Placez un point d'arrêt sur la ligne qui appelle 'CFRunLoopRunInMode'. Lorsque le point d'arrêt est atteint, copiez la trace de la pile. Modifiez votre question et collez-la dans la trace de la pile. –

Répondre

1

La boucle d'événements est construite au-dessus d'une boucle d'exécution, mais c'est plus que cela. Exécuter simplement la boucle d'exécution n'est pas suffisant pour recevoir et gérer les événements.

Vous pouvez peut-être réaliser une partie de ce que vous essayez de faire en construisant une boucle autour de -[NSWindow nextEventMatchingMask:untilDate:inMode:dequeue:] et -sendEvent:, mais en réalité, votre objectif n'est pas clair. Si vous expliquez cela, il y a probablement des approches supérieures. Par exemple, si vous voulez présenter un dialogue modal, vous devez utiliser -[NSApplication runModalForWindow:].

+0

Merci Ken, en effet il fonctionne parfaitement comme prévu en utilisant simplement les deux lignes suivantes dans ma boucle locale: – Dominique

+0

'event = [mainWindow nextEventMatchingMask: NSUIntegerMax untilDate: [NSDate dateWithTimeIntervalSinceNow: 0.010] inMode: NSDefaultRunLoopMode dequeue: OUI]; if (event) [mainWindow sendEvent: event]; ' – Dominique

+0

Le principal problème auquel je suis confronté dans ce code hérité (300 000 lignes de code C++) est qu'il y a beaucoup de boucles" modales "toutes incluses dans leur fonction. La plupart de ces fonctions sont des gestionnaires spécifiques (mais assez complexes) d'une action utilisateur commençant par une souris, manipulant le flux de mouvements de la souris et ne quittant la fonction que sur l'événement de la souris. Refactoriser le code entier pour séparer le traitement de chaque action de la souris serait un gros travail et introduirait probablement des bogues dans une partie du code qui fonctionne bien, car ces interactions sont assez complexes. – Dominique