I have a thread that catches a key pressed through getch
and if the key pressed is arrowUp or arrowDown then it scrolls my terminal using ncurses functions (incrementing an integer variable used to show elements from a linked list). This works fine most of the times but sometimes (usually when i hold an arrow pressed) ncurses prints on terminal weird and unexpected characters like 9;32H
(it seems like an uncatched input). Does anyone know how i can solve this?
Here an MCVE
#include <ncurses.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX(a,b) ((a) > (b) ? (a) : (b))
void * listener(void* p){
int* shift = (int*) p;
int ch;
while (1)
{
ch = getch();
if(ch == KEY_UP){
*shift = MAX(0, *shift - 1);
}
else if(ch == KEY_DOWN){
*shift = *shift + 1;
}
}
}
int main(){
char* c = malloc(100);
for(int i = 0; i < 100; i++){
c[i] = 'A' + (random() % 26);
}
int shift = 0;
pthread_t th;
initscr();
raw();
noecho();
keypad(stdscr, TRUE);
start_color();
curs_set(0);
pthread_create(&th, NULL, listener, (void*) &shift);
while(1){
for(int j = shift; j < shift+stdscr->_maxy; ++j){
move(j-shift,0);
clrtoeol();
mvaddch(j-shift, 0, c[j]);
refresh();
}
}
endwin();
free(c);
return 0;
}
This snippet shows my issue if you hold arrow down
EDIT:
The issue seems to be related to getch()
from different thread that modifies global variables of ncurses library. Does anyone know a thread-safe way to get a char input?
I actually solved my issue using getchar
instead of getch
since it seems not to be thread safe. I found out that getch
modifies ncurses global variable and calls refresh()
at the end, so if another thread is changing ncurses stuff (e.g. cursor position) your program may have an unexpected behavior (in my case printing escape characters representing set cursor position)