Mouse movement events in NCurses

2019-01-18 12:37发布

问题:

I wonder if there is such a thing as mouse movement events in NCurses, and if there is a way to catch them. Following the Interfacing with the mouse (from the NCurses programming HOWTO) it seems that by enabling the REPORT_MOUSE_POSITION bit in the call to mousemask, one can indeed catch mouse movement events.

So, I tried that and it does not seem to work. I have something like this:

int ch, count=0;
mmask_t old;

initscr ();
noecho ();
cbreak ();
mousemask (ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, &old);
keypad (stdscr, TRUE);

while ((ch = getchar ()) != 'q')
{
  count++;
  if (ch == KEY_MOUSE)
  {
     MEVENT event;
     assert (getmouse (&event) == OK);
     mvprintw (0, 0, "Mouse Event!\n");
  }
  mvprintw (1, 1, "Event number %4d",count);
}

...

I expected that as I'll move my mouse cursor, I'll see the event counter increasing. But it didn't. I also tried moving it while mouse button 1 is down to see if generates "drag" events, and it also didn't do anything. The question is, if it's simply a problem of my terminal emulator? Or maybe I'm misunderstanding what NCurses considers as mouse movement events? All the other mouse events were received (and I can operate programs in the console that use the mouse).

I tried gnome-terminal, xterm, and some other stuff. I also tried a textual environment (without X) by going to the tty's of my linux machine (Fedora 15, Ctrl+Alt+F2) and that did not work.

Finally, assuming I do get this right and those events should be reported, what is the bstate field of a MEVENT for a mouse movement evenet?

Many thanks in advance!

回答1:

You need:

  1. a terminal which supports mouse event reporting;
  2. $TERM pointing to a terminfo entry which has an appropriate XM entry to initialise the terminal correctly.

xterm at least satisfies (1); for (2), it's likely that you'll need to set a different value for TERM.

Try:

  • TERM=xterm-1002 to get a position event when the cursor moves to a different cell while a button is being held down; or
  • TERM=xterm-1003 to always get a position event whenever the cursor moves to a different cell, even if no button is pressed.

The resulting events have the REPORT_MOUSE_POSITION bit set on the bstate field.

(The "PORTABILITY" section of the curs_mouse(3x) man page describes the terminal initialisation, and the "Mouse Tracking" section of the Xterm Control Sequences documentation describes the relevant "private mode" extensions.)

The code that you've given above needs to use getch(), not getchar(); and needs a refresh() inside the loop! Other than that, it works for me with xterm when using one of the appropriate TERM settings.