This commit is contained in:
cyn 2025-04-04 22:24:08 +00:00 committed by GitHub
commit 8fd28647a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 179 additions and 0 deletions
source
Main.hx
funkin
ui/transition/preload
util

View file

@ -41,6 +41,11 @@ class Main extends Sprite
{
super();
#if (cpp && windows)
// Enable dark mode support for the title bar.
funkin.util.WindowUtil.setWindowDarkMode(true, true);
#end
// Initialize custom logging.
haxe.Log.trace = funkin.util.logging.AnsiTrace.trace;
funkin.util.logging.AnsiTrace.traceBF();

View file

@ -121,6 +121,11 @@ class FunkinPreloader extends FlxBasePreloader
public function new()
{
#if (cpp && windows)
// Enable dark mode support for the title bar.
funkin.util.WindowUtil.setWindowDarkMode(true, true);
#end
super(Constants.PRELOADER_MIN_STAGE_TIME);
// We can't even call trace() yet, until Flixel loads.

View file

@ -1,5 +1,6 @@
package funkin.util;
import flixel.util.FlxColor;
import flixel.util.FlxSignal.FlxTypedSignal;
using StringTools;
@ -8,10 +9,59 @@ using StringTools;
* Utilities for operating on the current window, such as changing the title.
*/
#if (cpp && windows)
@:buildXml('
<target id="haxe">
<lib name="dwmapi.lib" if="windows"/>
</target>
')
@:cppFileCode('
#include <iostream>
#include <windows.h>
#include <psapi.h>
#include <dwmapi.h>
#include <winuser.h>
#define attributeDarkMode 20
#define attributeDarkModeFallback 19
#define attributeBorderColor 34
#define attributeCaptionColor 35
#define attributeTextColor 36
struct HandleData {
DWORD pid = 0;
HWND handle = 0;
};
BOOL CALLBACK findByPID(HWND handle, LPARAM lParam) {
DWORD targetPID = ((HandleData*)lParam)->pid;
DWORD curPID = 0;
GetWindowThreadProcessId(handle, &curPID);
if (targetPID != curPID || GetWindow(handle, GW_OWNER) != (HWND)0 || !IsWindowVisible(handle)) {
return TRUE;
}
((HandleData*)lParam)->handle = handle;
return FALSE;
}
HWND curHandle = 0;
void getHandle() {
if (curHandle == (HWND)0) {
HandleData data;
data.pid = GetCurrentProcessId();
EnumWindows(findByPID, (LPARAM)&data);
curHandle = data.handle;
}
}
void forceRedraw() {
if (curHandle != (HWND)0) {
SetWindowPos(curHandle, HWND_TOP, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
RedrawWindow(curHandle, nullptr, nullptr, RDW_INVALIDATE | RDW_NOERASE | RDW_UPDATENOW | RDW_FRAME);
}
}
')
#end
class WindowUtil
@ -157,4 +207,123 @@ class WindowUtil
{
lime.app.Application.current.window.title = value;
}
/**
* Enables or disables dark mode support for the title bar.
*
* Only works on Windows 1809 and later.
*
* @param enable Whether to enable or disable dark mode support.
* @param instant Whether to skip the transition tween.
*/
public static function setWindowDarkMode(enable:Bool = true, instant:Bool = false):Void
{
#if (cpp && windows)
var success:Bool = false;
untyped __cpp__('
getHandle();
if (curHandle != (HWND)0) {
const BOOL darkMode = enable ? TRUE : FALSE;
success = (S_OK == DwmSetWindowAttribute(curHandle, attributeDarkMode, (LPCVOID)&darkMode, (DWORD)sizeof(darkMode)));
if (!success) {
// Pre-20H1
success = (S_OK == DwmSetWindowAttribute(curHandle, attributeDarkModeFallback, (LPCVOID)&darkMode, (DWORD)sizeof(darkMode)));
}
if (success && !instant) {
forceRedraw();
}
}
');
if (success && instant)
{
final curBarColor:Null<FlxColor> = windowBarColor;
windowBarColor = 0x00000000;
windowBarColor = curBarColor;
}
#else
// Do nothing.
#end
}
/**
* The color of the window title bar. If `null`, the system default is used (`0xffffffff`).
*
* Only works on Windows 21H2 and later.
*/
public static var windowBarColor(default, set):Null<FlxColor> = null;
public static function set_windowBarColor(value:Null<FlxColor>):Null<FlxColor>
{
#if (cpp && windows)
final intColor:Int = Std.isOfType(value, Int) ? cast FlxColor.fromRGB(value.blue, value.green, value.red, value.alpha) : 0xffffffff;
untyped __cpp__('
getHandle();
if (curHandle != (HWND)0) {
const COLORREF targetColor = (COLORREF)intColor;
if (S_OK == DwmSetWindowAttribute(curHandle, attributeCaptionColor, (LPCVOID)&targetColor, (DWORD)sizeof(targetColor))) {
forceRedraw();
}
}
');
#else
// Do nothing.
#end
return windowBarColor = value;
}
/**
* The color of the window title bar text. If `null`, the system default is used (`0xffffffff`).
*
* Only works on Windows 21H2 and later.
*/
public static var windowTextColor(default, set):Null<FlxColor> = null;
public static function set_windowTextColor(value:Null<FlxColor>):Null<FlxColor>
{
#if (cpp && windows)
final intColor:Int = Std.isOfType(value, Int) ? cast FlxColor.fromRGB(value.blue, value.green, value.red, value.alpha) : 0xffffffff;
untyped __cpp__('
getHandle();
if (curHandle != (HWND)0) {
const COLORREF targetColor = (COLORREF)intColor;
if (S_OK == DwmSetWindowAttribute(curHandle, attributeTextColor, (LPCVOID)&targetColor, (DWORD)sizeof(targetColor))) {
forceRedraw();
}
}
');
#else
// Do nothing.
#end
return windowTextColor = value;
}
/**
* The color of the window border. If `null`, the system default is used (`0xffffffff`).
* Setting to `0xfffeffff` will disable the border entirely (use a color with alpha 0 to re-enable it).
*
* Only works on Windows 21H2 and later.
*/
public static var windowBorderColor(default, set):Null<FlxColor> = null;
public static function set_windowBorderColor(value:Null<FlxColor>):Null<FlxColor>
{
#if (cpp && windows)
final intColor:Int = Std.isOfType(value, Int) ? cast FlxColor.fromRGB(value.blue, value.green, value.red, value.alpha) : 0xffffffff;
untyped __cpp__('
getHandle();
if (curHandle != (HWND)0) {
const COLORREF targetColor = (COLORREF)intColor;
if (S_OK == DwmSetWindowAttribute(curHandle, attributeBorderColor, (LPCVOID)&targetColor, (DWORD)sizeof(targetColor))) {
forceRedraw();
}
}
');
#else
// Do nothing.
#end
return windowBorderColor = value;
}
}