Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dark Mode under Windows #197

Open
rfindler opened this issue Jul 16, 2020 · 11 comments
Open

Dark Mode under Windows #197

rfindler opened this issue Jul 16, 2020 · 11 comments

Comments

@rfindler
Copy link
Member

The OS-drawn controls aren't working properly when DrRacket is in dark mode.

This issue was created by culling the specific comments from racket/drracket#235.

@jcolivo wrote

Hello Racket Team,
I appreciate all the hard work on trying to improve the dark mode in DrRacket. Thank you.

Just hoping that you won't forget us Windows users. ;-)
My issues are as pointed out in this thread: https://groups.google.com/forum/#!topic/racket-dev/xYjE9JCe9u0

If there is anything I can do to help (I'm not a programmer, but can certainly help with testing), please let me know.

Have a wonderful weekend!

@alex-hhh wrote

The registry key AppsUseLightTheme in
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize,
will be 1 or missing if applications use the "light" theme and will be 0 if
the applications should use a dark theme.

I verified that AppsUseLightTheme changes to 0 if I select "dark" mode in
my preferences on my Windows 10 machine. The key is missing if "Dark" mode
was never selected on a machine.

white-on-black-panel-scheme? could just look for this key on Windows?

Source:
https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application

@mflatt wrote:

More ideas for dark mode on Windows based on various undocumented flags and functions: mflatt/gui@fd38e76

Last time I looked at this, I concluded that system Win32 control classes like buttons or checkboxes (I forget which, but I think it was buttons) don't support dark mode.

@jcolivo wrote

I found the Windows Registry Key as @default-kramer mentioned above referencing the StackOverflow thread:
https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application

If you want the "Choose your default app mode" setting, I'm pretty sure that I can find it in the Windows registry somewhere. (In fact, this looks like it: https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application) I can try to make a PR for mrlib if this is the desired behavior. I don't have any older versions of Windows handy, so it will likely support Win10 only.

On my system (64 bit Windows 10, latest version), I verified the location of the registry key:
Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize

This is a screenshot of the key when light theme is chosen. Notice the ApsUseLightTheme value set at 0x00000001 (1)
Light Theme On

This is a screenshot of the key when dark theme is chosen. Notice the ApsUseLightTheme value now set at 0x00000000 (0)
Light Theme Off

Would this feature require Racket code to look for this specific registry key value, or would the code be written at a lower level?

@alex-hhh
Copy link
Contributor

I switched my Windows machine to Dark mode, and only some of the applications changed to Dark mode. In particular, most of the Windows tools, such as control panel property boxes remained to the default "light" mode.

I suspect the registry setting and the windows message about the mode change is more an "advisory" setting. Applications built on .Net technologies will use it because the .Net libraries use it, but the Win32 controls don't. As such, if DrRacket (and the Racket GUI library) would like to implement Dark mode, it would either have to change to use the .Net GUI libraries, or do their own drawing of controls such as buttons, and consult the registry to determine if dark mode is enabled or not.

@samusz
Copy link

samusz commented Nov 13, 2021

Dark mode in the preferences of DrRacket may be the easy route to go ?

@rfindler
Copy link
Member Author

It looks like there has been some movement in the Windows API documentation related to dark mode. Here's an article from the end of 2022: Support Dark and Light themes in Win32 apps.

Currently the get-label-{background,foreground}-color functions are implemented using GetSysColor and the results do not seem to change when changing my Windows 10 VM into dark mode as described here.

The article above seems to suggest using UISettings.GetColorValue(UIColorType::Foreground) but I don't know how to make that call from our FFI. This seems to be the docs for UISettings.GetColorValue. Does anyone know how to call that function and get its value back into Racketdom?

@DexterLagan
Copy link

Would that be helpful?
Ref: https://learn.microsoft.com/en-us/answers/questions/715081/how-to-detect-windows-dark-mode

It depends on Windows versions
On recent OS (>= Windows 10 1903) :

    [DllImport("UXTheme.dll", SetLastError = true, EntryPoint = "#138")] 
    public static extern bool ShouldSystemUseDarkMode();

test :

    bool bRet = ShouldSystemUseDarkMode();

@DexterLagan
Copy link

Another uglier option: wrapping around PowerShell. I found this, but it doesn't work on my system. Maybe there's a way:

(New-Object Windows.UI.ViewManagement.UISettings).GetColorValue("background")

Ref: https://stackoverflow.com/questions/38734615/how-can-i-detect-windows-10-light-dark-mode

@DexterLagan
Copy link

Also, according to this, Visual Styles have to be enabled for GetThemeSysColor to work.

Ref: https://stackoverflow.com/questions/63159666/get-windows-10-theme-color-in-classic-c-winapi-win32-application

@DexterLagan
Copy link

Found the header file for the windows.ui.viewmanagement class for accessing UISettings, but for WinRT.
Maybe these constants can help us with the FFI?
Ref: https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/winrt/windows.ui.viewmanagement.h

@DexterLagan
Copy link

Here's a hack that uses an undocumented dark mode API introduced in Windows 10 1809: https://github.com/ysc3839/win32-darkmode
I wouldn't use it, but it's a start?

@DexterLagan
Copy link

Another example in low(er) level C, using uxtheme.dll:
https://github.com/ysc3839/VCMPBrowser/blob/darkmode/DarkMode.h

Cheers

@LiberalArtist
Copy link
Contributor

I was reminded of this by a Discourse thread. I haven't thought about this in the last year, but I'll consolidate thoughts I had then into this issue.

In #293 (comment) I wrote:

On Windows, the de facto way seems to be using RegNotifyChangeKeyValue to detect changes to the AppsUseLightTheme value of HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize (which may not exist).

In #293 (comment) I wrote:

I've looked into windows (and there is an issue discussing it somewhere, I think) and the OS doesn't seem to provide a way to detect the theme.

That's my understanding, too, as far as detecting the theme. There's a Microsoft article recommending basically the same strategy white-on-black-panel-scheme? uses, but using a Windows-specific API. The registry key I mentioned is undocumented, but seems to be used by a number of projects, like Chromium, to detect changes to the theme.

@racket-discourse-github-bot

This issue has been mentioned on Racket Discourse. There might be relevant details there:

https://racket.discourse.group/t/scope-and-purpose-of-racket-gui/2965/2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants