Clayton Stanley
Clayton Stanley

Reputation: 7784

How to tell when actions triggered by a CGEvent have finished?

I am using CGEventPost() to programmatically post keyboard and mouse events. Those events will end up triggering other events/actions (e.g., certain windows become active, buttons are pressed, letters are entered in text fields). In order to synchronize threads, I would like to know when all of those events that were triggered by a specific CGEvent have finished processing.

All CGEventPost()s will end up acting on a single window of a single application.

EDIT:

Nielsbot's solution worked just fine. I ended up with a rough implementation of MCL's event-dispatch function for CCL. This function blocks until all current events in the Cocoa run process loop have finished executing. Since all keyboard and mouse events end up triggering actions that run on this thread, this approach works just fine.

My only worry with this is that the event-dispatch gets called 'before' the CGEvent triggers an action in the event loop, but my tests are currently showing that this is not happening. So I'm rolling with this solution for now.

Just FYSA, it seems to take a conservative 1ms for a posted event to hit the run loop, at least on my setup.

(defun event-dispatch ()
  (with-shadow (gui::queue-for-event-process
                 (lambda (f &key at-start)
                   (declare (ignore at-start)) 
                   (funcall fun-orig f :at-start nil))) 
    (gui::call-in-event-process (lambda () ()))))

Upvotes: 0

Views: 532

Answers (1)

nielsbot
nielsbot

Reputation: 16031

What about inserting a custom event type queue as a marker? Wait until that event triggers some of your own code--this might give good enough indication that all previous events posted by you have been handled...

Upvotes: 1

Related Questions