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

Node.js tty.ReadStream does not pass in mouse event ANSI escape codes in Windows terminal #56338

Open
liujingbreak opened this issue Dec 22, 2024 · 0 comments
Labels
tty Issues and PRs related to the tty subsystem.

Comments

@liujingbreak
Copy link

Version

v22.9.0

Platform

Microsoft Windows NT 10.0.19045.0 x64

Subsystem

No response

What steps will reproduce the bug?

  1. Save blew code snippet to file named like "mouse-test.js"
process.stdout.write('\x1b[?1000h');
process.stdout.write('\x1b[?1003h'); // Enable all mouse events (including drag)

process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.setEncoding('utf8');

// eslint-disable-next-line no-console
console.log("Mouse event reporting enabled. Move or click the mouse to see events. Press 'q' to quit.");

process.stdin.on('data', (chunk) => {
  if (chunk === '\u0003' || chunk === 'q') { // Ctrl+C or 'q' to exit
    // Disable mouse event reporting before exiting
    process.stdout.write('\x1b[?1000l');
    process.exit();
  }

  // Parse mouse event data
  if (chunk.startsWith('\x1b[M')) {
    const mouseData = chunk.slice(3);
    const buttonCode = mouseData.charCodeAt(0) - 32;
    const x = mouseData.charCodeAt(1) - 32;
    const y = mouseData.charCodeAt(2) - 32;

    // eslint-disable-next-line no-console
    console.log(`Mouse event: button=${buttonCode}, x=${x}, y=${y}`);
  }
});
  1. Running the Script

    Run the Script: Open Windows Terminal and navigate to the directory where your mouse-test.js script is located. Run the script using Node.js:

    node mouse-test.js
  1. Interact with the Terminal: Once the script is running, move the mouse or click within the terminal window. The script will output mouse events to the console.

  2. Quit the Script: Press q or Ctrl+C to quit the script. The script will disable mouse event reporting before exiting.

Explanation

  • Enabling Mouse Event Reporting: The script enables mouse event reporting using the ANSI escape codes \x1b[?1000h and \x1b[?1003h.
  • Reading Input: The script sets the terminal input to raw mode and starts reading input.
  • Handling Mouse Events: Mouse events are identified by the \x1b[M sequence. The script parses the mouse event data to extract the button code, x, and y coordinates.
  • Outputting Events: The parsed mouse event details are printed to the console.
  • Quitting the Script: Pressing q or Ctrl+C will disable mouse event reporting and exit the script.

By running this script, you can verify if Windows Terminal supports mouse event reporting via ANSI escape codes. If mouse events are correctly reported, you will see the mouse event details printed in the terminal.

How often does it reproduce? Is there a required condition?

Always happens.

What is the expected behavior? Why is that the expected behavior?

I am writing a command line based UI application.
I found same problem was addressed under Window Terminal's repo and it has been well explained by some thoughtful comments in an issue of Windows terminal, I think the linked comment explained that this is a missing behavior or case in source code of tty.c.

Let me quote some original sentences here:

A little searching though the nodejs source suggests it is getting in the middle and trying to help you, but incompletely. In here you'll see it's using both SetConsoleMode and ReadConsoleInput to simulate some VT codes itself, but doesn't ask for or pass through mouse input at all

nodejs reading the input on Windows via ReadConsoleInput and then generating it's own VT sequences for a set of inputs it knows about, which notably does not include mouse inputs
Hopefully in the future it will learn to either generate mouse input or enable VT input when you put it in raw mode, but right now it does neither

The impact is that some Node.js based command line or terminal UI applications are not able to support mouse event without some Windows native executable's help in Window terminal, but same function works fine in those popular terminal emulators for Linux and Mac OS, e.g. iTerm2 in Mac OS, WSL...

The above script I have tested successfully in iTerm2 for Mac OS, WSL and Termux of Android OS, it prints out mouse point location when I move or clicks mouse button.

So I feel that this issue may can also be considered as a feature which is unexpectedly worked for OS environments other than Windows, and it leaves Windows as the last missing piece.

What do you see instead?

I see not text output when I click and move mouse, which is supposed to print mouse point coordinates.

Additional information

No response

@lpinca lpinca added the tty Issues and PRs related to the tty subsystem. label Dec 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tty Issues and PRs related to the tty subsystem.
Projects
None yet
Development

No branches or pull requests

2 participants