Terminal: [Conpty] Добавить поддержку ввода с помощью мыши

Созданный на 18 февр. 2019  ·  48Комментарии  ·  Источник: microsoft/terminal

На: Microsoft Windows [Version 10.0.17763.134]

Я реализовал conpty в своем эмуляторе терминала:
https://github.com/wez/wezterm

Я могу успешно запустить target\debug\wezterm.exe для создания консольных приложений, таких как cmd.exe powershell.exe и bash .

Проблема, с которой я сталкиваюсь, заключается в том, что когда я запускаю bash, либо косвенно через cmd.exe или напрямую через средство запуска bash, conpty, похоже, проглатывает escape-последовательности, сообщаемые мышью; Я не вижу, чтобы они были получены парсером моего терминала, и поэтому vim не имеет эффективной поддержки мыши, несмотря на то, что он настроен с помощью set mouse=a .

Запуск той же установки WSL через wsl-terminal действительно поддерживает рабочую мышь, а wezterm был моим ежедневным драйвером в Linux около года с поддержкой рабочей мыши, поэтому мы можем исключить очевидную неправильную конфигурацию с помощью vim и парсер в wezterm .

Я также пробовал echo -e "\e[?1000h" чтобы вручную включить создание отчетов с помощью мыши из оболочки; обычно (в linux и через wsl-terminal) это вызывает щелчки в терминале для отправки данных в оболочку (которая отображается как ввод мусора), но при запуске моего терминала с conpty они также где-то поглощаются.

Требуется ли что-то особенное, чтобы приложения, которые я запускаю на моем компьютере, могли работать с мышью?

Если вы хотите дважды проверить ключевую часть кода, соответствующий файл:
https://github.com/wez/wezterm/blob/master/src/winpty.rs
Поток состоит в том, чтобы CreatePipe пара каналов, CreatePseudoConsole , а затем передать это порожденному дочернему элементу через атрибуты threadproc, как это делают также образцы в документах MSDN и этом репозитории.

Area-Interop Issue-Feature Product-Conpty

Самый полезный комментарий

Просто к сведению всех членов сообщества, которые, возможно, интересовались этим (/ cc @SamuelEnglard!), Мы официально наняли команду разработчиков для этого. Надеюсь, мы не наступаем вам на цыпочки!

Все 48 Комментарий

Привет @wez ,
К сожалению, ConPTY не передает отчеты о мышах (или, из размещенного приложения, _запросы на отчеты о мышах_). У нас есть элемент невыполненной работы, отслеживающий это, и мы надеемся, что скоро доберемся до него.

К сожалению, мы не можем просто передавать закодированные события мыши: поскольку ConPTY может размещать стандартные консольные приложения Windows, подобные которым ожидают прихода MOUSE_EVENT s через ReadConsoleInput , мы нужно сделать перевод.

Во всем остальном, однако, похоже, что вы правильно настраиваете псевдоконсоль.


Отслеживание: MSFT: 20469462

@ DHowett-MSFT спасибо за ответ!
Немного обидно, что сообщения мыши еще нет, но все же хорошо, что остальная часть pty теперь возможна!

Мне нечего добавить, кроме того, что я действительно хочу поддерживать мышь с ConPTY. Теперь, когда alacritty имеет поддержку ConPTY с использованием alacritty + ssh + tmux, это невероятный Linux-терминал в Windows, теперь отсутствует только поддержка мыши.

Я активно использую midnight commander в своей оболочке Ubuntu bash, где он отлично работает. К сожалению, вкладка оболочки Ubuntu в Терминале Windows 0.3.2171.0, похоже, не отправляет ЛЮБЫЕ события мыши через приложение mc, что чрезвычайно затрудняет мне использование. Я собирался опубликовать ошибку, но я это дублировал.

Для меня отправка событий мыши имеет первостепенное значение для хорошего опыта работы с vim и tmux.

Я просто отказываюсь от поддержки этого здесь, плюс немного контекста. За последний месяц я прекратил двойную загрузку и начал использовать «быстрое» кольцо для инсайдерской сборки Windows 10 в качестве основного личного компьютера. На этом у меня отлично работает wsl2, отлично работает x410, отлично работает терминал Microsoft, отлично работает код визуальной студии wsl2, а взаимодействие explorer.exe отлично работает.

Этот билет ввода с помощью мыши - практически единственное, что мешает мне назвать терминал wsl2 / microsoft разумной заменой отдельного раздела / блока разработки. Поскольку некоторые места здесь имеют открытый исходный код, есть ли какие-нибудь указатели на то, как увидеть вводимые данные устройства мыши откуда-то из /dev или я должен просто держаться?

Спасибо за все это! В остальном мне очень нравится :)

Еще один голос, чтобы сказать / попросить, чтобы поддержка мыши была такой приятной, и ее очень не хватает всем, кто использует tmux, хотя можно обойтись и без нее.

Пожалуйста, включите поддержку мыши 😄

@ DHowett-MSFT, извините за ворчание, есть ли планы исправить это в ближайшее время? Видеть ярлыки / приоритеты, назначенные по другим вопросам, но это не одна из них, поэтому просто проверяю. Спасибо.

@damnskippy Приоритет назначается вещам, которые нам нужно исправить на встроенном хосте консоли Windows (из-за внутренних сроков устранения ошибок). Это _ огромная_ функция (и требует соответствующей масштабируемой спецификации), и хотя мы знаем, что она нужна нам для версии 1.0, сегодня активно над ней не работаем.

Если бы мы могли просто «исправить» это как ошибку, мне бы это понравилось, но для этого нужно гораздо больше, чем исправление.

Спасибо за обновления. Ваша работа ценится.

Мне нравится то, что вы здесь делаете, мне нравится, но до тех пор, пока мы не получим поддержку мыши, мы должны дополнить этот терминал другим терминалом, что в некоторой степени противоречит цели этого терминала.

Без него Midnight Commander - кошмар.

Ввод с помощью мыши в целом может быть полезен, например, если кто-то из сообщества создаст надстройку и профиль DosBox, которые можно будет запускать в Терминале Windows.

Я активно пользуюсь vim; даже мне не хватает поддержки мыши 😢

Я только что прочитал обновление блога @ cinnamon-msft, кажется, команда стремится к версии 1.0 к концу этого года ? Значит ли это, что к концу года мы получим поддержку мыши? Если да, то активно ли над этим сейчас работают?

Значит ли это, что к концу года мы получим поддержку мыши?

Может быть, но никаких жестких коммитов. Оценить, сколько времени потребуется для создания программного обеспечения, примерно так же сложно, как доказать, что P == NP. Я бы даже сказал, что без этого терминал не был бы готов к версии 1.0.

Если да, то активно ли над этим сейчас работают?

Не сейчас. Никто не назначается для выполнения задачи, и обычно, когда кто-то в команде откусывает задачу, он назначает себя сам.

Из любопытства, все ли для этого здесь нужно? Может ли амбициозный (читай: сумасшедший) разработчик взяться за дело и устроить пиар?

Конечно, любой амбициозный человек может попробовать это самостоятельно. С чего начать?

Во-первых, давайте наметим некоторые рамки. С вводом с помощью мыши нужно проделать много работы, поэтому было бы лучше начать с малого и работать по частям, чтобы получить полное решение. Я думаю, что первое, с чем мы должны работать, - это простые последовательности движений мыши вверх / вниз в

Начните с просмотра InputStateMachineEngine.cpp . InputStateMachineEngine отвечает за синтаксический анализ ввода, отправленного через conpty, и переводит его в INPUT_RECORD s. Предприимчивый молодой разработчик захотел бы изменить этот класс, чтобы иметь возможность также анализировать эти последовательности мыши и переводить их в INPUT_RECORD s. Как только у вас будет INPUT_RECORD s, вызовите InteractDispatch::WriteInput . Это добавит эти INPUT_RECORD во входной буфер. Как только они окажутся во входном буфере, они будут доставлены в подключенное клиентское консольное приложение в обычном режиме.

Вещи, на которые я буду обращать внимание:

  • conhost может вообще не вставлять MouseEvents в буфер, если мы не находимся в режиме ввода с помощью мыши. Если это так, то мы должны просто игнорировать эти последовательности.
  • Приложения, которым требуется ввод мыши от VT, получат не поток INPUT_RECORD s, а поток символов. В какой-то момент в conhost мы пытаемся преобразовать эти INPUT_RECORD s мыши в поток символов, если присоединенное приложение находится в режиме мыши VT. Если мы сделаем это преобразование _до_ того, как события мыши находятся в буфере, то выполнение вышеуказанного может не сработать для приложений VT (читайте: wsl ). Если это так, то нам нужно убедиться, что перевод от mouse INPUT_RECORD к событиям мыши с кодировкой VT выполняется вручную для событий мыши, сгенерированных InputStateMachineEngine .

    • Если посмотреть на это подробнее, это действительно похоже на случай. К сожалению, мы переводим ввод мыши только для событий, которые были инициированы окном. Смотрите этот код:

      https://github.com/microsoft/terminal/blob/2c8b3243dca0c48dd05ecd7b420a7a03b3e19c93/src/interactivity/win32/windowio.cpp#L113 -L129

      terminalMouseInput.HandleMouse будет синтезировать последовательности VT для клиентского приложения, но, к сожалению, он вызывается только из процесса окна. Итак, нам нужно каким-то образом предоставить способ вызова InputStateMachineEngine (с помощью нового метода на InteractDispatch ), и если этот метод не сработает, то сгенерировать соответствующий INPUT_RECORD s.

    • Технически, кто-то может вместо этого переместить вызов terminalMouseInput.HandleMouse на чтение InputBuffer и заставить его попытаться перевести INPUT_RECORD s прямо по мере чтения, но это может быть сложнее.

Что за дело с этим вопросом? Мышь отлично работает в старой консоли Windows. Означает ли это, что я должен придерживаться консоли, пока это не будет исправлено?

Если вам нужна поддержка мыши VT, да.

Просто к сведению всех членов сообщества, которые, возможно, интересовались этим (/ cc @SamuelEnglard!), Мы официально наняли команду разработчиков для этого. Надеюсь, мы не наступаем вам на цыпочки!

Я думал об этом, но не смог выделить свое собственное время так прекрасно, лол!

Я просто играл с VSCode с расширениями для удаленной разработки и обнаружил, что встроенный в него терминал действительно поддерживает режим мыши в tmux! Выбор панели, выбор окна, изменение размера панели и колесо прокрутки поддерживают всю работу. Я новичок в этих проектах, поэтому я не знаю, является ли терминал частью VS Codium с открытым исходным кодом и может ли он использоваться в качестве отправной точки ... извините, если это не очень полезная информация

Просто к сведению всех членов сообщества, которые, возможно, интересовались этим (/ cc @SamuelEnglard!), Мы официально наняли команду разработчиков для этого. Надеюсь, мы не наступаем вам на цыпочки!

@ DHowett-MSFT @ zadjii-msft @bitcrazed Ваше общение по этому вопросу здесь и в других местах было фантастическим; это пример успешного вовлечения сообщества в создание вашего программного обеспечения, и это видно. Ваша команда (консоль / WSL / msft-linux) несет личную ответственность за то, что у меня вообще есть установки Windows (не nix). Продолжайте в том же духе

@thinkjrs Большое спасибо за добрые слова.

И наша искренняя благодарность вам и всем в нашем сообществе, кто запускает и тестирует / регистрирует ошибки / отправляет запросы, идеи и pull-запросы для Терминала, кода Cascadia, WSL и т. Д. Ваши отзывы напрямую влияют на нас, поскольку мы расставляем приоритеты в работе и планируем и конструктивные особенности.

Мы не шутили, когда говорили, что создаем эти функции для нашего сообщества и вместе с ним 😜

Каков процесс? Есть ли в WSL функциональные мышки? Т.е. tmux переключение панели, нажатие для изменения канала / сервера в weechat & irssi , (n)vim кликов, aptitude click, htop нажатие и т. д.

Каков процесс? Есть ли в WSL функциональные мышки? Т.е. tmux переключение панели, нажатие для изменения канала / сервера в weechat & irssi , (n)vim кликов, aptitude click, htop нажатие и т. д.

@dmxt В настоящее время я использую wsltty, который оказался для меня наиболее совместимым из всех вариантов терминала. Я с нетерпением жду перехода на Терминал, когда появятся некоторые из этих функций.

Каков процесс? Есть ли в WSL функциональные мышки? Т.е. tmux переключение панели, нажатие для изменения канала / сервера в weechat & irssi , (n)vim кликов, aptitude click, htop нажатие и т. д.

@dmxt В настоящее время я использую wsltty, который оказался для меня наиболее совместимым из всех вариантов терминала. Я с нетерпением жду перехода на Терминал, когда появятся некоторые из этих функций.

Я согласен с вашим комментарием, опробовав все известные общественности эмуляторы терминала для Windows за последние несколько лет, на момент написания статьи wsltty - лучший из существующих. Их официальное репо тоже отличное, у них есть прекрасное руководство, чтобы я мог быстро начать работу. Вы не могли и мечтать о лучшем с остроумием, он получил полную поддержку мыши без сбоев в различных рабочих процессах и инструментах.

Я заметил небольшую задержку ввода-вывода и считаю, что это узкое место системы WSL1. Я использую Linux без операционной системы, и при вводе с помощью мыши задержка составляет 0 мс.

@dmxt @offero Я добился успеха с XShell (настоящая командная строка из экспериментальных функций или ssh в WSL) - есть поддержка мыши и т. д., просто FYI. Также приложения, которым остро нужна поддержка мыши, - это Midnight Commander и микроредактор.

Посмотрите, как это решается в ConEmu

Есть ли план или график, когда именно это будет реализовано? Кажется, это очень важная функция для выпуска. Меня несколько удивляет, что v1.0 выпускается без решения этой проблемы. Думаю, в настоящее время управление версиями ничего не значит.

@kvnxiao в последней версии Microsoft Store для ввода мыши терминала Windows поддерживается (по крайней мере, в Vim), насколько я могу судить

@ fat0troll Насколько я могу судить, это точно не так. Даже в vim с set mouse=a ввод с помощью мыши работает на старом conhost, но не на 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, я попытался использовать neovim, созданный для Windows, в качестве исполняемого файла Windows. Если другие говорят, что поддержка мыши работает для vim (например, через ssh / wsl и т. Д.), То я не сомневаюсь в вас, но это показывает, что «полной» поддержки пока не существует, что представляет собой более конкретную вопрос:

Что будет оставлено в дорожной карте для «полной» поддержки мыши по сравнению с тем, на что в настоящее время способен conhost?

Я говорю о том, что хочу запускать общие терминальные приложения, которые поддерживают ввод с помощью мыши (и работают в conhost) через WT. Например, запуск нескольких текстовых / терминальных приложений с пользовательским интерфейсом, созданных непосредственно как исполняемый файл Windows. Они отлично работают при двойном щелчке мыши для запуска, которые прибегают к использованию conhost, но при запуске через терминал Windows они заканчивают тем, что отображаемый текст выбирается только мышью.

@niklaskorz Какой смысл голосовать за и против вышеупомянутых комментариев, когда у таких людей, как я, есть соответствующие вопросы, относящиеся к этой теме, которые могут или не могут все еще оставаться нерешенными?

Вы совершенно правы. Этот рабочий элемент, который вы правильно определили как предназначенный для консольных приложений Win32, получающих события мыши от любого терминала, предназначен для «терминала 1.x» (этап), что означает, что мы хотим заняться этим в период с настоящего момента до версии 2.0. У меня нет более точной оценки, чем эта.

Спасибо за разъяснения! Немного грустно, что этот рабочий элемент не смог побороться за 1.0, но я с нетерпением жду, когда это произойдет, и, надеюсь, это не будет долгим ожиданием 😀.

FIWW, если вы не знали об этом, новый Powershell Out-ConsoleGridView (https://github.com/PowerShell/GraphicalTools) - отличный тест для этого. См. Здесь ошибку отслеживания, связанную с мышью: https://github.com/PowerShell/GraphicalTools/issues/95

Он построен на основе Terminal.Gui (https://github.com/tig/gui.cs).

Кроме того, мы только что создали новый пример приложения для Terminal.Gui которое вы все должны использовать для тестирования поддержки мыши, когда она появляется в WT.

Действительно с нетерпением жду этого!

Могу ли я как-нибудь помочь решить эту проблему? Это настоящий облом для консольных приложений с графическим интерфейсом, созданных с помощью Terminal.Gui (https://github.com/tig/gui.cs).

@kvnxiao Я предполагаю, что вы используете OpenSSH_For_Windows_7.7. В нем есть ошибка (исправленная в 8.x), которая не позволяет ему работать в режиме мыши.

Мы явно реализовали это для всех приложений VT, которые хотят получать ввод от мыши.

Думаю, в настоящее время управление версиями ничего не значит.

Не нужно быть недобрым.

Как я могу обновить встроенный openssh до последней версии?

@kvnxiao Я предполагаю, что вы используете OpenSSH_For_Windows_7.7. В нем есть ошибка (исправленная в 8.x), которая не позволяет ему работать в режиме мыши.
Мы явно реализовали это для всех приложений VT, которые хотят получать ввод от мыши.

Думаю, в настоящее время управление версиями ничего не значит.

Не нужно быть недобрым.

Как я могу обновить встроенный openssh до последней версии?

Думаю, вы ищете что-то, что описано в этом сообщении в блоге (установка Openssh из шоколадного): https://blog.frankfu.com.au/2019/03/21/moving-from-windows-1809s-openssh-to- openssh-портативный /

Я предполагаю, что вы используете OpenSSH_For_Windows_7.7. В нем есть ошибка (исправленная в 8.x), которая не позволяет ему работать в режиме мыши.

Мы явно реализовали это для всех приложений VT, которые хотят получать ввод от мыши.

@DHowett из этого контекста, похоже, что использование OpenSSH_for_Windows_8.0p1, LibreSSL 2.6.5 должно работать?

Я использую предварительную сборку терминала для SSH на машине Ubuntu с включенным режимом мыши tmux, но мои вводы мыши по-прежнему, похоже, управляют только самим терминалом.

Я также пробовал обновить сервер до OpenSSH 8.0, но это тоже не помогло.

Эта проблема все еще блокирует работу такого рода вещей?

Ах, x в 8.x может быть 1. Я не знал, что они выпустили сборку 8.0.

Ах, x в 8.x может быть 1. Я не знал, что они выпустили сборку 8.0.

Я попробую.

Оно работает! Потрясающе, спасибо!

Я начал разбираться в этом вопросе.

К сожалению, MS еще не реализует функцию ввода с помощью мыши Win32 API в Windows Terminal.
(Поддерживается только escape-последовательность 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);

Затем ввод от мыши может быть получен как escape-последовательность VT (sgr-1006) (например, \x1b[<0;10;20M ).

Но возникла другая проблема.

Некоторые вводимые с помощью клавиш (например, клавиши со стрелками) также принимаются как escape-последовательность VT (например, \x1b[A ).

Я попытался преобразовать эти нежелательные escape-последовательности VT в ключевое событие Win32 API,
но это неполно.
(виртуальный ключевой код и виртуальный скан-код случайно становятся нулевыми и т. д.)

Мой код здесь.
https://gist.github.com/Hamayama/6add968870269f2426716fad79724b31
(PDC_read_console_input_w и PDC_peek_console_input_w - альтернативные функции.)

Мне нужен метод отключения escape-последовательности 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 (перевод VT-последовательностей SGR в INPUT_RECORD s).

Другими словами, Терминал отправляет VT-последовательности для ConPTY, а 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:

Windows PowerShell

PS C:\Users> [char]0x1b + "[?1003;1004;1006h"

Командная строка

C:\Users> echo Ctrl + [ [?1003;1004;1006h

Параметры
  • 1003 - ANY_EVENT_MOUSE_MODE
  • 1004 - любой неподдерживаемый режим (например, 1001 или 9999 ) для пересылки последовательности через ConPTY на сам Терминал
  • 1006 - SGR_EXTENDED_MODE

в результате Терминал начнет отправлять события мыши в ConpTY, который начнет генерировать INPUT_RECORD s для классического консольного приложения.

Хороший улов. Нам нужно будет убедиться, что мы исправим это, когда мы действительно перейдем к поддержке этого: smile:

Была ли эта страница полезной?
0 / 5 - 0 рейтинги