Skip to content

Discussion: Dark mode for applications #41

@sylveon

Description

@sylveon

Discussion: Dark mode for applications

Currently, reliably detecting dark mode in Win32 applications requires either reading the registry or using undocumented methods from uxtheme.dll.

I strongly suggest to document those two existing methods:

  • ShouldAppsUseDarkMode:
    • This allows apps to detect whether the dark theme is used for apps.
    • Particularly useful to follow system settings, like Microsoft Edge and UWP-based apps do.
    • Changes to this can be detected by listening for WM_SETTINGCHANGE.
  • ShouldSystemUseDarkMode:
    • This allows apps to detect whether the taskbar, start menu and other system shell elements uses the dark theme or not.
    • Particularly useful for determining if a white or black notification area icon should be used. OneDrive already does this.
    • Changes to this can be detected by listening for WM_SETTINGCHANGE.

This will allow existing apps to easily implement dark theme support, and to follow system settings without relying on workarounds. A WinRT API should probably be exposed (the two settings and an event to listen for changes) as well, but some applications are already tentatively using those two APIs, so it would be the best case to document the Win32 APIs, as those won't have to do any significant work to adopt an official solution rather than an undocumented one (and, truth be told, they are much simpler to use than their WinRT counterparts, especially if your language doesn't have a WinRT projection available)

Also, there exists other APIs in uxtheme.dll which might be of interest for people transitioning to WinUI and/or XAML islands:

  • SetPreferredAppMode:
    • This allows apps to enable dark theme support for Win32 controls. This is notably used by Windows Explorer for its dark theme.
  • AllowDarkModeForWindow:
    • Once the app mode is set to AllowDark using the API above, it is a per-window opt-in.
    • Once this method is called, the Win32 controls in the window uses dark theme if the system dark theme is enabled, and automatically switches to light theme when the user changes their settings.
    • Note that some controls might need to have their theme manually set to DarkMode_Explorer for this to be effective
    • Dark mode ribbon can be opt-in with the window property UI_PKEY_DarkModeRibbon

Those methods are useful because when transitioning, it allows developers to use a dark theme for old controls and new controls alike, to get a somewhat consistent UI. Darkening Win32 or winforms controls manually is extremely hard to get right, and leveraging the work done in Windows Explorer would prevent a lot of misdirected attempts at dark theming Win32 controls.

EVEN MORE, there's an undocumented window attribute allowing dark mode title bars (DWMWA_USE_IMMERSIVE_DARK_MODE). This one was even used by the command prompt itself and openly on GitHub, before it got removed from the OSS version because it was internal (see microsoft/terminal@bc7eb96#diff-e26a93b2aa9fea92ebf24336c4fe6412L19-L22). No true dark mode comes without a dark titlebar, and customizing the titlebar is a complex endeavour that would be greatly simplified by the publication of this attribute.

All of the APIs mentioned have been added since the introduction of dark mode Explorer, and have proven to be stable or only very slightly modified, so I'm sad they are being kept private because it would allow so many apps to get a dark mode (light mode makes me cry 😢)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions