diff --git a/windows/window.c b/windows/window.c index 57abad83..0c92a8f5 100644 --- a/windows/window.c +++ b/windows/window.c @@ -3160,57 +3160,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) {