Search code examples
terminalmouseeventncurses

Ncurses not reporting mouse movements after columns 94


With the following example, I am able to get the mouse position inside my terminal until column 94. Where is the limitation?

#include <curses.h>

int main()
{
    initscr();
    cbreak();
    noecho();

    keypad(stdscr, TRUE);
    mousemask(ALL_MOUSE_EVENTS, NULL);

    MEVENT event;
    for (;;)
        if (wgetch(stdscr) == KEY_MOUSE && getmouse(&event) == OK)
            mvprintw(0, 0, "Mouse at row=%03d and column=%03d", event.y, event.x);
}

Tested in:

  • Windows Terminal (WSL2)
  • cmd.exe (WSL2)

But it is working in :

  • mintty (WSL2)

What am I missing?

In all terminal, I get the same result by manually enabling mouse reporting with echo -e "\e[?1000;1006;1015h". So it seems Ncurses is using something else...


Solution

  • ncurses uses the terminal description to determine if the terminal supports xterm's 1006 mouse-mode. It looks at the XM flag (see user_caps(5)):

    The XM capability has a single parameter. If nonzero, the mouse protocol should be enabled. If zero, the mouse protocol should be disabled. ncurses inspects this capability if it is present, to see whether the 1006 protocol is used. If so, it expects the responses to use the SGR 1006 xterm mouse protocol.

    To see that flag, you can use infocmp, e.g.,

    infocmp -1x |grep XM,
    

    to see if it is defined. For mintty, you might see this:

    $ infocmp -1x mintty | grep XM
            XM=\E[?1006;1000%?%p1%{1}%=%th%el%;,
    

    For those others, it helps to know what TERM is set to (also, the version of ncurses, since it could be too old).

    That 1015 in the question bears comment: that is an rxvt-unicode feature, which is not recognized by Windows Terminal. Nor is it mentioned in the documentation for Windows cmd. It is implemented in PuTTY (also xterm, though PuTTY's implementation differs from xterm). In both PuTTY/xterm, that 1006 which precedes the 1015 in the echo command will cause those terminals to use xterm's 1006 ("SGR mode"), which is implemented by Windows Terminal. If you had omitted the 1006, then it would not work with ncurses, because the protocols differ—and ncurses does not have support for the 1015 encoding.