Skip to content

Commit 454bb73

Browse files
TBar09NeeEooNexIsDumb
authored
Fixed Window dark mode issue for Windows 10 users! (#449)
* 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 <NeeEoo@users.noreply.github.com> Co-authored-by: ⍚~Nex <87421482+NexIsDumb@users.noreply.github.com>
1 parent a2a12f1 commit 454bb73

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

source/funkin/backend/system/Main.hx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ class Main extends Sprite
156156
FlxG.signals.postStateSwitch.add(onStateSwitchPost);
157157

158158
FlxG.mouse.useSystemCursor = true;
159+
#if DARK_MODE_WINDOW
160+
if(funkin.backend.utils.NativeAPI.hasVersion("Windows 10")) funkin.backend.utils.NativeAPI.redrawWindowHeader();
161+
#end
159162

160163
ModsFolder.init();
161164
#if MOD_SUPPORT

source/funkin/backend/utils/NativeAPI.hx

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package funkin.backend.utils;
33
import funkin.backend.utils.native.*;
44
import flixel.util.typeLimit.OneOfTwo;
55
import flixel.util.typeLimit.OneOfThree;
6+
import flixel.util.FlxColor;
67

78
/**
89
* Class for functions that talk to a lower level than haxe, such as message boxes, and more.
@@ -84,12 +85,86 @@ class NativeAPI {
8485
#end
8586
}
8687

88+
/**
89+
* WINDOW COLOR MODE FUNCTIONS.
90+
*/
91+
92+
/**
93+
* Switch the window's color mode to dark or light mode.
94+
*/
8795
public static function setDarkMode(title:String, enable:Bool) {
8896
#if windows
97+
if(title == null) title = lime.app.Application.current.window.title;
8998
Windows.setDarkMode(title, enable);
9099
#end
91100
}
92101

102+
/**
103+
* Switch the window's color to any color.
104+
*
105+
* WARNING: This is exclusive to windows 11 users, unfortunately.
106+
*
107+
* NOTE: Setting the color to 0x00000000 (FlxColor.TRANSPARENT) will set the border (must have setBorder on) invisible.
108+
*/
109+
public static function setWindowBorderColor(title:String, color:FlxColor, setHeader:Bool = true, setBorder:Bool = true) {
110+
#if windows
111+
if(title == null) title = lime.app.Application.current.window.title;
112+
Windows.setWindowBorderColor(title, [color.red, color.green, color.blue, color.alpha], setHeader, setBorder);
113+
#end
114+
}
115+
116+
/**
117+
* Resets the window's border color to the default one.
118+
*
119+
* WARNING: This is exclusive to windows 11 users, unfortunately.
120+
**/
121+
public static function resetWindowBorderColor(title:String, setHeader:Bool = true, setBorder:Bool = true) {
122+
#if windows
123+
if(title == null) title = lime.app.Application.current.window.title;
124+
Windows.setWindowBorderColor(title, [-1, -1, -1, -1], setHeader, setBorder);
125+
#end
126+
}
127+
128+
/**
129+
* Switch the window's title text to any color.
130+
*
131+
* WARNING: This is exclusive to windows 11 users, unfortunately.
132+
*/
133+
public static function setWindowTitleColor(title:String, color:FlxColor) {
134+
#if windows
135+
if(title == null) title = lime.app.Application.current.window.title;
136+
Windows.setWindowTitleColor(title, [color.red, color.green, color.blue, color.alpha]);
137+
#end
138+
}
139+
140+
/**
141+
* Resets the window's title color to the default one.
142+
*
143+
* WARNING: This is exclusive to windows 11 users, unfortunately.
144+
**/
145+
public static function resetWindowTitleColor(title:String) {
146+
#if windows
147+
if(title == null) title = lime.app.Application.current.window.title;
148+
Windows.setWindowTitleColor(title, [-1, -1, -1, -1]);
149+
#end
150+
}
151+
152+
/**
153+
* Forces the window header to redraw, causes a small visual jitter so use it sparingly.
154+
*/
155+
public static function redrawWindowHeader() {
156+
#if windows
157+
flixel.FlxG.stage.window.borderless = true;
158+
flixel.FlxG.stage.window.borderless = false;
159+
#end
160+
}
161+
162+
/**
163+
* Can be used to check if your using a specific version of an OS (or if your using a certain OS).
164+
*/
165+
public static function hasVersion(vers:String)
166+
return lime.system.System.platformLabel.toLowerCase().indexOf(vers.toLowerCase()) != -1;
167+
93168
/**
94169
* Shows a message box
95170
*/

source/funkin/backend/utils/native/Windows.hx

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,57 @@ class Windows {
134134
HWND window = FindWindowA(NULL, title.c_str());
135135
// Look for child windows if top level aint found
136136
if (window == NULL) window = FindWindowExA(GetActiveWindow(), NULL, NULL, title.c_str());
137+
// If still not found, try to get the active window
138+
if (window == NULL) window = GetActiveWindow();
139+
if (window == NULL) return;
137140

138-
if (window != NULL && S_OK != DwmSetWindowAttribute(window, 19, &darkMode, sizeof(darkMode))) {
141+
if (S_OK != DwmSetWindowAttribute(window, 19, &darkMode, sizeof(darkMode))) {
139142
DwmSetWindowAttribute(window, 20, &darkMode, sizeof(darkMode));
140143
}
144+
UpdateWindow(window);
141145
')
142146
public static function setDarkMode(title:String, enable:Bool) {}
143147

148+
@:functionCode('
149+
HWND window = FindWindowA(NULL, title.c_str());
150+
if (window == NULL) window = FindWindowExA(GetActiveWindow(), NULL, NULL, title.c_str());
151+
if (window == NULL) window = GetActiveWindow();
152+
if (window == NULL) return;
153+
154+
COLORREF finalColor;
155+
if(color[0] == -1 && color[1] == -1 && color[2] == -1 && color[3] == -1) { // bad fix, I know :sob:
156+
finalColor = 0xFFFFFFFF; // Default border
157+
} else if(color[3] == 0) {
158+
finalColor = 0xFFFFFFFE; // No border (must have setBorder as true)
159+
} else {
160+
finalColor = RGB(color[0], color[1], color[2]); // Use your custom color
161+
}
162+
163+
if(setHeader) DwmSetWindowAttribute(window, 35, &finalColor, sizeof(COLORREF));
164+
if(setBorder) DwmSetWindowAttribute(window, 34, &finalColor, sizeof(COLORREF));
165+
166+
UpdateWindow(window);
167+
')
168+
public static function setWindowBorderColor(title:String, color:Array<Int>, setHeader:Bool = true, setBorder:Bool = true) {}
169+
170+
@:functionCode('
171+
HWND window = FindWindowA(NULL, title.c_str());
172+
if (window == NULL) window = FindWindowExA(GetActiveWindow(), NULL, NULL, title.c_str());
173+
if (window == NULL) window = GetActiveWindow();
174+
if (window == NULL) return;
175+
176+
COLORREF finalColor;
177+
if(color[0] == -1 && color[1] == -1 && color[2] == -1 && color[3] == -1) { // bad fix, I know :sob:
178+
finalColor = 0xFFFFFFFF; // Default border
179+
} else {
180+
finalColor = RGB(color[0], color[1], color[2]); // Use your custom color
181+
}
182+
183+
DwmSetWindowAttribute(window, 36, &finalColor, sizeof(COLORREF));
184+
UpdateWindow(window);
185+
')
186+
public static function setWindowTitleColor(title:String, color:Array<Int>) {}
187+
144188
@:functionCode('
145189
// https://stackoverflow.com/questions/15543571/allocconsole-not-displaying-cout
146190

0 commit comments

Comments
 (0)