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

Bracketed paste using INPUT_RECORD marks #10905

Closed
o-sdn-o opened this issue Dec 11, 2023 · 5 comments
Closed

Bracketed paste using INPUT_RECORD marks #10905

o-sdn-o opened this issue Dec 11, 2023 · 5 comments
Labels

Comments

@o-sdn-o
Copy link

o-sdn-o commented Dec 11, 2023

Since wsl reads the input stream using ReadConsoleInput, could you consider adding a support for "Bracketed Paste" marks in the INPUT_RECORD's stream. This could be done by handling boundary marks for the inserted block in the following form:

rec.EventType == MENU_EVENT;
rec.Event.MenuEvent.dwCommandId = 0x8001; // paste_begin

// set of recs with wchar-by-wchar copy
// of the block pasted from the clipboard
rec.EventType == KEY_EVENT;
rec.Event.KeyEvent.uChar.UnicodeChar = wchar; // Pasted data set

rec.EventType == MENU_EVENT;
rec.Event.MenuEvent.dwCommandId`= 0x8002; // paste_end

This approach greatly simplifies the task of cross-platform transferring an inserted immutable block via SSH between hosts. Both from unix to windows to unix, and from windows to unix to windows.

x-link PowerShell/PowerShell#20896

@OneBlue
Copy link
Collaborator

OneBlue commented Dec 13, 2023

Thank you @o-sdn-o. Can you add some details on what you'd like WSL's behavior to be in that case ? We forward tty input from the Windows to the Linux side so even if a copy / paste operation is detected, key strokes still need to be sent to the Linux side

@o-sdn-o
Copy link
Author

o-sdn-o commented Dec 13, 2023

On the WSL side, it is necessary to understand INPUT_RECORD marks and accordingly replace it with in-text marks (\e[200~ \e[201~). Optionally, WSL can remove spurious in-text marks from the inserted block if they suddenly appear there between the INPUT_RECORD marks.

This approach is necessary on Windows hosts to insert immutable binary blocks from the clipboard (e.g. received via ssh) into an arbitrary console application that expects it. Since WSL doesn't expect binary data, it simply replace INPUT_RECORD marks with in-text marks.

We could make this replacement on our side, but it is not known in advance who is waiting for the input.

I described the problem in the following comment: PowerShell/PowerShell#20896 (comment)

Here I mean placing marks on the operating system side (condrv), and not on the application side. In particular, vtm, receiving a block for insertion via SSH, forms on the condrv side a set of INPUT_RECORD records that Application/PSReadLine/WSL is waiting for.

PowerShell/PSReadLine/WSL can on their end treat pastes from the clipboard purely as alphanumeric text without control characters, but for an arbitrary console application expecting an immutable binary block to be pasted from the clipboard, the best option is to use INPUT_RECORD marks. The blocking use of INPUT_RECORD marks is the difficulty of detecting the final recipient of the insertion - if PowerShell/PSReadLine/WSL (or any shell relying on ReadConsoleInput) does not support such an insertion format, then this cannot be used for any console application either, since it is necessary to somehow determine the recipient of the pasting block and select the appropriate format for the inbound INPUT_RECORD set.

You can play around with this using vtm by sshing to win<->wsl or wsl<->win (this requires vtm on both sides):

vtm ssh user@host vtm

@o-sdn-o
Copy link
Author

o-sdn-o commented Dec 13, 2023

For a more visual example, you can create a file ~/.config/vtm/settings.xml in your home directory on Windows (or in WSL if you run vtm from wsl) (replace test@::1 with your username@host):

<config>
    <menu>
        <item splitter label="ssh tests"/>
        <item id="far manager via ssh" type=xlvt param="ssh test@::1 vtm -r headless far"/>
        <item id="cmd in terminal via ssh" type=xlvt param="ssh test@::1 vtm -r term cmd"/>
        <item id="cmd via ssh" type=xlvt param="ssh test@::1 vtm -r headless cmd"/>
        <item id="wsl via ssh" type=xlvt param="ssh test@::1 vtm -r headless wsl"/>
        <item id="mc via ssh" type=xlvt param="ssh test@::1 vtm -r headless mc"/>
        <item id="wsl mc via ssh" type=xlvt param="ssh test@::1 vtm -r headless wsl mc"/>
    </menu>
</config>

and then just run vtm and test the interaction between wsl and win32 over ssh there.

PS: It is necessary to add vtm to PATH to avoid specifying the full vtm path (for both sides: vtm binary for linux and vtm.exe for windows).

PS: vtm doesn’t rely on ConPTY infrastructure, so it works even on Win8.

@o-sdn-o
Copy link
Author

o-sdn-o commented Dec 14, 2023

Related to PowerShell/PSReadLine#1471

@o-sdn-o
Copy link
Author

o-sdn-o commented Dec 18, 2023

We can do this on our side by checking the ENABLE_VIRTUAL_TERMINAL_INPUT flag. Sorry I didn't realize this right away.

@o-sdn-o o-sdn-o closed this as not planned Won't fix, can't repro, duplicate, stale Dec 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants