Skip to content

Enable sending input to the Terminal with a keybinding #3799

Closed

Description

@compulim

Description of the new feature/enhancement

On Windows, there are difference between CTRL + C and CTRL + BREAK, as mentioned in #1118.

Some keyboard layouts do not have the BREAK key. For example, on Surface keyboard, there are no BREAK key. In some situations, CTRL + BREAK is a crucial way to break some processes.

Will be great if Windows Terminal has a command to map CTRL + BREAK to some other keys, e.g. CTRL + SHIFT + BREAK.

Proposed technical implementation details (optional)

Activity

  1. added
    Issue-FeatureComplex enough to require an in depth planning process and actual budgeted, scheduled work.
    on Dec 2, 2019
  2. ghost added
    Needs-TriageIt's a new issue that the core contributor team needs to triage at the next triage meeting
    on Dec 2, 2019
  3. ghost added
    Needs-Tag-FixDoesn't match tag requirements
    on Dec 2, 2019
  4. zadjii-msft commented on Dec 2, 2019

    @zadjii-msft
    Member

    I could have sworn that we had an issue that was "I want to be able to send input to the Terminal with a keybinding" but it doesn't seem like we do. Congratulations! This is now that issue ☺️

    Previously mentioned (in #2046):

  5. changed the title [-]Command for sending CTRL+BREAK[/-] [+]Enable sending input to the Terminal with a keybinding[/+] on Dec 2, 2019
  6. ghost removed
    Needs-Tag-FixDoesn't match tag requirements
    on Dec 2, 2019
  7. j4james commented on Dec 2, 2019

    @j4james
    Collaborator

    In case this affects the implementation, note that there are a couple of VT escape sequences for reprogramming the keyboard which we may want to support one day (e.g. DECUDK and DECPFK).

    Also I think issue #2005 is quite similar to this.

  8. 7 remaining items

  9. zadjii-msft commented on Jul 31, 2020

    @zadjii-msft
    Member

    No real commitments on this one quite yet. I especially want to do this for it's potential integration with the command palette (#5400). The hardest part of this is honestly just designing exactly how the setting should work. How will arrow keys be encoded in the settings file? Trailing newlines? etc.

    The implementation itself should be fairly trivial

  10. damnskippy commented on Jul 31, 2020

    @damnskippy

    Wonder if it's an option to specify a sequence/string of characters bound to a key shortcut. User can input the escape sequence for the key they want to enter. For example, left arrrow will be "\x1b[D". This would also allow for the other use case for this i.e. to be able to enter an arbitrary text (as opposed to mapping to another key). Say F12 is mapped to a character sequence "text entered over and over again\n" (including the newline). I believe Alacritty does something like this.

    Just a thought, not sure how useful.

  11. lhecker commented on Aug 10, 2020

    @lhecker
    Member

    I'd like to implement this feature, if you don't mind. 🙂

    I believe this feature is crucial, but realistically will probably only be used by a small fraction of all Windows Terminal users.
    As such it'd be best in my opinion to keep the feature as straightforward and low level as possible. That way it's easy to implement and simultaneously very powerful.

    Config

    I imagine a potential config setting to look like the following:

    {
        "keybindings":
        [
            // Bind Ctrl+Shift+C to the Delete key
            { "keys": "ctrl+shift+c", "command": { "action": "sendInput", "input": "\u007f" } },
    
            // Send some text when pressing F12
            { "keys": "f12", "command": { "action": "sendInput", "input": "text entered over and over again\n" } },
    
            // Swap left/right arrow keys (lol)
            { "keys": "left", "command": { "action": "sendInput", "input": "\u001b[C" } },
            { "keys": "right", "command": { "action": "sendInput", "input": "\u001b[D" } },
    
            // Send a VK_PLAY (media play/pause button) key press to your shell
            { "keys": "f11", "command": { "action": "sendInput", "input": "\u001b[250;0;0;1;0;1_\u001b[250;0;0;0;0;1_" } },
        ]
    }

    Unfortunately I don't have a solution for CtrlBreak as that's equivalent to calling TerminateProcess and AFAICS you may just as well close the offending tab, right? 🤔

    Implementation

    • Similar to other actions, extend ShortcutActionDispatch with SendInput.
    • Add a TerminalPage::_HandleSendInput method which calls TermControl::SendInput with the command.input value .
    • Add a TermControl::SendInput method which calls TermControl::_SendInputToConnection with the given input value.

    Future extension

    The above solution is very technical, but IMO sufficient for an initial implementation and can still be extended later on.
    For instance the Win32 key sequences could also be represented with a JSON object instead.

  12. zadjii-msft commented on Aug 10, 2020

    @zadjii-msft
    Member

    Thoughts off the top of the dome:

    • I think we'll need \u001b to be the encoding for escape (for json's sake). I don't love that, but I think json will explode on \x1b
    • As far as implementation is concerned, I think it might be easier to just expose TermControl::SendInput(hstring input) as a method projected off of the TermControl class, rather than return a tuple from TryKeyChord. Then, just have TerminalPage actually send the string to the control, kinda like it handles paste or other actions with args:
        void TerminalPage::_HandleSendInput(const IInspectable& /*sender*/,
                                            const TerminalApp::ActionEventArgs& args)
        {
            if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::SendInputArgs>())
            {
                const auto termControl = _GetActiveControl();
                args.Handled(termControl.SendInput(realArgs.Input()));
            }
        }

    The implementation of SendInput would be as easy as you suggest - the contents of realArgs.Input() are directly given to TermControl::_SendInputToConnection.

    I'm totally on board with this, thanks for the writeup! I'll throw you on the Assigned To line 😉

  13. lhecker commented on Aug 10, 2020

    @lhecker
    Member

    Aww... I always thought WT uses JSON5, but it seems it's using JSONC. (JSON5 supports \xNN escape codes.) *insert comment about using YAML here* 😄

    Thanks Mike Griese (@zadjii-msft)! I wasn't aware about AppKeyBindings::SetDispatch and how it integrates into TerminalPage.
    I've edited my proposal above to use unicode escape codes and changed the implementation section.

  14. ghost added
    In-PRThis issue has a related PR
    on Aug 11, 2020
  15. ghost closed this as completedin #7249on Aug 12, 2020
  16. ghost removed
    In-PRThis issue has a related PR
    on Aug 12, 2020
  17. ghost added a commit that references this issue on Aug 12, 2020
    a2721c1
  18. ghost added
    Resolution-Fix-CommittedFix is checked in, but it might be 3-4 weeks until a release.
    on Aug 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Area-InputRelated to input processing (key presses, mouse, etc.)Area-TerminalControlIssues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.)Help WantedWe encourage anyone to jump in on these.Issue-FeatureComplex enough to require an in depth planning process and actual budgeted, scheduled work.Product-TerminalThe new Windows Terminal.Resolution-Fix-CommittedFix is checked in, but it might be 3-4 weeks until a release.

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions