Skip to content

Commit

Permalink
Taskbar height and icon size v1.2.15 (#1142)
Browse files Browse the repository at this point in the history
* Applying changes to the taskbar button width option no longer requires restarting explorer.
  • Loading branch information
m417z authored Oct 25, 2024
1 parent 32c17fb commit 08efbf9
Showing 1 changed file with 154 additions and 94 deletions.
248 changes: 154 additions & 94 deletions mods/taskbar-icon-size.wh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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==

Expand All @@ -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==

Expand All @@ -74,7 +77,9 @@ Tweaker](https://tweaker.ramensoftware.com/).

#undef GetCurrentTime

#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Media.h>

#include <algorithm>
Expand Down Expand Up @@ -108,19 +113,11 @@ std::atomic<int> 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<HWND> 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,
Expand Down Expand Up @@ -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<FrameworkElement>(),
winrt::put_abi(toggleButtonElement));
if (!toggleButtonElement) {
return;
}

auto panelElement =
FindChildByName(toggleButtonElement, L"ExperienceToggleButtonRootPanel")
.try_as<Controls::Grid>();
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
Expand Down Expand Up @@ -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<std::wstring_view> symbols;
void** pOriginalFunction;
Expand Down Expand Up @@ -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))",
Expand Down Expand Up @@ -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);
}
Expand All @@ -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();
}
}

0 comments on commit 08efbf9

Please sign in to comment.