Dark theme in context menus after update

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Dark theme in context menus after update

Postby digory » Wed Jun 28, 2023 2:34 am

I updated from CEF 101.0.18+g367b4a0 to CEF 114.2.11+g87c8807, and now all context menus through our applications are in a dark theme. This happens before an actual browser window is opened, so I suspect CefInitialize does this. Our application uses a light theme throughout, so this is not acceptable. I searched MSDN for a way how to set the theme for the entire app, but I could not find anything. Also, I could not find any related preference value in CefSettings or CefBrowserSettings. How to bring the light theme back?
digory
Expert
 
Posts: 118
Joined: Wed Oct 26, 2016 3:13 am

Re: Dark theme in context menus after update

Postby magreenblatt » Wed Jun 28, 2023 2:51 am

What OS? Is the OS configured to use dark theme? What CEF runtime mode (Alloy or Chrome)? If Alloy, are you using the Views framework?
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: Dark theme in context menus after update

Postby digory » Wed Jun 28, 2023 4:15 am

It's C++ CEF, Windows platform. Not sure about runtime mode, but I guess it's Chrome (we see the typical Chrome subprocesses such as gpu and renderer).

Yes, Windows is configured to use dark mode. Our application, however, doesn't care and it always in light mode.
digory
Expert
 
Posts: 118
Joined: Wed Oct 26, 2016 3:13 am

Re: Dark theme in context menus after update

Postby magreenblatt » Wed Jun 28, 2023 4:23 am

You can try Chromium's "--disable-features=DarkMode" command-line switch. If that doesn't work then we'll need to implement something specific for CEF, and you can add a new issue (feature request) at https://github.com/chromiumembedded/cef/issues.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: Dark theme in context menus after update

Postby digory » Wed Jun 28, 2023 4:31 am

Where would I set this switch? The following did not work:

Code: Select all
void KisCefBrowserProcessHandler::OnBeforeChildProcessLaunch(CefRefPtr<CefCommandLine> cmdLine) {
   cmdLine->AppendSwitchWithValue("disable-features", "DarkMode");
}
digory
Expert
 
Posts: 118
Joined: Wed Oct 26, 2016 3:13 am

Re: Dark theme in context menus after update

Postby magreenblatt » Wed Jun 28, 2023 4:32 am

Another currently available option is to implement the context menus using JavaScript instead of using the default native menus.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: Dark theme in context menus after update

Postby magreenblatt » Wed Jun 28, 2023 4:41 am

Where would I set this switch?

Try setting it from the command-line first. If that works, then you can set it in OnBeforeCommandLineProcessing using AppendSwitchWithValue. When using OnBeforeCommandLineProcessing you also need to set the default disabled features for your CEF version (check the existing “Command Line” by loading chrome://version in CEF).
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: Dark theme in context menus after update

Postby digory » Wed Jun 28, 2023 4:55 am

Our application does not allow setting CEF arguments from command line. (We suppress this somewhere.) But we already use OnBeforeCommandLineProcessing. I added cmdLine->AppendSwitchWithValue("disable-features", "DarkMode") there, but it still doesn't work.

Actually, it isn't important that dark mode be disabled inside CEF. What bothers me is that CEF's/Chrome's decision to use the dark theme somehow affects our entire application. There must be some Win32 API involved that sets the theme. I guess I could simply set it back after CefInitialize if I knew what API to call. I'm currently searching Chromium sources, there's ui/native_theme, but I haven't found the piece of code yet that sets the application theme. Unfortunately, I can't step into cef_initialize from debugger, I'm looking into that, too.
digory
Expert
 
Posts: 118
Joined: Wed Oct 26, 2016 3:13 am

Re: Dark theme in context menus after update

Postby digory » Wed Jun 28, 2023 7:49 am

magreenblatt wrote:Another currently available option is to implement the context menus using JavaScript instead of using the default native menus.

This isn't an option for us, because CEF only renders part of our application. The vast majority of forms and dialogs are implemented in C++ and a proprietary scripting language. The transition between CEF/JavaScript and the legacy forms is not visible to users, so context menus in JavaScript should look exactly the same as those that come from the native part.
digory
Expert
 
Posts: 118
Joined: Wed Oct 26, 2016 3:13 am

Re: Dark theme in context menus after update

Postby digory » Thu Jun 29, 2023 1:30 am

I found a hack that restores the light mode. If I call this right after CefInitialize, light mode is back:

Code: Select all
    // Code was taken from https://github.com/komiyamma/win32-darkmode
    void restoreLightMode()
    {
       enum class PreferredAppMode { Default, AllowDark, ForceDark, ForceLight };
       using fnRtlGetNtVersionNumbers = void (WINAPI *)(LPDWORD major, LPDWORD minor, LPDWORD build);
       using fnAllowDarkModeForApp = bool (WINAPI *)(bool allow); // ordinal 135, in 1809
       using fnSetPreferredAppMode = PreferredAppMode(WINAPI *)(PreferredAppMode appMode); // ordinal 135, in 1903
       auto hNTDLL = GetModuleHandleW(L"ntdll.dll");
   
       if (hNTDLL)
       {
          auto RtlGetNtVersionNumbers = reinterpret_cast<fnRtlGetNtVersionNumbers>(GetProcAddress(hNTDLL, "RtlGetNtVersionNumbers"));
   
          if (RtlGetNtVersionNumbers)
          {
             DWORD major, minor, buildNumber;
             RtlGetNtVersionNumbers(&major, &minor, &buildNumber);
             buildNumber &= ~0xF0000000;
   
             if (major >= 10 && (
                buildNumber == 17763 || // 1809
                buildNumber == 18362 || // 1903
                buildNumber == 18363 || // 1909
                buildNumber == 19041 || // 2004
                buildNumber >= 19042 // over 2009
                ))
             {
                HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
   
                if (hUxtheme)
                {
                   auto ord135 = GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135));
   
                   if (buildNumber < 18362)
                   {
                      auto AllowDarkModeForApp = reinterpret_cast<fnAllowDarkModeForApp>(ord135);
                      AllowDarkModeForApp(false);
                   }
                   else
                   {
                      auto SetPreferredAppMode = reinterpret_cast<fnSetPreferredAppMode>(ord135);
                      SetPreferredAppMode(PreferredAppMode::ForceLight);
                   }
                }
             }
          }
       }
    }


I really wish there was a better way to do it, because this is ugly, it uses undocumented Windows API, which may break at any time!
digory
Expert
 
Posts: 118
Joined: Wed Oct 26, 2016 3:13 am

Next

Return to Support Forum

Who is online

Users browsing this forum: No registered users and 195 guests