Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/hxwindowmode/WindowColorMode.hx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class WindowColorMode {
* Useful for checking if you need to force redraw the window header.
*/
public static var isWindows10(get, never):Bool;
public static function get_isWindows10():Bool {

@:noCompletion
private static inline function get_isWindows10():Bool {
#if lime
//could use some C++ code but this works too
return (lime.system.System.platformLabel.toLowerCase().indexOf("windows 10") != -1);
Expand Down Expand Up @@ -153,9 +155,19 @@ class WindowColorMode {
*/
public static inline function redrawWindowHeader() {
#if lime
#if !desktop
trace('`redrawWindowHeader` is not available on this platform!');
#end
for (i in 0...2) lime.app.Application.current.window.borderless = !lime.app.Application.current.window.borderless;
#end
}

public static inline function isLightTheme() {
#if(!cpp || !windows)
trace('`isLightTheme` is not available on this platform!');
#end
return WindowBackend.isLightTheme();
}
}

enum abstract WindowCornerType(Int) {
Expand Down
3 changes: 3 additions & 0 deletions src/hxwindowmode/backend/WindowBackend.hx
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ extern class WindowBackend {

@:native("nativeWindowColorMode::updateWindow")
private static function updateWindow():Void;

@:native("nativeWindowColorMode::isLightTheme")
private static function isLightTheme():Bool;
}
1 change: 1 addition & 0 deletions src/hxwindowmode/backend/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
<target id="haxe">
<files id="hxWindowColorMode" />
<lib name="dwmapi.lib" if="windows" />
<lib name="Advapi32.lib" if="windows" />
</target>
</xml>
64 changes: 51 additions & 13 deletions src/hxwindowmode/backend/src/windowbackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
#ifdef HX_WINDOWS
#include <Windows.h>
#include <dwmapi.h>
#include <vector>
#include <string>
#include <stdexcept>
#endif

bool nativeWindowColorMode::setWindowColorMode(bool isDarkMode)
{
#ifdef HX_WINDOWS
#ifdef HX_WINDOWS
HWND window = GetActiveWindow();
int isDark = (isDarkMode ? 1 : 0);
bool hasChanged = (DwmSetWindowAttribute(window, 19, &isDark, sizeof(isDark)) == S_OK);
Expand All @@ -19,50 +22,85 @@ bool nativeWindowColorMode::setWindowColorMode(bool isDarkMode)
UpdateWindow(window);

return hasChanged;
#else
#else
return false;
#endif
#endif
}

void nativeWindowColorMode::setWindowBorderColor(::Array<int> color, bool setHeader, bool setBorder)
{
#ifdef HX_WINDOWS
#ifdef HX_WINDOWS
HWND window = GetActiveWindow();
auto finalColor = RGB(color[0], color[1], color[2]);

if(setHeader)
if (setHeader)
DwmSetWindowAttribute(window, 35, &finalColor, sizeof(COLORREF));
if(setBorder)
if (setBorder)
DwmSetWindowAttribute(window, 34, &finalColor, sizeof(COLORREF));

UpdateWindow(window);
#endif
#endif
}

void nativeWindowColorMode::setWindowTitleColor(::Array<int> color)
{
#ifdef HX_WINDOWS
#ifdef HX_WINDOWS
HWND window = GetActiveWindow();
auto finalColor = RGB(color[0], color[1], color[2]);

DwmSetWindowAttribute(window, 36, &finalColor, sizeof(COLORREF));
UpdateWindow(window);
#endif
#endif
}

void nativeWindowColorMode::setWindowCornerType(int cornerType)
{
#ifdef HX_WINDOWS
#ifdef HX_WINDOWS
HWND window = GetActiveWindow();

DwmSetWindowAttribute(window, 33, &cornerType, sizeof(cornerType));
UpdateWindow(window);
#endif
#endif
}

void nativeWindowColorMode::updateWindow()
{
#ifdef HX_WINDOWS
#ifdef HX_WINDOWS
UpdateWindow(GetActiveWindow());
#endif
#endif
}

/**
* @see https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
*/
bool nativeWindowColorMode::isLightTheme()
{
#ifdef HX_WINDOWS
// The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian
auto buffer = std::vector<char>(4);
auto cbData = static_cast<DWORD>(buffer.size() * sizeof(char));
auto res = RegGetValueW(
HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
L"AppsUseLightTheme",
RRF_RT_REG_DWORD, // expected value type
nullptr,
buffer.data(),
&cbData);

if (res != ERROR_SUCCESS)
{
throw std::runtime_error("Error: error_code=" + std::to_string(res));
}

// convert bytes written to our buffer to an int, assuming little-endian
auto i = int(buffer[3] << 24 |
buffer[2] << 16 |
buffer[1] << 8 |
buffer[0]);

return i == 1;
#else
return false;
#endif
}
1 change: 1 addition & 0 deletions src/hxwindowmode/backend/src/windowbackend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ namespace nativeWindowColorMode
void setWindowTitleColor(::Array<int> color);
void setWindowCornerType(int cornerType);
void updateWindow();
bool isLightTheme();
}