xtermjs / xterm.js

A terminal for the web
https://xtermjs.org/
MIT License
17.33k stars 1.61k forks source link

Unable to force hide cursor. #4949

Closed Whirlwind closed 6 months ago

Whirlwind commented 6 months ago

I want to hide the cursor to show the terminal as a monitor.

When I use xterm 4.40, the cursorWidth: 0 works:

  const aTerm = new Term({
    convertEol: true,
    fontFamily: "Menlo, Monaco, 'Courier New', monospace",
    fontSize: 12,
    lineHeight: 1.2,
    cursorStyle: 'bar',
    cursorWidth: 0,
  });

Upgrade xterm 5.3.0, I get the error:

Error: cursorWidth cannot be less than 1, value: 0

What can I do to hide the cursor?

Details

jerch commented 6 months ago

You can use DECTCEM for that, just write to the terminal '\x1b[?25l' for hiding, and '\x1b[?25h' for showing the cursor. Imho we dont have an explicit API method or setting for that.

Tyriar commented 6 months ago

I agree, just writing DECTCEM is easy

Whirlwind commented 6 months ago

I don't think it is good idea.

the xterm is a monitor, and it just show the information. If somebody print the \x1b[?25h, then the cursor will show in the xterm. I want to hide the cursor and ignore any DECTCEM.

jerch commented 6 months ago

I want to hide the cursor and ignore any DECTCEM.

Thats not possible by normal means, xterm.js is meant to support DECTCEM as VT feature.

It is still possible, if you alter xterm.js to your needs, eg. by a custom CSI handler. But this is quite involved and a reliable solution would need to access private internals, schematically (untested):

// your custom handler
function overloadedDECSET(params: IParams): boolean {
  // DECSET is a stacking sequence, thus may contain multiple commands in one go
  // therefore we have to filter out DECTCEM (param == 25)

  // filter logic on params (works because params is shared/borrowed across handlers)
  const pValues: number[] = [];
  for (let i = 0; i < params.length; i++) {
    if (params.params[i] !== 25) pValues.push(params.params[i]);
  }
  // if lengths differ, rewrite params w'o skipped values
  if (pValues.length !== params.length) {
    params.reset();
    for (let i = 0; i < pValues.length; i++) params.addParam(pValues[i]);
  }

  return false;
}
...
// attach to terminal
// here you cannot use registerCsiHandler from API, but have to use the
// internal one to get the borrow mechs of params
your_term_obj._core._inputHandler._parser.registerCsiHandler(
  { prefix: '?', final: 'h' },
  params => overloadedDECSET(params)
);
Whirlwind commented 6 months ago

If somebody print the \x1b[?25h to the terminal, Will the cursor show in the xterm again?

jerch commented 6 months ago

@Whirlwind If you read the code above carefully, you can answer that yourself.