Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mouse not works in builtin terminal for ncurses app #21106

Closed
haolian9 opened this issue Nov 18, 2022 · 19 comments · Fixed by #24547
Closed

mouse not works in builtin terminal for ncurses app #21106

haolian9 opened this issue Nov 18, 2022 · 19 comments · Fixed by #24547
Labels
bug issues reporting wrong behavior terminal built-in :terminal or :shell
Milestone

Comments

@haolian9
Copy link

haolian9 commented Nov 18, 2022

Neovim version (nvim -v)

NVIM v0.8.0

Vim (not Nvim) behaves the same?

not tested

Operating system/version

archlinux

Terminal name/version

xterm 375

$TERM environment variable

in xterm it is xterm, in nvim terminal it is xterm-256color

Installation

system package manager

How to reproduce the issue

Expected behavior

mouse works in nvim's builtin terminal for ncurses app;

Actual behavior

mouse left, right click and scroll up, down do not work as expected, and the two programs are ncurses based.
if I run them in xterm directly, the mouse works well.

more tests

If i do as this, then the mouse works well:

  • $ xterm
  • `$ nvim --clean +'terminal'
  • $ echo '\x1b[?1002h # now we are in nvim's builtin terminal
  • $ nnn
@haolian9 haolian9 added the bug issues reporting wrong behavior label Nov 18, 2022
@zeertzjq zeertzjq added the terminal built-in :terminal or :shell label Nov 18, 2022
@zeertzjq
Copy link
Member

zeertzjq commented Nov 19, 2022

It seems that when $TERM is xterm or xterm-256color, nnn sends \x1b[?1006;1000h to enable mouse, which seems not recognized by libvterm. When $TERM is something else it sends \x1b[?1000h to enable mouse. So a workaround is to set $TERM to something else when running nnn.

@zeertzjq zeertzjq added the has:workaround issue is not fixed but can be circumvented until then label Nov 19, 2022
@zeertzjq
Copy link
Member

From curs_mouse(3X):

       If the terminfo entry contains a XM string, this is used in the xterm mouse driver to control the way the terminal is initialized for mouse operation.  The default, if  XM  is  not
       found, corresponds to private mode 1000 of xterm:

          \E[?1000%?%p1%{1}%=%th%el%;

       The mouse driver also recognizes a newer xterm private mode 1006, e.g.,

          \E[?1006;1000%?%p1%{1}%=%th%el%;

From user_caps(5):

             Here are examples from the terminal database for the most commonly used xterm mouse protocols:

               xterm+x11mouse|X11 xterm mouse protocol,
                       kmous=\E[M, XM=\E[?1000%?%p1%{1}%=%th%el%;,
                       xm=\E[M
                          %?%p4%t%p3%e%{3}%;%' '%+%c
                          %p2%'!'%+%c
                          %p1%'!'%+%c,

               xterm+sm+1006|xterm SGR-mouse,
                       kmous=\E[<, XM=\E[?1006;1000%?%p1%{1}%=%th%el%;,
                       xm=\E[<%i%p3%d;
                          %p1%d;
                          %p2%d;
                          %?%p4%tM%em%;,

So it indeed seems to be xterm-256color causing the problem here.

@haolian9
Copy link
Author

a bit off-topic, i'm amazed by your debugging skill, could you share how you know nnn sends \x1b[?1006;1000h?
Minutes later, i managed to do it with strace -o file nnn, but i'm still wondering the way you used.

@zeertzjq
Copy link
Member

I was just using script.

@haolian9
Copy link
Author

haolian9 commented Nov 19, 2022

It seems that when $TERM is xterm or xterm-256color, nnn sends \x1b[?1006;1000h to enable mouse

confirmed.

... which seems not recognized by libvterm. a workaround is to set $TERM to something else like tmux-256color

I saw centos 7 does not has tmux-256color terminfo. oh i see, maybe libvterm uses its own xterm-256color terminfo which does not match the one provided by the system?

@zeertzjq
Copy link
Member

libvterm itself by default does not seem to set $TERM variable. Nvim sets it to xterm-256color in termopen()

@haolian9
Copy link
Author

haolian9 commented Nov 19, 2022

that explains why the TERM workaround works in some terminal emulators for nnn used by nnn.nvim, while in some other terminals, it does not. eg. xterm, konsole.
If i need to set the TERM env, maybe the screen-256color is the most well-supported option for this case.

@luukvbaal

This comment was marked as off-topic.

@zeertzjq

This comment was marked as off-topic.

@erw7
Copy link
Contributor

erw7 commented Nov 22, 2022

So a workaround is to set $TERM to something else like tmux-256color when running nnn.

Do not suggest as a workaround an improper method that sets $TERM to an incorrect value. That workaround will create a new problem where the Home and End key will not work. You know that issue tracker of neovim also contains a lot of issues when $TERM is set to the wrong value.

A more appropriate workaround is to send a sequence that enables mouse input before invoking nnn, such as using a function like the following:

function nnn() {
  printf "\x1b[?1000h"
  /usr/bin/nnn ${1+"$@"}
  printf "\x1b[?1000l"
}

@erw7
Copy link
Contributor

erw7 commented Nov 22, 2022

There doesn't seem to be much discussion about this. Vim's :terminal already lets :terminal inherit $TERM, while in Nvim $TERM has always been xterm-256color in :terminal since it was first added in #2076, and there doesn't seem to be discussion about this in #2076 either.

Regardless of the host terminal, neovim terminals always behave like xterm. Therefore, it is inappropriate to inherit $TERM without discussion.

It is clear from the following code that vim inherits $TERM only if it starts with xterm. It may be debatable whether to implement the same in neovim. However, as far as I know, the only recent terminal where xterm is appropriate for $TERM and 256 colors are not available is the FreeBSD console. Thus I see little need to implement it.

Ref. https://github.com/vim/vim/blob/ce30ccc06af7f2c03762e5b18dde37b26ea6ec42/src/os_unix.c#L5638-L5640

// Use 'term' or $TERM if it starts with "xterm", otherwise fall
// back to "xterm" or "xterm-color".
if (term == NULL || *term == NUL || STRNCMP(term, "xterm", 5) != 0)

@justinmk
Copy link
Member

justinmk commented Nov 22, 2022

vim inherits $TERM only if it starts with xterm. It may be debatable whether to implement the same in neovim

Yep. Makes no sense for :terminal to claim it is some other $TERM (except perhaps something custom like xterm-nvim, but really, it's better if we just aim to be a satisfactory implementation of xterm and claim xterm-256color).

Child processes can check $NVIM to confirm that they are running in :terminal.

@vlada-dudr
Copy link

Isn't correct solution to claim TERM=nvim and provide appropriate terminfo (and maybe termcap) databases? Maybe providing several entries and setting correct one depending on features of parent terminal, like nvim-256color and nvim-truecolor.

@neovim-discourse
Copy link

This issue has been mentioned on Neovim Discourse. There might be relevant details there:

https://neovim.discourse.group/t/how-can-i-enable-the-mouse-for-the-programs-i-run-on-the-terminal/4016/5

@Zeioth
Copy link

Zeioth commented May 31, 2023

For terminal progams this has to be setted:

set mouse=a
printf "\x1b[?1000h"

But for for the actual terminal, to enable mouse support one must

set mouse=""
printf "\x1b[?1000l"

Then to make the mouse work on neovim one must

set mouse=a

All this work, but it is super hackish. What if we make a neovim option to do all this stuff for the user? I don't think the average user is gonna be willing to go through all of this just to have mouse support.

The issue is this may not work for all terminals, but most modern terminals are xterm-256color, so it should be fine.

I can think 3 solutions to this border case:

  • Give the user options to set the term codes.
  • We detect the term and set the codes automatically.
  • We just let the user opt-out the mouse support and be on its own.

@zeertzjq
Copy link
Member

zeertzjq commented Jun 2, 2023

Applying the following patch to libvterm may fix this issue:

diff --git a/src/libvterm/src/state.c b/src/libvterm/src/state.c
index ee4482469..478b1317c 100644
--- a/src/libvterm/src/state.c
+++ b/src/libvterm/src/state.c
@@ -1370,8 +1370,9 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
     break;
 
   case LEADER('?', 0x68): // DEC private mode set
-    if(!CSI_ARG_IS_MISSING(args[0]))
-      set_dec_mode(state, CSI_ARG(args[0]), 1);
+    for (int i = 0; i < argcount; i++)
+      if(!CSI_ARG_IS_MISSING(args[i]))
+        set_dec_mode(state, CSI_ARG(args[i]), 1);
     break;
 
   case 0x6a: // HPB - ECMA-48 8.3.58
@@ -1392,8 +1393,9 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
     break;
 
   case LEADER('?', 0x6c): // DEC private mode reset
-    if(!CSI_ARG_IS_MISSING(args[0]))
-      set_dec_mode(state, CSI_ARG(args[0]), 0);
+    for (int i = 0; i < argcount; i++)
+      if(!CSI_ARG_IS_MISSING(args[i]))
+        set_dec_mode(state, CSI_ARG(args[i]), 0);
     break;
 
   case 0x6d: // SGR - ECMA-48 8.3.117

But I don't know if this change is desired.

@Zeioth
Copy link

Zeioth commented Jun 2, 2023

@zeertzjq I've:

  • uninstalled libvterm on my system
  • downloaded and patched libvterm from here
  • sudo make install

I don't see any change of behavior on nvim term. I'm not sure what is supposed to happen.

@zeertzjq
Copy link
Member

zeertzjq commented Jun 2, 2023

Works for me using extra/neovim and AUR neovim-git packages. If you are using AUR neovim-nightly-bin then it will not work.

@Zeioth
Copy link

Zeioth commented Jun 3, 2023

Neovim installed from extra
screenshot_2023-06-03_05-59-41_906526916
screenshot_2023-06-03_06-00-49_750322281

libvterm patched
screenshot_2023-06-03_06-02-53_373618739
screenshot_2023-06-03_06-03-39_590450208
screenshot_2023-06-03_06-04-02_846755217

How I've tested

  • Open neovim
  • :term → No changes
  • ranger → No changes

Questions

What terminal are you running neovim on? I'm using foot terminal with xterm256color.

zeertzjq added a commit to zeertzjq/neovim that referenced this issue Aug 3, 2023
zeertzjq added a commit that referenced this issue Aug 3, 2023
zeertzjq added a commit to zeertzjq/neovim that referenced this issue Aug 4, 2023
@zeertzjq zeertzjq added this to the 0.9.2 milestone Aug 4, 2023
@zeertzjq zeertzjq removed the has:workaround issue is not fixed but can be circumvented until then label Aug 4, 2023
clason pushed a commit to clason/neovim that referenced this issue Aug 8, 2023
catlee pushed a commit to catlee/neovim that referenced this issue Aug 8, 2023
haolian9 pushed a commit to haolian9/neovim that referenced this issue Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug issues reporting wrong behavior terminal built-in :terminal or :shell
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants