microsoft / microsoft/terminal
OpenConsole: Cursor visibility prevents programmatic scrolling
- 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
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