[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Possible bug with scrolling regions in pads?

From: Rob King
Subject: Possible bug with scrolling regions in pads?
Date: Thu, 25 Jul 2019 23:09:48 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0

Hello everyone,

    I think there may be a bug with pads and scrolling regions in
ncurses-6.1 (and probably earlier versions too).

    Take for example the following program (an adaptation of vttest's
"accordion" test):

    WINDOW *pad = newpad(LINES * 2, COLS);
    scrollok(pad, TRUE);

    int y = 0, x = 0, top_of_screen = 0, bottom_of_screen = 0;
    getmaxyx(pad, y, x);

    top_of_screen = y - LINES;
    bottom_of_screen = top_of_screen + LINES - 1;

    wmove(pad, top_of_screen, 0);
    waddstr(pad, "TOP OF SCREEN");
    wmove(pad, bottom_of_screen, 0);
    waddstr(pad, "BOTTOM OF SCREEN");

    for (int i = top_of_screen + 1; i < bottom_of_screen; i++)
        mvwaddstr(pad, i, 0, "XXXXXXX");
    prefresh(pad, top_of_screen, 0, 0, 0, LINES - 1, COLS - 1);

    wsetscrreg(pad, top_of_screen + 1, bottom_of_screen - 1);
    for (int i = 0; i < LINES + 10; i++){
        wscrl(pad, i % 2? i : -i);
        prefresh(pad, top_of_screen, 0, 0, 0, LINES - 1, COLS - 1);


This program creates a pad taller than the screen, and treats the bottom
part of the pad as the part that will get drawn to the screen. It then
draws "TOP OF SCREEN" to the line in the pad that will be placed at the
top of the physical screen, "BOTTOM OF SCREEN" at the bottom, and every
other to-be-screen line with X's.

It then sets the scrolling region such that only the X's will scroll. It
then calls wscrl with increasing positive and negative scrolling values.

When it is run, the X's bounce up and down as expected, losing a line
each iteration. However, at the end, when the scrolling values get large
enough, the lines outside the top and bottom of the scrolling region are
scrolled away (the "TOP/BOTTOM OF SCREEN" lines). Given the value of the
scrolling region, this shouldn't happen (unless I'm mistaken).

As an experiment, I modified lib_scroll.c to look like the following:

    /* shift n lines downwards */
    if (n < 0) {
    limit = top - n;
    for (line = bottom; line >= limit && line >= 0 && line >= top;
line--) { /* added line >= top */
        TR(TRACE_MOVE, ("...copying %d to %d", line + n, line));
           win->_line[line + n].text,
        if_USE_SCROLL_HINTS(win->_line[line].oldindex =
                win->_line[line + n].oldindex);
    for (line = top; line < limit && lines <= win->_maxy && line <=
bottom; line++) { /* added line <= bottom */
        TR(TRACE_MOVE, ("...filling %d", line));
        for (j = 0; j <= win->_maxx; j++)
        win->_line[line].text[j] = blank;
        if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX);

(and similarly for the positive n case). This appears to resolve the issue.

Of course, there are two other possibilities: (a) scrolling isn't
supposed to work like this in pads or (b) I'm mistaken with my test
case. If it turns out to be (b), it wouldn't be the first time...

Please let me know if this makes sense.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]