terminal icon indicating copy to clipboard operation
terminal copied to clipboard

Incorrect cursor position on full lines

Open zamadatix opened this issue 1 year ago • 8 comments

Windows Terminal version

1.7.11461.0

Windows build number

10.0.22621.0

Other Software

No response

Steps to reproduce

Create a character string which is one character short of the full line width:

image

Add the final character and note the cursor appears one character left of where it should:

image

Expected Behavior

Cursor should appear at the end of the line when the line is full.

Actual Behavior

Cursor appears one character before the end of the line. Operationally the cursor functions according to the correct position ("delete" does nothing and "backspace" removes the "L"). This is an off-by-one error on just the display side.

zamadatix avatar Aug 28 '23 15:08 zamadatix

Thanks for reporting this!

You'd be surprised -- this is actually working as intended! Applications are allowed to write text all the way to the edge of the screen without incurring line wrapping. However, the cursor cannot go off the edge of the screen to indicate that the next character will go into outer space.

Different terminal emulators handle this differently: image

It looks funny when the default cursor is set to the vertical bar... but the cursor technically occupies a cell, and not a place between cells.

/cc @j4james, as I am probably getting some details wrong 😄

DHowett avatar Aug 29 '23 16:08 DHowett

Hi, i wonder if this is the same issue i'm having with vim on windows terminal, where cursor always appears one character to the left from the end of the line? 2023-08-29_20-13-04

pere3 avatar Aug 29 '23 17:08 pere3

In your case (@pere3), the position of the cursor is controlled by vim. :smile:

DHowett avatar Aug 29 '23 17:08 DHowett

Hey DHowett, thanks for taking the time to respond and spread some knowledge 😊:

You'd be surprised -- this is actually working as intended! Applications are allowed to write text all the way to the edge of the screen without incurring line wrapping. However, the cursor cannot go off the edge of the screen to indicate that the next character will go into outer space.

Different terminal emulators handle this differently: image

It looks funny when the default cursor is set to the vertical bar... but the cursor technically occupies a cell, and not a place between cells.

Hmm that's fair. I guess I was just used to the behavior of the original console where even the full sized cursor would wrap:

image

If I remember the console APIs correctly this is a behavior the app can choose to override but idk, to me it makes more sense for the cursor to always display where it is but maybe there is nothing saying that's how it's supposed to be.

There is another inconsistency I've noticed with the way the end of line is handled. If you type to the end of a line like this:

image

You can press the right arrow and nothing happens, as would be expected given the current positioning logic. If you instead press left then right (i.e., leave the position and return back to it) the cursor follows the "move to next line" behavior even though the position is the same as before when it followed the "stay at end of line" behavior:

image

I'm not sure if this behavior is inherent to the way the line wrapping logic is supposed to work in this method but it certainly feels inconsistent to someone unfamiliar.

@DHowett I'll leave it up to you to divine if this second behavior would be categorized as a bug or not. In either scenario, I'd like to make the case that it (feels) more consistent to just wrap the cursor to the next line as the default behavior, if both are valid, but agree that may not fit under the "bug" tag.

zamadatix avatar Aug 29 '23 17:08 zamadatix

You'd be surprised -- this is actually working as intended! Applications are allowed to write text all the way to the edge of the screen without incurring line wrapping. However, the cursor cannot go off the edge of the screen to indicate that the next character will go into outer space.

@DHowett I think there's more to this, though, because it works differently in conhost. I had a brief look at what was going on and it appears that pwsh is using a mix of VT and legacy APIs. When you type a character at the end of the line, it redraws the line in VT mode, leaving the cursor in the last column. But it also then calls SetConsoleCursorPosition to manually reposition the cursor on the next line. That final cursor position doesn't seem to be forwarded over conpty. So I think there is likely a genuine bug here.

j4james avatar Aug 29 '23 18:08 j4james

Huh! I get to be the one who is surprised! Thanks for looking, James. :smile:

DHowett avatar Aug 29 '23 22:08 DHowett

I was looking through other issues and couldn't find an answer to that, so... If we ever move the rendering of the viewport margins into the renderers, could we perhaps draw the cursor inside the margin (if the margin is >0)? That would be different to other terminals, but would pretty cool.

BTW while writing this I just noticed that our margins aren't quite uniform... Edit: Opened #15903

lhecker avatar Aug 30 '23 12:08 lhecker

could we perhaps draw the cursor inside the margin (if the margin is >0)?

If we do, it should definitely be an option, preferably off by default, because from a standards point of view that's just wrong. When the terminal is in this state, the cursor position is explicitly defined as the last column. The reported position is going to be the last column. Any movement operation is going to be relative to the last column. If you're rendering the cursor somewhere else, it's going to appear broken. Maybe it's a personal preference, but if I saw a terminal doing this I'd assume it was a bug.

j4james avatar Aug 31 '23 13:08 j4james