FlatLaf icon indicating copy to clipboard operation
FlatLaf copied to clipboard

Windows: update native window prefs for dark mode

Open Numerok opened this issue 3 months ago • 2 comments

	private static void updateNativeWindowPrefs(boolean dark, Window frame) {
		WinUser.HWND hwnd = new WinUser.HWND(Native.getWindowPointer(frame));

		User32Ex.INSTANCE.SetWindowPos(hwnd, hwnd, 0, 0, 0, 0, WinUser.SWP_NOMOVE | WinUser.SWP_NOSIZE | WinUser.SWP_NOZORDER | WinUser.SWP_FRAMECHANGED);

		WinUser.HMODULE hModule = Kernel32.INSTANCE.GetModuleHandle("uxtheme.dll");
		Function function = Function.getFunction(Kernel32.INSTANCE.GetProcAddress(hModule, 133));//AllowDarkModeForWindow
		function.invoke(new Object[] { hwnd, new WinUser.BOOL(dark) });

		function = Function.getFunction(Kernel32.INSTANCE.GetProcAddress(hModule, 135));//SetPreferredAppMode
		function.invoke(new Object[] { new WinUser.DWORD(dark ? 2 : 3) });

		DWMAPI.INSTANCE.DwmSetWindowAttribute(hwnd, DWMAPI.DWMWA_USE_IMMERSIVE_DARK_MODE, new WinUser.BOOLByReference(new WinUser.BOOL(dark)), WinUser.BOOL.SIZE);
		function = Function.getFunction(Kernel32.INSTANCE.GetProcAddress(hModule, 104));
		function.invoke(new Object[] {});
		function = Function.getFunction(Kernel32.INSTANCE.GetProcAddress(hModule, 136));
		function.invoke(new Object[] {});
	}

Currently in my app i have to switch the native window theme using this code (this allows windows to see the window as using dark mode, including the native appbar menu) can this be included in the native lib to run if dark theme is used?

this can probably also help to show the native file chooser dialog in the correct theme, https://github.com/JFormDesigner/FlatLaf/pull/988

Numerok avatar Dec 05 '25 10:12 Numerok

Thanks, will try...

Do you know the function names of 104 and 136?

Do you have some links where I can some information about how this works?

DevCharly avatar Dec 05 '25 11:12 DevCharly

Thanks, will try...

Do you know the function names of 104 and 136?

Do you have some links where I can some information about how this works?

I don't remember where exactly i got them from because i researched this over a year ago but i do know these calls are done to call for an ui update from the windows side, as i understand these functions are community named, because uxtheme does not export their names(or there can be a leaked uxtheme dll with name exports, i dont know).

133 - AllowDarkModeForWindow (Enables Dark Mode) 135 - SetPreferredAppMode (Sets the preferred theme) (or it can be AllowDarkModeForApp if build number is below 18362)

104 - RefreshImmersiveColorPolicyState (Refreshes system UI (Taskbar/Titlebars) color policy) 136 - FlushMenuThemes (Clears cached menu themes to fix context menu coloring)

from my tests calling 104 and 136 helps the theme to switch immediately without delay or hiding-showing the changed window

found one lib in cpp with the names clearly stated here: https://github.com/stefankueng/sktoolslib/blob/main/DarkModeHelper.cpp

Numerok avatar Dec 07 '25 07:12 Numerok