Rolf
Rolf

Reputation: 84

how to enable mouse movement events in curses

How do I enable mouse movement events in curses?

I found this Mouse movement events in NCurses, Xterm Control Sequences and ncurses_mouse_movement but I don't understand from that, how to enable mouse movement events in python-curses. I figure it has something to do with TERM=xterm-1003 but I don't know how to set that in python-curses.

this is what I did to enable any mouse events:

curses.mousemask(curses.REPORT_MOUSE_POSITION | curses.ALL_MOUSE_EVENTS)

Upvotes: 1

Views: 2544

Answers (2)

Mia
Mia

Reputation: 2676

I know this is a pretty old question and the OP might not need it anymore, but I'm leaving it here for anyone who stumbles upon this question after hours of googling and head scratching:

import curses

def main(win:curses.window):
    win.clear()
    win.nodelay(True)
    curses.mousemask(curses.REPORT_MOUSE_POSITION)
    print('\033[?1003h') # enable mouse tracking with the XTERM API
    # https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking

    while True:
        ch=win.getch()
        if ch==curses.KEY_MOUSE:
            win.clear()
            win.addstr(0,0,str(curses.getmouse()[1:3]))
            win.refresh()

curses.wrapper(main)

The most important line here is the print('\033[?1003h'), which enables the mouse position reporting to the program, while the mousemask enables curses to interpret the input from the terminal. Note that the print must appear after the mousemask() is called.

Tested on macOS 10.14.6 with iTerm2. There is no tweak to the terminfo.

Upvotes: 4

Abram
Abram

Reputation: 413

I finally got it to work. On Ubuntu it worked by simply setting TERM=screen-256color, but on OSX I had to edit a terminfo file, using the instructions here:

Which $TERM to use to have both 256 colors and mouse move events in python curses?

but on my system the format was different so I added the line:

XM=\E[?1003%?%p1%{1}%=%th%el%;,

to my terminfo. To test it, I used this Python code (note screen.keypad(1) is very necessary, otherwise mouse events cause getch to return escape key codes).

import curses

screen = curses.initscr()
screen.keypad(1)
curses.curs_set(0)
curses.mousemask(curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION)
curses.flushinp()
curses.noecho()
screen.clear()

while True:
    key = screen.getch()
    screen.clear()
    screen.addstr(0, 0, 'key: {}'.format(key))
    if key == curses.KEY_MOUSE:
        _, x, y, _, button = curses.getmouse()
        screen.addstr(1, 0, 'x, y, button = {}, {}, {}'.format(x, y, button))
    elif key == 27:
        break

curses.endwin()
curses.flushinp()

Upvotes: 2

Related Questions