[quote]Cocoa exceptions are no longer logged to the console.
Workaround: none yet.
Note: Trying to prepare applications for Mojave are hard when things have changed, which causes a Cocoa Exception. This results in a function silently failing, with no pointers or indication why. You must manually step through code until you find the line it fails on, then do research to figure out why that line fails.[/quote]
This just bit me in a big way.
I was trying to work out the declares to detect Dark Mode, and used the following code:
#if TargetMacOS
function IsDarkMode() as boolean
// see https://developer.apple.com/documentation/appkit/nsappearance
Declare Function NSClassFromString Lib "Foundation" (classname As CFStringRef) As Ptr
Declare Function NSAppearanceCurrentApperance Lib "Foundation" Selector "currentAppearance:" (classname As Ptr) As Ptr
Declare Function NSAppearanceName Lib "Foundation" Selector "name:" (obj As Ptr) As CFStringRef
dim nsa as Ptr = NSClassFromString("NSAppearance")
dim currentAppearance as Ptr = NSAppearanceCurrentApperance(nsa)
if currentAppearance <> nil then
dim name as string = NSAppearanceName(currentAppearance)
if name = "NSAppearanceNameDarkAqua" then
return true
end if
end if
return false
#else
return false
#endif
end function
Looks good, right?
Except there are two flaws which are subtle but fatal.
Without fixing the flaws, this function dies silently mid-stream. And by “dies” I do not mean “crashes” or “throws an exception” - no. Instead, the thread just disappears. This is extremely hard to debug and very user unfriendly. Very non “Xojo” like.
Puzzle:
can anyone identify the flaws?
Questions:
can Xojo do something to prevent these types of errors from being so incredibly hard to find and fix?
You need to get the appearance from an Appearance compatible object (one that adheres to the Appearance protocol), mainly a window, or under Mojave, the application also.
Huh? My understanding of the appearance framework was that it only worked on the objects that it adhered to? At least that’s how I’ve been using it. Then again, I am more familiar with using it in 10.10 + to force my applications to have a dark theme.
p.s. If you use the right declares at the right time (i.e. right event) you don’t need to know which theme is being used, you’ll get the correct colors for the controls that the OS doesn’t auto update for you.
Without having checked the code completely: Two selectors are wrong. They must be
"currentAppearance" and "name"
(without the colons).
EDIT: Ive been searching console up and down and finally found a clue under the “devices” tab (Mojave 18A353d):
EDIT II: Below that message, I see two private errors listed marked “” (showing only the pid and thread ID), and further below
[quote]standard 10:45:28.905691 +0200 My Application.debug 27366555: RECEIVED OUT-OF-SEQUENCE NOTIFICATION: 191 vs 296, 512,
standard 10:45:30.639889 +0200 My Application.debug LSExceptions shared instance invalidated for timeout.[/quote]
Could that be a hint to the reason macOS does not show a crash window in this case?
[quote=399929:@Ulrich Bogun]Without having checked the code completely: Two selectors are wrong. They must be
“currentAppearance” and “name”
(without the colons).[/quote]
This is correct!
Weirdly, that doesn’t seem to matter - the corrected code works for me (in 10.12.6 and 10.14 beta 6 at least):
Public Function IsDarkMode() as boolean
#if TargetMacOS
// see https://developer.apple.com/documentation/appkit/nsappearance
Declare Function NSClassFromString Lib "Foundation" (classname As CFStringRef) As Ptr
Declare Function NSAppearanceCurrentApperance Lib "Foundation" Selector "currentAppearance" (classname As Ptr) As Ptr
Declare Function NSAppearanceName Lib "Foundation" Selector "name" (obj As Ptr) As CFStringRef
dim nsa as Ptr = NSClassFromString("NSAppearance")
dim currentAppearance as Ptr = NSAppearanceCurrentApperance(nsa)
if currentAppearance <> nil then
dim name as string = NSAppearanceName(currentAppearance)
if name = "NSAppearanceNameDarkAqua" then
return true
end if
end if
return false
#else
return false
#endif
End Function
Does Xojo or macOS have some sort of search function to find the function even if we provide the wrong framework?