Florian Bach
Florian Bach

Reputation: 989

Detect OS dark mode in Python

I'm writing a small program in python with a GUI that I'm using tkinter for. What I'd like to do is add dark mode support to my program. Mac OS, Ubuntu (at least Gnome) and Windows 10 all have a system-wide setting for "dark mode" that'll make all programs automatically run with a dark theme.

But how do I check that settings (ideally, OS-independant) so my program knows if it needs to render light mode or dark mode? I found a bunch of libraries like darkdetect that'll handle this for MacOS, but I haven't found anything for Ubuntu and Windows 10.

I know that I can use stuff like ttkthemes to create a dark themed design for my program, but how do I know when to enable that? How can a python script running on Windows 10 or on Ubuntu 20.04 figure out if the user enabled the dark mode in the operating system settings?

Ideally I'm looking for a solution / code that'll work on all three operating systems, but if that's not possible (as I suspect) OS-dependant code would be fine as well. I just can't find proper examples for non-MacOS systems anywhere.

Upvotes: 20

Views: 9361

Answers (5)

Ganesh Iyer
Ganesh Iyer

Reputation: 1

app = QApplication(sys.argv)        

decide_theme(app.palette().base().color())

def decide_theme(color: QColor) -> None:
    theme: str = ""
    r, g, b, a = color.getRgb()
    hsp = math.sqrt((0.241 * r * r) + (0.691 * g * g) + (0.068 * b * b))
    if hsp > 127.5:
       theme = "light"
    else:
       theme = "dark"    

This works fine for me in Kde-Plasma.

Upvotes: -1

VoteCoffee
VoteCoffee

Reputation: 5117

I was going to create my own universal function but it looks like someone already made a nice package for all OS: https://pypi.org/project/darkdetect/

import darkdetect

darkdetect.theme()
# Returns 'Dark'

darkdetect.isDark()
# Returns True

darkdetect.isLight()
# Returns False

Upvotes: 6

Arn
Arn

Reputation: 2015

On Gnome the dark mode switch is theme-dependent. The following function should work on default themes in Ubuntu 20.04:

import subprocess


def detectDarkModeGnome():
    '''Detects dark mode in GNOME'''
    getArgs = ['gsettings', 'get', 'org.gnome.desktop.interface', 'gtk-theme']

    currentTheme = subprocess.run(
        getArgs, capture_output=True
    ).stdout.decode("utf-8").strip().strip("'")

    darkIndicator = '-dark'
    if currentTheme.endswith(darkIndicator):
        return True
    return False

Upvotes: 2

Saad
Saad

Reputation: 3430

On macOS, the Dark/Light mode comes under appearance which can be checked by running a simple command defaults read -g AppleInterfaceStyle on the terminal.

  • On Dark mode the command returns

    Dark
    

    It'll just return Dark meaning AppleInterfaceStyle exist.

  • On Light mode the same command returns

    2020-12-18 17:44:21.870 defaults[20253:5665627] 
    The domain/default pair of (kCFPreferencesAnyApplication, AppleInterfaceStyle) does not exist
    

    By default light mode is enabled so AppleInterfaceStyle doesn't exist and that's why it is returning an error.


We can simply make a function which will return True if the Dark mode is enabled and False if the Light mode is enabled.

import subprocess

def check_appearance():
    """Checks DARK/LIGHT mode of macos."""
    cmd = 'defaults read -g AppleInterfaceStyle'
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE, shell=True)
    return bool(p.communicate()[0])

Upvotes: 9

Maximilian Peters
Maximilian Peters

Reputation: 31739

Quick answer for Windows 10

def detect_darkmode_in_windows(): 
    try:
        import winreg
    except ImportError:
        return False
    registry = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
    reg_keypath = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize'
    try:
        reg_key = winreg.OpenKey(registry, reg_keypath)
    except FileNotFoundError:
        return False

    for i in range(1024):
        try:
            value_name, value, _ = winreg.EnumValue(reg_key, i)
            if value_name == 'AppsUseLightTheme':
                return value == 0
        except OSError:
            break
    return False
  • It checks if winreg can be imported, if not you are probably not using Windows
  • The relevant registry key is searched, if not found, it is assumed that dark mode is not enabled
  • If the registry key is present and the value is set to 0, dark mode is set

Upvotes: 10

Related Questions