From cc16769179b730a75ff2edee83298f65c6c8f217 Mon Sep 17 00:00:00 2001 From: Mohammad Amin Mollazadeh Date: Sun, 4 May 2025 18:41:44 +0330 Subject: [PATCH] [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 --- .../shell32/shellmenu/CMenuFocusManager.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dll/win32/shell32/shellmenu/CMenuFocusManager.cpp b/dll/win32/shell32/shellmenu/CMenuFocusManager.cpp index 0e5631d9935..43e83ac1c6a 100644 --- a/dll/win32/shell32/shellmenu/CMenuFocusManager.cpp +++ b/dll/win32/shell32/shellmenu/CMenuFocusManager.cpp @@ -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