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

Clean up InputBuffer coalescing and preprocessing #15671

Merged

Conversation

lhecker
Copy link
Member

@lhecker lhecker commented Jul 7, 2023

This reverts a number of changes to input handling to how it used to be
in conhost v1. It merges the input event coalescing logic into a single
function and inlines the console suspension event handling, because
soon these functions will receive std::span arguments which cannot
be preprocessed anymore, unlike a std::deque.

It also adds back support for Ctrl-S being an alias for VK_PAUSE
which was lost in commit fccc741 in 2018.

Closes #809

Validation Steps Performed

  • Unit and feature tests are ✅
  • Ctrl-S pauses output 🎉

@lhecker lhecker added the Area-CodeHealth Issues related to code cleanliness, linting, rules, warnings, errors, static analysis, etc. label Jul 7, 2023
@@ -611,6 +611,7 @@ class InputBufferTests
auto inputEvent2 = IInputEvent::Create(record2);
// write another event to a non-empty buffer
waitEvent = false;
storage.clear();
Copy link
Member Author

Choose a reason for hiding this comment

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

Starting with this PR, _WriteBuffer moves its items out of the argument, without emptying the argument. This results in this test failing. In a follow-up PR this will not be a problem anymore, because I'll remove IInputEvent.

UnblockWriteConsole(CONSOLE_OUTPUT_SUSPENDED);
continue;
}
// intercept control-s
Copy link
Member

Choose a reason for hiding this comment

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

hey uh, does this fix #809?

Copy link
Member

Choose a reason for hiding this comment

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

Does Ctrl+Q un-suspend it?

Copy link
Member

Choose a reason for hiding this comment

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

wait, ^S is not VK_PAUSe...

this is the problem with the old comments you found...

Copy link
Member Author

@lhecker lhecker Jul 7, 2023

Choose a reason for hiding this comment

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

Ah, you're right. The old code looked like this:

// intercept control-s
if ((g_ciConsoleInformation.pInputBuffer->InputMode & ENABLE_LINE_INPUT) &&
    (InputEvent->Event.KeyEvent.wVirtualKeyCode == VK_PAUSE || IsPauseKey(&InputEvent->Event.KeyEvent)))
{

I'll add that back. It fits into the PR.

@@ -779,40 +796,12 @@ void InputBuffer::_WriteBuffer(_Inout_ std::deque<std::unique_ptr<IInputEvent>>&
// record at a time because this is the original behavior of
// the input buffer. Changing this behavior may break stuff
// that was depending on it.
if (initialInEventsSize == 1 && !_storage.empty())
if (initialInEventsSize == 1 && !_storage.empty() && _CoalesceEvent(inEvents[0]))
Copy link
Member

Choose a reason for hiding this comment

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

I find it strange that we're doing a size check and a [0] inside a range-for-loop. Is that the clearest way to represent this concept?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not at all! 😄
The old code did this check once, at the start of the function and outside of the loop. But I felt like this is a good tradeoff between making the code simpler while not changing too much.

@@ -905,76 +826,44 @@ bool InputBuffer::_CanCoalesce(const KeyEvent& a, const KeyEvent& b) const noexc
// the buffer with updated values from an incoming event, instead of
// storing the incoming event (which would make the original one
// redundant/out of date with the most current state).
bool InputBuffer::_CoalesceRepeatedKeyPressEvents(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents)
bool InputBuffer::_CoalesceEvent(const std::unique_ptr<IInputEvent>& inEvent) const noexcept
Copy link
Member

Choose a reason for hiding this comment

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

How can this be const? It modifies lastEvent which is in _storage

Copy link
Member Author

Choose a reason for hiding this comment

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

Because std::unique_ptr is a pointer and const in C++ has about as much meaning as me saying that I won't eat that second pudding today: https://godbolt.org/z/38334rzjc

Copy link
Member Author

@lhecker lhecker Jul 7, 2023

Choose a reason for hiding this comment

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

(The const will go away once I use INPUT_RECORD, because then there's no std::unique_ptr anymore.)

(lastKey.GetVirtualScanCode() == inKey.GetVirtualScanCode() || WI_IsFlagSet(inKey.GetActiveModifierKeys(), NLS_IME_CONVERSION)) &&
lastKey.GetCharData() == inKey.GetCharData() &&
lastKey.GetActiveModifierKeys() == inKey.GetActiveModifierKeys() &&
// TODO: This behavior is an import from old conhost v1 and has been broken for decades.
Copy link
Member

Choose a reason for hiding this comment

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

track with issue#?

Copy link
Member Author

Choose a reason for hiding this comment

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

If you don't mind, I don't want to track that separately in my backlog. After all, this is a bug that is directly standing in my path of removing IsGlyphFullWidth everywhere that is outside of TextBuffer (and ROW) and thus would get addressed by me anyways in the near term.

Copy link
Member

Choose a reason for hiding this comment

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

Hell I mean, you could just say TODO:GH#8000 since that's the megathread tracking your crusade, but idgaf

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, right I could've done that... 😮
But... Eh, I don't want to wait 30min for the CI. I'll just cross my fingers to not die within the next few months. 😄

@lhecker lhecker added Product-Conhost For issues in the Console codebase Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-3 A description (P3) Area-Input Related to input processing (key presses, mouse, etc.) labels Jul 7, 2023
Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

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

Wow it's kinda horrifying looking at that old code nowadays

(lastKey.GetVirtualScanCode() == inKey.GetVirtualScanCode() || WI_IsFlagSet(inKey.GetActiveModifierKeys(), NLS_IME_CONVERSION)) &&
lastKey.GetCharData() == inKey.GetCharData() &&
lastKey.GetActiveModifierKeys() == inKey.GetActiveModifierKeys() &&
// TODO: This behavior is an import from old conhost v1 and has been broken for decades.
Copy link
Member

Choose a reason for hiding this comment

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

Hell I mean, you could just say TODO:GH#8000 since that's the megathread tracking your crusade, but idgaf

@lhecker lhecker added the AutoMerge Marked for automatic merge by the bot when requirements are met label Jul 12, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot merged commit e1ab64e into main Jul 12, 2023
15 checks passed
@microsoft-github-policy-service microsoft-github-policy-service bot deleted the dev/lhecker/8000-InputBuffer-Write branch July 12, 2023 17:18
@Gemesys
Copy link

Gemesys commented Mar 8, 2024

Ok, it's March 2024. Can I have Ctrl-s actually pause my running program now? Like I could do for many years, on various Windows platforms? I have a newish Windows-11 HP laptop, it updates itself regularly, and when I am running a program that outputs diagnostics to Cmd session window, I still cannot ctrl-s pause the running prgm (like I can on all my Linux and MacOS machines...) Do I need to edit the registry or something? It's in my left-hand's muscle-memory - rest left thumb on CTRL key, press "s" key, have a look, press "q" to continue. Works on Linux and MacOS. How do I re-enable this on my Window-11 machine?

@oising
Copy link
Collaborator

oising commented Mar 8, 2024

@DHowett-MSFT you guys need to re-open #809 -- the bot closed it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-CodeHealth Issues related to code cleanliness, linting, rules, warnings, errors, static analysis, etc. Area-Input Related to input processing (key presses, mouse, etc.) AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-3 A description (P3) Product-Conhost For issues in the Console codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Re-investigate Ctrl+S pausing
5 participants