Skip to content
Open
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
45ca5bd
Add Physics for Panels mod suite
Prashant-modder Aug 2, 2026
cd69136
Update and rename local@physics-shell.wh.cpp to physics-shell.wh.cpp
Prashant-modder Aug 2, 2026
5e61ed0
Update and rename local@physics-detector.wh.cpp to physics-detector.w…
Prashant-modder Aug 2, 2026
84c9182
Update physics-detector.wh.cpp
Prashant-modder Aug 2, 2026
61573f5
Update physics-shell.wh.cpp
Prashant-modder Aug 2, 2026
adf1657
Update physics-shell.wh.cpp
Prashant-modder Aug 2, 2026
115bfce
Update physics-detector.wh.cpp
Prashant-modder Aug 2, 2026
966c1b0
Update physics-detector.wh.cpp
Prashant-modder Aug 2, 2026
0eddf84
Update physics-detector.wh.cpp
Prashant-modder Aug 2, 2026
17ee8bf
Update physics-shell.wh.cpp
Prashant-modder Aug 2, 2026
e75e9f5
Update physics-detector.wh.cpp
Prashant-modder Aug 2, 2026
88aa3e9
Update physics-detector.wh.cpp
Prashant-modder Aug 2, 2026
2212d4f
Update physics-shell.wh.cpp
Prashant-modder Aug 2, 2026
2627937
Update physics-shell.wh.cpp
Prashant-modder Aug 2, 2026
9ed4aea
Update physics-shell.wh.cpp
Prashant-modder Aug 2, 2026
7f72604
Update physics-shell.wh.cpp
Prashant-modder Aug 2, 2026
4113174
Update physics-detector.wh.cpp
Prashant-modder Aug 2, 2026
987a2a8
Update physics-shell.wh.cpp
Prashant-modder Aug 3, 2026
cc23030
Update physics-shell.wh.cpp
Prashant-modder Aug 3, 2026
2791102
Delete mods/physics-shell.wh.cpp
Prashant-modder Aug 3, 2026
72cef4e
Update physics-detector.wh.cpp
Prashant-modder Aug 3, 2026
77446e5
Update physics-detector.wh.cpp
Prashant-modder Aug 3, 2026
d04e312
Update physics-detector.wh.cpp
Prashant-modder Aug 3, 2026
c6cbd67
Update physics-detector.wh.cpp
Prashant-modder Aug 3, 2026
00c9afd
Update physics-detector.wh.cpp
Prashant-modder Aug 3, 2026
a732520
Update physics-detector.wh.cpp
Prashant-modder Aug 3, 2026
19f3562
Rename physics-detector.wh.cpp to taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 3, 2026
2e88d6c
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 5, 2026
8641919
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 5, 2026
dccfdf0
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 5, 2026
3691c9a
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 5, 2026
43002fc
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 5, 2026
dba17dd
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 5, 2026
3160348
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 5, 2026
610ef17
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 5, 2026
01d2d5d
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 5, 2026
115aed0
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 5, 2026
169be75
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 6, 2026
c611557
Update taskbar-auto-hide-flyouts.wh.cpp
Prashant-modder Aug 6, 2026
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
200 changes: 200 additions & 0 deletions mods/taskbar-auto-hide-flyouts.wh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
// ==WindhawkMod==
// @id taskbar-auto-hide-flyouts
// @name Taskbar Auto-Hide Flyout Fix
// @description Prevents the auto-hiding taskbar from disappearing while the Quick Settings, Notification Center, or calendar flyouts are open.
// @version 1.0.0
// @author Zicronium
// @github https://github.com/Prashant-modder/
// @include explorer.exe
// @architecture x86-64
// @compilerOptions -luser32 -ldwmapi -lcomctl32
// ==/WindhawkMod==

// ==WindhawkModReadme==
/*
# Taskbar Auto-Hide Flyout Fix

This mod ensures that the Windows 11 auto-hiding taskbar stays reliably visible on screen whenever the system flyouts (Quick Settings, Notification Center, or Calendar) are active.

It handles mouse actions as well as Win+A / Win+N hotkeys gracefully by monitoring window cloaking states and intercepting both the legacy TrayUI system and the modern WinRT ViewCoordinator layout controllers.
*/
// ==/WindhawkModReadme==

#include <windows.h>
#include <dwmapi.h>
#include <windhawk_api.h>
#include <windhawk_utils.h>

#define TIMER_REARM_ID 8821
#define TIMER_POLL_INTERVAL 250
#define kTrayUITimerHide 2

static HWND FindCurrentProcessTaskbarWnd() {
HWND hTaskbar = FindWindowW(L"Shell_TrayWnd", nullptr);
if (hTaskbar) {
DWORD pid = 0;
GetWindowThreadProcessId(hTaskbar, &pid);
if (pid == GetCurrentProcessId()) {
return hTaskbar;
}
}
return nullptr;
}

// ---------------------------------------------------------------------------
// Advanced Flyout State Analysis (DWMWA_CLOAKED verification)
// ---------------------------------------------------------------------------
static bool IsTargetWindowActive(HWND hWnd) {
if (!hWnd || !IsWindowVisible(hWnd)) return false;

BOOL cloaked = FALSE;
if (FAILED(DwmGetWindowAttribute(hWnd, DWMWA_CLOAKED, &cloaked, sizeof(cloaked)))) {
cloaked = FALSE;
}
return !cloaked;
}

static bool AreShellFlyoutsOpen() {
HWND hFlyout = nullptr;
while ((hFlyout = FindWindowExW(nullptr, hFlyout, L"ControlCenterWindow", nullptr)) != nullptr) {
if (IsTargetWindowActive(hFlyout)) return true;
}

HWND hUwpWindow = nullptr;
while ((hUwpWindow = FindWindowExW(nullptr, hUwpWindow, L"Windows.UI.Core.CoreWindow", nullptr)) != nullptr) {
DWORD pid = 0;
GetWindowThreadProcessId(hUwpWindow, &pid);
HANDLE hProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (hProc) {
WCHAR imgName[MAX_PATH];
DWORD len = ARRAYSIZE(imgName);
if (QueryFullProcessImageNameW(hProc, 0, imgName, &len)) {
if (wcsstr(imgName, L"ShellExperienceHost.exe") != nullptr) {
if (IsTargetWindowActive(hUwpWindow)) {
CloseHandle(hProc);
return true;
}
}
}
CloseHandle(hProc);
}
}
return false;
}

// ---------------------------------------------------------------------------
// Hook Layers: Subclass-Safe Rearming Timers
// ---------------------------------------------------------------------------
using TrayUI__Hide_t = void(WINAPI*)(void* pThis);
TrayUI__Hide_t TrayUI__Hide_Original;

LRESULT CALLBACK TaskbarSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, DWORD_PTR dwRefData) {
if (uMsg == WM_TIMER && wParam == TIMER_REARM_ID) {
if (!AreShellFlyoutsOpen()) {
KillTimer(hWnd, TIMER_REARM_ID);
SetTimer(hWnd, kTrayUITimerHide, 0, nullptr);
}
return 0;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

void WINAPI TrayUI__Hide_Hook(void* pThis) {
if (AreShellFlyoutsOpen()) {
HWND hTaskbar = FindCurrentProcessTaskbarWnd();
if (hTaskbar) {
WindhawkUtils::SetWindowSubclassFromAnyThread(hTaskbar, TaskbarSubclassProc, TIMER_REARM_ID);
SetTimer(hTaskbar, TIMER_REARM_ID, TIMER_POLL_INTERVAL, nullptr);
}
return;
}
TrayUI__Hide_Original(pThis);
}

using CSecondaryTray__AutoHide_t = void(WINAPI*)(void* pThis, bool hide);
CSecondaryTray__AutoHide_t CSecondaryTray__AutoHide_Original;

void WINAPI CSecondaryTray__AutoHide_Hook(void* pThis, bool hide) {
if (hide && AreShellFlyoutsOpen()) {
return;
}
CSecondaryTray__AutoHide_Original(pThis, hide);
}

// ---------------------------------------------------------------------------
// Modern Win11 Hook Layer: ViewCoordinator Layout Suppression
// ---------------------------------------------------------------------------
using ShouldTaskbarBeExpanded_t = bool(__cdecl*)(void* pThis);
ShouldTaskbarBeExpanded_t ShouldTaskbarBeExpanded_Original;

bool __cdecl ShouldTaskbarBeExpanded_Hook(void* pThis) {
if (AreShellFlyoutsOpen()) {
return true;
}
return ShouldTaskbarBeExpanded_Original(pThis);
}

using LoadLibraryExW_t = HMODULE(WINAPI*)(LPCWSTR, HANDLE, DWORD);
LoadLibraryExW_t LoadLibraryExW_Original;

HMODULE WINAPI LoadLibraryExW_Hook(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) {
HMODULE hMod = LoadLibraryExW_Original(lpLibFileName, hFile, dwFlags);
if (hMod && lpLibFileName && (wcsstr(lpLibFileName, L"Taskbar.View.dll") || wcsstr(lpLibFileName, L"ExplorerExtensions.dll"))) {
// Taskbar.View.dll
WindhawkUtils::SYMBOL_HOOK hooks[] = {
{
{ LR"(public: bool __cdecl winrt::Taskbar::implementation::ViewCoordinator::ShouldTaskbarBeExpanded(void))" },
&ShouldTaskbarBeExpanded_Original,
ShouldTaskbarBeExpanded_Hook,
true
}
};
WindhawkUtils::HookSymbols(hMod, hooks, ARRAYSIZE(hooks));
}
return hMod;
}

// ---------------------------------------------------------------------------
// Mod Framework Initializer Context
// ---------------------------------------------------------------------------
BOOL Wh_ModInit() {
HMODULE hTaskbarDll = LoadLibraryExW(L"taskbar.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (hTaskbarDll) {
// taskbar.dll
WindhawkUtils::SYMBOL_HOOK hooks[] = {
{
{ LR"(public: virtual void __cdecl TrayUI::_Hide(void))" },
&TrayUI__Hide_Original,
TrayUI__Hide_Hook,
false
},
{
{ LR"(public: void __cdecl CSecondaryTray::_AutoHide(bool))" },
&CSecondaryTray__AutoHide_Original,
CSecondaryTray__AutoHide_Hook,
true
}
};
WindhawkUtils::HookSymbols(hTaskbarDll, hooks, ARRAYSIZE(hooks));
}

HMODULE hKernelBase = GetModuleHandleW(L"kernelbase.dll");
if (hKernelBase) {
auto pLoadLibraryExW = (LoadLibraryExW_t)GetProcAddress(hKernelBase, "LoadLibraryExW");
if (pLoadLibraryExW) {
WindhawkUtils::SetFunctionHook((void*)pLoadLibraryExW, (void*)LoadLibraryExW_Hook, (void**)&LoadLibraryExW_Original);
}
}

return TRUE;
}

void Wh_ModUninit() {
HWND hTaskbar = FindCurrentProcessTaskbarWnd();
if (hTaskbar) {
KillTimer(hTaskbar, TIMER_REARM_ID);
// FIX: Provided TaskbarSubclassProc to cleanly match the utility signature
WindhawkUtils::RemoveWindowSubclassFromAnyThread(hTaskbar, TaskbarSubclassProc);
SetTimer(hTaskbar, kTrayUITimerHide, 0, nullptr);
}
}
Loading