osx_app_in_plain_c
osx_app_in_plain_c copied to clipboard
Fixes for menu not being accessible and crash on macbookpro with touchbar
Menu not being accessible is due to creating the menu where some API stuff is not yet ready at the MacOS OS level. Some people suggested to do some dirty hacks to avoid this "bug", but what worked reliably to me is to create the menu and to bring up the window after the applicationDidFinishLaunching event on the application delegate:
Check this (kotlin port using JNA of your code): https://github.com/soywiz/jna-cocoa/blob/e2e55d271644da30a995e5c0a747377e66536d51/src/main/kotlin/HelloJna.kt#L26
It seems that new macbok pros with touchbar have consistent crashes with this code (trying to conform protocol). After struggling a lot, we found that you missed calling the objc_registerClassPair function for each objc_allocateClassPair. I solved it here:
https://github.com/soywiz/jna-cocoa/blob/e2e55d271644da30a995e5c0a747377e66536d51/src/main/kotlin/Cocoa.kt#L98
In my case I'm allocating the class pairs, then adding the methods and then calling the objc_registerClassPair to somehow finalize the class definition.
It happens on macbookprops with touchbar only since normal apple computers doesn't do anything reflective with your app/app delegates/window delegates, but when there is touchbar it seems that there is a new protocol, and that the app itself check if your app is implementing that protocol to determine whether to call it or not, and crashing with class_conformsToProtocol because the class is not fully finalized/available to other processes or whatever.
More info about the crash here: https://github.com/korlibs/korge/issues/48
Hope it helps other people!
I am running into the same issue. Here's the stack trace:
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x44)
frame #0: 0x00007fff6a71ee05 libobjc.A.dylib`class_conformsToProtocol + 313
libobjc.A.dylib`class_conformsToProtocol:
-> 0x7fff6a71ee05 <+313>: testl %eax, 0x44(%rbx)
0x7fff6a71ee08 <+316>: jne 0x7fff6a71ee1b ; <+335>
0x7fff6a71ee0a <+318>: movq 0x8(%rbx), %rdi
0x7fff6a71ee0e <+322>: callq 0x7fff6a717a28 ; getProtocol(char const*)
Target 2: (cyan_debug) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x44)
* frame #0: 0x00007fff6a71ee05 libobjc.A.dylib`class_conformsToProtocol + 313
frame #1: 0x00007fff6a71eca2 libobjc.A.dylib`-[NSObject conformsToProtocol:] + 47
frame #2: 0x00007fff2f195301 AppKit`-[NSApplication(NSTouchBarFinder) NS_touchBarProviders] + 403
frame #3: 0x00007fff2f19632d AppKit`_NSTouchBarFinderGatherProvidersForContainer + 64
frame #4: 0x00007fff2f19645f AppKit`_NSTouchBarFinderGatherProvidersForContainer + 370
frame #5: 0x00007fff2f19645f AppKit`_NSTouchBarFinderGatherProvidersForContainer + 370
frame #6: 0x00007fff2f19599d AppKit`___NSTouchBarFinderSetNeedsUpdateOnMain_block_invoke + 240
frame #7: 0x00007fff2f196268 AppKit`___NSRunLoopObserverCreateWithHandler_block_invoke + 41
frame #8: 0x00007fff3185e335 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
frame #9: 0x00007fff3185e267 CoreFoundation`__CFRunLoopDoObservers + 457
frame #10: 0x00007fff3185ce79 CoreFoundation`CFRunLoopRunSpecific + 521
frame #11: 0x00007fff30489abd HIToolbox`RunCurrentEventLoopInMode + 292
frame #12: 0x00007fff304896f4 HIToolbox`ReceiveNextEventCommon + 359
frame #13: 0x00007fff30489579 HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 64
frame #14: 0x00007fff2eacf039 AppKit`_DPSNextEvent + 883
frame #15: 0x00007fff2eacd880 AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
It seems like deferring the menu creation until applicationDidFinishLaunching may be a bit of a hack. @soywiz - did adding all the missing objc_registerClassPairs (for each objc_allocateClassPair) fix the issue? Or was the only way to fix this to defer menu creation until after the application finished launching? Would be great to figure out exactly how to fix for the C source