Closed kfh83 closed 9 months ago
Are you using a custom bulr method? We can't reproduce it.
Using CustomBlur method.
Are you using a custom bulr method? We can't reproduce it.
Yes
this is happening to me too, inactive blend color just doesn't do anything, it's always the active color, doesn't matter what kind of blur i choose
What software do you guys use besides StartIsBack? We've tested fresh installs of Windows 10 21H2 and 22H2 and neither of them can reproduce the problem. No issues with StartIsBack + 3rd party themes either.
What software do you guys use besides StartIsBack? We've tested fresh installs of Windows 10 21H2 and 22H2 and neither of them can reproduce the problem. No issues with StartIsBack + 3rd party themes either.
I'm on 21H2 and at the time i took the screenshot i hadn't installed StartIsBack yet, although still happens with it.
Release_x64.zip Please try this version, as I'm not sure then what other software is being used, I can only undo some of the changes first to confirm what's causing it.
I can confirm this seems to fix the issue.
Issue is fixed.
However this is not good news because it means that some software you have installed broke DwmBlurGlass and we need to know exactly which one. 🤔
However this is not good news because it means that some software you have installed broke DwmBlurGlass and we need to know exactly which one. 🤔
I didn't install anything from trying the original 2.0.1 binaries and the ones uploaded just now.
This is not possible, you may have installed some windhawk mods, or perhaps a udwm patch, or something else, because DwmBlurGlass works normally on a fresh install of Windows.
I just reverted it and tested it without any windhawk mods or patches (i don't patch uDWM anyways) and the issue still happens.
This is not possible, you may have installed some windhawk mods, or perhaps a udwm patch, or something else, because DwmBlurGlass works normally on a fresh install of Windows.
Oh nevermind, it seems like it's the caption button restorer mod on windhawk. I restarted DWM and the issue wouldn't happen, then i opened windhawk with the mod enabled and it did break the inactive colors @angelbruni
But why did it work before?
DwmBlurGlass used to read memory directly from a specific address, however this is a dangerous behavior and leads to poor compatibility.
After inspecting the Windhawk mod, I've concluded that the problem is caused by the TreatAsActiveWindow
hook.
The Windhawk mod does
bool CTopLevelWindow_TreatAsActiveWindow_Hook(void) { return TRUE; };
in order to keep the inactive buttons not faded, like Windows 7.
With the hook:
Without the hook:
If a similar thing could be implemented in DWMBlurGlass it would be nice.
Where is this module released?
Previously, we accessed the active state of a window by hard-coding its memory address; in the recent update we switched to using the TreatAsActiveWindow function directly so this caused this issue. Before After
But this reduces maintainability and compatibility, that's why we made the adjustment.
Looks like we'll have to emulate TreatAsActiveWindow's behavior in every Windows version from now on, sadly!
I am sorry, I've copied the wrong code. Edited my comment (15 minutes ago). Unfortunately it has not been released and it's not ours either. I can give you only part of the mod that does the TreatAsActiveWindow behaviour.
bool (*CTopLevelWindow_TreatAsActiveWindow_Original)(void);
bool CTopLevelWindow_TreatAsActiveWindow_Hook(void) {
return TRUE;
}
BOOL Wh_ModInit(void) {
HMODULE uDWM = GetModuleHandle(L"uDWM.dll");
if (!uDWM)
return FALSE;
WH_FIND_SYMBOL findSymbol;
HANDLE findSymbolHandle = Wh_FindFirstSymbol(uDWM, nullptr, &findSymbol);
if (!findSymbolHandle) {
Wh_Log(L"Wh_FindFirstSymbol failed");
return FALSE;
}
void* TreatAsActiveWindowAddr = nullptr;
do {
if (_wcsicmp(findSymbol.symbol,
L"private: bool __cdecl "
L"CTopLevelWindow::TreatAsActiveWindow(void)") == 0) {
TreatAsActiveWindowAddr = findSymbol.address;
Wh_Log(L"symbol: %s, Addr: %i", findSymbol.symbol,
findSymbol.address);
}
} while (Wh_FindNextSymbol(findSymbolHandle, &findSymbol));
Wh_SetFunctionHook(TreatAsActiveWindowAddr,
(void*)CTopLevelWindow_TreatAsActiveWindow_Hook,
(void**)&CTopLevelWindow_TreatAsActiveWindow_Original);
return TRUE;
}
TreatAsActiveWindow is a behaviour in every Windows version from now on, but is there an alternative to disable the fading? Maybe finding the value that sets the opacity/alpha?
Did @dulappy write this?
Yes. This a small portion of the pre-pre-pre-pre-pre-alpha of the final code (which is probably very different and that we don't have access to), so it could be doomed to break soon (like it is with the usage of DWMBlurGlass in this specific occasion).
Did @Dulappy write this?
Yes
Edit : I would like to retract my statement and return to just observing the conversation :)
I think it's possible to patch the CTopLevelWindow::UpdateButtonVisuals call to CTopLevelWindow::TreatAsActiveWindow, and modifying the offset corresponding to 0xE8 should work. Here's a sample code.
class TrampolinePool
{
public:
UCHAR* Allocate(PVOID detourFunction)
{
if (!m_buffer)
{
return nullptr;
}
#ifdef _WIN64
UCHAR jmpCode[14]{ 0xFF, 0x25 };
memcpy_s(&jmpCode[6], sizeof(PVOID), &detourFunction, sizeof(detourFunction));
#else
UCHAR jmpCode[]{ 0xB8, 0, 0, 0, 0, 0xFF, 0xE0, 0 };
memcpy_s(&jmpCode[1], sizeof(PVOID), &detourFunction, sizeof(detourFunction));
#endif
if (m_current + sizeof(jmpCode) > m_end)
{
return nullptr;
}
auto startPos{ m_current };
memcpy(startPos, jmpCode, sizeof(jmpCode));
m_current += sizeof(jmpCode);
return startPos;
}
TrampolinePool(PVOID startAddress)
{
m_buffer.reset(
static_cast<UCHAR*>(DetourAllocateRegionWithinJumpBounds(startAddress, &m_bufferSize))
);
m_current = m_buffer.get();
m_end = m_current + m_bufferSize;
}
~TrampolinePool() = default;
private:
DWORD m_bufferSize{0};
wil::unique_virtualalloc_ptr<UCHAR> m_buffer{ nullptr };
UCHAR* m_current{ nullptr }, * m_end{ nullptr };
};
LONG ReplaceE8Call(LONG* callOffset, PVOID trampolineAddress)
{
auto callBaseAddress{ reinterpret_cast<UCHAR*>(reinterpret_cast<DWORD64>(callOffset) + sizeof(LONG)) };
auto originalOffset{ *callOffset };
HookHelper::WriteMemory(callOffset, [&]
{
*callOffset = static_cast<LONG>(reinterpret_cast<UCHAR*>(trampolineAddress) - callBaseAddress);
});
return originalOffset;
}
Please relay this to Dulappy if you can, we don't want to simulate the behavior of TreatAsActiveWindow.
Good luck with getting it to work! I was simply inspecting the code. Unfortunately, I have no coding expertise but thought I should help in any way I can.
There is also CButton::UpdateCurrentGlyphOpacity
This simple Windhawk mod always sets the glyph opacity to 1, tested on windows 21H2 LTSC
// ==WindhawkMod==
// @id inactive-button-opacity
// @name Inactive Button Opacity
// @version 0.1
// @include dwm.exe
// ==/WindhawkMod==
#include <windhawk_utils.h>
bool (__thiscall *CButton__UpdateCurrentGlyphOpacity_orig)(void *, bool);
bool __thiscall CButton__UpdateCurrentGlyphOpacity_hook(void *pThis, bool param_1) {
*((float *)pThis + 101) = 1.0;
return CButton__UpdateCurrentGlyphOpacity_orig(pThis, param_1);
}
BOOL Wh_ModInit() {
Wh_Log(L"Init");
HMODULE uDWM = LoadLibraryW(L"uDWM.dll");
if (!uDWM) {
Wh_Log(L"Failed to load uDWM.dll");
return FALSE;
}
WindhawkUtils::SYMBOL_HOOK symbolHook[] = {
{
{L"private: void __cdecl CButton::UpdateCurrentGlyphOpacity(bool)"},
(void**)&CButton__UpdateCurrentGlyphOpacity_orig,
(void*)CButton__UpdateCurrentGlyphOpacity_hook,
},
};
if (!WindhawkUtils::HookSymbols(uDWM, symbolHook, 1)) {
Wh_Log(L"Error hooking");
return FALSE;
}
return TRUE;
}
Now that you have a solution, I will close it.
As the title says. I've already tried deleting my old config, restarting my machine and DWM itself and no change, except that it worked once after installing.