Reputation: 199
I am currently writing a piece of code which uses an event tap. It is working as it should, but I've got a few questions about some options that are not very well documented or that I'm not sure to understand 100% well. Most often when explained, the event tap procedures are quite given as "just do that" but with no further explanations, and I noticed some different possibilities, and the apple developer doc didn't enlighten me very much (so it's either too little or too much info at a time)... So :
CFMachPortRef machPortRef = CGEventTapCreate(kCGSessionEventTap, kCGTailAppendEventTap, kCGEventTapOptionDefault, kCGEventMaskForAllEvents, eventTapCallback, NULL);
First line, no problem all is pretty clear.
//// -----> kCFAllocatorDefault or NULL ???
CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, machPortRef, 0);
1) Here, I always saw that you should put kCFAllocatorDefault
, but all the doc states is "The allocator to use to allocate memory for the new object. Pass NULL or kCFAllocatorDefault to use the current default allocator."
So not being familiar with those allocators or other crocodiles, why would we pass NULL
??? I suppose NULL
isn't a very efficient allocator... (that's quite a bonus question, just curiosity).
//// -----> CFRunLoopGetMain() or CFRunLoopGetCurrent() ???
CFRunLoopRef runLoop = CFRunLoopGetMain();
//CFRunLoopRef runLoop = CFRunLoopGetCurrent();
2) What's the difference between getting the main loop with CFRunLoopGetMain()
and the current loop with CFRunLoopGetCurrent()
??? Which one is the best to use in which case ???
//// -----> kCFRunLoopCommonModes or kCFRunLoopDefaultMode
CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopCommonModes);
//CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);
3) What's the difference between kCFRunLoopCommonModes
and kCFRunLoopDefaultMode
??? From what I understood, kCFRunLoopCommonModes
include the kCFRunLoopDefaultMode
. So when do you use one or the other ???
CGEventTapEnable(machPortRef, true);
Don't forget to activate your tap hehe.
Thanks a lot by advance. I think these deserve some clear and concise explanations, that would be a great help and time saver for people getting into event taps.
Upvotes: 1
Views: 1459
Reputation: 16660
1) It doesn't matter. By passing kCFAllocatorDefault
you explicitly select the default allocator, by passing NULL
you implicitly select the default allocator. The system will not use NULL
of course, but the default allocator.
Personally I make such things explicit, if I care about the default ("Yes, I need the default allocator") otherwise I use NULL ("Don't care, the system will do right.")
2) Every thread has a run loop attached. With CFRunLoopGetMain()
you get the run loop of the main thread, with CFRunLoopGetCurrent()
you get the run loop of the thread, your code is currently running on. This is the same, if your code runs in main thread, otherwise a different run loop.
The main run loop on the main thread is automatically started as the main thread is automatically run.
You can add additional threads (with their own run loops) to your process. Usually you do not want to use the thread's run loop, because you do longer computations or so in the additional (background) thread. But sometimes you need the run loop in this background threads, if something is handled via run loop, i. e. networking.
3) Add a timer to the main run loop in default mode that writes out something every second and enter the menu with your mouse. You will see the difference …
The sources added to the default mode are only dispatched, when the run loop is in default mode, that means – to make a long story short – when the application is in an unmodal state. For example the menu or "local run loop dispatching" while drag & drop is not done in the default mode.
Simply think of modes as a group of sources. Every source in a mode is only dispatched, if the run loop runs in that mode. So it is a kind of selection of sources.
Sources in the common run loop mode are special, because they always dispatched independently of the mode.
Upvotes: 2