Skip to content
This repository has been archived by the owner on Jun 12, 2023. It is now read-only.

Support for DWM with more accurate colors #50

Merged
merged 5 commits into from
Jun 13, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.5.1

- Add support for DWM/Windows Aero's color ([#50](https://github.com/material-foundation/material-dynamic-color-flutter/pull/50))

## 1.5.0

- Add support for GTK's accent color on Linux ([#47](https://github.com/material-foundation/material-dynamic-color-flutter/pull/47))
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ A Flutter package to create Material color schemes based on a platform's impleme
- Android S+: [color from user wallpaper](https://m3.material.io/styles/color/dynamic-color/user-generated-color)
- Linux: GTK+ theme's `@theme_selected_bg_color`
- macOS: [app accent color](https://developer.apple.com/design/human-interface-guidelines/macos/overview/whats-new-in-macos/#app-accent-colors)
- Windows: [accent color](https://docs.microsoft.com/en-us/windows/apps/design/style/color#accent-color)
- Windows: [accent](https://docs.microsoft.com/en-us/windows/apps/design/style/color#accent-color) and [window/glass](https://web.archive.org/web/20080812195923/http://www.microsoft.com/windows/windows-vista/features/aero.aspx?tabid=2&catid=4) color
Craftplacer marked this conversation as resolved.
Show resolved Hide resolved

This package also supports color and color scheme harmonization.

Expand Down
5 changes: 3 additions & 2 deletions lib/src/dynamic_color_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ class DynamicColorPlugin {

/// Returns the OS' accent color asynchronously as a [Color].
///
/// Supported on macOS starting with 10.14 (Mojave), on Windows with
/// Windows 10, and on GTK-based Linux desktops.
/// Supported on macOS starting with 10.14 (Mojave), on Windows starting with
/// Vista, and on GTK-based Linux desktops.
///
/// See also:
///
/// * [Apple's introduction to macOS accent color](https://developer.apple.com/design/human-interface-guidelines/macos/overview/whats-new-in-macos/#app-accent-colors)
/// * [macOS's NSColor.controlAccentColor documentation](https://developer.apple.com/documentation/appkit/nscolor/3000782-controlaccentcolor)
/// * [Windows' accent color](https://docs.microsoft.com/en-us/windows/apps/design/style/color#accent-color)
/// * [Windows Aero](https://web.archive.org/web/20080812195923/http://www.microsoft.com/windows/windows-vista/features/aero.aspx?tabid=2&catid=4)
/// * [Change colors in Windows](https://support.microsoft.com/en-us/windows/change-colors-in-windows-d26ef4d6-819a-581c-1581-493cfcc005fe)
static Future<Color?> getAccentColor() async {
final result = await channel.invokeMethod(accentColorMethodName);
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: dynamic_color
description: A Flutter package to create Material color schemes based on a platform's implementation of dynamic color.
version: 1.5.0
version: 1.5.1
repository: https://github.com/material-foundation/material-dynamic-color-flutter

environment:
Expand Down
2 changes: 1 addition & 1 deletion windows/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
# dependencies here.
target_include_directories(${PLUGIN_NAME} INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin)
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin dwmapi.lib)

# List of absolute paths to libraries that should be bundled with the plugin.
# This list could contain prebuilt libraries, or libraries created by an
Expand Down
14 changes: 14 additions & 0 deletions windows/dwm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <windows.h>

typedef struct COLORIZATIONPARAMS
{
COLORREF clrColor;
COLORREF clrAftGlow;
UINT nIntensity;
UINT clrAftGlowBal;
UINT clrBlurBal;
UINT clrGlassReflInt;
BOOL fOpaque;
} COLORIZATIONPARAMS;

HRESULT (WINAPI *DwmGetColorizationParameters) (COLORIZATIONPARAMS *colorparam);
107 changes: 90 additions & 17 deletions windows/dynamic_color_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

// This must be included before many other Windows headers.
#include <windows.h>
#include <dwmapi.h>
#include "dwm.c"

// For getPlatformVersion; remove unless needed for your plugin implementation.
#include <VersionHelpers.h>
Expand Down Expand Up @@ -37,27 +39,98 @@ DynamicColorPlugin::DynamicColorPlugin() {}

DynamicColorPlugin::~DynamicColorPlugin() {}

static BOOL GetAccentColorViaRegistry(int64_t& argbColor) {
DWORD abgr = 0;
DWORD resultSize = sizeof (abgr);

if (
RegGetValue(
HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Accent",
L"AccentColorMenu",
RRF_RT_REG_DWORD,
nullptr,
&abgr,
&resultSize
) == S_OK
) {
argbColor = (abgr & 0xFF00FF00) + ((abgr & 0xFF) << 16) + ((abgr & 0xFF0000) >> 16);
return TRUE;
}

return FALSE;
}

static BOOL GetWindowColorViaDwmUndocd(int64_t& argbColor) {
HMODULE hDwmDll = LoadLibrary(L"dwmapi.dll");
if (!hDwmDll) {
return FALSE;
}

*(FARPROC *)&DwmGetColorizationParameters = GetProcAddress(hDwmDll,(LPCSTR)127);

COLORIZATIONPARAMS colorParams;
if (SUCCEEDED(DwmGetColorizationParameters(&colorParams))) {
argbColor = colorParams.clrColor;
FreeLibrary(hDwmDll);
return TRUE;
}

FreeLibrary(hDwmDll);
return FALSE;
}

static BOOL GetWindowColorViaDwmRegistry(int64_t& argbColor) {
DWORD argb = 0;
DWORD resultSize = sizeof(argb);

if (SUCCEEDED(
RegGetValue(
HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\DWM",
L"ColorizationColor",
RRF_RT_REG_DWORD,
nullptr,
&argb,
&resultSize
)
)) {
argbColor = argb;
return TRUE;
}

return FALSE;
}

void DynamicColorPlugin::HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue> &method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (!method_call.method_name().compare("getAccentColor")) {
int64_t argbColor = 0;
DWORD abgr = 0;
DWORD resultSize = sizeof (abgr);
if (
RegGetValue(
HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Accent",
L"AccentColorMenu",
RRF_RT_REG_DWORD,
nullptr,
&abgr,
&resultSize
) == S_OK
) {
argbColor = (abgr & 0xFF00FF00) + ((abgr & 0xFF) << 16) + ((abgr & 0xFF0000) >> 16);
result->Success(flutter::EncodableValue(argbColor));
} else result->Success(nullptr);
int64_t argb = 0;
BOOL successful = FALSE;

// Try one method after the other until one works
if (IsWindows10OrGreater()) {
successful = GetAccentColorViaRegistry(argb);
}
if (!successful && IsWindowsVistaOrGreater()) {
BOOL dwmEnabled = FALSE;
if (SUCCEEDED(DwmIsCompositionEnabled(&dwmEnabled)) && dwmEnabled == TRUE) {
successful = GetWindowColorViaDwmUndocd(argb);

// Our attempt at using the undocumented DWM
// function failed, let's retry using the registry.
if (!successful) {
successful = GetWindowColorViaDwmRegistry(argb);
}
}
}

if (successful) {
result->Success(flutter::EncodableValue(argb));
} else {
result->Success(nullptr);
}
} else {
result->NotImplemented();
}
Expand Down