5

Currently if I set the TERM environment variable to 'xterm-1003' I can get mouse move events but I get crappy colors and curses.can_change_color() == False

os.environ['TERM'] = 'xterm-1003'
...
curses.mousemask(curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION)
...
while True:
    event = screen.getch()
    if event == curses.KEY_MOUSE:
        # I get nice events whenever I move the mouse (no click required)
        _, mx, my, _, _ = curses.getmouse()

and if I set the TERM env var to 'xterm-256color' I get a nice color palette plus curses.can_change_color() == True, however I do not receive mouse events unless I click a button!

>ls /usr/share/terminfo/x/ 

reports

xfce           xterm-256color  xterm-hp      xterm-r5     xterm-xf86-v32   xterm-xfree86
xterm          xterm-88color   xterm-new     xterm-r6     xterm-xf86-v33   xterm-xi
xterm-1002     xterm-8bit      xterm-nic     xterm-sco    xterm-xf86-v333  xterms
xterm-1003     xterm-basic     xterm-noapp   xterm-sun    xterm-xf86-v40
xterm-16color  xterm-bold      xterm-old     xterm-vt220  xterm-xf86-v43
xterm-24       xterm-color     xterm-pcolor  xterm-vt52   xterm-xf86-v44

None of the ones I tried seem to support both curses.can_change_color() == True and mouse move events. Is there a way I can get both of them via setting an appropriate $TERM value or some other way?

Thank you!

Wulfire
  • 105
  • 3

3 Answers3

10

You can always make your own, using infocmp (to show the contents of an entry), and tic (to compile an entry). If you do not have permission to write in the system area, it goes to $HOME/.terminfo

Start by comparing xterm-1003 and xterm-256color:

> infocmp -x xterm-1003 xterm-256color
comparing xterm-1003 to xterm-256color.
    comparing booleans.
        ccc: F:T.
    comparing numbers.
        colors: 8, 256.
        pairs: 64, 32767.
    comparing strings.
        initc: NULL, '\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\'.
        setab: '\E[4%p1%dm', '\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m'.
        setaf: '\E[3%p1%dm', '\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m'.
        setb: '\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m', NULL.
        setf: '\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m', NULL.
        XM: '\E[?1003%?%p1%{1}%=%th%el%;', NULL.

Essentially, all you are interested in is adding the XM capability to a copy of xterm-256color.

So...

  1. infocmp -x xterm-256color >foo
  2. edit foo, adding the XM string
  3. tic -x foo

The "-x" option is needed for tic to compile the XM capability, which is an extended (user-defined) capability which ncurses happens to recognize as noted in comments for the terminal database.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • 1
    Why was this answer never accepted? I have the exact issue (albeit with another programming language) and it solves problem, is detailed, and links to references for research. – Norman B. Lancaster Jan 01 '17 at 11:20
2

Try This answer, it's simple and no impact to the system.

curses.mousemask(curses.REPORT_MOUSE_POSITION)
print('\033[?1003h') # enable mouse tracking with the XTERM API

Note that the print must appear after the mousemask() is called.

tinyhare
  • 2,271
  • 21
  • 25
1

The problem: Mouse position reported even when no mouse button held down.

This answer is intended to be an extension of the other answer here posted by Thomas Dickey. Using the links provided and basic steps, I managed to find an XM string that gave me the mouse behavior I wanted.

The problem I had with the XM string in the other answer is the mouse position was reported even when no mouse button was held down. I wanted mouse position only when a mouse button was down. In other words, I wanted "mouse drag" events. The constant reporting might be good for implementing a "mouse hover" feature, but I didn't need that so all the extra reporting was just causing wasted cycles in the app's event loop.

The steps I took to find the right XM string were:

  1. Create a 'foo' file as described in the other answer: infocmp -x xterm-256color > foo
  2. Take the text from the terminal database link and extract all the XM strings (provided below).
  3. Add one of the XM strings to my copy of 'foo' and issue tic -x foo (the new config is immediately active).
  4. Run my program to see if the mouse position behaved as wanted.
  5. If the behavior was different, go back to step 3 and try the next string.

The (commented out) XM strings as extracted from the "terminal database" link:

#    XM=\E[?9%?%p1%{1}%=%th%el%;,
#    XM=\E[?9%?%p1%{1}%=%th%el%;,
#    xm=\E[M%p3%' '%+%c%p2%'!'%+%c%p1%'!'%+%c,
#    XM=\E[?1000%?%p1%{1}%=%th%el%;,
#    xm=\E[M%?%p4%t%p3%e%{3}%;%'\s'%+%c%p2%'!'%+%c%p1%'!'%+%c,
#    XM=\E[?1001%?%p1%{1}%=%th%el%;,
#    XM=\E[?1002%?%p1%{1}%=%th%el%;,
#    XM=\E[?1003%?%p1%{1}%=%th%el%;,
#    XM=\E[?1005;1000%?%p1%{1}%=%th%el%;,
#    xm=\E[M%?%p4%t3%e%p3%'\s'%+%c%;%p2%'!'%+%u%p1%'!'%+%u,
#    XM=\E[?1006;1000%?%p1%{1}%=%th%el%;,
#    xm=\E[<%i%p3%d;%p1%d;%p2%d;%?%p4%tM%em%;,

The string that worked for my Ubuntu 20 sytem's bash terminal was:

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

I anticipate some extra future work enabling this behavior on other systems when my app is nearly ready for distribution.

Another potential problem is this hack may affect bash behavior generally - not just when my app is running in a bash terminal. Maybe a better solution would be not to tweak the xterm-256color file, but create a custom file of another name unlikely to be confused with the standard files. Then in my application set the TERM environment variable to it before initiating curses.

    os.environ['TERM'] = 'mouse-tweaked-xterm-256color'
    curses.wrapper(start_my_app)

Update: The new xterm-256color file produced by tic was located on my system under ${HOME}/.terminfo/x/. I changed its name and implemented the above code to set TERM in the application.

Todd
  • 4,669
  • 1
  • 22
  • 30