diff --git a/mods/taskbar-icon-size.wh.cpp b/mods/taskbar-icon-size.wh.cpp index 949858647..0d24303c9 100644 --- a/mods/taskbar-icon-size.wh.cpp +++ b/mods/taskbar-icon-size.wh.cpp @@ -2,7 +2,7 @@ // @id taskbar-icon-size // @name Taskbar height and icon size // @description Control the taskbar height and icon size, improve icon quality (Windows 11 only) -// @version 1.2.14 +// @version 1.2.15 // @author m417z // @github https://github.com/m417z // @twitter https://twitter.com/m417z @@ -33,17 +33,22 @@ versions of the 32x32 variants, which makes them blurry. This mod allows to change the size of icons, and so the original quality icons can be used, as well as any other icon size. -![Before screenshot](https://i.imgur.com/9F4ibhX.png) \ +![Before screenshot](https://i.imgur.com/TLza5fp.png) \ *Icon size: 24x24, taskbar height: 48 (Windows 11 default)* -![After screenshot, large icons](https://i.imgur.com/DtsNIew.png) \ +![After screenshot, large icons](https://i.imgur.com/3b8h40F.png) \ *Icon size: 32x32, taskbar height: 52* -![After screenshot, small icons](https://i.imgur.com/HrKj49g.png) \ +![After screenshot, small icons](https://i.imgur.com/Xy04Zcu.png) \ *Icon size: 16x16, taskbar height: 34* +![After screenshot, small and narrow icons](https://i.imgur.com/fsx8C56.png) \ +*Icon size: 16x16, taskbar height: 34, taskbar button width: 28* + Only Windows 11 is supported. For older Windows versions check out [7+ Taskbar Tweaker](https://tweaker.ramensoftware.com/). + +Also check out the **Taskbar tray icon spacing** mod. */ // ==/WindhawkModReadme== @@ -61,8 +66,6 @@ Tweaker](https://tweaker.ramensoftware.com/). $name: Taskbar button width $description: >- The width, in pixels, of the taskbar buttons (Windows 11 default: 44) - - Note: Explorer has to be restarted after changing this option */ // ==/WindhawkModSettings== @@ -74,7 +77,9 @@ Tweaker](https://tweaker.ramensoftware.com/). #undef GetCurrentTime +#include #include +#include #include #include @@ -108,19 +113,11 @@ std::atomic g_hookCallCounter; int g_originalTaskbarHeight; int g_taskbarHeight; bool g_inSystemTrayController_UpdateFrameSize; +bool g_taskbarButtonWidthCustomized; bool g_inAugmentedEntryPointButton_UpdateButtonPadding; double* double_48_value_Original; -HANDLE g_restartExplorerPromptThread; -std::atomic g_restartExplorerPromptWindow; - -constexpr WCHAR kRestartExplorerPromptTitle[] = - L"Taskbar height and icon size - Windhawk"; -constexpr WCHAR kRestartExplorerPromptText[] = - L"Explorer needs to be restarted to apply the new taskbar button width. " - L"Restart now?"; - WINUSERAPI UINT WINAPI GetDpiForWindow(HWND hwnd); typedef enum MONITOR_DPI_TYPE { MDT_EFFECTIVE_DPI = 0, @@ -617,6 +614,116 @@ int WINAPI TaskbarFrame_MeasureOverride_Hook( return ret; } +void* TaskListButton_UpdateIconColumnDefinition_Original; + +using TaskListButton_UpdateButtonPadding_t = void(WINAPI*)(void* pThis); +TaskListButton_UpdateButtonPadding_t + TaskListButton_UpdateButtonPadding_Original; + +using TaskListButton_UpdateVisualStates_t = void(WINAPI*)(void* pThis); +TaskListButton_UpdateVisualStates_t TaskListButton_UpdateVisualStates_Original; +void WINAPI TaskListButton_UpdateVisualStates_Hook(void* pThis) { + Wh_Log(L">"); + + if (TaskListButton_UpdateIconColumnDefinition_Original && + (g_applyingSettings || g_taskbarButtonWidthCustomized)) { + static LONG mediumTaskbarButtonExtentOffset = []() -> LONG { + // 40:53 | push rbx + // 48:83EC 60 | sub rsp,60 + // 0F297424 50 | movaps xmmword ptr ss:[rsp+50],xmm6 + // 48:8B05 B2EB1F00 | mov rax,qword ptr ds:[<__security_cookie>] + // 48:33C4 | xor rax,rsp + // 48:894424 48 | mov qword ptr ss:[rsp+48],rax + // F2:0F10B1 38030000 | movsd xmm6,qword ptr ds:[rcx+338] + const BYTE* start = + (const BYTE*)TaskListButton_UpdateIconColumnDefinition_Original; + const BYTE* end = start + 0x200; + for (const BYTE* p = start; p != end; p++) { + if (p[0] == 0xF2 && p[1] == 0x0F && p[2] == 0x10 && + (p[3] & 0x81) == 0x81) { + LONG offset = *(LONG*)(p + 4); + Wh_Log(L"mediumTaskbarButtonExtentOffset=0x%X", offset); + return offset; + } + + if (p[0] == 0xF2 && p[1] == 0x44 && p[2] == 0x0F && + p[3] == 0x10 && (p[4] & 0x81) == 0x81) { + LONG offset = *(LONG*)(p + 5); + Wh_Log(L"mediumTaskbarButtonExtentOffset=0x%X", offset); + return offset; + } + } + + Wh_Log(L"mediumTaskbarButtonExtentOffset not found"); + return 0; + }(); + + if (mediumTaskbarButtonExtentOffset > 0) { + double* mediumTaskbarButtonExtent = + (double*)((BYTE*)pThis + mediumTaskbarButtonExtentOffset); + if (*mediumTaskbarButtonExtent >= 1 && + *mediumTaskbarButtonExtent < 10000) { + double newValue = + g_unloading ? 44 : g_settings.taskbarButtonWidth; + if (newValue != *mediumTaskbarButtonExtent) { + Wh_Log( + L"Updating MediumTaskbarButtonExtent for " + L"TaskListButton: %f->%f", + *mediumTaskbarButtonExtent, newValue); + *mediumTaskbarButtonExtent = newValue; + g_taskbarButtonWidthCustomized = true; + TaskListButton_UpdateButtonPadding_Original(pThis); + } + } + } + } + + TaskListButton_UpdateVisualStates_Original(pThis); +} + +using ExperienceToggleButton_UpdateButtonPadding_t = void(WINAPI*)(void* pThis); +ExperienceToggleButton_UpdateButtonPadding_t + ExperienceToggleButton_UpdateButtonPadding_Original; +void WINAPI ExperienceToggleButton_UpdateButtonPadding_Hook(void* pThis) { + Wh_Log(L">"); + + ExperienceToggleButton_UpdateButtonPadding_Original(pThis); + + if (!g_applyingSettings) { + return; + } + + FrameworkElement toggleButtonElement = nullptr; + ((IUnknown**)pThis)[1]->QueryInterface(winrt::guid_of(), + winrt::put_abi(toggleButtonElement)); + if (!toggleButtonElement) { + return; + } + + auto panelElement = + FindChildByName(toggleButtonElement, L"ExperienceToggleButtonRootPanel") + .try_as(); + if (!panelElement) { + return; + } + + double buttonWidth = panelElement.Width(); + if (!(buttonWidth > 0)) { + return; + } + + auto buttonPadding = panelElement.Padding(); + double newWidth = (g_unloading ? 44 : g_settings.taskbarButtonWidth) - 4 + + (buttonPadding.Left + buttonPadding.Right); + if (newWidth != buttonWidth) { + Wh_Log( + L"Updating MediumTaskbarButtonExtent for ExperienceToggleButton: " + L"%f->%f", + buttonWidth, newWidth); + panelElement.Width(newWidth); + } +} + using AugmentedEntryPointButton_UpdateButtonPadding_t = void(WINAPI*)(void* pThis); AugmentedEntryPointButton_UpdateButtonPadding_t @@ -914,68 +1021,6 @@ void ApplySettings(int taskbarHeight) { g_applyingSettings = false; } -void PromptForExplorerRestart() { - if (g_restartExplorerPromptThread) { - if (WaitForSingleObject(g_restartExplorerPromptThread, 0) != - WAIT_OBJECT_0) { - return; - } - - CloseHandle(g_restartExplorerPromptThread); - } - - g_restartExplorerPromptThread = CreateThread( - nullptr, 0, - [](LPVOID lpParameter) WINAPI -> DWORD { - TASKDIALOGCONFIG taskDialogConfig{ - .cbSize = sizeof(taskDialogConfig), - .dwFlags = TDF_ALLOW_DIALOG_CANCELLATION, - .dwCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON, - .pszWindowTitle = kRestartExplorerPromptTitle, - .pszMainIcon = TD_INFORMATION_ICON, - .pszContent = kRestartExplorerPromptText, - .pfCallback = [](HWND hwnd, UINT msg, WPARAM wParam, - LPARAM lParam, LONG_PTR lpRefData) - WINAPI -> HRESULT { - switch (msg) { - case TDN_CREATED: - g_restartExplorerPromptWindow = hwnd; - SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE); - break; - - case TDN_DESTROYED: - g_restartExplorerPromptWindow = nullptr; - break; - } - - return S_OK; - }, - }; - - int button; - if (SUCCEEDED(TaskDialogIndirect(&taskDialogConfig, &button, - nullptr, nullptr)) && - button == IDYES) { - WCHAR commandLine[] = - L"cmd.exe /c " - L"\"taskkill /F /IM explorer.exe & start explorer\""; - STARTUPINFO si = { - .cb = sizeof(si), - }; - PROCESS_INFORMATION pi{}; - if (CreateProcess(nullptr, commandLine, nullptr, nullptr, FALSE, - 0, nullptr, nullptr, &si, &pi)) { - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - } - } - - return 0; - }, - nullptr, 0, nullptr); -} - struct SYMBOL_HOOK { std::vector symbols; void** pOriginalFunction; @@ -1528,6 +1573,38 @@ bool HookTaskbarViewDllSymbols(HMODULE module) { (void**)&TaskbarFrame_MeasureOverride_Original, (void*)TaskbarFrame_MeasureOverride_Hook, }, + { + { + LR"(private: void __cdecl winrt::Taskbar::implementation::TaskListButton::UpdateIconColumnDefinition(void))", + LR"(private: void __cdecl winrt::Taskbar::implementation::TaskListButton::UpdateIconColumnDefinition(void) __ptr64)", + }, + (void**)&TaskListButton_UpdateIconColumnDefinition_Original, + nullptr, + true, // Missing in older Windows 11 versions. + }, + { + { + LR"(private: void __cdecl winrt::Taskbar::implementation::TaskListButton::UpdateButtonPadding(void))", + LR"(private: void __cdecl winrt::Taskbar::implementation::TaskListButton::UpdateButtonPadding(void) __ptr64)", + }, + (void**)&TaskListButton_UpdateButtonPadding_Original, + }, + { + { + LR"(private: void __cdecl winrt::Taskbar::implementation::TaskListButton::UpdateVisualStates(void))", + LR"(private: void __cdecl winrt::Taskbar::implementation::TaskListButton::UpdateVisualStates(void) __ptr64)", + }, + (void**)&TaskListButton_UpdateVisualStates_Original, + (void*)TaskListButton_UpdateVisualStates_Hook, + }, + { + { + LR"(protected: virtual void __cdecl winrt::Taskbar::implementation::ExperienceToggleButton::UpdateButtonPadding(void))", + LR"(protected: virtual void __cdecl winrt::Taskbar::implementation::ExperienceToggleButton::UpdateButtonPadding(void) __ptr64)", + }, + (void**)&ExperienceToggleButton_UpdateButtonPadding_Original, + (void*)ExperienceToggleButton_UpdateButtonPadding_Hook, + }, { { LR"(protected: virtual void __cdecl winrt::Taskbar::implementation::AugmentedEntryPointButton::UpdateButtonPadding(void))", @@ -1726,17 +1803,6 @@ void Wh_ModBeforeUninit() { void Wh_ModUninit() { Wh_Log(L">"); - HWND restartExplorerPromptWindow = g_restartExplorerPromptWindow; - if (restartExplorerPromptWindow) { - PostMessage(restartExplorerPromptWindow, WM_CLOSE, 0, 0); - } - - if (g_restartExplorerPromptThread) { - WaitForSingleObject(g_restartExplorerPromptThread, INFINITE); - CloseHandle(g_restartExplorerPromptThread); - g_restartExplorerPromptThread = nullptr; - } - while (g_hookCallCounter > 0) { Sleep(100); } @@ -1745,15 +1811,9 @@ void Wh_ModUninit() { void Wh_ModSettingsChanged() { Wh_Log(L">"); - int oldTaskbarButtonWidth = g_settings.taskbarButtonWidth; - LoadSettings(); if (g_taskbarViewDllLoaded) { ApplySettings(g_settings.taskbarHeight); } - - if (g_settings.taskbarButtonWidth != oldTaskbarButtonWidth) { - PromptForExplorerRestart(); - } }