Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for horizontal scrolling sequences #15368

Conversation

j4james
Copy link
Collaborator

@j4james j4james commented May 16, 2023

This PR introduces four new escapes sequences: DECIC (Insert Column),
DECDC (Delete Column), DECBI (Back Index), and DECFI (Forward
Index), which allow for horizontal scrolling within a margin area.

References and Relevant Issues

This follows on from the horizontal margins PR #15084 to complete the
requirements for the horizontal scrolling extension.

Detailed Description of the Pull Request / Additional comments

The implementation is fairly straightforward, since they're all built on
top of the existing _ScrollRectHorizontally method.

Validation Steps Performed

Thanks to @al20878, these operations have been extensively tested on a
number of DEC terminals and I've manually confirmed our implementation
matches their behavior.

I've also added a unit tests that covers the basic execution of each of
the operations.

Closes #15109

@microsoft-github-policy-service microsoft-github-policy-service bot added Issue-Task It's a feature request, but it doesn't really need a major design. Area-VT Virtual Terminal sequence support Product-Conhost For issues in the Console codebase labels May 16, 2023
@DHowett
Copy link
Member

DHowett commented May 17, 2023

SWEET! Is it weird for us to ship DECLRMM/DECSLRM support in 1.18 without this? Will applications fail in new and exciting ways?

@j4james
Copy link
Collaborator Author

j4james commented May 17, 2023

SWEET! Is it weird for us to ship DECLRMM/DECSLRM support in 1.18 without this? Will applications fail in new and exciting ways?

I don't think that will be an issue. Until we report the horizontal scrolling extension in DA1, there should be no expectation that these sequences are supported. And the DECSLRM functionality is still useful by itself for vertical scrolling within horizontal margins. If necessary, that can be detected separately from horizontal scrolling with a DECRQM query.

In practice, though, I suspect a lot of apps (maybe most apps) don't know how to do proper feature detection. They're more likely to have a hard coded list of terminal names that are known to support specific features. But at least we're providing accurate information for those that do choose to look for it.

@j4james j4james marked this pull request as ready for review May 17, 2023 00:52
void ScreenBufferTests::HorizontalScrollOperations()
{
BEGIN_TEST_METHOD_PROPERTIES()
TEST_METHOD_PROPERTY(L"Data:op", L"{0, 1, 2, 3}")
Copy link
Member

Choose a reason for hiding this comment

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

Instead of adding cleanup annotations, you can also use method isolation. It's maybe not worth changing now, but worth considering in the future :)

I don't know what downsides exist... so that could be a problem.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It depends how much cleanup is involved, but I usually try to avoid method isolation if I can help it, because I thought it made the tests quite a bit slower. It also makes them more painful to debug, because you can only step through a single iteration and then it complains about TAEF needing to start a second test host (I don't know if there's a workaround for that which I'm just not aware of).

Comment on lines +2126 to +2128
const auto [topMargin, bottomMargin] = _GetVerticalMargins(viewport, true);
const auto [leftMargin, rightMargin] = _GetHorizontalMargins(bufferWidth);
if (row >= topMargin && row <= bottomMargin && col >= leftMargin && col <= rightMargin)
Copy link
Member

@lhecker lhecker May 22, 2023

Choose a reason for hiding this comment

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

If we had a _GetMargins function we could use a til::point / til::rect check.
BTW I recently wrote a range<T> struct for AtlasEngine (here) which has a contains() function. This might be useful for code like this too. (Although it would need to be split up into range and inclusive_range or something.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That range class will be very useful! I'm not going to try and integrate it now, but it's definitely worth investigating at some point. There's a lot of margin testing which could probably benefit from that.

// - delta - Number of columns to modify (positive if inserting, negative if deleting).
// Return Value:
// - <none>
void AdaptDispatch::_InsertDeleteColumnHelper(const VTInt delta)
Copy link
Member

Choose a reason for hiding this comment

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

Given that _ScrollRectHorizontally takes a int32_t I think this should do the same... I think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually now that I've had a look at them, all the int32_t parameters should really be VTInt - that's what they already are in the header! I think originally the VT parameters where coming in as an unsigned int of some sort, so we had to cast to the signed int32_t when they were used as a delta. But since VTInt is now signed, that's no longer necessary.

const auto [topMargin, bottomMargin] = _GetVerticalMargins(viewport, true);

// If the cursor is at the left of the margin area, we shift the buffer right.
if (cursorPosition.x == leftMargin && cursorPosition.y >= topMargin && cursorPosition.y <= bottomMargin)
Copy link
Member

Choose a reason for hiding this comment

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

Can the cursor be outside of the margins? I mean should we use <= here instead of ==?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, when it's left of the margin it just keeps moving left until it hits column 0 (that's handled in the branch below this).

@zadjii-msft zadjii-msft added the AutoMerge Marked for automatic merge by the bot when requirements are met label May 25, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot merged commit 3c3b1aa into microsoft:main May 25, 2023
@j4james j4james deleted the feature-horizontal-scroll branch May 30, 2023 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-VT Virtual Terminal sequence support AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Task It's a feature request, but it doesn't really need a major design. Product-Conhost For issues in the Console codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for horizontal scrolling sequences
4 participants