[SHELL32] Fix focus glitch when hovering separators with submenu open (#7932)

CORE-20124

Since `TB_HITTEST` returns negative numbers for ID for separator menu items [^1],
shell menu assumes mouse moved outside of the menu popup, highlighting the menu
item for currently open submenu.
To fix this behavior, we can detect separators in `CMenuFocusManager::ProcessMouseMove`
and negate the ID returned by `TB_HITTEST` to make it a positive number again,
so the shell menu wouldn't glitch.

[^1]: https://learn.microsoft.com/en-us/windows/win32/controls/tb-hittest
This commit is contained in:
Mohammad Amin Mollazadeh 2025-05-04 18:41:44 +03:30 committed by GitHub
parent 3e342246d4
commit cc16769179
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -348,6 +348,23 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg)
iHitTestResult = SendMessageW(child, TB_HITTEST, 0, (LPARAM) &pt);
isTracking = entry->mb->_IsTracking();
if (iHitTestResult < -1)
{
// TB_HITTEST would return negative numbers for separators
iHitTestResult = -iHitTestResult;
}
else if (iHitTestResult == -1)
{
// TB_HITTEST would return -1 in two cases:
// 1. the mouse is outside the toolbar;
// 2. the mouse is over the first item, and that item is a separator.
// Confirm the second scenario by checking first item's rect.
RECT rc;
SendMessageW(child, TB_GETITEMRECT, 1, (LPARAM)&rc);
if (PtInRect(&rc, pt))
iHitTestResult = 1;
}
if (SendMessage(child, WM_USER_ISTRACKEDITEM, iHitTestResult, 0) == S_FALSE)
{
// The current tracked item has changed, notify the toolbar