Related to this other question: I have the need to gather information about what is the current active application, on macOS.
The linked QA answer provide a mechanism to get alerted (event) when the active application changes, but it crashes when run on a separated thread:
FocusDetector::AppFocus focus;
focus.run();
//std::thread threadListener(&FocusDetector::AppFocus::run, &focus); //Does not works
//if (threadListener.joinable())
//{
// threadListener.join();
//}
.
*** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /xxxxxxx/NSUndoManager.m:363
2020-11-24 08:54:41.758 focus_detection[81935:18248374] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff3006cb57 __exceptionPreprocess + 250
1 libobjc.A.dylib 0x00007fff68eb35bf objc_exception_throw + 48
2 CoreFoundation 0x00007fff30095d08 +[NSException raise:format:arguments:] + 88
3 Foundation 0x00007fff32787e9d -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
4 Foundation 0x00007fff326c45ee +[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 440
5 AppKit 0x00007fff2d25165c -[NSApplication run] + 864
6 focus_detection 0x0000000104b1a010 _ZN13FocusDetector8AppFocus3runEv + 128
7 focus_detection 0x0000000104b19547 _ZNSt3__1L8__invokeIMN13FocusDetector8AppFocusEFvvEPS2_JEvEEDTcldsdeclsr3std3__1E7forwardIT0_Efp0_Efp_spclsr3std3__1E7forwardIT1_Efp1_EEEOT_OS6_DpOS7_ + 119
8 focus_detection 0x0000000104b1944e _ZNSt3__1L16__thread_executeINS_10unique_ptrINS_15__thread_structENS_14default_deleteIS2_EEEEMN13FocusDetector8AppFocusEFvvEJPS7_EJLm2EEEEvRNS_5tupleIJT_T0_DpT1_EEENS_15__tuple_indicesIJXspT2_EEEE + 62
9 focus_detection 0x0000000104b18c66 _ZNSt3__114__thread_proxyINS_5tupleIJNS_10unique_ptrINS_15__thread_structENS_14default_deleteIS3_EEEEMN13FocusDetector8AppFocusEFvvEPS8_EEEEEPvSD_ + 118
10 libsystem_pthread.dylib 0x00007fff6a260109 _pthread_start + 148
11 libsystem_pthread.dylib 0x00007fff6a25bb8b thread_start + 15
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Abort trap: 6
This is obviously related with NSApplication
, for which the documentation state:
Every app uses a single instance of NSApplication to control the main event loop
In consequence, I am looking for another way to listen on events, which is not restricted to the main event-loop ( or main thread.
Intuitively, it should be possible to get information about the current application with focus, in a separated thread.
I have no idea how to approach this problem, sorry for not providing much research. I did researched on internet for "NSNotification not in main thread" and other similar sentences, but without success.
Question:
How to listen on activeAppDidChange
NSNotification outside the main thread?
Just proof you can receive Notifications on Threads that are not mainThread.
and instance and starting is done like..
stopping
So as looptime is set to 1 sec it will check each second if the last received bundleIdentifier was changed. You could extend the
-(void)mimi:
method by checking if the bundleIdentifier differs from[[NSBundle mainBundle] bundleIdentifier]
to know if you became active yourself and ignore that when needed.Edit from Apple Docs