B4J Question Detect OSX Dark Mode?

Chris Lee

Member
Licensed User
One of the new features in OSX Mojave is dark mode, which allows the user to pick either the traditional light theme, or select a dark theme system wide.

I know how to theme the interface, but i'm wondering if its possible to detect if the user has dark mode enabled?

From research I found this article

https://stackoverflow.com/questions/33477294/menubar-icon-for-dark-mode-on-os-x-in-java/33477375

This suggests using inline java code might work. Although this appears to be executing an external process which might bring other issues.
I can't get this working, but i have only limited knowledge on running inline Java.
Anyone know how I might check if dark or light is selected?


B4X:
private boolean isMacMenuBarDarkMode() {
    try {
        // check for exit status only. Once there are more modes than "dark" and "default", we might need to analyze string contents..
        final Process proc = Runtime.getRuntime().exec(new String[] {"defaults", "read", "-g", "AppleInterfaceStyle"});
        proc.waitFor(100, TimeUnit.MILLISECONDS);
        return proc.exitValue() == 0;
    } catch (IOException | InterruptedException | IllegalThreadStateException ex) {
        // IllegalThreadStateException thrown by proc.exitValue(), if process didn't terminate
        LOG.warn("Could not determine, whether 'dark mode' is being used. Falling back to default (light) mode.");
        return false;
    }
}
 

moster67

Expert
Licensed User
Had a look at your code. You're probably missing some imports
B4X:
import java.io.IOException;
import java.util.concurrent.TimeUnit;

but the post goes back to 2016 and I am not sure if that code would still work today.

Found this command:
B4X:
defaults read -g AppleInterfaceStyle
If I run it from a terminal prompt, I get the result "Dark" which is correct since I am using dark mode.

upload_2018-12-27_1-2-33.png


Perhaps if you use the jShell library, you can run the command and get the result.
You could use the DetectOS snippet to determine the OS the app is running on so you can decide whether to run the command or not.
 
Last edited:
Upvote 0

Erel

Administrator
Staff member
Licensed User
Don't use inline code for this. Use jShell. BTW, starting a process on the main thread is a bad practice.

B4X:
Private Sub IsMacMenuBarDarkMode As ResumableSub
   Dim shl As Shell
   shl.Initialize("shl", "defaults", Array("read", "-g", "AppleInterfaceStyle"))
   shl.Run(-1)
   Wait For shl_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
   Return ExitCode = 0
End Sub

Usage:
B4X:
Wait For (IsMacMenuBarDarkMode) Complete (DarkMode As Boolean)
Log(DarkMode)
 
Upvote 0
Top