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