Skip to content

Commit

Permalink
deploy: 9c2f042
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] committed Dec 16, 2024
1 parent e56340c commit 10a924a
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 95 deletions.
4 changes: 2 additions & 2 deletions catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -3013,7 +3013,7 @@
"published": 1706376839000,
"rating": 10,
"ratingUsers": 99,
"updated": 1729696417000,
"updated": 1734387432000,
"users": 4496
},
"metadata": {
Expand All @@ -3030,7 +3030,7 @@
],
"name": "Taskbar tray icon spacing",
"twitter": "https://twitter.com/m417z",
"version": "1.1"
"version": "1.1.1"
}
},
"taskbar-notification-icons-show-all": {
Expand Down
5 changes: 5 additions & 0 deletions changelogs/taskbar-notification-icon-spacing.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.1.1 ([Dec 16, 2024](https://github.com/ramensoftware/windhawk-mods/blob/9c2f0424b09b758e4e82b06da5b4d94e206e05a4/mods/taskbar-notification-icon-spacing.wh.cpp))

* Fixed buggy tray overflow placement when it's shown at the first time after system startup.
* Fixed tray overflow styles not being restored on mod unload.

## 1.1 ([Oct 23, 2024](https://github.com/ramensoftware/windhawk-mods/blob/a7c329d411e81a6e0b20c90efc77c36fca9fec5a/mods/taskbar-notification-icon-spacing.wh.cpp))

* Renamed from "Taskbar notification icon spacing" to "Taskbar tray icon spacing", as tray is the more familiar term.
Expand Down
164 changes: 91 additions & 73 deletions mods/taskbar-notification-icon-spacing.wh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// @id taskbar-notification-icon-spacing
// @name Taskbar tray icon spacing
// @description Reduce or increase the spacing between tray icons on the taskbar (Windows 11 only)
// @version 1.1
// @version 1.1.1
// @author m417z
// @github https://github.com/m417z
// @twitter https://twitter.com/m417z
Expand Down Expand Up @@ -63,6 +63,7 @@ versions check out [7+ Taskbar Tweaker](https://tweaker.ramensoftware.com/).

#include <windhawk_utils.h>

#include <atomic>
#include <functional>
#include <list>

Expand All @@ -81,25 +82,23 @@ struct {
int overflowIconsPerRow;
} g_settings;

std::atomic<bool> g_unloading;

using FrameworkElementLoadedEventRevoker = winrt::impl::event_revoker<
IFrameworkElement,
&winrt::impl::abi<IFrameworkElement>::type::remove_Loaded>;

std::list<FrameworkElementLoadedEventRevoker> g_autoRevokerList;

bool g_overflowApplied;
winrt::weak_ref<FrameworkElement> g_overflowRootGrid;

HWND GetTaskbarWnd() {
static HWND hTaskbarWnd;

if (!hTaskbarWnd) {
HWND hWnd = FindWindow(L"Shell_TrayWnd", nullptr);
HWND hTaskbarWnd = FindWindow(L"Shell_TrayWnd", nullptr);

DWORD processId = 0;
if (hWnd && GetWindowThreadProcessId(hWnd, &processId) &&
processId == GetCurrentProcessId()) {
hTaskbarWnd = hWnd;
}
DWORD processId = 0;
if (!hTaskbarWnd || !GetWindowThreadProcessId(hTaskbarWnd, &processId) ||
processId != GetCurrentProcessId()) {
return nullptr;
}

return hTaskbarWnd;
Expand Down Expand Up @@ -447,18 +446,18 @@ bool ApplyStyle(XamlRoot xamlRoot, int width) {
return somethingSucceeded;
}

using IconView_IconView_t = void(WINAPI*)(PVOID pThis);
using IconView_IconView_t = void*(WINAPI*)(void* pThis);
IconView_IconView_t IconView_IconView_Original;
void WINAPI IconView_IconView_Hook(PVOID pThis) {
void* WINAPI IconView_IconView_Hook(void* pThis) {
Wh_Log(L">");

IconView_IconView_Original(pThis);
void* ret = IconView_IconView_Original(pThis);

FrameworkElement iconView = nullptr;
((IUnknown**)pThis)[1]->QueryInterface(winrt::guid_of<FrameworkElement>(),
winrt::put_abi(iconView));
if (!iconView) {
return;
return ret;
}

g_autoRevokerList.emplace_back();
Expand Down Expand Up @@ -498,9 +497,7 @@ void WINAPI IconView_IconView_Hook(PVOID pThis) {
iconView, g_settings.notificationIconWidth);
} else if (IsChildOfElementByName(iconView, L"MainStack") ||
IsChildOfElementByName(iconView,
L"NonActivatableStack") ||
IsChildOfElementByName(iconView,
L"ControlCenterButton")) {
L"NonActivatableStack")) {
ApplyNotifyIconViewStyle(
iconView, g_settings.notificationIconWidth);
}
Expand All @@ -512,32 +509,11 @@ void WINAPI IconView_IconView_Hook(PVOID pThis) {
}
}
});
}

using OverflowXamlIslandManager_ShowWindow_t =
void(WINAPI*)(void* pThis, POINT pt, int inputDeviceKind);
OverflowXamlIslandManager_ShowWindow_t
OverflowXamlIslandManager_ShowWindow_Original;
void WINAPI OverflowXamlIslandManager_ShowWindow_Hook(void* pThis,
POINT pt,
int inputDeviceKind) {
Wh_Log(L">");

OverflowXamlIslandManager_ShowWindow_Original(pThis, pt, inputDeviceKind);

if (g_overflowApplied) {
return;
}

g_overflowApplied = true;

FrameworkElement overflowRootGrid = nullptr;
((IUnknown**)pThis)[5]->QueryInterface(winrt::guid_of<Controls::Grid>(),
winrt::put_abi(overflowRootGrid));
if (!overflowRootGrid) {
return;
}
return ret;
}

void ApplyOverflowStyle(FrameworkElement overflowRootGrid) {
Controls::WrapGrid wrapGrid = nullptr;

FrameworkElement child = overflowRootGrid;
Expand All @@ -554,13 +530,16 @@ void WINAPI OverflowXamlIslandManager_ShowWindow_Hook(void* pThis,
return;
}

int width = g_settings.overflowIconWidth;
int width = g_unloading ? 40 : g_settings.overflowIconWidth;
int maxRows = g_unloading ? 5 : g_settings.overflowIconsPerRow;
Wh_Log(
L"Setting ItemWidth/ItemHeight=%d, MaximumRowsOrColumns=%d for "
L"WrapGrid",
width, maxRows);

Wh_Log(L"Setting ItemWidth, ItemWidth=%d for WrapGrid", width);
wrapGrid.ItemWidth(width);
wrapGrid.ItemHeight(width);

wrapGrid.MaximumRowsOrColumns(g_settings.overflowIconsPerRow);
wrapGrid.MaximumRowsOrColumns(maxRows);

EnumChildElements(wrapGrid, [width](FrameworkElement child) {
auto className = winrt::get_class_name(child);
Expand All @@ -579,12 +558,42 @@ void WINAPI OverflowXamlIslandManager_ShowWindow_Hook(void* pThis,
});
}

using OverflowXamlIslandManager_InitializeIfNeeded_t =
void(WINAPI*)(void* pThis);
OverflowXamlIslandManager_InitializeIfNeeded_t
OverflowXamlIslandManager_InitializeIfNeeded_Original;
void WINAPI OverflowXamlIslandManager_InitializeIfNeeded_Hook(void* pThis) {
Wh_Log(L">");

OverflowXamlIslandManager_InitializeIfNeeded_Original(pThis);

if (g_overflowRootGrid.get()) {
return;
}

FrameworkElement overflowRootGrid = nullptr;
((IUnknown**)pThis)[5]->QueryInterface(winrt::guid_of<Controls::Grid>(),
winrt::put_abi(overflowRootGrid));
if (!overflowRootGrid) {
Wh_Log(L"No OverflowRootGrid");
return;
}

if (!overflowRootGrid.IsLoaded()) {
Wh_Log(L"OverflowRootGrid not loaded");
return;
}

g_overflowRootGrid = overflowRootGrid;
ApplyOverflowStyle(overflowRootGrid);
}

void* CTaskBand_ITaskListWndSite_vftable;

using CTaskBand_GetTaskbarHost_t = PVOID(WINAPI*)(PVOID pThis, PVOID* result);
using CTaskBand_GetTaskbarHost_t = void*(WINAPI*)(void* pThis, void** result);
CTaskBand_GetTaskbarHost_t CTaskBand_GetTaskbarHost_Original;

using std__Ref_count_base__Decref_t = void(WINAPI*)(PVOID pThis);
using std__Ref_count_base__Decref_t = void(WINAPI*)(void* pThis);
std__Ref_count_base__Decref_t std__Ref_count_base__Decref_Original;

XamlRoot GetTaskbarXamlRoot(HWND hTaskbarWnd) {
Expand All @@ -593,19 +602,19 @@ XamlRoot GetTaskbarXamlRoot(HWND hTaskbarWnd) {
return nullptr;
}

PVOID taskBand = (PVOID)GetWindowLongPtr(hTaskSwWnd, 0);
PVOID taskBandForTaskListWndSite = taskBand;
for (int i = 0; *(PVOID*)taskBandForTaskListWndSite !=
void* taskBand = (void*)GetWindowLongPtr(hTaskSwWnd, 0);
void* taskBandForTaskListWndSite = taskBand;
for (int i = 0; *(void**)taskBandForTaskListWndSite !=
CTaskBand_ITaskListWndSite_vftable;
i++) {
if (i == 20) {
return nullptr;
}

taskBandForTaskListWndSite = (PVOID*)taskBandForTaskListWndSite + 1;
taskBandForTaskListWndSite = (void**)taskBandForTaskListWndSite + 1;
}

PVOID taskbarHostSharedPtr[2]{};
void* taskbarHostSharedPtr[2]{};
CTaskBand_GetTaskbarHost_Original(taskBandForTaskListWndSite,
taskbarHostSharedPtr);
if (!taskbarHostSharedPtr[0] && !taskbarHostSharedPtr[1]) {
Expand All @@ -630,17 +639,17 @@ XamlRoot GetTaskbarXamlRoot(HWND hTaskbarWnd) {
return result;
}

using RunFromWindowThreadProc_t = void(WINAPI*)(PVOID parameter);
using RunFromWindowThreadProc_t = void(WINAPI*)(void* parameter);

bool RunFromWindowThread(HWND hWnd,
RunFromWindowThreadProc_t proc,
PVOID procParam) {
void* procParam) {
static const UINT runFromWindowThreadRegisteredMsg =
RegisterWindowMessage(L"Windhawk_RunFromWindowThread_" WH_MOD_ID);

struct RUN_FROM_WINDOW_THREAD_PARAM {
RunFromWindowThreadProc_t proc;
PVOID procParam;
void* procParam;
};

DWORD dwThreadId = GetWindowThreadProcessId(hWnd, nullptr);
Expand Down Expand Up @@ -689,13 +698,13 @@ void LoadSettings() {
g_settings.overflowIconsPerRow = Wh_GetIntSetting(L"overflowIconsPerRow");
}

void ApplySettings(int width) {
void ApplySettings() {
struct ApplySettingsParam {
HWND hTaskbarWnd;
int width;
};

Wh_Log(L"Applying settings: %d", width);
Wh_Log(L"Applying settings");

HWND hTaskbarWnd = GetTaskbarWnd();
if (!hTaskbarWnd) {
Expand All @@ -705,16 +714,15 @@ void ApplySettings(int width) {

ApplySettingsParam param{
.hTaskbarWnd = hTaskbarWnd,
.width = width,
.width = g_unloading ? 32 : g_settings.notificationIconWidth,
};

RunFromWindowThread(
hTaskbarWnd,
[](PVOID pParam) WINAPI {
[](void* pParam) WINAPI {
ApplySettingsParam& param = *(ApplySettingsParam*)pParam;

g_autoRevokerList.clear();
g_overflowApplied = false;

auto xamlRoot = GetTaskbarXamlRoot(param.hTaskbarWnd);
if (!xamlRoot) {
Expand All @@ -725,6 +733,10 @@ void ApplySettings(int width) {
if (!ApplyStyle(xamlRoot, param.width)) {
Wh_Log(L"ApplyStyles failed");
}

if (auto overflowRootGrid = g_overflowRootGrid.get()) {
ApplyOverflowStyle(overflowRootGrid);
}
},
&param);
}
Expand Down Expand Up @@ -755,34 +767,34 @@ bool HookTaskbarViewDllSymbols() {
IconView_IconView_Hook,
},
{
{LR"(private: void __cdecl winrt::SystemTray::OverflowXamlIslandManager::ShowWindow(struct tagPOINT,enum winrt::WindowsUdk::UI::Shell::InputDeviceKind))"},
&OverflowXamlIslandManager_ShowWindow_Original,
OverflowXamlIslandManager_ShowWindow_Hook,
{LR"(private: void __cdecl winrt::SystemTray::OverflowXamlIslandManager::InitializeIfNeeded(void))"},
&OverflowXamlIslandManager_InitializeIfNeeded_Original,
OverflowXamlIslandManager_InitializeIfNeeded_Hook,
},
};

return HookSymbols(module, symbolHooks, ARRAYSIZE(symbolHooks));
}

BOOL HookTaskbarDllSymbols() {
bool HookTaskbarDllSymbols() {
HMODULE module = LoadLibrary(L"taskbar.dll");
if (!module) {
Wh_Log(L"Failed to load taskbar.dll");
return FALSE;
return false;
}

WindhawkUtils::SYMBOL_HOOK taskbarDllHooks[] = {
{
{LR"(const CTaskBand::`vftable'{for `ITaskListWndSite'})"},
(void**)&CTaskBand_ITaskListWndSite_vftable,
&CTaskBand_ITaskListWndSite_vftable,
},
{
{LR"(public: virtual class std::shared_ptr<class TaskbarHost> __cdecl CTaskBand::GetTaskbarHost(void)const )"},
(void**)&CTaskBand_GetTaskbarHost_Original,
&CTaskBand_GetTaskbarHost_Original,
},
{
{LR"(public: void __cdecl std::_Ref_count_base::_Decref(void))"},
(void**)&std__Ref_count_base__Decref_Original,
&std__Ref_count_base__Decref_Original,
},
};

Expand All @@ -808,19 +820,25 @@ BOOL Wh_ModInit() {
void Wh_ModAfterInit() {
Wh_Log(L">");

ApplySettings(g_settings.notificationIconWidth);
ApplySettings();
}

void Wh_ModUninit() {
void Wh_ModBeforeUninit() {
Wh_Log(L">");

ApplySettings(32);
g_unloading = true;

ApplySettings();
}

void Wh_ModUninit() {
Wh_Log(L">");
}

void Wh_ModSettingsChanged() {
Wh_Log(L">");

LoadSettings();

ApplySettings(g_settings.notificationIconWidth);
ApplySettings();
}
Loading

0 comments on commit 10a924a

Please sign in to comment.