Skip to content

Commit c58a338

Browse files
authored
Remove flicker on hover (#4490)
1 parent 453bb94 commit c58a338

1 file changed

Lines changed: 42 additions & 6 deletions

File tree

mods/fix-legacy-taskbar-tray-input-indicator.wh.cpp

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// @id fix-legacy-taskbar-tray-input-indicator
33
// @name Fix language indicator in Win10 taskbar under Win11 24H2+
44
// @description Fixes text orientation in the keyboard layout indicator in Win10 taskbar running under Win11 24H2+
5-
// @version 1.4.0
5+
// @version 1.5
66
// @author Anixx
77
// @github https://github.com/Anixx
88
// @include explorer.exe
@@ -32,13 +32,15 @@ Windows 11 taskbar.
3232
#include <windows.h>
3333

3434
static wchar_t g_text[8] = {};
35+
static wchar_t g_lastDrawnText[8] = {};
3536
static LOGFONTW g_font = {};
3637
static int g_srcW = 0;
3738
static int g_srcH = 0;
3839
static bool g_pending = false;
3940
static DWORD g_threadId = 0;
4041
static COLORREF g_lastGoodBg = CLR_INVALID;
4142
static bool g_firstBltDone = false;
43+
static bool g_alreadyDrawn = false;
4244

4345
static bool LooksLikeLayoutText(LPCWSTR s, int len) {
4446
if (!s || len < 2 || len > 4) return false;
@@ -66,6 +68,17 @@ BOOL WINAPI ExtTextOutW_Hook(HDC hdc, int x, int y, UINT options,
6668
LOGFONTW lf = {};
6769

6870
if (LooksLikeLayoutText(lpString, len) && IsRotatedFont(hdc, &lf)) {
71+
72+
wchar_t newText[8] = {};
73+
wcsncpy_s(newText, lpString, len);
74+
newText[len] = 0;
75+
76+
bool textChanged = (wcscmp(newText, g_lastDrawnText) != 0);
77+
78+
if (textChanged) {
79+
g_alreadyDrawn = false;
80+
}
81+
6982
HBITMAP hbm = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
7083
BITMAP bm = {};
7184
if (hbm && GetObject(hbm, sizeof(bm), &bm)) {
@@ -114,7 +127,6 @@ BOOL WINAPI BitBlt_Hook(HDC hdcDest, int xDest, int yDest, int w, int h,
114127
return result;
115128
}
116129

117-
// BitBlt #1: точное совпадение с исходным размером — пропускаем
118130
bool isFirstBlit = (w == g_srcW && h == g_srcH);
119131
if (isFirstBlit) {
120132
g_firstBltDone = true;
@@ -125,15 +137,38 @@ BOOL WINAPI BitBlt_Hook(HDC hdcDest, int xDest, int yDest, int w, int h,
125137
return result;
126138
}
127139

128-
// BitBlt #2: первый после #1, размер БОЛЬШЕ исходного
129-
// (индикатор всегда больше чем маленький bitmap с текстом)
130-
// Ширина должна быть >= srcH (текст был повёрнут, теперь горизонтальный)
131140
bool isIndicator = (w > g_srcW || h > g_srcH) && (w >= g_srcH);
132141

133142
if (!isIndicator) {
134143
return result;
135144
}
136145

146+
// Если уже был нарисован (это hover) — рисуем поверх того что уже есть
147+
// не очищая фон, чтобы сохранить hover-эффект Windows
148+
if (g_alreadyDrawn) {
149+
RECT rc = { 0, 0, w, h };
150+
151+
LOGFONTW lfH = g_font;
152+
lfH.lfEscapement = 0;
153+
lfH.lfOrientation = 0;
154+
155+
HFONT hFont = CreateFontIndirectW(&lfH);
156+
if (hFont) {
157+
HFONT hOld = (HFONT)SelectObject(hdcDest, hFont);
158+
SetBkMode(hdcDest, TRANSPARENT);
159+
SetTextColor(hdcDest, GetSysColor(COLOR_BTNTEXT));
160+
161+
DrawTextW(hdcDest, g_text, -1, &rc,
162+
DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
163+
164+
SelectObject(hdcDest, hOld);
165+
DeleteObject(hFont);
166+
}
167+
168+
g_pending = false;
169+
return result;
170+
}
171+
137172
COLORREF bgColor = GetPixel(hdcDest, w - 1, h - 1);
138173

139174
if (bgColor != CLR_INVALID && bgColor != 0x000000) {
@@ -167,6 +202,8 @@ BOOL WINAPI BitBlt_Hook(HDC hdcDest, int xDest, int yDest, int w, int h,
167202
DeleteObject(hFont);
168203
}
169204

205+
wcscpy_s(g_lastDrawnText, g_text);
206+
g_alreadyDrawn = true;
170207
g_pending = false;
171208

172209
return result;
@@ -182,4 +219,3 @@ BOOL Wh_ModInit() {
182219
(void**)&BitBlt_Original);
183220
return TRUE;
184221
}
185-

0 commit comments

Comments
 (0)