tresf
tresf

Reputation: 7922

Detect dark windows taskbar

For theming purposes, I'm looking to detect the color of the Windows taskbar (in my case, for a tray icon).

I'm using Java, but any solutions are welcome as I'd happily convert them over as needed.

Assuming I don't want to rely on the white/black color of the Windows logo, is there a way to detect this?

Related:

Upvotes: 4

Views: 1633

Answers (3)

Daniel Gyorffy
Daniel Gyorffy

Reputation: 21

You can use the Windows Registry Value SystemUsesLightTheme that is available at this Registry Path: Software\Microsoft\Windows\CurrentVersion\Themes\Personalize for detecting the dark/light theme.

I found a library called JRegistry that allows you to access this value.

        RegistryKey windowsPersonalizeKey = new RegistryKey("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
        RegistryValue systemUsesLightThemeValue = windowsPersonalizeKey.getValue("SystemUsesLightTheme");
        if (systemUsesLightThemeValue != null) {
            //this value is available

            //getting the actual value
            byte[] data = systemUsesLightThemeValue.getByteData();
            byte actualValue = data[0];
            boolean windows10Dark = actualValue == 0;

            if (windows10Dark) {
               //the theme is dark
            } else {
                // the theme is light
            }
        }

Also, if you want to listen to this value dynamically:

        RegistryKey registryKey = new RegistryKey("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
        RegistryWatcher.addRegistryListener((RegistryEvent registryEvent) -> {
            RegistryKey changedKey = registryEvent.getKey();
            if (changedKey.equals(registryKey)) {
                RegistryValue value = changedKey.getValue("SystemUsesLightTheme");
                //....
            }
        });
        RegistryWatcher.watchKey(registryKey);

Upvotes: 2

tresf
tresf

Reputation: 7922

When the documented registry entries are missing, it appears something in the OS is coded to fallback the following settings:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize\

  • If AppsUseLightTheme is missing, assume it's 1
    • ... and then make the dark/light Windowing decisions based on this value.
  • If SystemUsesLightTheme is missing, assume it's 0
    • ... and then make the dark/light Taskbar/SystemTray decisions based on the this value.

The glory details...

Although fresh Windows Home installs defaults to the Light theme, these fresh installers also set the registry keys properly, so the combination of a missing registry key and a light taskbar is extremely unlikely (and probably impossible). To a similar point, studying modern OSs may -- improperly -- suggest the defaults come from the file C:\Windows\resources\Themes\aero.theme**, but don't be fooled! Older OSs didn't have a differentiating entry either... More below.

Instinct would suggest that the CurrentTheme or perhaps the InstallTheme registry values would serve as a sane fallback value, but changing these values appear to be for historical purposes and do not appear to actually change the light/dark theme.

reg query HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes /v InstallTheme
>>> returns the path to aero.theme

type %SystemRoot%\resources\Themes\aero.theme |find "SystemMode"
>>> returns SystemMode=dark

Even changing the InstallTheme for the entire machine (HKEY_LOCAL_MACHINE) doesn't modify this behavior of preferring SystemMode=dark (note, even this entry wasn't available in older Windows 10 versions. For example, Windows 10 v1507 doesn't have this entry in the theme file either).

Chasing the aero.theme hit some dead ends too. Attempts to directly modify aero.theme failed due to permissions, but copying aero.theme to the Desktop and changing SystemMode=dark to SystemMode=light and then double-clicking the theme file will make the taskbar go white, but only on newer Windows versions that supported the light theme.

So, yes, I have to agree with @strive-sun-msft the SystemUsesLightTheme registry entry is the best location. When testing, even the Task Bar itself monitors this, deleting it will reset it back to black. Unfortunately that fallback black Task Bar color remains to be a mystery. I can only assume it's hard-coded into the task bar itself.

Another workaround for this behavior is to just install the aero.theme file again by running it if the registry entries are missing. On newer Windows 10 versions, simply running this file will create the missing entries. Unfortunately, this doesn't work on older Windows 10 versions and worse, this will reset any custom preferences set by the user.

So the least intrusive way to detect the color of the taskbar is to read the registry and if the keys are missing, simply assume the theme Windows 10 shipped with is still in effect: Dark Taskbar, Light Windows.

Upvotes: 4

Strive Sun
Strive Sun

Reputation: 6299

So far, I have not encountered the lack of SystemUsesLightTheme and AppsUseLightTheme in the registry.

But I think recreating the key-values is worth trying.

Here is code sample(C++):

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <Windows.h>

using namespace std;


int main() {


    HKEY key;
    if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"), &key) != ERROR_SUCCESS)
    {
        cout << "unable to open registry";
    }

    DWORD value_data = 0;

    if (RegSetValueEx(key, TEXT("SystemUsesLightTheme"), 0, REG_DWORD, (const BYTE*)&value_data, sizeof(value_data)) != ERROR_SUCCESS)
    {
        RegCloseKey(key);
        cout << "Unable to set registry value value_name";
    }
    else
    {
        cout << "value_name was set" << endl;
    }

}

Upvotes: 3

Related Questions