Fixes https://bugs.winehq.org/show_bug.cgi?id=55640.
-- v8: windows.ui: Support accent colors in uisettings3_GetColorValue.
From: Myah Caron qsniyg@protonmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55640 Signed-off-by: Myah Caron qsniyg@protonmail.com --- dlls/windows.ui/tests/uisettings.c | 95 ++++++++++++++++++++++++++++++ dlls/windows.ui/uisettings.c | 71 ++++++++++++++++++++-- 2 files changed, 161 insertions(+), 5 deletions(-)
diff --git a/dlls/windows.ui/tests/uisettings.c b/dlls/windows.ui/tests/uisettings.c index 8d739cb7bef..30e95bdced5 100644 --- a/dlls/windows.ui/tests/uisettings.c +++ b/dlls/windows.ui/tests/uisettings.c @@ -75,6 +75,45 @@ static DWORD set_app_theme( DWORD mode ) return ret; }
+static BOOL get_accent_palette( DWORD *colors, DWORD *len ) +{ + BOOL ret = TRUE; + DWORD type; + HKEY hkey; + + if (RegOpenKeyExW( HKEY_CURRENT_USER, L"Software\Microsoft\Windows\CurrentVersion\Explorer\Accent", 0, KEY_QUERY_VALUE, &hkey )) return FALSE; + if (RegQueryValueExW( hkey, L"AccentPalette", NULL, &type, (BYTE *)colors, len ) || type != REG_BINARY) ret = FALSE; + RegCloseKey( hkey ); + return ret; +} + +static BOOL delete_accent_palette(void) +{ + BOOL ret = TRUE; + HRESULT res; + HKEY hkey; + + res = RegOpenKeyExW( HKEY_CURRENT_USER, L"Software\Microsoft\Windows\CurrentVersion\Explorer\Accent", 0, KEY_SET_VALUE, &hkey ); + if (res != 0) return res == ERROR_FILE_NOT_FOUND; + + res = RegDeleteValueW( hkey, L"AccentPalette" ); + if (res != 0 && res != ERROR_FILE_NOT_FOUND) ret = FALSE; + + RegCloseKey( hkey ); + return ret; +} + +static DWORD set_accent_palette( DWORD *colors, DWORD len ) +{ + DWORD ret = 1; + HKEY hkey; + + if (RegOpenKeyExW( HKEY_CURRENT_USER, L"Software\Microsoft\Windows\CurrentVersion\Explorer\Accent", 0, KEY_SET_VALUE, &hkey )) return 0; + if (RegSetValueExW( hkey, L"AccentPalette", 0, REG_BINARY, (const BYTE *)&colors, len )) ret = 0; + RegCloseKey( hkey ); + return ret; +} + static void reset_color( Color *value ) { value->A = 1; @@ -83,6 +122,60 @@ static void reset_color( Color *value ) value->B = 1; }
+static BOOL compare_dword_color( Color color, DWORD dword ) +{ + return (color.R == (dword & 0xFF) && color.G == ((dword >> 8) & 0xFF) && color.B == ((dword >> 16) & 0xFF)); +} + +static void test_single_accent( IUISettings3 *uisettings3, UIColorType type, DWORD expected ) +{ + Color value; + HRESULT hr; + BOOL result; + + reset_color( &value ); + hr = IUISettings3_GetColorValue( uisettings3, type, &value ); + ok( hr == S_OK, "GetColorValue returned %#lx\n", hr ); + + result = compare_dword_color( value, expected ); + ok( result, "got unexpected value.A == %d value.R == %d value.G == %d value.B == %d (type = %d)\n", value.A, value.R, value.G, value.B, type ); +} + +static void test_AccentColor( IUISettings3 *uisettings3 ) +{ + DWORD default_palette[8]; + DWORD default_palette_len = 8 * sizeof(DWORD); + DWORD accent_palette[8]; + DWORD accent_palette_len = 8 * sizeof(DWORD); + + if (!get_accent_palette( default_palette, &default_palette_len )) default_palette_len = 0; + + /* deleting AccentPalette fills a default value */ + ok( delete_accent_palette(), "failed to delete AccentPalette key.\n"); + ok( !get_accent_palette( accent_palette, &accent_palette_len ), "AccentPalette should not be available.\n" ); + + test_single_accent( uisettings3, UIColorType_Accent, 0x00d77800 ); + ok( get_accent_palette( accent_palette, &accent_palette_len ), "failed to retrieve AccentPalette key.\n" ); + + /* default values */ + test_single_accent( uisettings3, UIColorType_AccentDark1, 0x009e5a00 ); + test_single_accent( uisettings3, UIColorType_AccentDark2, 0x00754200 ); + test_single_accent( uisettings3, UIColorType_AccentDark3, 0x00422600 ); + test_single_accent( uisettings3, UIColorType_AccentLight1, 0x00e39c42 ); + test_single_accent( uisettings3, UIColorType_AccentLight2, 0x00edb976 ); + test_single_accent( uisettings3, UIColorType_AccentLight3, 0x00ffd8a6 ); + + test_single_accent( uisettings3, UIColorType_Accent, accent_palette[3] ); + test_single_accent( uisettings3, UIColorType_AccentDark1, accent_palette[4] ); + test_single_accent( uisettings3, UIColorType_AccentDark2, accent_palette[5] ); + test_single_accent( uisettings3, UIColorType_AccentDark3, accent_palette[6] ); + test_single_accent( uisettings3, UIColorType_AccentLight1, accent_palette[2] ); + test_single_accent( uisettings3, UIColorType_AccentLight2, accent_palette[1] ); + test_single_accent( uisettings3, UIColorType_AccentLight3, accent_palette[0] ); + + if (default_palette_len) set_accent_palette( default_palette, default_palette_len ); +} + static void test_UISettings(void) { static const WCHAR *uisettings_name = L"Windows.UI.ViewManagement.UISettings"; @@ -126,6 +219,8 @@ static void test_UISettings(void)
check_interface( inspectable, &IID_IAgileObject, TRUE );
+ test_AccentColor( uisettings3 ); + default_theme = get_app_theme();
/* Light Theme */ diff --git a/dlls/windows.ui/uisettings.c b/dlls/windows.ui/uisettings.c index 041388da33b..cdadb828593 100644 --- a/dlls/windows.ui/uisettings.c +++ b/dlls/windows.ui/uisettings.c @@ -266,6 +266,47 @@ static DWORD get_app_theme(void) return ret; }
+static DWORD initialize_accent_palette( DWORD offset ) +{ + DWORD palette[7] = { 0x00ffd8a6, 0x00edb976, 0x00e39c42, 0x00d77800, 0x009e5a00, 0x00754200, 0x00422600 }; + DWORD len = 7 * sizeof(DWORD); + HKEY hkey; + + if (RegCreateKeyW( HKEY_CURRENT_USER, L"Software\Microsoft\Windows\CurrentVersion\Explorer\Accent", &hkey )) return 0; + RegSetValueExW( hkey, L"AccentPalette", 0, REG_BINARY, (const BYTE *)&palette, len ); + RegCloseKey( hkey ); + + return palette[offset]; +} + +static void dword_to_color( DWORD color, Color *out ) +{ + out->R = color & 0xFF; + out->G = (color >> 8) & 0xFF; + out->B = (color >> 16) & 0xFF; + out->A = 0xFF; +} + +static void get_accent_palette_color( DWORD offset, Color *out ) +{ + DWORD ret = 0, len = 7 * sizeof(DWORD), type; + DWORD palette[7] = { 0 }; + HKEY hkey; + + if (RegOpenKeyExW( HKEY_CURRENT_USER, L"Software\Microsoft\Windows\CurrentVersion\Explorer\Accent", 0, KEY_QUERY_VALUE, &hkey )) + { + ret = initialize_accent_palette( offset ); + dword_to_color( ret, out ); + return; + } + + if (RegQueryValueExW( hkey, L"AccentPalette", NULL, &type, (BYTE *)&palette, &len ) || type != REG_BINARY) ret = initialize_accent_palette( offset ); + else ret = palette[offset]; + + RegCloseKey( hkey ); + dword_to_color( ret, out ); +} + static void set_color_value( BYTE a, BYTE r, BYTE g, BYTE b, Color *out ) { out->A = a; @@ -283,19 +324,39 @@ static HRESULT WINAPI uisettings3_GetColorValue( IUISettings3 *iface, UIColorTyp switch (type) { case UIColorType_Foreground: + theme = get_app_theme(); + set_color_value( 255, theme ? 0 : 255, theme ? 0 : 255, theme ? 0 : 255, value ); + break; case UIColorType_Background: theme = get_app_theme(); + set_color_value( 255, theme ? 255 : 0, theme ? 255 : 0, theme ? 255 : 0, value ); + break; + case UIColorType_Accent: + get_accent_palette_color( 3, value ); + break; + case UIColorType_AccentDark1: + get_accent_palette_color( 4, value ); + break; + case UIColorType_AccentDark2: + get_accent_palette_color( 5, value ); + break; + case UIColorType_AccentDark3: + get_accent_palette_color( 6, value ); + break; + case UIColorType_AccentLight1: + get_accent_palette_color( 2, value ); + break; + case UIColorType_AccentLight2: + get_accent_palette_color( 1, value ); + break; + case UIColorType_AccentLight3: + get_accent_palette_color( 0, value ); break; default: FIXME( "type %d not implemented.\n", type ); return E_NOTIMPL; }
- if (type == UIColorType_Foreground) - set_color_value( 255, theme ? 0 : 255, theme ? 0 : 255, theme ? 0 : 255, value ); - else - set_color_value( 255, theme ? 255 : 0, theme ? 255 : 0, theme ? 255 : 0, value ); - TRACE( "Returning value.A = %d, value.R = %d, value.G = %d, value.B = %d\n", value->A, value->R, value->G, value->B ); return S_OK; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=139474
Your paranoid android.
=== w11pro64 (32 bit report) ===
windows.ui: uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 0 value.G == 120 value.B == 212 (type = 5) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 0 value.G == 103 value.B == 192 (type = 4) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 0 value.G == 62 value.B == 146 (type = 3) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 0 value.G == 26 value.B == 104 (type = 2) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 0 value.G == 145 value.B == 248 (type = 6) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 76 value.G == 194 value.B == 255 (type = 7) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 153 value.G == 235 value.B == 255 (type = 8)
=== w11pro64_amd (64 bit report) ===
windows.ui: uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 0 value.G == 120 value.B == 212 (type = 5) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 0 value.G == 103 value.B == 192 (type = 4) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 0 value.G == 62 value.B == 146 (type = 3) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 0 value.G == 26 value.B == 104 (type = 2) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 0 value.G == 145 value.B == 248 (type = 6) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 76 value.G == 194 value.B == 255 (type = 7) uisettings.c:141: Test failed: got unexpected value.A == 255 value.R == 153 value.G == 235 value.B == 255 (type = 8)
On Thu Nov 2 08:57:25 2023 +0000, Mohamad Al-Jaf wrote:
This could use some tests.
I've rewritten the MR and added tests. It should match Windows's behavior now.
Multiple applications are affected by the bug this patch is fixing.
So it would be good to have this in upcoming wine 9.0 I think. Any chance one of the core developers could have a review to improve chances that this patch gets in? Thanks in advance