In the attached program, I've encountered two surprises.

1.  ungetmouse() seems to work only once.  Once I've retrieved the two
    event I push onto the mouse event stack by typing 'z', my loop stops
    behaving as I expect.  Typing 'z' 3 times, I get:

    16777216 524288 X X X X X X

    (The integers are the values of get bstate member of the MEVENT
    struct; "X" means that getmouse() returned ERR, that is, the mouse
    event stack was empty.)

2.  Multiple-clicking with a long mouse interval (set here to 1 second)
    does not work as I expect.  Here is what I see if I:

    Left-triple-click then left-single-click within the interval, then
    Left-triple-click then left-double-click within the interval, then
    Left-triple-click then left-triple-click within the interval.

    4 16 X 4 16 X 4 16 X

    I expected either:

    (a) the click count to "saturate" within the interval, and return
    only BUTTON1_TRIPLE_CLICKED (16); or

    (b) to receive one event of each kind, which only met my
    expectations in the first case.  So in that scenario I expected:

    4 16 X 8 16 X 16 X

Can someone elucidate the model I should have in my head?  It sounds
like I have the wrong one.

If it matters, I'm using stock ncurses v6_5_20250628 and XTerm(395) with
TERM=xterm-256color.

Regards,
Branden
#include <locale.h> // setlocale()
#include <stdlib.h> // EXIT_SUCCESS, exit()
#include <string.h> // strlen()

#include <curses.h>

int main(void) {
	setlocale(LC_ALL, "");
	initscr();
	cbreak();
	noecho();
	intrflush(stdscr, FALSE);
	keypad(stdscr, TRUE);

	if (mousemask(ALL_MOUSE_EVENTS, NULL) == 0) {
		endwin();
		fputs("Mouse doesn't support any events.\n", stderr);
		exit(EXIT_SUCCESS);
	}

	if (!has_mouse()) {
		endwin();
		fputs("No mouse is available.\n", stderr);
		exit(EXIT_SUCCESS);
	}

	mouseinterval(1000);

	char const message[] = "Oneko!  Press 'q' to quit.";

	(void) move((LINES / 2), ((COLS - strlen(message))/ 2));
	(void) addstr(message);
	(void) refresh();
	(void) addch('\n');

	int ch;
	MEVENT evt;

	while (TRUE) {
		evt.bstate = 0;
		ch = getch();
		if ('q' == ch) {
			break;
		}
		if (KEY_MOUSE == ch) {
			while (getmouse(&evt) != ERR) {
				(void) printw("%d ", evt.bstate);
			}
			(void) addstr("X ");
			(void) refresh();
		}
		if ('z' == ch) {
			evt.bstate = BUTTON4_TRIPLE_CLICKED;
			if (ungetmouse(&evt) == ERR) {
				(void) addstr("YYY ");
			}
			evt.bstate = BUTTON5_TRIPLE_CLICKED;
			if (ungetmouse(&evt) == ERR) {
				(void) addstr("ZZZ ");
			}
		}
	}

	endwin();
	fprintf(stderr, "This has been a demo of ncurses mouse protocol"
		" %d.\n", NCURSES_MOUSE_VERSION);
}

Attachment: signature.asc
Description: PGP signature

Reply via email to