Flickering when outputting characters on a white background (ncurses on WSL) #21451

Open
opened 2026-01-31 07:45:01 +00:00 by claunia · 1 comment
Owner

Originally created by @spinojara on GitHub (Mar 31, 2024).

Windows Terminal version

1.19.10821.0

Windows build number

10.0.22631.0

Other Software

I'm using ncurses on WSL.

WSL kernel: 5.15.146.1-microsoft-standard-WSL2
ncurses: 6.4
gcc: 13.2.1
glibc: 2.38

Steps to reproduce

Extra info

This (bug) reproduces every single time that I run the following program. I have tried changing the rendering settings, i.e. using AtlasEngine and not using AtlasEngine. Also using software rendering and not etc. All of the options give exactly the same result as shown in the video below. Note that the program below never ever prints something with a black background. It only every outputs characters with a white background. It works as expected on all terminals (that I have tried) on a native Linux installation. I have tried commenting the code, in the case that you are not familiar with the ncurses library. If you need more information than provided I will be happy to help.

Steps to reproduce

Compile and run the code that I have submitted. The code is compiled with
gcc -O2 main.c -lncurses -ltinfo
Depending on if your wsl-distribution has built the tinfo library separetely or not it is possible that you should instead compile it with
gcc -O2 main.c -lncurses
This is the most minimal example I could find that reproduces the bug. It was found while working on a larger project which outputs scrollable text.

#include <unistd.h>
#include <ncurses.h>

const int arr[262] = {
	0, 19, 18, 17, 0, 17, 17, 16, 16, 17, 19, 17, 19,
	0, 32, 0, 42, 0, 57, 25, 38, 23, 9, 0, 23, 21, 20,
	17, 39, 39, 35, 17, 40, 35, 57, 35, 17, 22, 22, 17,
	51, 39, 35, 17, 61, 35, 41, 35, 17, 22, 18, 36, 39,
	47, 31, 17, 33, 17, 36, 22, 16, 22, 9, 0, 52, 70,
	39, 1, 0, 35, 120, 19, 0, 34, 0, 18, 0, 29, 32, 74,
	26, 30, 0, 31, 49, 50, 41, 45, 17, 0, 55, 33, 0, 49,
	42, 83, 71, 50, 84, 45, 87, 30, 47, 107, 25, 59, 67,
	67, 63, 72, 37, 43, 86, 36, 82, 51, 86, 25, 42, 74,
	87, 25, 30, 83, 74, 25, 36, 74, 25, 45, 87, 25, 17,
	0, 32, 9, 26, 19, 1, 0, 24, 18, 35, 23, 17, 1, 0, 38,
	20, 22, 31, 23, 9, 28, 25, 30, 0, 45, 0, 15, 37, 30,
	32, 9, 14, 43, 0, 17, 1, 0, 64, 25, 44, 23, 9, 0,
	103, 33, 25, 9, 0, 18, 118, 0, 27, 27, 32, 22, 25,
	30, 27, 30, 22, 9, 0, 26, 26, 1, 0, 46, 28, 28, 22,
	21, 41, 25, 27, 0, 23, 60, 61, 11, 60, 1, 0, 43, 37,
	35, 47, 42, 71, 25, 0, 18, 32, 47, 33, 27, 38, 25,
	30, 39, 33, 28, 0, 49, 0, 64, 78, 88, 77, 77, 86, 75,
	81, 83, 84, 33, 0, 48, 41, 9, 0, 41, 27, 40, 9, 61,
	52, 0, 17, 1,
};

int main(void) {
	/* Start ncurses. */
	initscr();
	curs_set(0);

	/* Initialize colors and create the necessary color with white
	 * background. */
	start_color();
	init_pair(1, COLOR_BLACK, COLOR_WHITE);

	/* Set the color to (COLOR_BLACK, COLOR_WHITE). */
	attrset(COLOR_PAIR(1));

	/* This loop fills the entire screen with our background color.
	 * Our color was set to (COLOR_BLACK, COLOR_WHITE) on the previous
	 * line which means that the entire screen will be filled with white.
	 */
	for (int y = 0; y < LINES; y++)
		mvhline(y, 0, ' ', COLS);
	refresh();

	/* This loop successively fills the screen with the char 'x'
	 * in random places. There is nothing special about the character
	 * 'x', it works the same with any character (except the space
	 * character ' ').
	 */
	for (int i = 0; i < 100; i++) {
		/* Add the chars. */
		for (int y = 0; y <= COLS; y++)
			mvaddch(y, arr[y + i], 'x');

		/* Refresh the screen and sleep. */
		refresh();
		sleep(1);
	}
	
	/* End ncurses. */
	endwin();
}

Expected Behavior

I'm expecting it not to flicker with random black characters when I never output those characters.

Actual Behavior

It flickers with random black characters which I never output.

https://github.com/microsoft/terminal/assets/90049674/264ff3c4-6055-40e6-a9fc-800cd2122666

Originally created by @spinojara on GitHub (Mar 31, 2024). ### Windows Terminal version 1.19.10821.0 ### Windows build number 10.0.22631.0 ### Other Software I'm using ncurses on WSL. WSL kernel: 5.15.146.1-microsoft-standard-WSL2 ncurses: 6.4 gcc: 13.2.1 glibc: 2.38 ### Steps to reproduce ### Extra info This (bug) reproduces every single time that I run the following program. I have tried changing the rendering settings, i.e. using AtlasEngine and not using AtlasEngine. Also using software rendering and not etc. All of the options give exactly the same result as shown in the video below. Note that the program below _never_ ever prints something with a black background. It only every outputs characters with a white background. It works as expected on all terminals (that I have tried) on a native Linux installation. I have tried commenting the code, in the case that you are not familiar with the ncurses library. If you need more information than provided I will be happy to help. ### Steps to reproduce Compile and run the code that I have submitted. The code is compiled with `gcc -O2 main.c -lncurses -ltinfo` Depending on if your wsl-distribution has built the tinfo library separetely or not it is possible that you should instead compile it with `gcc -O2 main.c -lncurses` This is the most minimal example I could find that reproduces the bug. It was found while working on a larger project which outputs scrollable text. ``` #include <unistd.h> #include <ncurses.h> const int arr[262] = { 0, 19, 18, 17, 0, 17, 17, 16, 16, 17, 19, 17, 19, 0, 32, 0, 42, 0, 57, 25, 38, 23, 9, 0, 23, 21, 20, 17, 39, 39, 35, 17, 40, 35, 57, 35, 17, 22, 22, 17, 51, 39, 35, 17, 61, 35, 41, 35, 17, 22, 18, 36, 39, 47, 31, 17, 33, 17, 36, 22, 16, 22, 9, 0, 52, 70, 39, 1, 0, 35, 120, 19, 0, 34, 0, 18, 0, 29, 32, 74, 26, 30, 0, 31, 49, 50, 41, 45, 17, 0, 55, 33, 0, 49, 42, 83, 71, 50, 84, 45, 87, 30, 47, 107, 25, 59, 67, 67, 63, 72, 37, 43, 86, 36, 82, 51, 86, 25, 42, 74, 87, 25, 30, 83, 74, 25, 36, 74, 25, 45, 87, 25, 17, 0, 32, 9, 26, 19, 1, 0, 24, 18, 35, 23, 17, 1, 0, 38, 20, 22, 31, 23, 9, 28, 25, 30, 0, 45, 0, 15, 37, 30, 32, 9, 14, 43, 0, 17, 1, 0, 64, 25, 44, 23, 9, 0, 103, 33, 25, 9, 0, 18, 118, 0, 27, 27, 32, 22, 25, 30, 27, 30, 22, 9, 0, 26, 26, 1, 0, 46, 28, 28, 22, 21, 41, 25, 27, 0, 23, 60, 61, 11, 60, 1, 0, 43, 37, 35, 47, 42, 71, 25, 0, 18, 32, 47, 33, 27, 38, 25, 30, 39, 33, 28, 0, 49, 0, 64, 78, 88, 77, 77, 86, 75, 81, 83, 84, 33, 0, 48, 41, 9, 0, 41, 27, 40, 9, 61, 52, 0, 17, 1, }; int main(void) { /* Start ncurses. */ initscr(); curs_set(0); /* Initialize colors and create the necessary color with white * background. */ start_color(); init_pair(1, COLOR_BLACK, COLOR_WHITE); /* Set the color to (COLOR_BLACK, COLOR_WHITE). */ attrset(COLOR_PAIR(1)); /* This loop fills the entire screen with our background color. * Our color was set to (COLOR_BLACK, COLOR_WHITE) on the previous * line which means that the entire screen will be filled with white. */ for (int y = 0; y < LINES; y++) mvhline(y, 0, ' ', COLS); refresh(); /* This loop successively fills the screen with the char 'x' * in random places. There is nothing special about the character * 'x', it works the same with any character (except the space * character ' '). */ for (int i = 0; i < 100; i++) { /* Add the chars. */ for (int y = 0; y <= COLS; y++) mvaddch(y, arr[y + i], 'x'); /* Refresh the screen and sleep. */ refresh(); sleep(1); } /* End ncurses. */ endwin(); } ``` ### Expected Behavior I'm expecting it not to flicker with random black characters when I never output those characters. ### Actual Behavior It flickers with random black characters which I never output. https://github.com/microsoft/terminal/assets/90049674/264ff3c4-6055-40e6-a9fc-800cd2122666
claunia added the Issue-BugArea-VTProduct-Terminal labels 2026-01-31 07:45:02 +00:00
Author
Owner

@spinojara commented on GitHub (Mar 31, 2024):

I have a small piece of additional information. If I refresh the screen more frequently the flickering disappears. That is, if I for example call refresh() after each call to mvaddch() on line 56 in the provided code.

It seems to be that the flickering starts when I output many characters on different lines which I all send to the terminal at the same time with a call to refresh().

I can thus get around the issue and get my program working as intended. However the bug still stands because I shouldn't have to call refresh() more than once.

@spinojara commented on GitHub (Mar 31, 2024): I have a small piece of additional information. If I refresh the screen more frequently the flickering disappears. That is, if I for example call refresh() after each call to mvaddch() on line 56 in the provided code. It seems to be that the flickering starts when I output many characters on different lines which I all send to the terminal at the same time with a call to refresh(). I can thus get around the issue and get my program working as intended. However the bug still stands because I shouldn't _have_ to call refresh() more than once.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#21451