CUU and CUD should not move "across" margins #4099

Closed
opened 2026-01-30 23:37:58 +00:00 by claunia · 6 comments
Owner

Originally created by @j4james on GitHub (Sep 27, 2019).

Originally assigned to: @zadjii-msft on GitHub.

Environment

Windows build number: Version 10.0.18362.295
Also tested with a recent commit 7faf3342e0

Steps to reproduce

In a conhost WSL shell, execute the following command:

echo -e "\e[6;19r\e[24H\e[99ACUU\e[1H\e[99BCUD\e[r"

This does the following:

  • sets the top and bottom DECSTBM margins to 6 and 19
  • moves to line 24 (i.e. below the bottom margin)
  • executes the CUU sequence with a count of 99, to move up 99 lines
  • writes out CUU
  • moves to line 1 (i.e. above the top margin)
  • executes the CUD sequence with a count of 99, to move down 99 lines
  • writes out CUD

Expected behavior

Quoting from the DEC STD 070 manual:

If the Active Position is at or below the Top Margin when the CUU control is executed, and an attempt is made to move the Active Position above the Top Margin, the control will be executed until the Active Position reaches the Top Margin. The Active Position will not move beyond the Top Margin.

Similarly for the CUD command:

If the Active Position is at or above the Bottom Margin when the CUD control is executed, and an attempt is made to move the Active Position below the Bottom Margin, the control will be executed until the Active Position reaches the Bottom Margin. The Active position will not move beyond the Bottom Margin.

So I would expect the CUU sequence to stop on line 6, the top margin, and the CUB sequence to stop on line 19, the bottom margin.

This is what the output looks like in XTerm:

image

Actual behavior

In the Windows console, the movement isn't constrained by the margins. As a result, the CUU sequences ends up at the top of the viewport, and the CUD sequences ends up at the bottom.

image

Note that this isn't a regression of #170. We do get it right if the initial cursor position was inside the margins. It's just when it starts off outside the margins that it's not being constrained.

The complication is that you sometimes don't want the cursor position constrained. For example, if you're moving up (with CUU), and you started off above the top margin, then there's no need to constrain the position below that margin.

Originally created by @j4james on GitHub (Sep 27, 2019). Originally assigned to: @zadjii-msft on GitHub. # Environment Windows build number: Version 10.0.18362.295 Also tested with a recent commit 7faf3342e0187841d590fd018452c5c69fd52271 # Steps to reproduce In a conhost WSL shell, execute the following command: echo -e "\e[6;19r\e[24H\e[99ACUU\e[1H\e[99BCUD\e[r" This does the following: - sets the top and bottom [`DECSTBM`](https://vt100.net/docs/vt510-rm/DECSTBM.html) margins to 6 and 19 - moves to line 24 (i.e. below the bottom margin) - executes the [`CUU`](https://vt100.net/docs/vt510-rm/CUU.html) sequence with a count of 99, to move up 99 lines - writes out *CUU* - moves to line 1 (i.e. above the top margin) - executes the [`CUD`](https://vt100.net/docs/vt510-rm/CUD.html) sequence with a count of 99, to move down 99 lines - writes out *CUD* # Expected behavior Quoting from the DEC STD 070 manual: > If the Active Position is at or below the Top Margin when the CUU control is executed, and an attempt is made to move the Active Position above the Top Margin, the control will be executed until the Active Position reaches the Top Margin. The Active Position will not move beyond the Top Margin. Similarly for the `CUD` command: > If the Active Position is at or above the Bottom Margin when the CUD control is executed, and an attempt is made to move the Active Position below the Bottom Margin, the control will be executed until the Active Position reaches the Bottom Margin. The Active position will not move beyond the Bottom Margin. So I would expect the `CUU` sequence to stop on line 6, the top margin, and the `CUB` sequence to stop on line 19, the bottom margin. This is what the output looks like in XTerm: ![image](https://user-images.githubusercontent.com/4181424/65733165-3ee6c100-e0c5-11e9-9d53-5490453c6b02.png) # Actual behavior In the Windows console, the movement isn't constrained by the margins. As a result, the `CUU` sequences ends up at the top of the viewport, and the `CUD` sequences ends up at the bottom. ![image](https://user-images.githubusercontent.com/4181424/65733174-473efc00-e0c5-11e9-9bf3-cf3cfb47ec28.png) Note that this isn't a regression of #170. We do get it right if the initial cursor position was inside the margins. It's just when it starts off outside the margins that it's not being constrained. The complication is that you sometimes *don't* want the cursor position constrained. For example, if you're moving up (with `CUU`), and you started off above the top margin, then there's no need to constrain the position below that margin.
Author
Owner

@DHowett-MSFT commented on GitHub (Sep 27, 2019):

Are CNL and CPL analogous to CUD and CUU? Should they share an implementation? If not, how do they differ? It seems like this and bug #2926 are asking for the same resolution.

@DHowett-MSFT commented on GitHub (Sep 27, 2019): Are CNL and CPL analogous to CUD and CUU? Should they share an implementation? If not, how do they differ? It seems like this and bug #2926 are asking for the same resolution.
Author
Owner

@j4james commented on GitHub (Sep 27, 2019):

They are quite similar - I think the only difference is that CNL and CPL also perform a carriage return - so there's definitely room for code sharing between the two groups. The current implementations are completely separate, though. And while CUD and CUU gets the margins right some of the time, CNL and CPL perform no margin checking at all.

@j4james commented on GitHub (Sep 27, 2019): They are quite similar - I think the only difference is that `CNL` and `CPL` also perform a carriage return - so there's definitely room for code sharing between the two groups. The current implementations are completely separate, though. And while `CUD` and `CUU` gets the margins right some of the time, `CNL` and `CPL` perform no margin checking at all.
Author
Owner

@egmontkob commented on GitHub (Sep 27, 2019):

Just a side note:

Origin Mode (DECOM) (CSI ? 6 high/low) is also relevant. When enabled, as far as I know the cursor is always guaranteed to stay within the scroll region. (Also, as its name implies, the origin for absolute cursor placement is different.)

The original report here showcases what's supposed to happen when DECOM is disabled (the default).

While fixing it, could you guys please also double check the behavior with DECOM enabled?

@egmontkob commented on GitHub (Sep 27, 2019): Just a side note: Origin Mode (DECOM) (`CSI` `?` `6` `h`igh/`l`ow) is also relevant. When enabled, as far as I know the cursor is always guaranteed to stay within the scroll region. (Also, as its name implies, the origin for absolute cursor placement is different.) The original report here showcases what's supposed to happen when DECOM is disabled (the default). While fixing it, could you guys please also double check the behavior with DECOM enabled?
Author
Owner

@zadjii-msft commented on GitHub (Sep 27, 2019):

This seems like a pretty well-scoped, manageable fix. I'd even consider it for 20H1, considering it's just loosening a margins.InBounds() to a > margins.Top() / < margins.Bottom() that's pseudocode check.

@zadjii-msft commented on GitHub (Sep 27, 2019): This seems like a pretty well-scoped, manageable fix. I'd even consider it for 20H1, considering it's just loosening a `margins.InBounds()` to a `> margins.Top()` / `< margins.Bottom()` <sub> that's pseudocode</sub> check.
Author
Owner

@ghost commented on GitHub (Oct 4, 2019):

:tada:This issue was addressed in #2996, which has now been successfully released as Windows Terminal Preview v0.5.2762.0.🎉

Handy links:

@ghost commented on GitHub (Oct 4, 2019): :tada:This issue was addressed in #2996, which has now been successfully released as `Windows Terminal Preview v0.5.2762.0`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v0.5.2762.0) * [Store Download](https://www.microsoft.com/store/apps/9n0dx20hk701?cid=storebadge&ocid=badge)
Author
Owner

@DHowett-MSFT commented on GitHub (Oct 30, 2019):

Hey! The fix for this went out in Windows in the Insider channel's Fast Ring with build 19013.

@DHowett-MSFT commented on GitHub (Oct 30, 2019): Hey! The fix for this went out in Windows in the Insider channel's Fast Ring with build 19013.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#4099