Skip to content

Conversation

vididvidid
Copy link

Summary of the Pull Request

This PR fixes a bug where programmatic scrolling would get stuck. The fix makes the "snap-on-input" feature conditional, activating it only for modern applications that use Virtual Terminal (VT) processing. This restores correct scrolling behavior for legacy applications without removing the feature for new ones.

References and Relevant Issues

Fixes #19390: OpenConsole: Cursor visibility prevents programmatic scrolling

Detailed Description of the Pull Request / Additional comments

The "snap-on-input" feature introduced in a previous PR caused an unintended side effect for older console programs that use the SetConsoleWindowInfo API to manage their own viewport. When such a program tried to scroll using a key press, the snap feature would immediately pull the view back to the cursor's position, causing the screen to flicker and get stuck.

This fix makes the snap-on-input feature smarter by checking the application's mode first.

Here is the technical breakdown:

A new private bool _snapOnInputEnabled was added to the SCREEN_INFORMATION class. It defaults to false to keep things working for old programs.

This flag is switched to true inside ApiRoutines::SetConsoleOutputModeImpl only when a program enables ENABLE_VIRTUAL_TERMINAL_PROCESSING.

The SnapOnInput() call in HandleGenericKeyEvent is now inside an if block and only runs if IsSnapOnInputEnabled() is true.

This way, only modern apps that ask for VT features get the snap behavior, and older apps work as expected.

Validation Steps Performed

Compiled the minimal C++ reproduction case from issue #19390.

Ran the test executable inside the newly built OpenConsole.exe.

Confirmed that scrolling with the Up/Down arrow keys now works correctly, even with a visible cursor. The view no longer flickers or gets stuck when the cursor moves outside the viewport.

Here is a video demonstrating the fix:

MicrosoftScreenFix.mp4

PR Checklist

@vididvidid
Copy link
Author

@microsoft-github-policy-service agree

Copy link
Member

@lhecker lhecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OOTL but this makes sense to me. 👍

void SetCursorType(const CursorType Type, const bool setMain = false) noexcept;

void SetSnapOnInputEnabled(const bool enabled) noexcept { _snapOnInputEnabled = enabled; }
[[nodiscard]] bool IsSnapOnInputEnabled() const noexcept { return _snapOnInputEnabled; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency I think these should go into the .cpp file (they aren't templates).


void SCREEN_INFORMATION::MakeCursorVisible(til::point position)
{

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra.

}
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra.

@DHowett
Copy link
Member

DHowett commented Oct 6, 2025

@lhecker qq about your thought process here - do you have a gut feeling about introducing new (possibly torn) state boolean rather than just the input mode directly?

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(want to noodle about this a little bit, sorry!)

@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Oct 6, 2025
@lhecker
Copy link
Member

lhecker commented Oct 6, 2025

Oh right I didn't think of that, since the input mode is stored elsewhere. Regarding duplicating it: my thought was that if we were to add a user setting for this (hypothetically), I would make it a bitfield, similar to the new "cursor inhibitors".

For now, I suppose it makes sense to just ask the input mode.

@microsoft-github-policy-service microsoft-github-policy-service bot removed the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Oct 6, 2025
@vididvidid
Copy link
Author

I think I just chose the long way to do it. There can be another way, like this:

Just change the file input.cpp and add the following line in the HandleGenericKeyEvent Function :

if (WI_IsFlagSet(buffer.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING))
{
    buffer.SnapOnInput(keyEvent.wVirtualKeyCode);
}

@vididvidid
Copy link
Author

Do you want me to remove all of that and prefer this change...

@vididvidid vididvidid requested review from DHowett and lhecker October 6, 2025 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenConsole: Cursor visibility prevents programmatic scrolling

3 participants