Skip to content

DECSCUSR() and DECSCUSR(0) should reflect the current user setting of the cursor shape #3293

@akinomyoga

Description

@akinomyoga

This was first reported at akinomyoga/ble.sh#95. In Visual Studio Code (VSCode), when a Bash plugin ble.sh is loaded in a Bash session, the cursor shape becomes always Block regardless of the user setting of the cursor shape.

This seems to be caused by the behavior of xterm.js for the control function DECSCUSR() (empty) and DECSCUSR(0) (0). I expect these parameters, empty and 0, change the cursor shape to the default one configured by the user, but, in xterm.js, empty and 0 are always treated as 1 (Blinking Block) which is just the default value for the user setting.

Behavior of other terminals

  • In all the other terminals that I tested (including Mintty, Alacritty, RLogin, GNOME Terminal (VTE), and Windows Terminal), when the user changed the default cursor shape from Block to another, DECSCUSR() and DECSCUSR(0) change the cursor shape to the user-configured default rather than to Block. The behavior can be checked with the following commands after the user default is changed.

    $ printf '\e[ q'
    $ printf '\e[0 q'
    $ printf '\e[1 q'

    I couldn't check xterm's behavior because I don't know how to change the default value for the cursor shape in xterm.

  • We can also find a related discussion in a code comment of VTE:

    We treat 0 and 1 differently, assuming that the VT510 does so too.

    See, according to the "VT510 Video Terminal Programmer Information", from vt100.net, paragraph "2.5.7 Cursor Display", there was a menu item in the "Terminal Set-Up" to set the cursor's style. It looks like that defaulted to blinking block. So it makes sense for 0 to mean "set cursor style to default (set by Set-Up)" and 1 to mean "set cursor style to blinking block", since that default need not be blinking block. Access to a VT510 is needed to test this theory, but it seems plausible. And, anyhow, we can even decide we know better than the VT510 designers!

  • In the original DEC implementation of DECSCUSR, the parameters empty and 0 meant the block style, but I guess it is just because the default cursor shape of VT series couldn't be configured so was always the block style (but maybe VT allowed some user configuration, see the previous item of the VTE comment). Anyway, empty and 0 typically meant the default for some other control functions, so I believe it is a natural guess that empty and 0 for DECSCUSR are also intended for the default cursor shape.

Note on ZDM

Here's a related note on the mode ZDM from @jerch:

Hmm good question. Maybe first some background on this on a general note - in the early days there was a so called ZDM* (zero default mode), which would tell the sequence parser that any functionXY() is equivalent to functionXY(0), meant as default value. This is what xterm.js' parser does atm. It works so far for all implemented DEC related features.

Later on that mode was removed from ECMA-48 with the note, that a parameter of 0 does not not mean default value anymore, but should stand for a numercial value 0 instead. Most sequence functions never applied that updated meaning for older models (e.g. cursor movement sequences still follow the default meaning as in CSI A == CSI 0 A == CSI 1 A). But without ZDM a missing parameter should mean default value, while 0 get its zero meaning (thus CSI A == CSI 1 A != CSI 0 A).

[...]

[*] As far as I know ZDM was completely removed from VTE.

Fix

From the same comment by @jerch,

For the sequence at hand I see a simple fix (since we have a default cursor style in the terminal options I wasnt aware of):

  • DECSCUSR() - switch to default value from settings
  • DECSCUSR(0) - switch to default value from settings
  • DECSCUSR(1) - steady block

This would be still in line with ZDM, but correctly map to the overwritten default in settings instead.

This is what other terminals do and I completely agree with this fix (though I think "steady block" is a typo of "blink block").

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions