1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 09:58:01 +00:00

Restore missing screen updates from scrollbar buttons.

In commit f69cf86a61, I added a call to term_update that happens
when we receive WM_VSCROLL / SB_THUMBPOSITION in the subsidiary
message loop that Windows creates during the handling of WM_SYSCOMMAND
/ SC_VSCROLL. The effect was that interactive dragging of the
scrollbar now redraws the window at every step, whereas previously it
didn't.

A user just pointed out that if you click on one of the scrollbar end
buttons and hold it down until it begins emulating key repeat, the
same bug occurs: the window isn't redrawn until you release the mouse
button and the subsidiary message loop ends.

This commit extends the previous fix to cover all of the WM_VSCROLL
subtypes, instead of just SB_THUMBPOSITION and SB_THUMBTRACK. Redraws
while holding down those scrollbar buttons now work again.

(cherry picked from commit 2029aa55c2)
This commit is contained in:
Simon Tatham 2021-07-03 11:01:09 +01:00
parent 1dc5659aa6
commit 22d7888b33

View File

@ -3160,58 +3160,55 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
if (GetScrollInfo(hwnd, SB_VERT, &si) == 0) if (GetScrollInfo(hwnd, SB_VERT, &si) == 0)
si.nTrackPos = HIWORD(wParam); si.nTrackPos = HIWORD(wParam);
term_scroll(term, 1, si.nTrackPos); term_scroll(term, 1, si.nTrackPos);
break;
}
}
if (in_scrollbar_loop) { if (in_scrollbar_loop) {
/* /*
* Allow window updates to happen during interactive * Allow window updates to happen during interactive
* scroll. * scroll.
* *
* When the user takes hold of our window's scrollbar * When the user takes hold of our window's scrollbar and
* and wobbles it interactively back and forth, the * wobbles it interactively back and forth, or presses on
* first thing that happens is that this window * one of the arrow buttons at the ends, the first thing
* procedure receives WM_SYSCOMMAND / SC_VSCROLL. [1] * that happens is that this window procedure receives
* The default handler for that window message starts * WM_SYSCOMMAND / SC_VSCROLL. [1] The default handler for
* a subsidiary message loop, which continues to run * that window message starts a subsidiary message loop,
* until the user lets go of the scrollbar again. All * which continues to run until the user lets go of the
* WM_VSCROLL / SB_THUMBTRACK messages are generated * scrollbar again. All WM_VSCROLL / SB_THUMBTRACK
* by the handlers within that subsidiary message * messages are generated by the handlers within that
* loop. * subsidiary message loop.
* *
* So, during that time, _our_ message loop is not * So, during that time, _our_ message loop is not
* running, which means toplevel callbacks and timers * running, which means toplevel callbacks and timers and
* and so forth are not happening, which means that * so forth are not happening, which means that when we
* when we redraw the window and set a timer to clear * redraw the window and set a timer to clear the cooldown
* the cooldown flag 20ms later, that timer never * flag 20ms later, that timer never fires, and we aren't
* fires, and we aren't able to keep redrawing the * able to keep redrawing the window.
* window.
* *
* The 'obvious' answer would be to seize that * The 'obvious' answer would be to seize that SYSCOMMAND
* SYSCOMMAND ourselves and inhibit the default * ourselves and inhibit the default handler, so that our
* handler, so that our message loop carries on * message loop carries on running. But that would mean
* running. But that would mean we'd have to * we'd have to reimplement the whole of the scrollbar
* reimplement the whole of the scrollbar handler! * handler!
* *
* So instead we apply a bodge: set a static variable * So instead we apply a bodge: set a static variable that
* that indicates that we're _in_ that sub-loop, and * indicates that we're _in_ that sub-loop, and if so,
* if so, decide it's OK to manually call * decide it's OK to manually call term_update() proper,
* term_update() proper, bypassing the timer and * bypassing the timer and cooldown and rate-limiting
* cooldown and rate-limiting systems completely, * systems completely, whenever we see an SB_THUMBTRACK.
* whenever we see an SB_THUMBTRACK. This shouldn't * This shouldn't cause a rate overload, because we're
* cause a rate overload, because we're only doing it * only doing it once per UI event!
* once per UI event!
* *
* [1] Actually, there's an extra oddity where * [1] Actually, there's an extra oddity where SC_HSCROLL
* SC_HSCROLL and SC_VSCROLL have their documented * and SC_VSCROLL have their documented values the wrong
* values the wrong way round. Many people on the * way round. Many people on the Internet have noticed
* Internet have noticed this, e.g. * this, e.g. https://stackoverflow.com/q/55528397
* https://stackoverflow.com/q/55528397
*/ */
term_update(term); term_update(term);
} }
break; break;
}
}
break;
case WM_PALETTECHANGED: case WM_PALETTECHANGED:
if ((HWND) wParam != hwnd && pal != NULL) { if ((HWND) wParam != hwnd && pal != NULL) {
HDC hdc = make_hdc(); HDC hdc = make_hdc();