From 454bb735719a13a444ad9cfafa20d25266e8f799 Mon Sep 17 00:00:00 2001 From: TBar09 <131258758+TBar09@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:30:17 -0600 Subject: [PATCH] Fixed Window dark mode issue for Windows 10 users! (#449) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added extras to NativeAPI.hx -Added `setWindowBorderColor()`, `hasVersion()`, and `redrawWindowHeader`. * Added `redrawWindowHeader` to Main.hx * Added setWindowBorderColor * Update NativeAPI.hx * Update Main.hx * Update Windows.hx * Update NativeAPI.hx * Update Windows.hx * Update NativeAPI.hx * Added FlxColorToArray to CoolUtil -Added the FlxColorToArray function to CoolUtil so people can easily use FlxColors with functions like setWindowBorderColor and setWindowTitleColor. * Update Windows.hx * Fix Windows.hx -You now have to use `FlxColor.fromRGB(255, 255, 254)` or 0xFFFFFFFE to set the border to normal * Update Windows.hx shhh * Update NativeAPI.hx * Small fixes * small optimization * eh imma add it here too --------- Co-authored-by: Ne_Eo Co-authored-by: ⍚~Nex <87421482+NexIsDumb@users.noreply.github.com> --- source/funkin/backend/system/Main.hx | 3 + source/funkin/backend/utils/NativeAPI.hx | 75 +++++++++++++++++++ source/funkin/backend/utils/native/Windows.hx | 46 +++++++++++- 3 files changed, 123 insertions(+), 1 deletion(-) diff --git a/source/funkin/backend/system/Main.hx b/source/funkin/backend/system/Main.hx index 6705b93c3..78369f607 100644 --- a/source/funkin/backend/system/Main.hx +++ b/source/funkin/backend/system/Main.hx @@ -156,6 +156,9 @@ class Main extends Sprite FlxG.signals.postStateSwitch.add(onStateSwitchPost); FlxG.mouse.useSystemCursor = true; + #if DARK_MODE_WINDOW + if(funkin.backend.utils.NativeAPI.hasVersion("Windows 10")) funkin.backend.utils.NativeAPI.redrawWindowHeader(); + #end ModsFolder.init(); #if MOD_SUPPORT diff --git a/source/funkin/backend/utils/NativeAPI.hx b/source/funkin/backend/utils/NativeAPI.hx index 78f0b38de..a8753a8a4 100644 --- a/source/funkin/backend/utils/NativeAPI.hx +++ b/source/funkin/backend/utils/NativeAPI.hx @@ -3,6 +3,7 @@ package funkin.backend.utils; import funkin.backend.utils.native.*; import flixel.util.typeLimit.OneOfTwo; import flixel.util.typeLimit.OneOfThree; +import flixel.util.FlxColor; /** * Class for functions that talk to a lower level than haxe, such as message boxes, and more. @@ -84,12 +85,86 @@ class NativeAPI { #end } + /** + * WINDOW COLOR MODE FUNCTIONS. + */ + + /** + * Switch the window's color mode to dark or light mode. + */ public static function setDarkMode(title:String, enable:Bool) { #if windows + if(title == null) title = lime.app.Application.current.window.title; Windows.setDarkMode(title, enable); #end } + /** + * Switch the window's color to any color. + * + * WARNING: This is exclusive to windows 11 users, unfortunately. + * + * NOTE: Setting the color to 0x00000000 (FlxColor.TRANSPARENT) will set the border (must have setBorder on) invisible. + */ + public static function setWindowBorderColor(title:String, color:FlxColor, setHeader:Bool = true, setBorder:Bool = true) { + #if windows + if(title == null) title = lime.app.Application.current.window.title; + Windows.setWindowBorderColor(title, [color.red, color.green, color.blue, color.alpha], setHeader, setBorder); + #end + } + + /** + * Resets the window's border color to the default one. + * + * WARNING: This is exclusive to windows 11 users, unfortunately. + **/ + public static function resetWindowBorderColor(title:String, setHeader:Bool = true, setBorder:Bool = true) { + #if windows + if(title == null) title = lime.app.Application.current.window.title; + Windows.setWindowBorderColor(title, [-1, -1, -1, -1], setHeader, setBorder); + #end + } + + /** + * Switch the window's title text to any color. + * + * WARNING: This is exclusive to windows 11 users, unfortunately. + */ + public static function setWindowTitleColor(title:String, color:FlxColor) { + #if windows + if(title == null) title = lime.app.Application.current.window.title; + Windows.setWindowTitleColor(title, [color.red, color.green, color.blue, color.alpha]); + #end + } + + /** + * Resets the window's title color to the default one. + * + * WARNING: This is exclusive to windows 11 users, unfortunately. + **/ + public static function resetWindowTitleColor(title:String) { + #if windows + if(title == null) title = lime.app.Application.current.window.title; + Windows.setWindowTitleColor(title, [-1, -1, -1, -1]); + #end + } + + /** + * Forces the window header to redraw, causes a small visual jitter so use it sparingly. + */ + public static function redrawWindowHeader() { + #if windows + flixel.FlxG.stage.window.borderless = true; + flixel.FlxG.stage.window.borderless = false; + #end + } + + /** + * Can be used to check if your using a specific version of an OS (or if your using a certain OS). + */ + public static function hasVersion(vers:String) + return lime.system.System.platformLabel.toLowerCase().indexOf(vers.toLowerCase()) != -1; + /** * Shows a message box */ diff --git a/source/funkin/backend/utils/native/Windows.hx b/source/funkin/backend/utils/native/Windows.hx index a536c75f8..8653d2e8c 100644 --- a/source/funkin/backend/utils/native/Windows.hx +++ b/source/funkin/backend/utils/native/Windows.hx @@ -134,13 +134,57 @@ class Windows { HWND window = FindWindowA(NULL, title.c_str()); // Look for child windows if top level aint found if (window == NULL) window = FindWindowExA(GetActiveWindow(), NULL, NULL, title.c_str()); + // If still not found, try to get the active window + if (window == NULL) window = GetActiveWindow(); + if (window == NULL) return; - if (window != NULL && S_OK != DwmSetWindowAttribute(window, 19, &darkMode, sizeof(darkMode))) { + if (S_OK != DwmSetWindowAttribute(window, 19, &darkMode, sizeof(darkMode))) { DwmSetWindowAttribute(window, 20, &darkMode, sizeof(darkMode)); } + UpdateWindow(window); ') public static function setDarkMode(title:String, enable:Bool) {} + @:functionCode(' + HWND window = FindWindowA(NULL, title.c_str()); + if (window == NULL) window = FindWindowExA(GetActiveWindow(), NULL, NULL, title.c_str()); + if (window == NULL) window = GetActiveWindow(); + if (window == NULL) return; + + COLORREF finalColor; + if(color[0] == -1 && color[1] == -1 && color[2] == -1 && color[3] == -1) { // bad fix, I know :sob: + finalColor = 0xFFFFFFFF; // Default border + } else if(color[3] == 0) { + finalColor = 0xFFFFFFFE; // No border (must have setBorder as true) + } else { + finalColor = RGB(color[0], color[1], color[2]); // Use your custom color + } + + if(setHeader) DwmSetWindowAttribute(window, 35, &finalColor, sizeof(COLORREF)); + if(setBorder) DwmSetWindowAttribute(window, 34, &finalColor, sizeof(COLORREF)); + + UpdateWindow(window); + ') + public static function setWindowBorderColor(title:String, color:Array, setHeader:Bool = true, setBorder:Bool = true) {} + + @:functionCode(' + HWND window = FindWindowA(NULL, title.c_str()); + if (window == NULL) window = FindWindowExA(GetActiveWindow(), NULL, NULL, title.c_str()); + if (window == NULL) window = GetActiveWindow(); + if (window == NULL) return; + + COLORREF finalColor; + if(color[0] == -1 && color[1] == -1 && color[2] == -1 && color[3] == -1) { // bad fix, I know :sob: + finalColor = 0xFFFFFFFF; // Default border + } else { + finalColor = RGB(color[0], color[1], color[2]); // Use your custom color + } + + DwmSetWindowAttribute(window, 36, &finalColor, sizeof(COLORREF)); + UpdateWindow(window); + ') + public static function setWindowTitleColor(title:String, color:Array) {} + @:functionCode(' // https://stackoverflow.com/questions/15543571/allocconsole-not-displaying-cout