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

[O erroneously inputted after exiting from Neovim 0.7.0 in latest Terminal Preview #13238

Closed
MatejKafka opened this issue Jun 6, 2022 · 18 comments · Fixed by #13260
Closed
Assignees
Labels
Area-Input Related to input processing (key presses, mouse, etc.) Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-2 A description (P2) Product-Conpty For console issues specifically related to conpty Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.

Comments

@MatejKafka
Copy link

MatejKafka commented Jun 6, 2022

Windows Terminal version

1.14.1451.0

Windows build number

10.0.19044.1706

Other Software

Neovim 0.7.0 (https://github.com/neovim/neovim/releases/tag/v0.7.0)

Steps to reproduce

  1. Install Neovim
  2. Open it by running nvim in your shell (works both in cmd and pwsh)
  3. exit it (:q)

Expected Behavior

Neovim exits, nothing else happens.

Actual Behavior

Neovim exits, and the shell receives [O on its console input.

image

My guess would be that the characters are part of a response to some VT escape code from Neovim, but for some reason they get written separately and the shell gets them instead of Neovim.

@MatejKafka MatejKafka added the Issue-Bug It either shouldn't be doing this or needs an investigation. label Jun 6, 2022
@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Jun 6, 2022
@zadjii-msft
Copy link
Member

Is it [0 or [O (the number, or the letter)/? I could very much see it being the letter O, from #12900

@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Jun 6, 2022
@MatejKafka
Copy link
Author

Oh, you're right, [O, sorry. :)

@ghost ghost added Needs-Attention The core contributors need to come back around and look at this ASAP. and removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something labels Jun 6, 2022
@MatejKafka MatejKafka changed the title [0 erroneously inputted after exiting from Neovim 0.7.0 in latest Terminal Preview [O erroneously inputted after exiting from Neovim 0.7.0 in latest Terminal Preview Jun 6, 2022
@zadjii-msft
Copy link
Member

Hmm. Brainstorming, not debugging.

  • Conpty always requests Focus events, Terminal always sends them.
  • The client app still needs to ask for focus events to actually get the \x1b[I \x1b[O on input
  • neovim must be asking for them, but not turning off that request on exit?
  • Alternatively maybe focus events mode needs to be reset on a soft reset, hard reset, alt buffer leave - something that neovim is doing on exit?

that's where I should start looking. What does neovim do on exit.

@zadjii-msft zadjii-msft added Product-Conpty For console issues specifically related to conpty Priority-1 A description (P1) and removed Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Attention The core contributors need to come back around and look at this ASAP. labels Jun 7, 2022
@zadjii-msft zadjii-msft added this to the Terminal v1.15 milestone Jun 7, 2022
@zadjii-msft zadjii-msft added Area-Input Related to input processing (key presses, mouse, etc.) Severity-Blocking We won't ship a release like this! No-siree. labels Jun 7, 2022
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Jun 7, 2022
@MatejKafka
Copy link
Author

Just to add one datapoint, latest Alacritty handles it correctly, not sure if it supports Focus events.

@zadjii-msft zadjii-msft self-assigned this Jun 7, 2022
@j4james
Copy link
Collaborator

j4james commented Jun 7, 2022

FYI, I had a brief look at this, and Neovim does turn off focus events on exit, but prior to that happening, it appears that someone is calling WriteConsoleInput with a FOCUS_EVENT record, and that's what triggers that final report. It's not the result of a WM_SETFOCUS or WM_KILLFOCUS event.

@nathpete-msft
Copy link
Member

It looks like there was an issue open on Neovim for something similar: neovim/neovim#17985
That says a fix has been merged in but trying the latest Neovim nightly still has the issue for me in Terminal, so it may not be related.

@zadjii-msft
Copy link
Member

zadjii-msft commented Jun 8, 2022

will continue adding notes here...

FYI, I had a brief look at this, and Neovim does turn off focus events on exit, but prior to that happening, it appears that someone is calling WriteConsoleInput with a FOCUS_EVENT record, and that's what triggers that final report. It's not the result of a WM_SETFOCUS or WM_KILLFOCUS event.

Thanks for that! That really made this investigation WAY easier.

>	OpenConsole.exe!_WriteConsoleInputWImplHelper(InputBuffer & context, std::deque<std::unique_ptr<IInputEvent,std::default_delete<IInputEvent>>,std::allocator<std::unique_ptr<IInputEvent,std::default_delete<IInputEvent>>>> & events, unsigned __int64 & written, const bool append) Line 429	C++
 	OpenConsole.exe!ApiRoutines::WriteConsoleInputWImpl(InputBuffer & context, const gsl::span<_INPUT_RECORD const ,-1> buffer, unsigned __int64 & written, const bool append) Line 514	C++
 	OpenConsole.exe!ApiDispatchers::ServerWriteConsoleInput(_CONSOLE_API_MSG * const m, int * const __formal) Line 894	C++
 	OpenConsole.exe!ApiSorter::ConsoleDispatchRequest(_CONSOLE_API_MSG * Message) Line 178	C++
 	OpenConsole.exe!IoDispatchers::ConsoleDispatchRequest(_CONSOLE_API_MSG * pMessage) Line 577	C++
 	OpenConsole.exe!IoSorter::ServiceIoOperation(_CONSOLE_API_MSG * const pMsg, _CONSOLE_API_MSG * * ReplyMsg) Line 33	C++
 	OpenConsole.exe!ConsoleIoThread(void * lpParameter) Line 978	C++

m.Descriptor.Process is a ConsoleProcessHandle* in this console.

Microsoft::Console::Interactivity::ServiceLocator::s_globals.ciConsoleInformation.ProcessHandleList has the processes.

The 0th process in the list is the one that sent it

image

Looks like the message is coming from neovim.

  Name Value Type
  context.InputMode 0x00000208 unsigned long
context._termInput._inputMode {_data=0x0000000000000201 } til::enumset<enum Microsoft::Console::VirtualTerminal::TerminalInput::Mode,unsigned __int64>

0x0201 is Mode::FocusEvent | Mode::Ansi, sure.

0x208 is ENABLE_VIRTUAL_TERMINAL_INPUT | ENABLE_WINDOW_INPUT

So, the console is in VT input mode, and is expecting the client can accept focus events. So this must be happening before neovim disables focus events mode...

Yep. Sticking a breakpoint in AdaptDispatch::_SetInputMode, when mode == TerminalInput::Mode::FocusEvent will get hit after the WriteConsoleInput one is resumed. So it definitely seems like the FOCUS_EVENT is getting written before they disable the focus event mode. Maybe they just need to drain all the pending console input?

@DHowett
Copy link
Member

DHowett commented Jun 8, 2022

neovim is sending a win32 console focus event right as it exits? I can't fathom why they'd do that: a synthetic focus event doesn't even say anything about the state of the world -- the absolute best it can accomplish is making a console app think it's in focus when it actually doesn't have win32 focus...

@zadjii-msft
Copy link
Member

Yea why are they doing that?

Value Meaning
FOCUS_EVENT 0x0010 The Event member contains a FOCUS_EVENT_RECORD structure. These events are used internally and should be ignored.

I guess that doesn't explicitly state "don't use this", but why

@zadjii-msft
Copy link
Member

@justinmk any chances you know how/why neovim would be doing this? I reckon this is something that should get moved over to neovim, but I just want to be sure.

@justinmk
Copy link

justinmk commented Jun 8, 2022

Probably not intentional.

Maybe they just need to drain all the pending console input?

Maybe.

If someone decides to create an issue at Nvim, please reference this issue.

@zadjii-msft
Copy link
Member

Filed neovim/neovim#18899 for investigation.

Theoretically, we might be able to route input in such a way that focus events from the API don't hit this path. Ultimately, I am curious why this is being sent in the first place. That might affect the route we want to go in mitigating this.

@zadjii-msft zadjii-msft added Priority-2 A description (P2) and removed Severity-Blocking We won't ship a release like this! No-siree. Priority-1 A description (P1) labels Jun 8, 2022
@zadjii-msft
Copy link
Member

Hmm. Considering this is something who's root cause is up in libuv (neovim/neovim#18899 (comment)), maybe we do need to think about this.

@zadjii-msft zadjii-msft added the Needs-Discussion Something that requires a team discussion before we can proceed label Jun 9, 2022
@zadjii-msft zadjii-msft removed their assignment Jun 9, 2022
@j4james
Copy link
Collaborator

j4james commented Jun 9, 2022

@zadjii-msft I'm quite partial to your idea of not sending the CSI I and CSI O reports when the focus events come from an API call.

If you look at the FocusEvent constructors, there's one that takes a FOCUS_EVENT_RECORD and one that takes a bool. As far as I can see, if it's constructed from an API call it'll use the former, and if it's the result of an actual focus change event it'll use the latter.

So I was thinking we could add a flag in FocusEvent that records whether it came from an input record, and then in TerminalInput, where we process those events, we just don't generate a focus report if that flag is set.

@j4james
Copy link
Collaborator

j4james commented Jun 9, 2022

Note that this fix works for both conhost and Terminal. In the case of conhost, the genuine FocusEvent records are generated in the HandleFocusEvent function, and for Terminal, they're generated in InteractDispatch.

@zadjii-msft zadjii-msft self-assigned this Jun 9, 2022
@zadjii-msft zadjii-msft removed the Needs-Discussion Something that requires a team discussion before we can proceed label Jun 9, 2022
@zadjii-msft
Copy link
Member

Sync'd with Dustin, I think we're both cool with the bool didIComeFromTheAPI solution. It's bodgy, but it'll work. We don't want to just entirely filter out Focus messages from the API, cause clearly there is a reason that libuv is sending them. And the boolean is probably the simplest way to get this fixed.

@ghost ghost added the In-PR This issue has a related PR label Jun 9, 2022
@ghost ghost closed this as completed in #13260 Jun 10, 2022
ghost pushed a commit that referenced this issue Jun 10, 2022
As described in #13238. libuv sends a focus event to jiggle the handle. Now that we support focus events as VT input (#12900), we'd translate those focus events to VT input as well. That combination of things caused exiting neovim to emit a `\x1b[O` to the input line of the shell when exited. 

To fix this, we're going to secretly filter out any focus events that came from the API, before translating to VT. We're fortunate here, the `FOCUS_EVENT_RECORD` version of the ctor is only called by the API. 

* [x] Closes #13238
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels Jun 10, 2022
DHowett pushed a commit that referenced this issue Jun 30, 2022
As described in #13238. libuv sends a focus event to jiggle the handle. Now that we support focus events as VT input (#12900), we'd translate those focus events to VT input as well. That combination of things caused exiting neovim to emit a `\x1b[O` to the input line of the shell when exited.

To fix this, we're going to secretly filter out any focus events that came from the API, before translating to VT. We're fortunate here, the `FOCUS_EVENT_RECORD` version of the ctor is only called by the API.

* [x] Closes #13238

(cherry picked from commit b22684e)
Service-Card-Id: 83027721
Service-Version: 1.14
@ghost
Copy link

ghost commented Jul 6, 2022

🎉This issue was addressed in #13260, which has now been successfully released as Windows Terminal v1.14.186.:tada:

Handy links:

@ghost
Copy link

ghost commented Jul 6, 2022

🎉This issue was addressed in #13260, which has now been successfully released as Windows Terminal Preview v1.15.186.:tada:

Handy links:

lhecker added a commit that referenced this issue Jun 27, 2023
This is an improved fix for #13238. Instead of handling focus events in
the `TerminalInput::HandleKey` function and the need to filter them
out depending on where they came from, we simply don't call `HandleKey`
in the first place. This makes the somewhat unreliable `CameFromApi`
function unnecessary and the code a bit more robust.

This change is required because `CameFromApi` is not representable
in a `INPUT_RECORD` and I'm getting rid of `IInputEvent`.

## Validation Steps Performed
* No `[O` when exiting nvim ✅
* Mouse input in nvim works ✅
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Input Related to input processing (key presses, mouse, etc.) Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-2 A description (P2) Product-Conpty For console issues specifically related to conpty Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants