wmcbrine / PDCurses

A curses library for environments that don't fit the termcap/terminfo model.
https://pdcurses.org/
1.03k stars 171 forks source link

background color issue when resizing a pad #122

Closed GiorgosXou closed 2 years ago

GiorgosXou commented 2 years ago

wresize-ing a pad immediately after wbkgd/setting a background-color to it, creates the issue demonstrated above in the image:

pdcursesbug gif

I've tried looking into the bkgd.c and window.c but i had no luck... (this issue is not present with ncurses)

I use unicurses with the latest 3.9 version of PDCurses

from unicurses import * # python3.9 -m pip install uni-curses 

def main():
    stdscr = initscr()

    cbreak()
    noecho()
    keypad(stdscr, True)
    start_color()
    init_pair(1, COLOR_RED  , COLOR_WHITE)
    refresh()

    pROWS = 40
    pCOLS = 50

    pad1 = newpad(pROWS,pCOLS)
    wbkgd(pad1, COLOR_PAIR(1))
    pad1_position = 0

    for i in range(pROWS -2):
        mvwaddstr(pad1,i+1,2, str(i+1) + ': This is a TEST LINE')        

    prefresh(pad1,pad1_position, 0, 5, 5, 15, pCOLS-2)

    ch = -1
    while ( (ch != CCHAR('q')) and (ch != CCHAR('Q')) ):
        ch = getch()
        if  ch == KEY_DOWN: # MOVING DOWN
            pad1_position += 1
            prefresh(pad1,pad1_position, 0, 5, 5, 15, pCOLS-2)
        elif ch == KEY_UP: # MOVING UP
            pad1_position -= 1
            prefresh(pad1,pad1_position, 0, 5, 5, 15, pCOLS-2)
        else: # ADDING A LINE AT BOTTOM OF PAD AND MOVING DOWN
            pROWS += 1
            pad1_position += 1
            y,x = getmaxyx(pad1) # proof that pad changes size.

            mvwaddstr(pad1,pROWS-2,2, str(pROWS-2) + ': This is a  NEW LINE | mY=' + str(y) + ', mX=' + str(x)) 
            wresize(pad1,pROWS,pCOLS)
            prefresh(pad1,pad1_position, 0, 5, 5, 15, pCOLS-2)
            #wbkgd(pad1, COLOR_PAIR(1)) # <-- this won't fix anything even if it is before prefresh

    endwin()

if __name__ == "__main__":
    main()
Bill-Gray commented 2 years ago

For what it's worth... same test in C (with the same problem).

By hitting the up arrow and setting pad1_position to be negative, one can also use this to test issue #121.

#include <curses.h>

int main( void)
{
    int pROWS = 40, pCOLS = 50;
    int pad1_position = 0, i, ch = -1;
    WINDOW *pad1;

    initscr();
    cbreak();
    noecho();
    keypad(stdscr, TRUE);
    start_color();
    init_pair(1, COLOR_RED, COLOR_WHITE);
    refresh();

    pad1 = newpad( pROWS,pCOLS);
    wbkgd(pad1, COLOR_PAIR(1));

    for( i = 0; i < pROWS - 2; i++)
        mvwprintw( pad1, i, 2, "%d: This is a TEST LINE", i + 1);

    while( ch != 'q' && ch != 'Q')
    {
        prefresh( pad1, pad1_position, 0, 5, 5, 15, pCOLS-2);
        ch = getch();
        if( ch == KEY_DOWN)    /* MOVING DOWN */
            pad1_position++;
        else if( ch == KEY_UP)         /* MOVING UP */
            pad1_position--;
        else    /* ADDING A LINE AT BOTTOM OF PAD AND MOVING DOWN */
        {
            int x, y;

            pROWS++;
            pad1_position++;
            getmaxyx(pad1, y, x); /* proof that pad changes size. */

            mvwprintw( pad1, 3, 3, "%d hit ", ch);
            mvwprintw(pad1,pROWS-2,2, "%d : This is a NEW LINE | mY=%d, mX=%d",
                        pROWS - 2, y, x);
            wresize(pad1,pROWS,pCOLS);
            /* wbkgd(pad1, COLOR_PAIR(1)) # <-- this won't fix anything
                       even if it is before prefresh */
        }
    }
    endwin();
    return( 0);
}
GiorgosXou commented 2 years ago

Any idea why this might happening?

GiorgosXou commented 2 years ago

@Bill-Gray I found another very wierd thing... if you do pCOLS++; resizing past sy1+1 times won't do anything to the size of columns pdcursesbug2 gif

UPDATE | I meant sx1 not sy1

wmcbrine commented 2 years ago

Any idea why this might happening?

Not so far. I tried a few things but got nowhere.

Bill-Gray commented 2 years ago

@GiorgosXou - re "another weird thing" : just to confirm, you are saying that adjusting pCOLS, a measurement of columns, to be greater than sy1 + 1, a measurement of rows, causes this? We're getting columns and rows mixed up?

I haven't figured out the background issue either. A possible clue : it appears to go beyond just pads. Modified version of your test, except applied to the main window, follows. Resize the window, and bits beyond the initial screen size (both horizontal and vertical) are left black.

#include <curses.h>

int main( void)
{
    initscr();
    start_color( );
    init_pair(1, COLOR_RED, COLOR_WHITE);
    bkgd( COLOR_PAIR( 1));
    addstr( "Resize the window.  Hit any key to exit.");
    refresh();

    while( getch( ) == KEY_RESIZE)
          resize_term( 0, 0);
    endwin( );
    return( 0);
}
GiorgosXou commented 2 years ago

@Bill-Gray @wmcbrine my fault i meant sx1, i am sorry for the confusion, i'm an idiot lol sx1+1

GiorgosXou commented 2 years ago

again sorry for the confusion (my brain not working well right now, i haven't slept that well today, i'm going to rest, if you find anything let me know, thanks)

UPDATE 19/10/2021

my fault again, it is the same issue but with columns, nothing new

Bill-Gray commented 2 years ago

I am reasonably sure the problem is here, in the resize_window() function.

new is created and werased, with the background still set to the default attribute (space, color pair 0). We then copy win into it. If win is smaller, the areas to the right or below are left as spaces with color pair 0.

Adding the line new->_bkgd = win->_bkgd just before calling werase(new);, so that the erasure is done with the "correct" background, fixes both your pad example and my window-resizing example.

GiorgosXou commented 2 years ago

Thanks 🙏