From 8195a025df8ce6bfbd9a3dab732811619d75d205 Mon Sep 17 00:00:00 2001 From: Michael Maltsev <4129781+m417z@users.noreply.github.com> Date: Mon, 28 Oct 2024 00:08:50 +0200 Subject: [PATCH] Taskbar on top for Windows 11 v1.0.4 (#1162) * Fixed the start menu opening on the left side of the screen, even if the icons on the taskbar are centered. The bug was caused by the attempt to change the incorrect jump list animation in version 1.0.3. As a result, if icons are centered, jump list animation will be incorrect again. This affects only Windows 11 23H2, there's no such issue on Windows 11 24H2. --- mods/taskbar-on-top.wh.cpp | 102 +++++++++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 3 deletions(-) diff --git a/mods/taskbar-on-top.wh.cpp b/mods/taskbar-on-top.wh.cpp index 55485e0b..d940ed28 100644 --- a/mods/taskbar-on-top.wh.cpp +++ b/mods/taskbar-on-top.wh.cpp @@ -2,14 +2,14 @@ // @id taskbar-on-top // @name Taskbar on top for Windows 11 // @description Moves the Windows 11 taskbar to the top of the screen -// @version 1.0.3 +// @version 1.0.4 // @author m417z // @github https://github.com/m417z // @twitter https://twitter.com/m417z // @homepage https://m417z.com/ // @include explorer.exe // @architecture x86-64 -// @compilerOptions -DWINVER=0x0A00 -ldwmapi -lole32 -loleaut32 -lruntimeobject -lshcore +// @compilerOptions -DWINVER=0x0A00 -ldwmapi -lole32 -loleaut32 -lruntimeobject -lshcore -lversion // ==/WindhawkMod== // Source code is published under The GNU General Public License v3.0. @@ -106,6 +106,7 @@ std::atomic g_hookCallCounter; bool g_inCTaskListThumbnailWnd_DisplayUI; bool g_inCTaskListThumbnailWnd_LayoutThumbnails; bool g_inOverflowFlyoutModel_Show; +int g_lastTaskbarAlignment; using FrameworkElementLoadedEventRevoker = winrt::impl::event_revoker< IFrameworkElement, @@ -130,6 +131,60 @@ using GetThreadDescription_t = WINBASEAPI HRESULT(WINAPI*)(HANDLE hThread, PWSTR* ppszThreadDescription); GetThreadDescription_t pGetThreadDescription; +VS_FIXEDFILEINFO* GetModuleVersionInfo(HMODULE hModule, UINT* puPtrLen) { + void* pFixedFileInfo = nullptr; + UINT uPtrLen = 0; + + HRSRC hResource = + FindResource(hModule, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION); + if (hResource) { + HGLOBAL hGlobal = LoadResource(hModule, hResource); + if (hGlobal) { + void* pData = LockResource(hGlobal); + if (pData) { + if (!VerQueryValue(pData, L"\\", &pFixedFileInfo, &uPtrLen) || + uPtrLen == 0) { + pFixedFileInfo = nullptr; + uPtrLen = 0; + } + } + } + } + + if (puPtrLen) { + *puPtrLen = uPtrLen; + } + + return (VS_FIXEDFILEINFO*)pFixedFileInfo; +} + +bool IsVersionAtLeast(WORD major, WORD minor, WORD build, WORD qfe) { + static VS_FIXEDFILEINFO* fixedFileInfo = + GetModuleVersionInfo(nullptr, nullptr); + if (!fixedFileInfo) { + return false; + } + + WORD moduleMajor = HIWORD(fixedFileInfo->dwFileVersionMS); + WORD moduleMinor = LOWORD(fixedFileInfo->dwFileVersionMS); + WORD moduleBuild = HIWORD(fixedFileInfo->dwFileVersionLS); + WORD moduleQfe = LOWORD(fixedFileInfo->dwFileVersionLS); + + if (moduleMajor != major) { + return moduleMajor > major; + } + + if (moduleMinor != minor) { + return moduleMinor > minor; + } + + if (moduleBuild != build) { + return moduleBuild > build; + } + + return moduleQfe >= qfe; +} + bool GetMonitorRect(HMONITOR monitor, RECT* rc) { MONITORINFO monitorInfo{ .cbSize = sizeof(MONITORINFO), @@ -331,7 +386,15 @@ void WINAPI TrayUI_GetStuckInfo_Hook(void* pThis, TrayUI_GetStuckInfo_Original(pThis, rect, taskbarPos); - *taskbarPos = ABE_TOP; + switch (g_settings.taskbarLocation) { + case TaskbarLocation::top: + *taskbarPos = ABE_TOP; + break; + + case TaskbarLocation::bottom: + *taskbarPos = ABE_BOTTOM; + break; + } } void TaskbarWndProcPreProcess(HWND hWnd, @@ -340,6 +403,16 @@ void TaskbarWndProcPreProcess(HWND hWnd, LPARAM* lParam) { switch (Msg) { case 0x5C3: { + // On Windows 11 23H2, setting the taskbar location here also causes + // the start menu to be opened on the left of the screen, even if + // the icons on the taskbar are centered. Therefore, only set it if + // the icons are aligned to left, not centered. The drawback is that + // the jump list animations won't be correct in this case. + if (g_lastTaskbarAlignment == 1 && + !IsVersionAtLeast(10, 0, 26100, 0)) { + break; + } + // The taskbar location that affects the jump list animations. if (*wParam == ABE_BOTTOM) { HMONITOR monitor = (HMONITOR)lParam; @@ -596,6 +669,22 @@ void* WINAPI XamlExplorerHostWindow_XamlExplorerHostWindow_Hook( rect, param3); } +using ITaskbarSettings_get_Alignment_t = HRESULT(WINAPI*)(void* pThis, + int* alignment); +ITaskbarSettings_get_Alignment_t ITaskbarSettings_get_Alignment_Original; +HRESULT WINAPI ITaskbarSettings_get_Alignment_Hook(void* pThis, + int* alignment) { + Wh_Log(L">"); + + HRESULT ret = ITaskbarSettings_get_Alignment_Original(pThis, alignment); + if (SUCCEEDED(ret)) { + Wh_Log(L"alignment=%d", *alignment); + g_lastTaskbarAlignment = *alignment; + } + + return ret; +} + void ApplyTaskbarFrameStyle(FrameworkElement taskbarFrame) { if (g_settings.taskbarLocation != TaskbarLocation::top) { return; @@ -1442,6 +1531,13 @@ bool HookTaskbarDllSymbols() { (void**)&XamlExplorerHostWindow_XamlExplorerHostWindow_Original, (void*)XamlExplorerHostWindow_XamlExplorerHostWindow_Hook, }, + { + { + LR"(public: virtual int __cdecl winrt::impl::produce::get_Alignment(int *))", + }, + (void**)&ITaskbarSettings_get_Alignment_Original, + (void*)ITaskbarSettings_get_Alignment_Hook, + }, }; return HookSymbols(module, taskbarDllHooks, ARRAYSIZE(taskbarDllHooks));