https://bugs.winehq.org/show_bug.cgi?id=56582
--- Comment #11 from Fabian Maurer dark.shadow4@web.de --- Problem occurs in this part of the code:
do { if (!NtUserGetMessage( &msg, 0, 0, 0 )) break; if (NtUserCallMsgFilter( &msg, MSGF_SCROLLBAR )) continue; if (msg.message == WM_LBUTTONUP || msg.message == WM_MOUSEMOVE || msg.message == WM_MOUSELEAVE || msg.message == WM_NCMOUSEMOVE || msg.message == WM_NCMOUSELEAVE || (msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER)) { pt.x = (short)LOWORD( msg.lParam ) - rect.left; pt.y = (short)HIWORD( msg.lParam ) - rect.top; handle_scroll_event( hwnd, scrollbar, msg.message, pt ); }
There is two delays:
/* Delay (in ms) before first repetition when holding the button down */ #define SCROLL_FIRST_DELAY 200
/* Delay (in ms) between scroll repetitions */ #define SCROLL_REPEAT_DELAY 50
The timer is set like follows:
NtUserSetSystemTimer( hwnd, SCROLL_TIMER, msg == WM_LBUTTONDOWN ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY );
So, when we get a WM_MOUSEMOVE, the timer will be set to the shorter repeat relay. Now, due to the regression, we get that WM_MOUSEMOVE instantly. Ir comes from:
BOOL release_capture(void) { HWND previous = NULL; BOOL ret;
ret = set_capture_window( 0, 0, &previous ); /* Somebody may have missed some mouse movements */ if (ret && previous) { INPUT input = { .type = INPUT_MOUSE }; input.mi.dwFlags = MOUSEEVENTF_MOVE; NtUserSendInput( 1, &input, sizeof(input) ); }
This is injected intentionally. Now it breaks the scrolling logic though.