Force Dark Mode TextArea to Light Mode?

I’m finding TextArea text-color selection to be particularly confusing for users in Dark Mode.

Although I am supporting DarkMode, I want my users to edit particular TextAreas with DarkMode suspended so they can easily see the effect of text-color selections as they will appear on the printed page.

I’ve been searching but I can’t seem to find it. Am I overlooking something obvious, or is this not possible?

You can use declares to set an appearance on the TextArea. Appearances are inherited, so an NSView gets the appearance of it’s parent unless it has on explicitly assigned.

This code in the open event of a textarea will keep it in “Aqua” regardless of the window’s appearance.

[code]#if TargetMacOS
declare function appearanceNamed lib “Cocoa” selector “appearanceNamed:” (obj as ptr, name as CFStringRef) as ptr
Declare Sub setAppearance lib “Cocoa” selector “setAppearance:” (obj_ref as ptr,value as ptr)
declare function NSClassFromString lib “Cocoa” (className as CFStringRef) as ptr

setAppearance(ptr(me.Handle),appearanceNamed(NSClassFromString(“NSAppearance”),“NSAppearanceNameAqua”))
#endif[/code]

Likewise, you can also pass nil to re-enable dark mode for a control:

setAppearance(ptr(me.Handle),nil)

Wow. Thanks, Jim. That works!

But I still think Xojo should add a SupportsDarkMode property to textAreas and TextFields. Xojo users should not have to resort to declares to get this functionality. I will enter a feature request.

Once again, this Xojo community is priceless.

Its more unusual to have part of the app opt in and part opt out (or some controls opt in and some not) which is where you need to resort to declares

[quote=430069:@jim mckay]You can use declares to set an appearance on the TextArea. Appearances are inherited, so an NSView gets the appearance of it’s parent unless it has on explicitly assigned.

This code in the open event of a textarea will keep it in “Aqua” regardless of the window’s appearance.

[code]#if TargetMacOS
declare function appearanceNamed lib “Cocoa” selector “appearanceNamed:” (obj as ptr, name as CFStringRef) as ptr
Declare Sub setAppearance lib “Cocoa” selector “setAppearance:” (obj_ref as ptr,value as ptr)
declare function NSClassFromString lib “Cocoa” (className as CFStringRef) as ptr

setAppearance(ptr(me.Handle),appearanceNamed(NSClassFromString(“NSAppearance”),“NSAppearanceNameAqua”))
#endif[/code][/quote]
You might want to check the return values of those things instead of chaining them together like that as an older OS may return Nil for one or more of those.

True it is good to check for nil, but NSAppearance and NSAppearanceNameAqua are available on 10.9+ and any other name will return nil and have no effect. So it’s only an issue if you’re building with a pre 2017 Xojo and a user is running something pre 10.9.

Really, the problem would be with NSAppearance not being defined in 10.8.x.

Here’s an update using extends with a check for NSAppearance for the old school folks:

[code]Public Sub DisableDarkMode(extends c as RectControl)
#if TargetMacOS
Declare function appearanceNamed lib “AppKit” selector “appearanceNamed:” (obj as ptr, name as CFStringRef) as ptr
Declare Sub setAppearance lib “AppKit” selector “setAppearance:” (obj_ref as ptr,value as ptr)
Declare function NSClassFromString lib “AppKit” (className as CFStringRef) as ptr

dim NSAppearance as ptr=NSClassFromString("NSAppearance")
if NSAppearance<>nil then
  setAppearance(ptr(c.Handle),appearanceNamed(NSAppearance,"NSAppearanceNameAqua"))
end if

#endif
End Sub
[/code]

This also works to disable dark mode on a window btw.