[PATCH] comctl32/tooltips: Prevent tooltip from reappearing immediately after a click.
When a mouse button is clicked while hovering over a tool, Windows hides the tooltip and suppresses it from reappearing until the cursor leaves the tool and re-enters it. Previously Wine would restart ID_TIMERSHOW on subsequent mouse moves over the same tool, causing the tooltip to pop up again immediately. Fix this by introducing a bClickCancelled flag that is set whenever any mouse button is pressed over an active tool, and cleared only when the cursor moves to a different tool. Also kill ID_TIMERSHOW in TOOLTIPS_Hide to prevent a pending show timer from firing after the tooltip is dismissed. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59520 Signed-off-by: Ivan Georgiev <ivanresen2006@gmail.com> --- dlls/comctl32/tooltips.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dlls/comctl32/tooltips.c b/dlls/comctl32/tooltips.c index 876736b11e4..becfe465471 100644 --- a/dlls/comctl32/tooltips.c +++ b/dlls/comctl32/tooltips.c @@ -144,6 +144,7 @@ typedef struct INT nInitialTime; RECT rcMargin; BOOL bToolBelow; + BOOL bClickCancelled; LPWSTR pszTitle; HICON hTitleIcon; int iconWidth; @@ -840,6 +841,8 @@ TOOLTIPS_Hide (TOOLTIPS_INFO *infoPtr) TTTOOL_INFO *toolPtr; NMHDR hdr; + KillTimer(infoPtr->hwndSelf, ID_TIMERSHOW); + TRACE("Hide tooltip %d, %p.\n", infoPtr->nCurrentTool, infoPtr->hwndSelf); if (infoPtr->nCurrentTool == -1) @@ -1504,6 +1507,10 @@ TOOLTIPS_RelayEvent (TOOLTIPS_INFO *infoPtr, LPMSG lpMsg) case WM_RBUTTONDOWN: case WM_RBUTTONUP: TOOLTIPS_Hide (infoPtr); + if (infoPtr->nTool != -1) { + infoPtr->bClickCancelled = TRUE; + SetTimer(infoPtr->hwndSelf, ID_TIMERLEAVE, infoPtr->nReshowTime, 0); + } break; case WM_MOUSEMOVE: @@ -1517,6 +1524,7 @@ TOOLTIPS_RelayEvent (TOOLTIPS_INFO *infoPtr, LPMSG lpMsg) TRACE("WM_MOUSEMOVE (%p %s)\n", infoPtr->hwndSelf, wine_dbgstr_point(&pt)); if (infoPtr->nTool != nOldTool) { + infoPtr->bClickCancelled = FALSE; if(infoPtr->nTool == -1) { /* Moved out of all tools */ TOOLTIPS_Hide(infoPtr); KillTimer(infoPtr->hwndSelf, ID_TIMERLEAVE); @@ -1537,7 +1545,7 @@ TOOLTIPS_RelayEvent (TOOLTIPS_INFO *infoPtr, LPMSG lpMsg) KillTimer(infoPtr->hwndSelf, ID_TIMERPOP); SetTimer(infoPtr->hwndSelf, ID_TIMERPOP, infoPtr->nAutoPopTime, 0); TRACE("timer 2 restarted\n"); - } else if(infoPtr->nTool != -1 && infoPtr->bActive) { + } else if(infoPtr->nTool != -1 && infoPtr->bActive && !infoPtr->bClickCancelled) { /* previous show attempt didn't result in tooltip so try again */ SetTimer(infoPtr->hwndSelf, ID_TIMERSHOW, infoPtr->nInitialTime, 0); TRACE("timer 1 started\n"); @@ -2042,6 +2050,7 @@ TOOLTIPS_Timer (TOOLTIPS_INFO *infoPtr, INT iTimer) TRACE("tool (%p) %d %d %d\n", infoPtr->hwndSelf, nOldTool, infoPtr->nTool, infoPtr->nCurrentTool); if (infoPtr->nTool != nOldTool) { + infoPtr->bClickCancelled = FALSE; if(infoPtr->nTool == -1) { /* Moved out of all tools */ TOOLTIPS_Hide(infoPtr); KillTimer(infoPtr->hwndSelf, ID_TIMERLEAVE); -- 2.53.0
Hi, please send this to https://gitlab.winehq.org/wine/wine. We don't use this mailing list for patch submission anymore. On 3/14/26 18:44, Ivan Georgiev via Wine-devel wrote:
When a mouse button is clicked while hovering over a tool, Windows hides the tooltip and suppresses it from reappearing until the cursor leaves the tool and re-enters it. Previously Wine would restart ID_TIMERSHOW on subsequent mouse moves over the same tool, causing the tooltip to pop up again immediately.
Fix this by introducing a bClickCancelled flag that is set whenever any mouse button is pressed over an active tool, and cleared only when the cursor moves to a different tool. Also kill ID_TIMERSHOW in TOOLTIPS_Hide to prevent a pending show timer from firing after the tooltip is dismissed.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59520 Signed-off-by: Ivan Georgiev <ivanresen2006@gmail.com> --- dlls/comctl32/tooltips.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/comctl32/tooltips.c b/dlls/comctl32/tooltips.c index 876736b11e4..becfe465471 100644 --- a/dlls/comctl32/tooltips.c +++ b/dlls/comctl32/tooltips.c @@ -144,6 +144,7 @@ typedef struct INT nInitialTime; RECT rcMargin; BOOL bToolBelow; + BOOL bClickCancelled; LPWSTR pszTitle; HICON hTitleIcon; int iconWidth; @@ -840,6 +841,8 @@ TOOLTIPS_Hide (TOOLTIPS_INFO *infoPtr) TTTOOL_INFO *toolPtr; NMHDR hdr;
+ KillTimer(infoPtr->hwndSelf, ID_TIMERSHOW); + TRACE("Hide tooltip %d, %p.\n", infoPtr->nCurrentTool, infoPtr->hwndSelf);
if (infoPtr->nCurrentTool == -1) @@ -1504,6 +1507,10 @@ TOOLTIPS_RelayEvent (TOOLTIPS_INFO *infoPtr, LPMSG lpMsg) case WM_RBUTTONDOWN: case WM_RBUTTONUP: TOOLTIPS_Hide (infoPtr); + if (infoPtr->nTool != -1) { + infoPtr->bClickCancelled = TRUE; + SetTimer(infoPtr->hwndSelf, ID_TIMERLEAVE, infoPtr->nReshowTime, 0); + } break;
case WM_MOUSEMOVE: @@ -1517,6 +1524,7 @@ TOOLTIPS_RelayEvent (TOOLTIPS_INFO *infoPtr, LPMSG lpMsg) TRACE("WM_MOUSEMOVE (%p %s)\n", infoPtr->hwndSelf, wine_dbgstr_point(&pt));
if (infoPtr->nTool != nOldTool) { + infoPtr->bClickCancelled = FALSE; if(infoPtr->nTool == -1) { /* Moved out of all tools */ TOOLTIPS_Hide(infoPtr); KillTimer(infoPtr->hwndSelf, ID_TIMERLEAVE); @@ -1537,7 +1545,7 @@ TOOLTIPS_RelayEvent (TOOLTIPS_INFO *infoPtr, LPMSG lpMsg) KillTimer(infoPtr->hwndSelf, ID_TIMERPOP); SetTimer(infoPtr->hwndSelf, ID_TIMERPOP, infoPtr->nAutoPopTime, 0); TRACE("timer 2 restarted\n"); - } else if(infoPtr->nTool != -1 && infoPtr->bActive) { + } else if(infoPtr->nTool != -1 && infoPtr->bActive && !infoPtr->bClickCancelled) { /* previous show attempt didn't result in tooltip so try again */ SetTimer(infoPtr->hwndSelf, ID_TIMERSHOW, infoPtr->nInitialTime, 0); TRACE("timer 1 started\n"); @@ -2042,6 +2050,7 @@ TOOLTIPS_Timer (TOOLTIPS_INFO *infoPtr, INT iTimer) TRACE("tool (%p) %d %d %d\n", infoPtr->hwndSelf, nOldTool, infoPtr->nTool, infoPtr->nCurrentTool); if (infoPtr->nTool != nOldTool) { + infoPtr->bClickCancelled = FALSE; if(infoPtr->nTool == -1) { /* Moved out of all tools */ TOOLTIPS_Hide(infoPtr); KillTimer(infoPtr->hwndSelf, ID_TIMERLEAVE);
participants (2)
-
Ivan Georgiev -
Zhiyi Zhang