Skip to content

Alt + numpad combination does not work anymore #17327

Closed

Description

@raksati

Windows Terminal version

1.21.1272.0

Windows build number

10.0.22631.0

Other Software

wsl terminal, powershell, etc.

Steps to reproduce

Sequential numpad keys combinations with the ALT key pressed to insert special characters ( for example the most common ones such as { with ALT+123, ~ with ALT+126, or the tilde ~ with ALT+126, etc. ) do not work anymore.

The latest working version is Microsoft.WindowsTerminal.Preview 1.20.11215.0, the next current one (1.21.1272.0) broke this functionality.

Expected Behavior

On previous versions the combination works

raksati@wsl:$ showkey -a

Press any keys - Ctrl-D will terminate this program

` 96 0140 0x60

^D 4 0004 0x04
raksati@wsl:~$

Actual Behavior

nothing is detected:

raksati@wsl:$ showkey -a

Press any keys - Ctrl-D will terminate this program

^D 4 0004 0x04
raksati@wsl:~$

Activity

  1. added
    Issue-BugIt either shouldn't be doing this or needs an investigation.
    Needs-TriageIt's a new issue that the core contributor team needs to triage at the next triage meeting
    on May 28, 2024
  2. j4james commented on May 28, 2024

    @j4james
    Collaborator

    Thanks for the report!

    I suspect this might be related to PR #17067. There are a couple of places in the code that mention Alt-Numpad being handled in TSFInputControl. For example see here:

    // Alt-Numpad# input will send us a character once the user releases
    // Alt, so we should be ignoring the individual keydowns. The character
    // will be sent through the TSFInputControl. See GH#1401 for more
    // details

    But TSFInputControl has now been replaced, so perhaps that functionality was lost in the rewrite.

    /cc Leonard Hecker (@lhecker)

  3. lhecker commented on May 28, 2024

    @lhecker
    Member

    It works in conhost because that one doesn't rely on the WinRT TSF stack via TextInputHost, and so it'll receive the Alt+Numpad key regularly via WM_CHAR. The weirdest thing is that even if I remove the new TSF implementation entirely (doesn't get instantiated) it'll not fix the issue. Does that mean the only way to get Alt+Numpad keys in a WinUI app is by using CoreTextServicesManager? That'd be quite surprising and kind of sad, because we fundamentally can't use that class.

  4. lhecker commented on May 28, 2024

    @lhecker
    Member

    Wow. Just after I wrote that I found that switching my keyboard layout to Korean or any other "complex" language fixes the issue. What in the heck!

  5. lhecker commented on May 29, 2024

    @lhecker
    Member

    So, with all that said, I think it'd be way easier to just write our own Alt+Numpad support in TermControl from scratch. ConEmu got all the info we need: https://conemu.github.io/en/AltNumpad.html

    If anyone wants to give it a shot, please do so!


    Windows internals for the curious follow below:

    I spent an unfathomable amount of time debugging this. 😄
    This happens basically because the UWP implementation of TSF does not like its own non-UWP sibling very much and switches off when it sees it.

    I tried solving this issue by adding this to TermControl:

    // The remaining callbacks must be implemented because SendInput should only be called if there's no active composition.
    const auto manager = Windows::UI::Text::Core::CoreTextServicesManager::GetForCurrentView();
    _editContext = manager.CreateEditContext();
    _editContext.TextUpdating([this](auto&&, auto&& args) { SendInput(args.Text()); });
    _editContext.TextRequested([](auto&&, auto&&) {});
    _editContext.SelectionRequested([](auto&&, auto&&) {});

    (And NotifyFocusEnter() / NotifyFocusLeave() calls must be added of course.)
    The problem is that for some mysterious reason these callbacks won't get called if our new TSF implementation got focus simultaneously (which it needs because otherwise we have no IME).

    We call ITfDocumentMgr::CreateContext here:

    THROW_IF_FAILED(_documentMgr->CreateContext(_clientId, 0, static_cast<ITfContextOwnerCompositionSink*>(this), _context.addressof(), &ecTextStore));

    It's implemented by CDocumentInputManager::CreateContext which calls QueryInterface on our ITfContextOwnerCompositionSink to check if it implements ITextInputClientOwner (86b4403f-c187-4a8b-b13e-c93c4ad1078c) and passes that as a bool to the CInputContext instance that's returned as the "context".

    (The TSF context is mostly an adapter between the public msctf.h interfaces and the private implementation. We need our own context because we need TS_SS_TRANSITORY. See Implementation.cpp for lots of details about this.)

    CInputContext::GetStatus then adapts our Implementation::GetStatus somewhat like this:

    HRESULT CInputContext::GetStatus(TS_STATUS* status)
    {
        YOUR_IMPLEMENTATION->GetStatus(status);
        if (YOU_IMPLEMENTED_THE_ITextInputClientOwner_INTERFACE?)
            status->dwStaticFlags |= TS_SS_UWPCONTROL;
        else
            status->dwStaticFlags &= ~TS_SS_UWPCONTROL;
    }

    The existence of this TS_SS_UWPCONTROL is what makes and breaks not just the Alt+Numpad support, but seemingly any support for any input whatsoever. If that flag is missing (= no TSF3), then somewhere something between TextInputHost and CoreTextEditContext breaks down. I couldn't quite figure out where and what exactly.

    I think that's a bug in the TSF implementation. The lack of Alt+Numpad support is likely a fallout from this, because when that flag is missing and TextInputHost is not sending any input anymore, then it should also re-enable sending Alt+Numpad via WM_CHAR, just like how it works for regular Win32 applications.

    In any case, if I pass any IUnknown instance as the ITextInputClientOwner in our Implementation, then that will fix the issue with the context that WinUI holds, because TextInputHost will then send messages again.

    The only problem with all that is that it doesn't solve the focus problem: To make this work we need to give both WinUI's context (for Alt+Numpad) and our context (= our IME) focus at the same, which means that both will receive the same input at the same time. That's really really bad, because TSF3 doesn't use TS_SS_TRANSITORY and I don't want to deal with the terminal-specific issues that this results in.

  6. added
    Help WantedWe encourage anyone to jump in on these.
    Area-TerminalControlIssues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.)
    on May 29, 2024
  7. removed
    Needs-TriageIt's a new issue that the core contributor team needs to triage at the next triage meeting
    on May 29, 2024
  8. inoperable commented on Jul 4, 2024

    @inoperable
  9. inoperable commented on Jul 4, 2024

    @inoperable
  10. lhecker commented on Jul 8, 2024

    @lhecker
  11. inoperable commented on Jul 8, 2024

    @inoperable
  12. added a commit that references this issue on Aug 7, 2024
    2fab986
  13. added a commit that references this issue on Aug 23, 2024
    6d9fb78
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-TerminalControlIssues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.)Help WantedWe encourage anyone to jump in on these.In-PRThis issue has a related PRIssue-BugIt either shouldn't be doing this or needs an investigation.Needs-Tag-FixDoesn't match tag requirementsPriority-3A description (P3)Product-TerminalThe new Windows Terminal.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions