Taskbar thumbnails use inactive window opacity #211
Replies: 14 comments
|
Since windows 10 1809 DWM has introduced a change making it possible for thumbnails to use inactive colorization, I will update the mod later to fix this. |
|
Try this // ==WindhawkMod==
// @id sxb-w7-shell-ui-accent-overrider
// @name SXB Win7 Shell UI Accent Overrider
// @description Override accent to dwm blur behind for sxb shell ui
// @version 1.2
// @author ALTaleX
// @github https://github.com/ALTaleX531
// @include explorer.exe
// @compilerOptions -ldwmapi -lgdi32
// ==/WindhawkMod==
#include <windhawk_api.h>
#include <wingdi.h>
#include <winuser.h>
#include <dwmapi.h>
struct ACCENT_POLICY
{
DWORD AccentState;
DWORD AccentFlags;
DWORD dwGradientColor;
DWORD dwAnimationId;
};
enum WINDOWCOMPOSITIONATTRIBUTE
{
WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
WCA_ACCENT_POLICY = 19
};
struct WINDOWCOMPOSITIONATTRIBUTEDATA
{
WINDOWCOMPOSITIONATTRIBUTE Attribute;
PVOID pvData;
SIZE_T cbData;
};
BOOL (WINAPI *pOriginalSetWindowCompositionAttribute)(HWND, const WINDOWCOMPOSITIONATTRIBUTEDATA*);
BOOL WINAPI SetWindowCompositionAttributeHook(HWND hWnd, const WINDOWCOMPOSITIONATTRIBUTEDATA* data)
{
auto& accentPolicy = *reinterpret_cast<ACCENT_POLICY*>(data->pvData);
if (
data->Attribute != WCA_ACCENT_POLICY ||
(
RegisterWindowMessageW(L"DV2ControlHost") != GetClassWord(hWnd, GCW_ATOM) &&
RegisterWindowMessageW(L"Shell_TrayWnd") != GetClassWord(hWnd, GCW_ATOM) &&
RegisterWindowMessageW(L"Shell_SecondaryTrayWnd") != GetClassWord(hWnd, GCW_ATOM) &&
RegisterWindowMessageW(L"SIBJumpView") != GetClassWord(hWnd, GCW_ATOM) &&
(!GetModuleHandleW(L"StartAllBackX64.dll") || RegisterWindowMessageW(L"TaskListThumbnailWnd") != GetClassWord(hWnd, GCW_ATOM))
)
)
{
return pOriginalSetWindowCompositionAttribute(hWnd, data);
}
if (accentPolicy.AccentState == 1)
{
DWM_BLURBEHIND blurBehind
{
.dwFlags = DWM_BB_ENABLE
};
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
return pOriginalSetWindowCompositionAttribute(hWnd, data);
}
DWM_BLURBEHIND blurBehind
{
.dwFlags = DWM_BB_ENABLE,
.fEnable = accentPolicy.AccentState != 0
};
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
ACCENT_POLICY replacedAccentPolicy{};
WINDOWCOMPOSITIONATTRIBUTEDATA replacedData
{
.Attribute = WCA_ACCENT_POLICY,
.pvData = &replacedAccentPolicy,
.cbData = sizeof(replacedAccentPolicy)
};
return pOriginalSetWindowCompositionAttribute(hWnd, &replacedData);
}
decltype(&SetWindowRgn) pOriginalSetWindowRgn;
int WINAPI SetWindowRgnHook(HWND hWnd, HRGN hRgn, WINBOOL bRedraw)
{
if (
RegisterWindowMessageW(L"DV2ControlHost") != GetClassWord(hWnd, GCW_ATOM)
)
{
return pOriginalSetWindowRgn(hWnd, hRgn, bRedraw);
}
ACCENT_POLICY accentPolicy{};
WINDOWCOMPOSITIONATTRIBUTEDATA data
{
.Attribute = WCA_ACCENT_POLICY,
.pvData = &accentPolicy,
.cbData = sizeof(accentPolicy)
};
pOriginalSetWindowCompositionAttribute(hWnd, &data);
return pOriginalSetWindowRgn(hWnd, hRgn, bRedraw);
}
HRESULT (WINAPI *pOriginalDwmpUpdateAccentBlurRect)(HWND, LPCRECT);
HRESULT WINAPI DwmpUpdateAccentBlurRectHook(HWND hWnd, LPCRECT lprc)
{
if (
RegisterWindowMessageW(L"TaskListThumbnailWnd") != GetClassWord(hWnd, GCW_ATOM) &&
RegisterWindowMessageW(L"SIBJumpView") != GetClassWord(hWnd, GCW_ATOM)
)
{
return pOriginalDwmpUpdateAccentBlurRect(hWnd, lprc);
}
ACCENT_POLICY accentPolicy{};
WINDOWCOMPOSITIONATTRIBUTEDATA data
{
.Attribute = WCA_ACCENT_POLICY,
.pvData = &accentPolicy,
.cbData = sizeof(accentPolicy)
};
pOriginalSetWindowCompositionAttribute(hWnd, &data);
BOOL active{ TRUE };
data =
{
.Attribute = WCA_FORCE_ACTIVEWINDOW_APPEARANCE,
.pvData = &active,
.cbData = sizeof(active),
};
pOriginalSetWindowCompositionAttribute(hWnd, &data);
HRESULT hr{ S_OK };
DWM_BLURBEHIND blurBehind
{
.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION,
.fEnable = TRUE,
.hRgnBlur = CreateRoundRectRgn(lprc->left, lprc->top, lprc->right, lprc->bottom + 2, 4, 4)
};
hr = DwmEnableBlurBehindWindow(hWnd, &blurBehind);
DeleteObject(blurBehind.hRgnBlur);
return hr;
}
// The mod is being initialized, load settings, hook functions, and do other
// initialization stuff if required.
BOOL Wh_ModInit()
{
Wh_Log(L"Init");
pOriginalSetWindowCompositionAttribute = reinterpret_cast<decltype(pOriginalSetWindowCompositionAttribute)>(GetProcAddress(GetModuleHandleW(L"user32.dll"), "SetWindowCompositionAttribute"));
pOriginalDwmpUpdateAccentBlurRect = reinterpret_cast<decltype(pOriginalDwmpUpdateAccentBlurRect)>(GetProcAddress(GetModuleHandleW(L"dwmapi.dll"), MAKEINTRESOURCEA(159)));
Wh_SetFunctionHook(reinterpret_cast<void*>(SetWindowRgn), reinterpret_cast<void*>(SetWindowRgnHook), reinterpret_cast<void**>(&pOriginalSetWindowRgn));
Wh_SetFunctionHook(reinterpret_cast<void*>(pOriginalSetWindowCompositionAttribute), reinterpret_cast<void*>(SetWindowCompositionAttributeHook), reinterpret_cast<void**>(&pOriginalSetWindowCompositionAttribute));
Wh_SetFunctionHook(reinterpret_cast<void*>(pOriginalDwmpUpdateAccentBlurRect), reinterpret_cast<void*>(DwmpUpdateAccentBlurRectHook), reinterpret_cast<void**>(&pOriginalDwmpUpdateAccentBlurRect));
return TRUE;
}
void Wh_ModAfterInit()
{
ACCENT_POLICY accentPolicy
{
.AccentState = 3
};
WINDOWCOMPOSITIONATTRIBUTEDATA data
{
.Attribute = WCA_ACCENT_POLICY,
.pvData = &accentPolicy,
.cbData = sizeof(accentPolicy)
};
if (const auto hWnd = FindWindowW(L"DV2ControlHost", nullptr); hWnd)
{
SetWindowCompositionAttributeHook(hWnd, &data);
}
if (const auto hWnd = FindWindowW(L"Shell_TrayWnd", nullptr); hWnd)
{
SetWindowCompositionAttributeHook(hWnd, &data);
}
if (const auto hWnd = FindWindowW(L"Shell_SecondaryTrayWnd", nullptr); hWnd)
{
SetWindowCompositionAttributeHook(hWnd, &data);
}
if (const auto hWnd = FindWindowW(L"TaskListThumbnailWnd", nullptr); hWnd)
{
SetWindowCompositionAttributeHook(hWnd, &data);
}
}
// The mod is being unloaded, free all allocated resources.
void Wh_ModUninit()
{
Wh_Log(L"Uninit");
ACCENT_POLICY accentPolicy
{
.AccentState = 4,
.AccentFlags = 0x13,
.dwGradientColor = 1
};
WINDOWCOMPOSITIONATTRIBUTEDATA data
{
.Attribute = WCA_ACCENT_POLICY,
.pvData = &accentPolicy,
.cbData = sizeof(accentPolicy)
};
DWM_BLURBEHIND blurBehind
{
.dwFlags = DWM_BB_ENABLE
};
if (const auto hWnd = FindWindowW(L"DV2ControlHost", nullptr); hWnd)
{
pOriginalSetWindowCompositionAttribute(hWnd, &data);
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
}
if (const auto hWnd = FindWindowW(L"Shell_TrayWnd", nullptr); hWnd)
{
pOriginalSetWindowCompositionAttribute(hWnd, &data);
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
}
if (const auto hWnd = FindWindowW(L"Shell_SecondaryTrayWnd", nullptr); hWnd)
{
pOriginalSetWindowCompositionAttribute(hWnd, &data);
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
}
if (const auto hWnd = FindWindowW(L"TaskListThumbnailWnd", nullptr); hWnd)
{
accentPolicy =
{
.AccentState = 3,
.AccentFlags = 0x200
};
data.pvData = &accentPolicy;
pOriginalSetWindowCompositionAttribute(hWnd, &data);
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
}
} |
|
This did not appear to resolve the issue on either test build 7 or Legacy 2.0.4. |
Let me test this further and I will get back to you. |
|
This works in the test build 8. I'll assume it continues to work in future builds. Closing for the time being. |
|
So this works only intermittently. It did work for a short time, but now it won't anymore... I just have not had the time to report back on it. If I disable the mod, it works fine, but causes black boxes to appear behind the taskbar preview during the raising animation. Not sure what caused it to work normally for a day, then right back to inactive later. I'm using the latest released legacy build now. |
|
Try this. // ==WindhawkMod==
// @id sxb-w7-shell-ui-accent-overrider
// @name SXB Win7 Shell UI Accent Overrider
// @description Override accent to dwm blur behind for sxb shell ui
// @version 1.3
// @author ALTaleX
// @github https://github.com/ALTaleX531
// @include explorer.exe
// @compilerOptions -ldwmapi -lgdi32
// ==/WindhawkMod==
#include <debugapi.h>
#include <mmsystem.h>
#include <windhawk_api.h>
#include <wingdi.h>
#include <winuser.h>
#include <dwmapi.h>
#include <string>
struct ACCENT_POLICY
{
DWORD AccentState;
DWORD AccentFlags;
DWORD dwGradientColor;
DWORD dwAnimationId;
};
enum WINDOWCOMPOSITIONATTRIBUTE
{
WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
WCA_ACCENT_POLICY = 19
};
struct WINDOWCOMPOSITIONATTRIBUTEDATA
{
WINDOWCOMPOSITIONATTRIBUTE Attribute;
PVOID pvData;
SIZE_T cbData;
};
BOOL (WINAPI *pOriginalSetWindowCompositionAttribute)(HWND, const WINDOWCOMPOSITIONATTRIBUTEDATA*);
bool g_workroundApplied{ false };
void ApplyColorizationWorkround(HWND hWnd)
{
if(g_workroundApplied)
{
return;
}
// workround for dwm weird behavior
BOOL active{ TRUE };
WINDOWCOMPOSITIONATTRIBUTEDATA data
{
.Attribute = WCA_FORCE_ACTIVEWINDOW_APPEARANCE,
.pvData = &active,
.cbData = sizeof(active),
};
pOriginalSetWindowCompositionAttribute(hWnd, &data);
SetWindowLongPtrW(hWnd, GWL_EXSTYLE, GetWindowLongPtrW(hWnd, GWL_EXSTYLE) &~ WS_EX_LAYERED);
SetWindowLongPtrW(hWnd, GWL_EXSTYLE, GetWindowLongPtrW(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
g_workroundApplied = true;
}
BOOL WINAPI SetWindowCompositionAttributeHook(HWND hWnd, const WINDOWCOMPOSITIONATTRIBUTEDATA* data)
{
auto& accentPolicy = *reinterpret_cast<ACCENT_POLICY*>(data->pvData);
// if (RegisterWindowMessageW(L"TaskListThumbnailWnd") == GetClassWord(hWnd, GCW_ATOM))
// {
// OutputDebugStringW((std::wstring(L"AccentFlags: ") + std::to_wstring(accentPolicy.AccentFlags)).c_str());
// OutputDebugStringW((std::wstring(L"dwGradientColor: ") + std::to_wstring(accentPolicy.dwGradientColor)).c_str());
// }
if (
data->Attribute != WCA_ACCENT_POLICY ||
(
RegisterWindowMessageW(L"DV2ControlHost") != GetClassWord(hWnd, GCW_ATOM) &&
RegisterWindowMessageW(L"Shell_TrayWnd") != GetClassWord(hWnd, GCW_ATOM) &&
RegisterWindowMessageW(L"Shell_SecondaryTrayWnd") != GetClassWord(hWnd, GCW_ATOM) &&
RegisterWindowMessageW(L"SIBJumpView") != GetClassWord(hWnd, GCW_ATOM) &&
RegisterWindowMessageW(L"TaskListThumbnailWnd") != GetClassWord(hWnd, GCW_ATOM)
)
)
{
return pOriginalSetWindowCompositionAttribute(hWnd, data);
}
if (accentPolicy.AccentState == 1)
{
DWM_BLURBEHIND blurBehind
{
.dwFlags = DWM_BB_ENABLE
};
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
return pOriginalSetWindowCompositionAttribute(hWnd, data);
}
DWM_BLURBEHIND blurBehind
{
.dwFlags = DWM_BB_ENABLE,
.fEnable = accentPolicy.AccentState != 0
};
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
ACCENT_POLICY replacedAccentPolicy{};
WINDOWCOMPOSITIONATTRIBUTEDATA replacedData
{
.Attribute = WCA_ACCENT_POLICY,
.pvData = &replacedAccentPolicy,
.cbData = sizeof(replacedAccentPolicy)
};
return pOriginalSetWindowCompositionAttribute(hWnd, &replacedData);
}
decltype(&SetWindowRgn) pOriginalSetWindowRgn;
int WINAPI SetWindowRgnHook(HWND hWnd, HRGN hRgn, WINBOOL bRedraw)
{
if (
RegisterWindowMessageW(L"DV2ControlHost") != GetClassWord(hWnd, GCW_ATOM)
)
{
return pOriginalSetWindowRgn(hWnd, hRgn, bRedraw);
}
ACCENT_POLICY accentPolicy{};
WINDOWCOMPOSITIONATTRIBUTEDATA data
{
.Attribute = WCA_ACCENT_POLICY,
.pvData = &accentPolicy,
.cbData = sizeof(accentPolicy)
};
pOriginalSetWindowCompositionAttribute(hWnd, &data);
return pOriginalSetWindowRgn(hWnd, hRgn, bRedraw);
}
HRESULT (WINAPI *pOriginalDwmpUpdateAccentBlurRect)(HWND, LPCRECT);
HRESULT WINAPI DwmpUpdateAccentBlurRectHook(HWND hWnd, LPCRECT lprc)
{
if (
RegisterWindowMessageW(L"TaskListThumbnailWnd") != GetClassWord(hWnd, GCW_ATOM) &&
RegisterWindowMessageW(L"SIBJumpView") != GetClassWord(hWnd, GCW_ATOM)
)
{
return pOriginalDwmpUpdateAccentBlurRect(hWnd, lprc);
}
ApplyColorizationWorkround(hWnd);
ACCENT_POLICY accentPolicy{};
WINDOWCOMPOSITIONATTRIBUTEDATA data
{
.Attribute = WCA_ACCENT_POLICY,
.pvData = &accentPolicy,
.cbData = sizeof(accentPolicy)
};
pOriginalSetWindowCompositionAttribute(hWnd, &data);
HRESULT hr{ S_OK };
DWM_BLURBEHIND blurBehind
{
.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION,
.fEnable = TRUE,
.hRgnBlur = CreateRoundRectRgn(lprc->left, lprc->top, lprc->right, lprc->bottom + 2, 4, 4)
};
hr = DwmEnableBlurBehindWindow(hWnd, &blurBehind);
DeleteObject(blurBehind.hRgnBlur);
return hr;
}
// The mod is being initialized, load settings, hook functions, and do other
// initialization stuff if required.
BOOL Wh_ModInit()
{
Wh_Log(L"Init");
pOriginalSetWindowCompositionAttribute = reinterpret_cast<decltype(pOriginalSetWindowCompositionAttribute)>(GetProcAddress(GetModuleHandleW(L"user32.dll"), "SetWindowCompositionAttribute"));
pOriginalDwmpUpdateAccentBlurRect = reinterpret_cast<decltype(pOriginalDwmpUpdateAccentBlurRect)>(GetProcAddress(GetModuleHandleW(L"dwmapi.dll"), MAKEINTRESOURCEA(159)));
Wh_SetFunctionHook(reinterpret_cast<void*>(SetWindowRgn), reinterpret_cast<void*>(SetWindowRgnHook), reinterpret_cast<void**>(&pOriginalSetWindowRgn));
Wh_SetFunctionHook(reinterpret_cast<void*>(pOriginalSetWindowCompositionAttribute), reinterpret_cast<void*>(SetWindowCompositionAttributeHook), reinterpret_cast<void**>(&pOriginalSetWindowCompositionAttribute));
Wh_SetFunctionHook(reinterpret_cast<void*>(pOriginalDwmpUpdateAccentBlurRect), reinterpret_cast<void*>(DwmpUpdateAccentBlurRectHook), reinterpret_cast<void**>(&pOriginalDwmpUpdateAccentBlurRect));
return TRUE;
}
void Wh_ModAfterInit()
{
ACCENT_POLICY accentPolicy
{
.AccentState = 3
};
WINDOWCOMPOSITIONATTRIBUTEDATA data
{
.Attribute = WCA_ACCENT_POLICY,
.pvData = &accentPolicy,
.cbData = sizeof(accentPolicy)
};
if (const auto hWnd = FindWindowW(L"DV2ControlHost", nullptr); hWnd)
{
SetWindowCompositionAttributeHook(hWnd, &data);
}
if (const auto hWnd = FindWindowW(L"Shell_TrayWnd", nullptr); hWnd)
{
SetWindowCompositionAttributeHook(hWnd, &data);
}
if (const auto hWnd = FindWindowW(L"Shell_SecondaryTrayWnd", nullptr); hWnd)
{
SetWindowCompositionAttributeHook(hWnd, &data);
}
if (const auto hWnd = FindWindowW(L"TaskListThumbnailWnd", nullptr); hWnd)
{
SetWindowCompositionAttributeHook(hWnd, &data);
ApplyColorizationWorkround(hWnd);
}
}
// The mod is being unloaded, free all allocated resources.
void Wh_ModUninit()
{
Wh_Log(L"Uninit");
ACCENT_POLICY accentPolicy
{
.AccentState = 4,
.AccentFlags = 0x13,
.dwGradientColor = 1
};
WINDOWCOMPOSITIONATTRIBUTEDATA data
{
.Attribute = WCA_ACCENT_POLICY,
.pvData = &accentPolicy,
.cbData = sizeof(accentPolicy)
};
DWM_BLURBEHIND blurBehind
{
.dwFlags = DWM_BB_ENABLE
};
if (const auto hWnd = FindWindowW(L"DV2ControlHost", nullptr); hWnd)
{
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
pOriginalSetWindowCompositionAttribute(hWnd, &data);
}
if (const auto hWnd = FindWindowW(L"Shell_TrayWnd", nullptr); hWnd)
{
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
pOriginalSetWindowCompositionAttribute(hWnd, &data);
}
if (const auto hWnd = FindWindowW(L"Shell_SecondaryTrayWnd", nullptr); hWnd)
{
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
pOriginalSetWindowCompositionAttribute(hWnd, &data);
}
if (const auto hWnd = FindWindowW(L"TaskListThumbnailWnd", nullptr); hWnd)
{
blurBehind.fEnable = TRUE;
blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
DwmEnableBlurBehindWindow(hWnd, &blurBehind);
DeleteObject(blurBehind.hRgnBlur);
accentPolicy.AccentState = 3;
accentPolicy.AccentFlags = 0x200;
data.pvData = &accentPolicy;
pOriginalSetWindowCompositionAttribute(hWnd, &data);
RECT blurRect{};
DwmpUpdateAccentBlurRectHook(hWnd, &blurRect);
}
} |
Just complied this in Windhawk and it seems to be playing nicely for right now. I'll give it a week, and if all is normal, I'll close the issue again. Edit to include initial tests: with dual monitors, it works fine on monitor 2, but it still uses the inactive color on the primary monitor. Wonder why it has issues for different monitors? Certainly curious. |
|
Still have the same issue as my last comment, but I also realized that the black boxes behind the thumbnails are back, as I mentioned in an earlier issue. Still testing for any other issues. |
|
This is not an OpenGlass issue, it's a mod issue, and updating OpenGlass will not fix this. |
|
Yes, I am aware. I just don't know what else we can do to the mod to make it appear correctly. From what I can read, it all looks correct. |
|
While I'm testing the borders issue, I noticed that after restarting DWM, the taskbar thumbnails show the active color properly now, but only after restarting DWM once OpenGlass loads. I don't know if this helps you solve anything though. |
|
This is dwm issue, this is a bug in windows. |

Uh oh!
There was an error while loading. Please reload this page.
Using StartIsBack, the taskbar preview for Aero Peek uses the inactive window opacity as opposed to the active window opacity. I wonder if this has anything to do with the reflections not being shown on the taskbar as well, however the taskbar does use the active window opacity.
All reactions