microsoft / microsoft/terminal

OpenConsole: Cursor visibility prevents programmatic scrolling

Open
#19,390 2 comments 0 reactions 0 assignees View on GitHub
Area-Server Issue-Bug Needs-Attention Priority-2 Product-Conhost
Dominant language
C++
Stars
105k
Forks
9.6k
Avg merge
3d 17h
Merged PRs (30d)
29

Description

### Windows Terminal version

1.25.2509.25001 or the latest source

### Windows build number

10.0.19045.6218

### Other Software

_No response_

### Steps to reproduce

1. Get the latest openconsole (compile or from the WT package)

Compile the code:

Code

```C++
#include

#include

static bool Scroll(int Lines)
{
const auto Out = GetStdHandle(STD_OUTPUT_HANDLE);

CONSOLE_SCREEN_BUFFER_INFO Info;
if (!GetConsoleScreenBufferInfo(Out, &Info))
return false;

if (!(Lines < 0 && Info.srWindow.Top) && !(Lines > 0 && Info.srWindow.Bottom != Info.dwSize.Y - 1))
return false;

Info.srWindow.Top += Lines;
Info.srWindow.Bottom += Lines;

if (Info.srWindow.Top < 0)
{
Info.srWindow.Bottom -= Info.srWindow.Top;
Info.srWindow.Top = 0;
}

if (Info.srWindow.Bottom >= Info.dwSize.Y)
{
Info.srWindow.Top -= (Info.srWindow.Bottom - (Info.dwSize.Y - 1));
Info.srWindow.Bottom = Info.dwSize.Y - 1;
}

if (!SetConsoleWindowInfo(Out, true, &Info.srWindow))
return false;

return true;
}

int main()
{
const auto In = GetStdHandle(STD_INPUT_HANDLE);
const auto Out = GetStdHandle(STD_OUTPUT_HANDLE);

{
CONSOLE_SCREEN_BUFFER_INFO Info;
GetConsoleScreenBufferInfo(Out, &Info);
if (Info.dwSize.Y < 1000)
{
Info.dwSize.Y = 1000;
SetConsoleScreenBufferSize(Out, { 80, 1000 });
}
}

for (size_t i = 0; i != 1000; ++i)
std::wcout << i << '\n';

std::wcout << "\nPress Up or Down to scroll\nPress C to toggle cursor";
std::wcout.flush();

for (;;)
{
INPUT_RECORD InputRecord;
DWORD Read;
if (!ReadConsoleInput(In, &InputRecord, 1, &Read) || !Read)
return EXIT_FAILURE;

if (InputRecord.EventType != KEY_EVENT)
continue;

const auto& KeyEvent = InputRecord.Event.KeyEvent;

if (!KeyEvent.bKeyDown)
continue;

switch (KeyEvent.wVirtualKeyCode)
{
case VK_UP:
case VK_DOWN:
Scroll(KeyEvent.wVirtualKeyCode == VK_UP ? -1 : 1);
break;

case 'C':
{
CONSOLE_CURSOR_INFO Info;
GetConsoleCursorInfo(Out, &Info);
Info.bVisible = !Info.bVisible;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &Info);
}
break;

default:
break;
}
}
}

```

2. Run it in openconsole.
3. Follow the instructions on the screen.
4. Try to move it far enough, so that the cursor is outside of the viewport.

### Expected Behavior

The code is a simple program that moves the viewport up or down as you press the corresponding buttons.

It's basically an isolated/simplified feature of another app (Far) that allows the user to inspect the scrollback without reaching for the mouse.

It worked as expected for years in legacy, conhost, and openconsole until recently.

### Actual Behavior

After some relatively recent changes it is only possible to move it while the cursor position stays in the viewport.
As soon as you reach the edge it blinks and reverts.

It is still possible to move it freely if the cursor is not visible (press 'C' to goggle).

Contributor guide

Open the contributing guide

Research direction

Compile and run the provided C++ reproducer in OpenConsole, then inspect the console cursor-visibility and viewport-scrolling behavior involved when the cursor reaches the edge. Done means programmatic scrolling continues to work at the viewport edge with the cursor visible, while the hidden-cursor behavior remains functional.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.