Skip to content

Commit 06c3b98

Browse files
committed
Vertical Taskbar for Windows 11 v1.3.12
* Fixed some supplementary language tray icons being rotated. * Improved compatibility with recent Windows 11 versions.
1 parent f0bc654 commit 06c3b98

1 file changed

Lines changed: 62 additions & 40 deletions

File tree

mods/taskbar-vertical.wh.cpp

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// @id taskbar-vertical
33
// @name Vertical Taskbar for Windows 11
44
// @description Finally, the missing vertical taskbar option for Windows 11! Move the taskbar to the left or right side of the screen.
5-
// @version 1.3.11
5+
// @version 1.3.12
66
// @author m417z
77
// @github https://github.com/m417z
88
// @twitter https://twitter.com/m417z
@@ -201,6 +201,10 @@ HWND g_notificationCenterWnd;
201201

202202
std::vector<winrt::weak_ref<XamlRoot>> g_notifyIconsUpdated;
203203

204+
// XamlRoots (taskbars) that already have a deferred ApplyStyle queued, used to
205+
// coalesce redundant applies.
206+
std::vector<XamlRoot> g_applyStyleQueued;
207+
204208
using FrameworkElementLoadedEventRevoker = winrt::impl::event_revoker<
205209
IFrameworkElement,
206210
&winrt::impl::abi<IFrameworkElement>::type::remove_Loaded>;
@@ -577,6 +581,7 @@ bool IsTaskbarWindow(HWND hWnd) {
577581

578582
bool UpdateNotifyIcons(XamlRoot xamlRoot);
579583
bool UpdateNotifyIconsIfNeeded(XamlRoot xamlRoot);
584+
bool ApplyStyleIfNeeded(XamlRoot xamlRoot);
580585

581586
HWND FindCurrentProcessTaskbarWnd() {
582587
HWND hTaskbarWnd = nullptr;
@@ -1112,7 +1117,7 @@ void WINAPI SystemTrayController_UpdateFrameSize_Hook(void* pThis) {
11121117
return 0;
11131118
}
11141119

1115-
// Find the last height offset to reset the height value.
1120+
// Find the last height offset to reset the height value.
11161121
#if defined(_M_X64)
11171122
// 66 0f 2e b3 b0 00 00 00 UCOMISD uVar4,qword ptr [RBX + 0xb0]
11181123
// 7a 4c JP LAB_180075641
@@ -1469,6 +1474,40 @@ bool ApplyStyle(XamlRoot xamlRoot) {
14691474
return true;
14701475
}
14711476

1477+
// Applies the style asynchronously, outside the measure pass that triggered it.
1478+
// Mutating layout properties from within MeasureOverride can cause an
1479+
// AG_E_LAYOUT_CYCLE fail-fast on some Taskbar.View.dll builds. At most one
1480+
// apply is queued per XamlRoot (taskbar) at a time, otherwise every measure
1481+
// pass of the taskbar and system tray frames would queue a redundant one.
1482+
void QueueApplyStyle(FrameworkElement element) {
1483+
auto xamlRoot = element.XamlRoot();
1484+
if (!xamlRoot) {
1485+
return;
1486+
}
1487+
1488+
if (std::find(g_applyStyleQueued.begin(), g_applyStyleQueued.end(),
1489+
xamlRoot) != g_applyStyleQueued.end()) {
1490+
return;
1491+
}
1492+
1493+
g_applyStyleQueued.push_back(xamlRoot);
1494+
1495+
element.Dispatcher().TryRunAsync(
1496+
winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [xamlRoot]() {
1497+
g_applyStyleQueued.erase(
1498+
std::remove(g_applyStyleQueued.begin(),
1499+
g_applyStyleQueued.end(), xamlRoot),
1500+
g_applyStyleQueued.end());
1501+
1502+
try {
1503+
ApplyStyleIfNeeded(xamlRoot);
1504+
} catch (...) {
1505+
HRESULT hr = winrt::to_hresult();
1506+
Wh_Log(L"Error %08X", hr);
1507+
}
1508+
});
1509+
}
1510+
14721511
using TaskbarFrame_MeasureOverride_t =
14731512
int(WINAPI*)(void* pThis,
14741513
winrt::Windows::Foundation::Size size,
@@ -1487,12 +1526,7 @@ int WINAPI TaskbarFrame_MeasureOverride_Hook(
14871526
->QueryInterface(winrt::guid_of<FrameworkElement>(),
14881527
winrt::put_abi(taskbarFrame));
14891528
if (taskbarFrame) {
1490-
try {
1491-
ApplyStyle(taskbarFrame.XamlRoot());
1492-
} catch (...) {
1493-
HRESULT hr = winrt::to_hresult();
1494-
Wh_Log(L"Error %08X", hr);
1495-
}
1529+
QueueApplyStyle(taskbarFrame);
14961530
}
14971531

14981532
int ret = TaskbarFrame_MeasureOverride_Original(pThis, size, resultSize);
@@ -1522,12 +1556,7 @@ int WINAPI SystemTrayFrame_MeasureOverride_Hook(
15221556
->QueryInterface(winrt::guid_of<FrameworkElement>(),
15231557
winrt::put_abi(systemTrayFrame));
15241558
if (systemTrayFrame) {
1525-
try {
1526-
ApplyStyle(systemTrayFrame.XamlRoot());
1527-
} catch (...) {
1528-
HRESULT hr = winrt::to_hresult();
1529-
Wh_Log(L"Error %08X", hr);
1530-
}
1559+
QueueApplyStyle(systemTrayFrame);
15311560
}
15321561

15331562
int ret = SystemTrayFrame_MeasureOverride_Original(pThis, size, resultSize);
@@ -1854,29 +1883,27 @@ void ApplySystemTrayIconStyle(FrameworkElement systemTrayIconElement) {
18541883
}
18551884
}
18561885

1857-
SystemTrayIconType iconType = SystemTrayIconType::Other;
1858-
1859-
auto iconContent =
1860-
FindChildByClassName(contentGrid, L"SystemTray.TextIconContent");
1861-
1862-
if (!iconContent) {
1863-
iconContent =
1864-
FindChildByClassName(contentGrid, L"SystemTray.BatteryIconContent");
1865-
if (iconContent) {
1866-
iconType = SystemTrayIconType::Battery;
1867-
}
1868-
}
1869-
1870-
if (!iconContent) {
1871-
iconContent = FindChildByClassName(
1872-
contentGrid, L"SystemTray.LanguageTextIconContent");
1873-
}
1886+
static const struct {
1887+
PCWSTR className;
1888+
SystemTrayIconType iconType;
1889+
} iconContentTypes[] = {
1890+
{L"SystemTray.TextIconContent", SystemTrayIconType::Other},
1891+
{L"SystemTray.BatteryIconContent", SystemTrayIconType::Battery},
1892+
{L"SystemTray.DateTimeIconContent", SystemTrayIconType::DateTime},
1893+
// Language bar main icon.
1894+
{L"SystemTray.LanguageTextIconContent", SystemTrayIconType::Other},
1895+
{L"SystemTray.LanguageImageIconContent", SystemTrayIconType::Other},
1896+
// Language bar supplementary icon.
1897+
{L"SystemTray.ImageIconContent", SystemTrayIconType::Other},
1898+
};
18741899

1875-
if (!iconContent) {
1876-
iconContent = FindChildByClassName(contentGrid,
1877-
L"SystemTray.DateTimeIconContent");
1900+
FrameworkElement iconContent = nullptr;
1901+
SystemTrayIconType iconType = SystemTrayIconType::Other;
1902+
for (const auto& [className, type] : iconContentTypes) {
1903+
iconContent = FindChildByClassName(contentGrid, className);
18781904
if (iconContent) {
1879-
iconType = SystemTrayIconType::DateTime;
1905+
iconType = type;
1906+
break;
18801907
}
18811908
}
18821909

@@ -2001,11 +2028,6 @@ void WINAPI DateTimeIconContent_OnApplyTemplate_Hook(void* pThis) {
20012028
}
20022029

20032030
bool ApplyStyleIfNeeded(XamlRoot xamlRoot) {
2004-
// Calling this when unloading causes a crash with a secondary taskbar.
2005-
if (g_unloading) {
2006-
return true;
2007-
}
2008-
20092031
FrameworkElement contentGrid =
20102032
xamlRoot.Content().try_as<FrameworkElement>();
20112033

0 commit comments

Comments
 (0)