I have currently compiled and run the example from this tutorial on OSX, and found that it does not work to capture the mouse event.
I modified it slightly to make it easier to debug. It looks like wgetch is never returning KEY_MOUSE and instead is just returning some arbitrary character when I click. I'm also fairly sure it is not a terminal setting issue because Vim has no problem capturing mouse clicks in the exact same terminal.
I suspect the example is simply out of date.
Does anyone know the modern way to use ncurses to capture the mouse?
Below is my modified version of the code, for context.
Also, I compiled with g++ -std=c++17 -o curses_play curses_play.cc -lncurses.
#include <ncurses.h>
#include <string.h>
#include <stdio.h>
#define WIDTH 30
#define HEIGHT 10
int startx = 0;
int starty = 0;
char *choices[] = { "Choice 1",
"Choice 2",
"Choice 3",
"Choice 4",
"Exit",
};
int n_choices = sizeof(choices) / sizeof(char *);
void print_menu(WINDOW *menu_win, int highlight);
void report_choice(int mouse_x, int mouse_y, int *p_choice);
int main()
{ int c, choice = 0;
WINDOW *menu_win;
MEVENT event;
/* Initialize curses */
initscr();
clear();
noecho();
cbreak(); //Line buffering disabled. pass on everything
/* Try to put the window in the middle of screen */
startx = (80 - WIDTH) / 2;
starty = (24 - HEIGHT) / 2;
attron(A_REVERSE);
mvprintw(23, 1, "Click on Exit to quit (Works best in a virtual console)");
refresh();
attroff(A_REVERSE);
/* Print the menu for the first time */
menu_win = newwin(HEIGHT, WIDTH, starty, startx);
print_menu(menu_win, 1);
/* Get all the mouse events */
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
while(1)
{ c = wgetch(menu_win);
switch(c)
{ case KEY_MOUSE:
mvprintw(24, 0, "Found mouse!");
if(getmouse(&event) == OK)
{ /* When the user clicks left mouse button */
if(event.bstate & BUTTON1_PRESSED)
{ report_choice(event.x + 1, event.y + 1, &choice);
if(choice == -1) //Exit chosen
goto end;
mvprintw(22, 1, "Choice made is : %d String Chosen is \"%10s\"", choice, choices[choice - 1]);
refresh();
}
}
print_menu(menu_win, choice);
break;
default:
mvprintw(24, 0, "Charcter pressed is = %3d Hopefully it can be printed as '%c'", c, c);
refresh();
break;
}
}
end:
endwin();
return 0;
}
void print_menu(WINDOW *menu_win, int highlight)
{
int x, y, i;
x = 2;
y = 2;
box(menu_win, 0, 0);
for(i = 0; i < n_choices; ++i)
{ if(highlight == i + 1)
{ wattron(menu_win, A_REVERSE);
mvwprintw(menu_win, y, x, "%s", choices[i]);
wattroff(menu_win, A_REVERSE);
}
else
mvwprintw(menu_win, y, x, "%s", choices[i]);
++y;
}
wrefresh(menu_win);
}
/* Report the choice according to mouse position */
void report_choice(int mouse_x, int mouse_y, int *p_choice)
{ int i,j, choice;
i = startx + 2;
j = starty + 3;
for(choice = 0; choice < n_choices; ++choice)
if(mouse_y == j + choice && mouse_x >= i && mouse_x <= i + strlen(choices[choice]))
{ if(choice == n_choices - 1)
*p_choice = -1;
else
*p_choice = choice + 1;
break;
}
}