Cursor shape gets reverted to legacy style after hiding the cursor and then making it visible again in console window #5788

Closed
opened 2026-01-31 00:21:39 +00:00 by claunia · 3 comments
Owner

Originally created by @daxian-dbw on GitHub (Jan 6, 2020).

Environment

Windows build number: Microsoft Windows [Version 10.0.18363.535]
Windows Terminal version (if applicable): NA

Any other software? No

Steps to reproduce

After setting the cursor shape in Properties->Terminal, hiding and then showing the cursor by setting Console.CursorVisible to false and then true causes the cursor shape to be restored to the legacy style in console host.

The following simple C# program can show the problem:

using System;
using System.Text;

namespace cursorShape
{
    class Program
    {
        static void Main(string[] args)
        {
            const string prompt = "PROMP> ";
            StringBuilder sb = new StringBuilder();
            int top = Console.CursorTop;

            Console.OutputEncoding = Encoding.UTF8;
            Console.Write(prompt);

            while (true)
            {
                var key = Console.ReadKey();
                if (key.Key == ConsoleKey.Q)
                {
                    break;
                }

                sb.Append(key.KeyChar);

                Console.CursorVisible = false;   // Hide the cursor before rewriting
                Console.SetCursorPosition(0, top);
                Console.Write($"{prompt}{sb}");
                Console.SetCursorPosition(Console.CursorLeft, top);
                Console.CursorVisible = true;    // Show the cursor afterwards
            }
        }
    }
}

Expected behavior

Setting Console.CursorVisible should not revert the cursor shape.

Actual behavior

The cursor shape gets reverted from Solid Box to the legacy style (Underline):
linux

Related issues

#409 and #1145 and https://github.com/PowerShell/PSReadLine/issues/903
Those 2 issues were reported in the PowerShell+PSReadLine context. PSReadLine depends on Console.CursorVisible to hide and show the cursor during rendering, so the cursor shape gets reverted.

Originally created by @daxian-dbw on GitHub (Jan 6, 2020). <!-- 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING: 1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement. 2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement. 3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number). 4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement. 5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement. All good? Then proceed! --> # Environment ```none Windows build number: Microsoft Windows [Version 10.0.18363.535] Windows Terminal version (if applicable): NA Any other software? No ``` # Steps to reproduce After setting the cursor shape in `Properties->Terminal`, hiding and then showing the cursor by setting `Console.CursorVisible` to `false` and then `true` causes the cursor shape to be restored to the legacy style in console host. The following simple C# program can show the problem: ``` using System; using System.Text; namespace cursorShape { class Program { static void Main(string[] args) { const string prompt = "PROMP> "; StringBuilder sb = new StringBuilder(); int top = Console.CursorTop; Console.OutputEncoding = Encoding.UTF8; Console.Write(prompt); while (true) { var key = Console.ReadKey(); if (key.Key == ConsoleKey.Q) { break; } sb.Append(key.KeyChar); Console.CursorVisible = false; // Hide the cursor before rewriting Console.SetCursorPosition(0, top); Console.Write($"{prompt}{sb}"); Console.SetCursorPosition(Console.CursorLeft, top); Console.CursorVisible = true; // Show the cursor afterwards } } } } ``` # Expected behavior Setting `Console.CursorVisible` should not revert the cursor shape. # Actual behavior The cursor shape gets reverted from `Solid Box` to the legacy style (`Underline`): ![linux](https://user-images.githubusercontent.com/127450/71843286-5e07ce00-3078-11ea-8949-bf8df0c03528.gif) # Related issues #409 and #1145 and https://github.com/PowerShell/PSReadLine/issues/903 Those 2 issues were reported in the PowerShell+PSReadLine context. PSReadLine depends on `Console.CursorVisible` to hide and show the cursor during rendering, so the cursor shape gets reverted.
Author
Owner

@DHowett-MSFT commented on GitHub (Jan 6, 2020):

Well, heck.

@DHowett-MSFT commented on GitHub (Jan 6, 2020): Well, heck.
Author
Owner

@j4james commented on GitHub (Jan 7, 2020):

As explained in #409, the problem is that calling the SetConsoleCursorInfo sets the cursor size, and setting the cursor size forces the cursor shape back to the legacy style (because that's the only shape for which the size is applicable AFAIK).

It's easy enough to "fix". We could just delete this line from the SetCursorInformation method:
6f667f48ae/src/host/screenInfo.cpp (L1778)

But that's a change in behavior for a public API, and it's possible some applications could actually be relying on that behavior (although I would think that unlikely).

Ideally the Console.CursorVisible property should be using an API that just sets the visibility and nothing else, but but I don't think there is such a thing. The best you could do is use a VT sequence, but that's obviously not going to work with older versions of Windows.

@j4james commented on GitHub (Jan 7, 2020): As explained in #409, the problem is that calling the `SetConsoleCursorInfo` sets the cursor size, and setting the cursor size forces the cursor shape back to the legacy style (because that's the only shape for which the size is applicable AFAIK). It's easy enough to "fix". We could just delete this line from the `SetCursorInformation` method: https://github.com/microsoft/terminal/blob/6f667f48ae109d4291cda1f8d4e977315c0dae8a/src/host/screenInfo.cpp#L1778 But that's a change in behavior for a public API, and it's possible some applications could actually be relying on that behavior (although I would think that unlikely). Ideally the `Console.CursorVisible` property should be using an API that just sets the visibility and nothing else, but but I don't think there is such a thing. The best you could do is use a VT sequence, but that's obviously not going to work with older versions of Windows.
Author
Owner

@ghost commented on GitHub (Apr 22, 2020):

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

Handy links:

@ghost commented on GitHub (Apr 22, 2020): :tada:This issue was addressed in #5251, which has now been successfully released as `Windows Terminal Preview v0.11.1121.0`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v0.11.1121.0) * [Store Download](https://www.microsoft.com/store/apps/9n0dx20hk701?cid=storebadge&ocid=badge)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#5788