15

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!

Barak Itkin
  • 4,872
  • 1
  • 22
  • 29

1 Answers1

25

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.

Matthew Slattery
  • 45,290
  • 8
  • 103
  • 119
  • 1
    I typed getchar in stackoverflow accidently, my real code did use getch. I skipped the refresh again when I typed the pseudo code here :P Anyways, many thanks - your suggestion with xterm worked very well! – Barak Itkin Sep 18 '11 at 21:22
  • Is there any way to make a program set that `TERM` variable for itself? I know you can start a program with it set by doing `TERM=xterm-1002 ./program`, for example, but is there any way to either somehow set it as the program's child process is created from the code, or have the program fork/start a new process of itself with the variable set? – Arthur Bouvier Jul 25 '22 at 04:04