在: Microsoft Windows [Version 10.0.17763.134]
我已经在我的终端模拟器中实现了 conpty:
https://github.com/wez/wezterm
我可以成功运行target\debug\wezterm.exe
来生成控制台应用程序,例如cmd.exe
powershell.exe
和bash
。
我看到的问题是,当我通过cmd.exe
间接启动 bash 或直接通过 bash 启动器启动 bash 时,conpty 似乎吞下了鼠标报告转义序列; 我没有看到我的终端解析器收到它们,因此尽管vim
配置了set mouse=a
但没有有效的鼠标支持。
通过wsl-terminal
运行相同的 WSL 安装确实有可用的鼠标支持,并且wezterm
一直是我在 Linux 上的日常驱动程序,支持可用鼠标大约一年,因此我们可以排除明显的配置错误vim
和wezterm
的解析器。
我也试过echo -e "\e[?1000h"
手动启用来自 shell 的鼠标报告; 通常(在 linux 上和通过 wsl 终端)这会导致终端中的点击将数据发送到 shell(显示为垃圾输入),但是当我的终端使用 conpty 运行时,这些也会在某处被吞没。
我在 pty 中生成的应用程序是否需要特殊的东西才能使用鼠标?
如果您想仔细检查代码的关键部分,相关文件是:
https://github.com/wez/wezterm/blob/master/src/winpty.rs
流程是CreatePipe
一对管道, CreatePseudoConsole
,然后通过 threadproc 属性将其传递给生成的孩子,就像 MSDN 文档中的示例和这个 repo 一样。
嘿@wez ,
不幸的是,ConPTY 不会传输鼠标报告(或者,来自托管应用程序的_鼠标报告请求_)。 我们有一个积压项目跟踪这个,我们希望很快就能做到。
不幸的是,我们不能只传递编码的鼠标事件:因为 ConPTY 可以托管标准的 Windows 控制台应用程序,例如期望MOUSE_EVENT
s 通过ReadConsoleInput
进入,我们将需要做一些翻译。
但是,在所有其他方面,听起来您正确设置了伪控制台。
追踪: MSFT:20469462
@DHowett-MSFT 感谢您的回复!
鼠标报告尚不存在,这有点令人沮丧,但是现在可以使用其余的 pty 内容仍然很好!
除了真的希望 ConPTY 支持鼠标之外,我没有什么可添加的。 随着 alacritty 现在使用 alacritty + ssh + tmux 获得 ConPTY 支持,这是 Windows 上令人难以置信的 linux 终端,现在只缺少鼠标支持。
我是我的 Ubuntu bash shell 中午夜指挥官的重度用户,它工作得很好。 不幸的是,Windows Terminal 0.3.2171.0 中的 Ubuntu shell 选项卡似乎没有将任何鼠标事件发送到 mc 应用程序,这让我很难使用。 我打算发布一个错误,但我认为它会重复这个。
对我而言,发送鼠标事件对于使用 vim 和 tmux 的良好体验至关重要。
只是在这里放弃我对此的支持,加上一点背景。 在过去的一个月里,我停止了双启动,并开始使用 Windows 10 内部构建“快速”环作为我的主要个人机器。 在这一点上,我让 wsl2 完美运行,x410 完美运行,微软终端运行良好,visual studio 代码 wsl2 互操作完美运行,并且 explorer.exe 互操作完美运行。
这个鼠标输入票几乎是唯一阻止我将 wsl2/microsoft 终端称为具有单独分区/开发框的合理替代品的原因。 由于这里的一些地方是开源的,是否有任何关于如何从/dev
某个地方查看鼠标设备输入的指示,或者我应该坚持下去?
感谢这一切! 否则我真的很喜欢它:)
再一次投票说/要求鼠标支持会如此甜蜜,并且任何使用 tmux 的人都会非常想念,尽管没有它也可以。
请启用鼠标支持😄
@DHowett-MSFT,抱歉唠叨,有没有计划尽快解决这个问题? 查看在其他问题上分配的标签/优先级,但这不是其中之一,因此只需检查即可。 谢谢你。
@damnskippy优先级被分配给我们需要在收件箱 Windows 控制台主机中修复的内容(由于内部错误截止日期)。 这是一个_巨大的_特性(并且需要一个适当扩展的规范),虽然我们知道 v1.0 需要它,但我们今天并没有积极地致力于它。
如果我们可以像修复错误一样“修复”它,我会很高兴——但它需要的不仅仅是修复。
感谢更新。 您的工作受到赞赏。
我喜欢你在这里所做的,我喜欢,但是在我们获得鼠标支持之前,我们必须用另一个终端来赞美这个终端,这有点违背了这个终端的目的。
没有这个的午夜指挥官是一场噩梦。
鼠标输入通常很有用,比如说,如果社区中的某个人要创建一个可以在 Windows 终端中运行的 DosBox 加载项和配置文件。
我是一个重度 vim 用户; 即使我想念鼠标支持 😢
我刚刚阅读了@cinnamon-msft 博客更新,似乎该团队的目标是在今年年底前实现 1.0? 这是否意味着我们将在年底前获得鼠标支持? 如果是这样,现在是否正在积极开展工作?
这是否意味着我们将在年底前获得鼠标支持?
也许,但没有硬性承诺。 估算完成软件所需的时间与证明 P==NP 一样困难。 我什至要说没有这个终端就不会为 1.0 做好准备。
如果是这样,现在是否正在积极开展工作?
不是现在。 没有人被分配到任务中,通常当团队中的某个人完成一项任务时,他们会分配给自己。
出于好奇,在这里做这件事需要一切吗? 一个雄心勃勃(阅读:疯狂)的开发人员可以接受它并进行公关吗?
当然,雄心勃勃的人绝对可以自己尝试一下。 从哪里开始?
首先,让我们概述一些范围。 鼠标输入有很多工作要做,因此最好从小处着手,然后逐个工作以获得完整的解决方案。 我认为我们应该开始工作的第一件事就是简单的SGR 编码鼠标向上/向下序列。 我们可以处理鼠标滚轮事件,然后可能悬停,然后单击,但我认为单击将解决_大多数_用例。
首先查看InputStateMachineEngine.cpp 。 InputStateMachineEngine
负责解析通过 conpty 发送的输入,并将其转换为INPUT_RECORD
s。 一个有进取心的年轻开发人员希望修改该类,以便也能够解析这些鼠标序列,并将它们转换为INPUT_RECORD
s。 一旦你有了INPUT_RECORD
s,调用InteractDispatch::WriteInput
。 这会将那些INPUT_RECORD
添加到输入缓冲区。 一旦它们在输入缓冲区中,它们将被正常传送到附加的控制台客户端应用程序。
我要注意的事情:
INPUT_RECORD
的流,而是字符流。 在 conhost 中的某个时刻,如果附加的应用程序处于 VT 鼠标模式,我们会尝试将这些鼠标INPUT_RECORD
转换为字符流。 如果我们在 _before_ 鼠标事件在缓冲区中进行转换,那么执行上述操作可能不适用于 VT 应用程序(阅读: wsl
)。 如果是这种情况,那么我们需要确保为InputStateMachineEngine
生成的鼠标事件手动完成从鼠标INPUT_RECORD
到 VT 编码鼠标事件的转换。terminalMouseInput.HandleMouse
将为客户端应用程序合成 VT 序列,但不幸的是它只能从窗口 proc 调用。 因此,我们需要以某种方式公开InputStateMachineEngine
调用它的方法(通过InteractDispatch
上的新方法),如果该方法失败,则生成适当的INPUT_RECORD
s。terminalMouseInput.HandleMouse
调用移动到 InputBuffer 的读取中,并让它尝试在读取时正确地翻译INPUT_RECORD
,但这可能会更复杂。这个问题怎么办? 鼠标在古老的 Windows 控制台中完美运行。 这是否意味着我必须坚持使用控制台才能解决这个问题?
如果您需要 VT 鼠标支持,是的。
仅供可能一直在研究此问题的任何社区成员(/cc @SamuelEnglard!),我们已正式预订开发团队的工作来执行此操作。 我希望我们不会踩到你的脚趾!
我想过,但一直无法预订我自己的时间如此完美,哈哈!
我只是在玩带有远程开发扩展的 VSCode,发现其中的集成终端实际上支持 tmux 中的鼠标模式! 面板选择、窗口选择、面板调整大小和滚轮支持所有工作。 我是这些项目的新手,所以我不知道终端是否是开源 VS Codium 的一部分并且可以用作起点......抱歉,如果这不是真正有用的信息
仅供可能一直在研究此问题的任何社区成员(/cc @SamuelEnglard!),我们已正式预订开发团队的工作来执行此操作。 我希望我们不会踩到你的脚趾!
@DHowett-MSFT @zadjii-msft @bitcrazed你在这里和其他地方就这个问题的交流非常棒; 这是一个成功地让社区参与构建您的软件的典范,它表明了这一点。 您的团队(控制台/WSL/msft-linux)对我安装 Windows(非 nix)的业务负有个人责任。 保持出色的工作🥇
@thinkjrs非常感谢您的客气话。
我们最诚挚地感谢您和我们社区中为终端、Cascadia 代码、WSL 等运行和测试/记录错误/提交问题、想法和拉取请求的每个人。您的反馈会直接影响我们,因为我们会优先考虑工作和计划和设计特点。
当我们说我们为社区并与社区一起构建这些功能时,我们并不是在开玩笑 😜
流程是什么? WSL 中是否有任何功能鼠标? 即tmux
面板切换,单击以更改weechat
和irssi
频道/服务器, (n)vim
点击, aptitude
点击, htop
点击等。
流程是什么? WSL 中是否有任何功能鼠标? 即
tmux
面板切换,单击以更改weechat
和irssi
频道/服务器,(n)vim
点击,aptitude
点击,htop
点击等。
@dmxt目前我使用 wsltty,
流程是什么? WSL 中是否有任何功能鼠标? 即
tmux
面板切换,单击以更改weechat
和irssi
频道/服务器,(n)vim
点击,aptitude
点击,htop
点击等。@dmxt目前我使用 wsltty,
我同意您的评论,在过去几年中尝试了所有公知的 Windows 终端仿真器之后,就目前而言,在撰写本文时,wsltty 是最好的。 他们的官方 repo 也很棒,他们为我提供了快速入门的精彩指南。 你不能用机智要求更好,它在各种不同的工作流程和工具中都得到了全面的鼠标支持,没有任何问题。
我注意到 I/O 中的轻微延迟,我认为这是 WSL1 系统的瓶颈。 我在裸机 Linux 上,鼠标输入有 0 毫秒的延迟。
请看一下ConEmu是怎么解决的
是否有任何路线图或时间表希望具体何时实施? 似乎是一个非常重要的功能要发布。 令我感到惊讶的是,v1.0 在没有解决这个问题的情况下就发布了。 我猜现在版本控制没有任何意义。
据我所知,支持最新 Microsoft Store 版本的 Windows 终端鼠标输入中的
@fat0troll据我所知,事实并非如此。 即使在带有set mouse=a
vim 中,鼠标输入也适用于旧主机,但不适用于 Windows Terminal 1.0.1401.0。
set nocompatible
syntax on
set number
set mouse=a
set backspace=indent,eol,start
使用该 vim 配置,我可以在 vim 的窗口内单击,光标将移动到我单击的位置。 1.0.1401.0,Windows 版本 18368.836(如果它对此有任何影响)。
@kvnxiao我猜你正在使用 OpenSSH_For_Windows_7.7。 其中有一个错误(在 8.x 中已解决)阻止它在鼠标模式下工作。
我们为所有想要接收鼠标输入的 VT 应用程序明确地实现了这一点。
我猜现在版本控制没有任何意义。
没有必要不友善。
关于vim,我尝试使用为windows构建的neovim作为windows可执行文件。 如果其他人说鼠标支持确实适用于 vim(例如,通过 ssh/wsl 等),那么我并不怀疑您,但这表明“完全”支持尚不存在,这提出了更具体的问题题:
与 conhost 目前的能力相比,“完整”鼠标支持的路线图中还剩下什么?
我说的是想要通过 WT 启动支持鼠标输入(并在 conhost 中工作)的基于终端的通用应用程序。 例如,运行几个直接构建为 Windows 可执行文件的基于文本的/终端用户界面应用程序。 这些在双击运行时确实可以正常工作,这需要使用 conhost,但是当通过 Windows 终端运行时,它们最终只用鼠标选择显示的文本。
@niklaskorz当像我这样的人有与此主题有关的相关问题时,对上述评论进行投票和
你完全正确。 您已正确识别为用于从任何终端接收鼠标事件的 Win32 控制台应用程序的工作项,计划用于“终端 1.x”(里程碑),这表明我们希望在现在和 2.0 之间解决它。 我没有比这更细粒度的估计。
感谢您的澄清! 有点遗憾这个工作项无法参与 1.0 的竞争,但我很期待它什么时候可以竞争,希望不会等太久😀。
FIWW,如果您不知道,新的 Powershell Out-ConsoleGridView
(https://github.com/PowerShell/GraphicalTools) 是一个杀手级测试用例。 请参阅此处与鼠标相关的跟踪错误: https :
它建立在Terminal.Gui
(https://github.com/tig/gui.cs) 之上。
此外,我们刚刚为Terminal.Gui
构建了一个新的示例应用程序,你们应该能够使用它来测试鼠标支持,因为它在 WT 中出现。
真的很期待!
有什么办法可以帮助我解决这个问题吗? 对于使用 Terminal.Gui (https://github.com/tig/gui.cs) 构建的 GUI 控制台应用程序来说,这真是令人失望。
@kvnxiao我猜你正在使用 OpenSSH_For_Windows_7.7。 其中有一个错误(在 8.x 中已解决)阻止它在鼠标模式下工作。
我们为所有想要接收鼠标输入的 VT 应用程序明确地实现了这一点。
我猜现在版本控制没有任何意义。
没有必要不友善。
如何将内置 openssh 更新到最新版本?
@kvnxiao我猜你正在使用 OpenSSH_For_Windows_7.7。 其中有一个错误(在 8.x 中已解决)阻止它在鼠标模式下工作。
我们为所有想要接收鼠标输入的 VT 应用程序明确地实现了这一点。我猜现在版本控制没有任何意义。
没有必要不友善。
如何将内置 openssh 更新到最新版本?
我猜你正在寻找这篇博客文章中描述的东西(从巧克力中安装 Openssh): https :
我猜你正在使用 OpenSSH_For_Windows_7.7。 其中有一个错误(在 8.x 中已解决)阻止它在鼠标模式下工作。
我们为所有想要接收鼠标输入的 VT 应用程序明确地实现了这一点。
@DHowett从这个上下文来看,听起来使用OpenSSH_for_Windows_8.0p1, LibreSSL 2.6.5
应该可以工作?
我正在使用终端预览版本通过 SSH 连接到启用了 tmux 鼠标模式的 Ubuntu 机器,但我的鼠标输入似乎仍然只控制终端本身。
我也尝试将服务器升级到 OpenSSH 8.0,但这也无济于事。
这个问题是否仍然阻止这种事情的工作?
啊,8.x 中的x
可能是 1。我不知道他们发布了 8.0 版本。
啊,8.x 中的 x 可能是 1。我不知道他们发布了 8.0 版本。
我会试一试。
有用! 太棒了,谢谢!
我开始了解这个问题。
遗憾的是,MS 还没有在 Windows 终端上实现 Win32 API 的鼠标输入功能。
(仅支持 VT 转义序列。)
我试图在我的应用程序中替换 ReadConsoleInputW 和 PeekConsoleInputW
在 Windows 终端上使用鼠标。
首先,我运行以下代码。
SetConsoleMode(hin, ENABLE_VIRTUAL_TERMINAL_INPUT);
SetConsoleMode(hout, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
char *vt_mouse_input_enable_cmd = "\x1b[?1000h\x1b[?1003h\x1b[?1006h";
DWORD written;
WriteConsoleA(hout, vt_mouse_input_enable_cmd, strlen(vt_mouse_input_enable_cmd), &written, NULL);
然后,鼠标输入可以作为 VT 转义序列 (sgr-1006) 接收(例如\x1b[<0;10;20M
)。
但是,另一个问题出现了。
某些键输入(例如箭头键)也作为 VT 转义序列接收(例如\x1b[A
)。
我试图将这些不需要的 VT 转义序列转换为 win32 API 的关键事件,
但这是不完整的。
(虚拟键码和虚拟扫描码随便变零等)
我的代码在这里。
https://gist.github.com/Hamayama/6add968870269f2426716fad79724b31
( PDC_read_console_input_w 和 PDC_peek_console_input_w 是替代函数。)
我想要一种方法来禁用除鼠标输入之外的 VT 转义序列。
例如
char *vt_key_input_disable_cmd = "\x1b[?9XXXl";
DWORD written;
WriteConsoleA(hout, vt_key_input_disable_cmd, strlen(vt_key_input_disable_cmd), &written, NULL);
或者
SetConsoleMode(hin, ENABLE_VIRTUAL_TERMINAL_MOUSE_INPUT_ONLY);
但是,这对未来来说可能是一个错误的想法......
我发现src/terminal/parser/InputStateMachineEngine.cpp: 391
没有跟踪鼠标移动(将 SGR VT 序列转换为INPUT_RECORD
s)。
换句话说,终端为 ConPTY 发送 VT 序列,但 ConPTY 只监视鼠标按钮的状态。 鼠标坐标的变化被忽略:
src/terminal/parser/InputStateMachineEngine.cpp: 391
:
success = _UpdateSGRMouseButtonState(id, firstParameter, buttonState, eventFlags);
success = success && _WriteMouseEvent(parameters.at(1), parameters.at(2), buttonState, modifierState, eventFlags);
根据当前支持鼠标输入的状态,可以使用以下选项。
您可以添加坐标跟踪,鼠标移动将在经典控制台应用程序中开始工作。
src/terminal/parser/InputStateMachineEngine.hpp: 172
:
+ size_t _mouseColumn = 0;
+ size_t _mouseLine = 0;
src/terminal/parser/InputStateMachineEngine.cpp: 391
:
- success = success && _WriteMouseEvent(parameters.at(1), parameters.at(2), buttonState, modifierState, eventFlags);
+ auto mouseColumn = parameters.at(1).value_or(0);
+ auto mouseLine = parameters.at(2).value_or(0);
+ auto isMoved = mouseColumn! = _mouseColumn || mouseLine! = _mouseLine;
+ if (isMoved)
+ {
+ _mouseColumn = mouseColumn;
+ _mouseLine = mouseLine;
+ }
+ success = (success || isMoved) && _WriteMouseEvent(mouseColumn, mouseLine, buttonState, modifierState, eventFlags);
注意:在启动经典控制台应用程序之前,您需要以 SGR 格式请求鼠标跟踪:
PS C:\Users> [char]0x1b + "[?1003;1004;1006h"
C:\Users> echo
Ctrl+[ [?1003;1004;1006h
1003
- ANY_EVENT_MOUSE_MODE1004
- 任何不支持的模式(例如1001
或9999
)通过 ConPTY 将序列转发到终端本身1006
- SGR_EXTENDED_MODE因此,终端将开始向 ConpTY 发送鼠标事件,ConpTY 将开始为经典控制台应用程序生成INPUT_RECORD
s。
接得好。 我们必须确保在我们真正采取行动支持这个时解决这个问题 :smile:
最有用的评论
仅供可能一直在研究此问题的任何社区成员(/cc @SamuelEnglard!),我们已正式预订开发团队的工作来执行此操作。 我希望我们不会踩到你的脚趾!