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 commitf69cf86a61
, 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 commit2029aa55c2
)
This commit is contained in:
parent
1dc5659aa6
commit
22d7888b33
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user