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

Filter focus events that came from the API #13260

Merged
7 commits merged into from
Jun 10, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/allow/allow.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ inlined
It'd
kje
libfuzzer
libuv
liga
lje
Llast
Expand Down
8 changes: 8 additions & 0 deletions src/terminal/input/terminalInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,14 @@ bool TerminalInput::HandleKey(const IInputEvent* const pInEvent)
if (pInEvent->EventType() == InputEventType::FocusEvent)
{
const auto& focusEvent = *static_cast<const FocusEvent* const>(pInEvent);

// BODGY
// GH#13238 - Filter out focus events that came from the API.
if (focusEvent.CameFromApi())
{
return true;
}

return HandleFocus(focusEvent.GetFocus());
}

Expand Down
13 changes: 13 additions & 0 deletions src/types/FocusEvent.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// BODGY: GH#13238
//
// It appears that some applications (libuv) like to send a FOCUS_EVENT_RECORD
// as a way to jiggle the input handle. Focus events really shouldn't ever be
// sent via the API, they don't really do anything internally. However, focus
// events in the input buffer do get translated by the TerminalInput to VT
// sequences if we're in the right input mode.
//
// To not prevent libuv from jiggling the handle with a focus event, and also
// make sure that we don't erroneously translate that to a sequence of
// characters, we're going to filter out focus events that came from the API
// when translating to VT.

#include "precomp.h"
#include "inc/IInputEvent.hpp"
Expand Down
13 changes: 11 additions & 2 deletions src/types/inc/IInputEvent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,12 +514,14 @@ class FocusEvent : public IInputEvent
{
public:
constexpr FocusEvent(const FOCUS_EVENT_RECORD& record) :
_focus{ !!record.bSetFocus }
Copy link
Member

Choose a reason for hiding this comment

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

and we're certain that nobody else uses this ctor?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Other than WriteConsoleInputAImpl and WriteConsoleInputWImpl, it's potentially used in a few places in the InputBuffer class when moving IInputEvent records around (calling IInputEvent::Create on the result of a ToInputRecord call). I don't think those are likely to be a problem though.

IInputEvent::Create is also called in a couple of places in InputStateMachineEngine, but those are exclusively for keyboard and mouse events as far as I can see.

I think the rest are all in tests, which I didn't bother looking at, but I see now they've resulted in some test failures. Hopefully those are just tests that need to be updated, though, and not an indication that there's something fundamentally wrong with this approach.

_focus{ !!record.bSetFocus },
_cameFromApi{ true }
{
}

constexpr FocusEvent(const bool focus) :
_focus{ focus }
_focus{ focus },
_cameFromApi{ false }
{
}

Expand All @@ -539,8 +541,15 @@ class FocusEvent : public IInputEvent

void SetFocus(const bool focus) noexcept;

// BODGY - see FocusEvent.cpp for details.
constexpr bool CameFromApi() const noexcept
{
return _cameFromApi;
}

private:
bool _focus;
const bool _cameFromApi;
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved

#ifdef UNIT_TESTING
friend std::wostream& operator<<(std::wostream& stream, const FocusEvent* const pFocusEvent);
Expand Down