Как реализовать правильную поддержку мыши в записи терминала / terminfo?

Я реализовал эмулятор терминала и соответствующую запись в terminfo, которая позволяет мне запускать программы ncurses, такие как emacs, mc (midnight commander) или < em> tig (браузер git). Я хочу добавить поддержку мыши в терминал, в первую очередь, чтобы поместить курсор в emacs, щелкнув окно. После долгих поисков в Google и некоторой помощи по stackoverflow я узнал о необходимых полях terminfo (в первую очередь kmous) и последовательностях управления (например, \E[?1000h) и «key» (\E[M...) и реализовал события кнопок мыши в моем терминале. Я написал небольшую программу ncurses, которая выглядит примерно так:

initscr ();
clear ();
noecho ();
cbreak ();

keypad (stdscr, TRUE);

mousemask (ALL_MOUSE_EVENT, NULL);

if (has_mouse ())
{
  while (1)
  {
    switch (getch ())
    {
    case KEY_MOUSE:
      if (getmouse (&event) == OK)
      {
        printf ("mouse event 0x%x at %i,%i\n", event.bstate, event.x, event.y);

Эта программа отлично работает на xterm и моем терминале, поэтому и мой терминал, и его запись terminfo не могут быть полностью неправильными.

Однако mc, похоже, не распознает поддержку мыши в моем терминале, даже не выдает никакой \E[?1000h последовательности для ее активации и, следовательно, совершенно сбит с толку событиями кнопки мыши, которые мой терминал отправляет (даже без \E[?1000hактивации).

Что мне не хватает?


person tesche    schedule 20.11.2013    source источник
comment
Разделы Отслеживание мыши в console_codes(4) и ctlseqs от xterm (в дистрибутивах Linux обычно есть копия по адресу /usr/share/doc/xterm/) могут помочь.   -  person ninjalj    schedule 21.11.2013
comment
Я уже нашел половину этой информации через Google, хотя приятно знать, что она у меня тоже есть локально в моей системе. Так что спасибо за это. Но тем временем я понял (или мне так кажется), что моя проблема заключается не в знании управляющих последовательностей или реализации терминала, а в том, что запись terminfo, которую я использую для этого терминала, еще не рекламирует поддержку мыши должным образом. Итак, я переписал свой вопрос.   -  person tesche    schedule 21.11.2013
comment
Это начинает становиться все более странным: я написал тестовую программу на C, используя has_mouse(), getch() == KEY_MOUSE и getmouse() из ncurses. Он отлично работает как под xterm, так и под моим терминалом. Тем не менее, mc и aptitude правильно используют мышь только под xterm, но не в моем терминале. Что мне не хватает?   -  person tesche    schedule 21.11.2013
comment
Я снова перешел к описанию проблемы.   -  person tesche    schedule 26.11.2013
comment
Обратите внимание, что xterm использует CSI ?1000h (h, а не m) для включения отслеживания мыши. mc имеет следующее жестко запрограммировано: CSI?1001s (сохранить старое отслеживание выделения мыши) _6 _ / _ 7_ (включить отслеживание мыши) CSI?1015h (включить расширенный отчет о координатах мыши urxvt). (Где CSI - это 7-битный CSI, т.е. ESC [)   -  person ninjalj    schedule 26.11.2013
comment
Правильно - я исправил «м» - «ч», чтобы другие люди, читающие это, не запутались. Но у меня все это время было правильно в моем терминале.   -  person tesche    schedule 03.12.2013
comment
Тем временем я также узнал, что в mc жестко запрограммировано обнаружение мыши: он смотрит на содержимое переменной окружения TERM, а не на функцию ncurses has_mouse(). Если он не запущен в xterm, он должен быть вызван с mc -x. Мой терминал все время был исправен.   -  person tesche    schedule 03.12.2013
comment
mc - особый случай, поскольку он игнорирует описание терминала и (см. это) обеспечивает поддержку мыши, в отличие от сленга ...   -  person Thomas Dickey    schedule 27.12.2018


Ответы (1)


Кто-то недавно указал на эту проблему (хотя вопрос не упоминался):

20181124

    + modify the initialization checks for mouse so that the xterm+sm+1006
      block will work with terminal descriptions not mentioning xterm
      (report by Tomas Janousek).

Проблема заключалась в том, что код использовал возможность kmous, если TERM имел «xterm», а в противном случае по умолчанию использовался бы исходный протокол мыши xterm (который не имел возможности «любое событие»). Это, вероятно, долгое время игнорировалось из-за инерции (люди, использующие описания терминалов "xterm" с другими терминалами).

справочная страница ncurses действительно сообщает, что предназначено:

Поскольку нет стандартных ответов терминала, которые могли бы служить для идентификации терминалов, поддерживающих протокол мыши xterm, ncurses предполагает, что если ваша переменная среды $TERM содержит "xterm" или kmous определяется в описании терминала, тогда терминал может отправлять события мыши.

person Thomas Dickey    schedule 27.12.2018